PaddlePaddle/PaddleOCR · error · ValueError
Incorrect 4D attention_mask shape: {tuple(attention_mask.sha
Error message
Incorrect 4D attention_mask shape: {tuple(attention_mask.shape)}; expected: {expected_shape}. What it means
When the caller passes a pre-built 4D attention mask to the UniMERNet head, the code validates its shape against (batch_size, 1, target_len, key_value_length), where key_value_length includes any past cached KV length. Any deviation raises this ValueError, because an incorrectly shaped additive mask would silently broadcast and corrupt attention scores.
Source
Thrown at ppocr/modeling/heads/rec_unimernet_head.py:452
)
key_value_length = input_shape[-1] + past_key_values_length
shape = attention_mask.shape
len_shape = len(shape)
if (attention_mask is not None) and (len_shape == 2):
attention_mask = attn_mask_converter.to_4d(
attention_mask,
input_shape[-1],
key_value_length=key_value_length,
dtype=inputs_embeds.dtype,
is_export=is_export,
)
return attention_mask
elif attention_mask is not None and len(attention_mask.shape) == 4:
expected_shape = (input_shape[0], 1, input_shape[1], key_value_length)
if tuple(attention_mask.shape) != expected_shape:
raise ValueError(
f"Incorrect 4D attention_mask shape: {tuple(attention_mask.shape)}; expected: {expected_shape}."
)
else:
inverted_mask = 1.0 - attention_mask
attention_mask = inverted_mask.masked_fill_(
inverted_mask.to(paddle.bool), paddle.finfo(inputs_embeds.dtype).min
)
else:
attention_mask = attn_mask_converter.to_causal_4d(
input_shape[0],
input_shape[-1],
key_value_length,
dtype=inputs_embeds.dtype,
)
return attention_mask
View on GitHub (pinned to 2661c7c0ef)
Solutions
- Pass a 2D attention_mask of shape [batch, seq_len] instead and let attn_mask_converter.to_4d build the 4D mask
- If a 4D mask is required, construct it as paddle.ones([bsz, 1, tgt_len, tgt_len + past_kv_len]) and apply your own 0/ -inf logic
- Verify inputs_embeds sequence length matches input_shape[-1] used to compute expected_shape
Example fix
# before attention_mask = mask_4d # shape [bsz, 1, tgt, tgt] model(input_ids=ids, inputs_embeds=emb, attention_mask=attention_mask) # after model(input_ids=ids, inputs_embeds=emb, attention_mask=mask_2d) # [bsz, seq_len]
Defensive patterns
Strategy: validation
Validate before calling
expected = (input_embeds.shape[0], 1, input_embeds.shape[1], input_embeds.shape[1] + past_kv_len)
assert attention_mask.shape == expected, f'mask {attention_mask.shape} != {expected}'
# safer: just pass the 2D mask
if attention_mask is not None and attention_mask.ndim == 4:
attention_mask = attention_mask[:, 0, 0, :] # reduce to 2D if it is a simple key mask Type guard
def is_valid_4d_mask(mask, bsz, tgt_len, kv_len) -> bool:
return mask is None or mask.ndim != 4 or tuple(mask.shape) == (bsz, 1, tgt_len, kv_len) Try / catch
try:
out = head(inputs_embeds=emb, attention_mask=mask)
except ValueError as e:
if '4D attention_mask shape' in str(e):
out = head(inputs_embeds=emb, attention_mask=mask_2d) # fall back to 2D
else:
raise Prevention
- Prefer 2D [bsz, seq] masks; let the head expand them
- When hand-building 4D masks, derive the last dim as tgt_len + past_key_values_length
When it happens
Trigger: Passing attention_mask with 4 dimensions whose shape is not exactly [batch, 1, tgt_len, key_value_length]; common when tgt_len was computed for a different sequence length or past_key_values length was not added to the last dimension.
Common situations: Migrating code from HuggingFace transformers where a 4D mask was accepted with slightly different conventions; incremental decoding where the mask last dim must be tgt_len + past_key_values_length but only tgt_len was built; batch dimension squeezed/expanded incorrectly.
Related errors
- Make sure that when passing `sliding_window` that its value
- Make sure that when passing `sliding_window` that its value
- Sliding window is currently only implemented for causal mask
- embed_dim must be divisible by num_heads (got `embed_dim`: {
- Head mask for a single layer should be of shape {(self.num_h
AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14).
Data as JSON: /api/errors/497736027222d020.
Report an issue: GitHub.