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

  1. Build head_mask with shape[0] == model.decoder.config.num_hidden_layers, e.g. paddle.ones([num_layers, 1, 1, hidden]) style allocation
  2. Or omit head_mask entirely (pass None) when you do not need head masking
  3. 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

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


AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14). Data as JSON: /api/errors/2dac46549a389d23. Report an issue: GitHub.