PaddlePaddle/PaddleOCR · error · ValueError
The `{mask_name}` should be specified for {len(self.layers)}
Error message
The `{mask_name}` should be specified for {len(self.layers)} layers, but it is for {attn_mask.size()[0]}. What it means
head_mask and cross_attn_head_mask let you zero-out attention heads per layer; the decoder validates that the first dimension equals the number of decoder layers (len(self.layers)). A mask sized for a different layer count raises this ValueError.
Source
Thrown at ppocr/modeling/heads/rec_ppformulanet_head.py:541
"`use_cache=True` is incompatible with gradient checkpointing`. Setting `use_cache=False`..."
)
use_cache = False
# decoder layers
all_hidden_states = () if output_hidden_states else None
all_self_attns = () if output_attentions else None
all_cross_attentions = (
() if (output_attentions and encoder_hidden_states is not None) else None
)
next_decoder_cache = () if use_cache else None
# check if head_mask/cross_attn_head_mask has a correct number of layers specified if desired
for attn_mask, mask_name in zip(
[head_mask, cross_attn_head_mask], ["head_mask", "cross_attn_head_mask"]
):
if attn_mask is not None:
if attn_mask.size()[0] != len(self.layers):
raise ValueError(
f"The `{mask_name}` should be specified for {len(self.layers)} layers, but it is for"
f" {attn_mask.size()[0]}."
)
for idx, decoder_layer in enumerate(self.layers):
# add LayerDrop (see https://arxiv.org/abs/1909.11556 for description)
if output_hidden_states:
all_hidden_states += (hidden_states,)
if self.training:
dropout_probability = paddle.rand([])
if dropout_probability < self.layerdrop:
continue
past_key_value = (
past_key_values[idx] if past_key_values is not None else None
)
if self.gradient_checkpointing and self.training:
layer_outputs = self._gradient_checkpointing_func(
decoder_layer.__call__,View on GitHub (pinned to 2661c7c0ef)
Solutions
- Build head_mask with shape[0] == model.decoder.config.num_hidden_layers, e.g. paddle.ones([num_layers, 1, 1, hidden]) style allocation
- Or omit head_mask entirely (pass None) when you do not need head masking
- If loading masks from checkpoints, re-allocate/resize them after any config change to num_layers
Example fix
# before head_mask = paddle.ones([6, 1, 1, 1]) # but decoder has 8 layers # after n = len(model.decoder.layers) head_mask = paddle.ones([n, 1, 1, 1])
Defensive patterns
Strategy: validation
Validate before calling
def check_head_mask(mask, num_layers, name='head_mask'):
if mask is not None and mask.shape[0] != num_layers:
raise ValueError(f'{name} has {mask.shape[0]} entries, decoder has {num_layers} layers')
return mask
# check_head_mask(head_mask, len(model.decoder.layers)) Type guard
def mask_matches_layers(mask, num_layers) -> bool:
return mask is None or mask.shape[0] == num_layers Try / catch
null # misconfiguration; fix construction instead of catching
Prevention
- Derive mask shapes from len(model.decoder.layers), never hardcode
- Drop head_mask (None) unless head pruning is actually used
- Re-allocate masks after changing num_layers in config
When it happens
Trigger: Passing head_mask (or cross_attn_head_mask) shaped (N, ...) where N != number of decoder layers — e.g. built with num_layers taken from the encoder config, from a different model size, or hardcoded from another experiment.
Common situations: Head-pruning experiments ported between model variants (base vs large with different num_hidden_layers); copying an HF example that builds head_mask with the encoder's layer count; reusing a saved mask tensor after changing num_layers in config.
Related errors
- Incorrect 4D attention_mask shape: {tuple(attention_mask.sha
- Make sure that when passing `sliding_window` that its value
- This attention mask converter is causal. Make sure to pass `
- Sliding window is currently only implemented for causal mask
- You cannot specify both decoder_input_ids and decoder_inputs
AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14).
Data as JSON: /api/errors/2dac46549a389d23.
Report an issue: GitHub.