{"record":{"id":"b506d86f08d0ca1a","repo":"open-mmlab/mmdetection","slug":"the-size-of-the-3d-attn-mask-is-not-correct","errorCode":null,"errorMessage":"The size of the 3D attn_mask is not correct.","messagePattern":"The size of the 3D attn_mask is not correct\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"mmdet/models/layers/transformer/utils.py","lineNumber":578,"sourceCode":"                   '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\n        q = q.contiguous().view(bs, tgt_len, self.num_heads,\n                                head_dims).permute(0, 2, 1, 3).flatten(0, 1)\n        if k is not None:\n            k = k.contiguous().view(bs, src_len, self.num_heads,\n                                    head_dims).permute(0, 2, 1,\n                                                       3).flatten(0, 1)\n        if v is not None:\n            v = v.contiguous().view(bs, src_len, self.num_heads,","sourceCodeStart":560,"sourceCodeEnd":596,"githubUrl":"https://github.com/open-mmlab/mmdetection/blob/cfd5d3a985b0249de009b67d04f37263e11cdf3d/mmdet/models/layers/transformer/utils.py#L560-L596","documentation":"A 3D attn_mask passed to MultiheadAttention.forward_attn must have shape exactly [bs*num_heads, len_q, len_k] because it is applied per-head after reshaping. Any other shape raises RuntimeError.","triggerScenarios":"Passing attn_mask of shape [bs, len_q, len_k] (forgot the head dimension) or [bs*num_heads, len_k, len_k] (used key length for rows).","commonSituations":"Porting masks from vanilla nn.MultiheadAttention (which accepts [bs*num_heads, L, S]); mismatched num_heads between the mask producer and this attention module.","solutions":["Repeat/expand the mask to [bs*num_heads, len_q, len_k]: attn_mask = attn_mask.repeat_interleave(num_heads, dim=0)","Verify module num_heads matches what the mask was built with","Or use a 2D mask [len_q, len_k] broadcast over batch and heads"],"exampleFix":"# before\nattn_mask = torch.zeros(bs, q_len, k_len)\n# after\nattn_mask = torch.zeros(bs, q_len, k_len).repeat_interleave(num_heads, dim=0)","handlingStrategy":"validation","validationCode":"expected = (query.size(0) * num_heads, query.size(1), key.size(1))\nassert attn_mask.shape == expected, (attn_mask.shape, expected)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use repeat_interleave(num_heads, 0) consistently when making 3D masks","Log num_heads and batch size alongside mask shape during dev"],"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"}