{"record":{"id":"f7bb7075c49c2fdb","repo":"open-mmlab/mmdetection","slug":"the-size-of-the-2d-attn-mask-is-not-correct","errorCode":null,"errorMessage":"The size of the 2D attn_mask is not correct.","messagePattern":"The size of the 2D attn_mask is not correct\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"mmdet/models/layers/transformer/utils.py","lineNumber":570,"sourceCode":"        v = value\n\n        if attn_mask is not None:\n            assert attn_mask.dtype == torch.float32 or \\\n                   attn_mask.dtype == torch.float64 or \\\n                   attn_mask.dtype == torch.float16 or \\\n                   attn_mask.dtype == torch.uint8 or \\\n                   attn_mask.dtype == torch.bool, \\\n                   'Only float, byte, and bool types are supported for \\\n                    attn_mask'\n\n            if attn_mask.dtype == torch.uint8:\n                warnings.warn('Byte tensor for attn_mask is deprecated.\\\n                     Use bool tensor instead.')\n                attn_mask = attn_mask.to(torch.bool)\n            if attn_mask.dim() == 2:\n                attn_mask = attn_mask.unsqueeze(0)\n                if list(attn_mask.size()) != [1, query.size(1), key.size(1)]:\n                    raise RuntimeError(\n                        'The size of the 2D attn_mask is not correct.')\n            elif attn_mask.dim() == 3:\n                if list(attn_mask.size()) != [\n                        bs * self.num_heads,\n                        query.size(1),\n                        key.size(1)\n                ]:\n                    raise RuntimeError(\n                        'The size of the 3D attn_mask is not correct.')\n            else:\n                raise RuntimeError(\n                    \"attn_mask's dimension {} is not supported\".format(\n                        attn_mask.dim()))\n        # attn_mask's dim is 3 now.\n\n        if key_padding_mask is not None and key_padding_mask.dtype == int:\n            key_padding_mask = key_padding_mask.to(torch.bool)\n","sourceCodeStart":552,"sourceCodeEnd":588,"githubUrl":"https://github.com/open-mmlab/mmdetection/blob/cfd5d3a985b0249de009b67d04f37263e11cdf3d/mmdet/models/layers/transformer/utils.py#L552-L588","documentation":"In MultiheadAttention.forward_attn, a 2D attn_mask is unsqueezed to [1, len_q, len_k]; if its shape does not exactly equal [1, query.size(1), key.size(1)] a RuntimeError is raised because the mask cannot be broadcast by the underlying attention math.","triggerScenarios":"Passing attn_mask of shape [len_k, len_k] or [len_q+1, len_k] where query and key have different sequence lengths (cross-attention with text/encoder memory of different length).","commonSituations":"Using square masks from self-attention code in cross-attention (query len != key len); padding/truncating sequences inconsistently between queries and keys; language-guided detection where text tokens count mismatches.","solutions":["Build the mask with shape [num_queries, num_keys] i.e. [query.size(1), key.size(1)]","Print query.shape, key.shape and attn_mask.shape before the call and align them","For per-head masks supply a 3D mask of shape [bs*num_heads, len_q, len_k]"],"exampleFix":"# before\nattn_mask = torch.zeros(k, k)  # used in cross-attn with q_len != k_len\n# after\nattn_mask = torch.zeros(q_len, k_len)","handlingStrategy":"validation","validationCode":"assert attn_mask.shape == (query.size(1), key.size(1)), attn_mask.shape","typeGuard":"def valid_2d_mask(m, q, k): return m.dim() == 2 and m.shape == (q, k)","tryCatchPattern":null,"preventionTips":["Always construct masks from actual query/key lengths at call time","Add shape asserts in debugging hooks for cross-attention"],"tags":["mmdet","attention","attn-mask","shape-mismatch"],"backgroundTag":"tensor-shape-mismatch","analyzedSha":"cfd5d3a985b0249de009b67d04f37263e11cdf3d","analyzedAt":"2026-08-27T20:54:20.183Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}