{"record":{"id":"3b3ff83ec328c4ba","repo":"PaddlePaddle/PaddleOCR","slug":"head-mask-for-a-single-layer-should-be-of-shape","errorCode":null,"errorMessage":"Head mask for a single layer should be of shape {(self.num_heads,)}, but is {layer_head_mask.shape}","messagePattern":"Head mask for a single layer should be of shape (.+?), but is (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"ppocr/modeling/heads/rec_unimernet_head.py","lineNumber":628,"sourceCode":"        key_states = key_states.reshape(proj_shape)\n        value_states = value_states.reshape(proj_shape)\n\n        src_len = key_states.shape[1]\n        attn_weights = paddle.bmm(query_states, key_states.transpose([0, 2, 1]))\n\n        if attention_mask is not None:\n            attn_weights = (\n                attn_weights.reshape([bsz, self.num_heads, tgt_len, src_len])\n                + attention_mask\n            )\n            attn_weights = attn_weights.reshape(\n                [bsz * self.num_heads, tgt_len, src_len]\n            )\n\n        attn_weights = nn.functional.softmax(attn_weights, axis=-1)\n        if layer_head_mask is not None:\n            if tuple(layer_head_mask.shape) != (self.num_heads,):\n                raise ValueError(\n                    f\"Head mask for a single layer should be of shape {(self.num_heads,)}, but is\"\n                    f\" {layer_head_mask.shape}\"\n                )\n            attn_weights = layer_head_mask.reshape(\n                [1, -1, 1, 1]\n            ) * attn_weights.reshape([bsz, self.num_heads, tgt_len, src_len])\n            attn_weights = attn_weights.reshape(\n                [bsz * self.num_heads, tgt_len, src_len]\n            )\n\n        if output_attentions:\n            attn_weights_reshaped = attn_weights.reshape(\n                [bsz, self.num_heads, tgt_len, src_len]\n            )\n            attn_weights = attn_weights_reshaped.reshape(\n                [bsz * self.num_heads, tgt_len, src_len]\n            )\n        else:","sourceCodeStart":610,"sourceCodeEnd":646,"githubUrl":"https://github.com/PaddlePaddle/PaddleOCR/blob/2661c7c0ef5c613e8f93c6e93b2e052399f0f854/ppocr/modeling/heads/rec_unimernet_head.py#L610-L646","documentation":"In the eager attention path of the UniMERNet decoder layer, an optional per-layer head mask must have exactly num_heads elements so it can scale each attention head's weights. The code validates tuple(layer_head_mask.shape) == (num_heads,) before applying the mask, raising ValueError otherwise because a wrong-size mask would broadcast incorrectly over the [bsz, num_heads, tgt, src] weights.","triggerScenarios":"Passing head_mask (or cross_attn_head_mask) to the decoder forward with a per-layer slice whose shape is not (num_heads,), e.g. shape [num_layers] used directly, or a scalar broadcast mask.","commonSituations":"Porting generation code from transformers where head_mask semantics differ; debugging attention with a custom mask tensor whose leading layer dimension was indexed incorrectly.","solutions":["Pass head_mask=None (the normal path for this head; head pruning is rarely needed)","If masking heads, supply shape [num_layers, num_heads] so each layer slice is (num_heads,)"],"exampleFix":"# before\nout = layer(hidden, head_mask=head_mask_scalar)  # wrong shape\n# after\nout = layer(hidden, head_mask=None)","handlingStrategy":"validation","validationCode":"if head_mask is not None:\n    assert head_mask.shape[1:] == (num_heads,), f'per-layer head mask must be ({num_heads},)'","typeGuard":"def valid_head_mask(mask, num_layers: int, num_heads: int) -> bool:\n    return mask is None or (tuple(mask.shape) == (num_layers, num_heads))","tryCatchPattern":null,"preventionTips":["Default to head_mask=None; head masking is a debugging feature","Derive mask shapes from the live model (len(decoder.layers)) instead of hardcoded ints"],"tags":["paddle","attention","head-mask","shape-mismatch"],"backgroundTag":null,"analyzedSha":"2661c7c0ef5c613e8f93c6e93b2e052399f0f854","analyzedAt":"2026-08-14T20:17:30.180Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}