hankcs/HanLP · error · ValueError

The head_mask should be specified for {len(self.layers)} lay

Error message

The head_mask should be specified for {len(self.layers)} layers, but it is for {head_mask.size()[0]}.

What it means

For classification accuracy, predictions are (..., num_classes) scores while gold labels are class indices with one fewer dimension. If gold_labels.dim() != predictions.dim()-1 (e.g. one-hot gold labels, or score-shaped targets), __call__ raises ValueError.

Source

Thrown at hanlp/components/amr/amrbart/model_interface/modeling_bart.py:818

        embed_pos = self.embed_positions(input_shape)

        hidden_states = inputs_embeds + embed_pos
        hidden_states = self.layernorm_embedding(hidden_states)
        hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training)

        # expand attention_mask
        if attention_mask is not None:
            # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len]
            attention_mask = _expand_mask(attention_mask, inputs_embeds.dtype)

        encoder_states = () if output_hidden_states else None
        all_attentions = () if output_attentions else None

        # check if head_mask has a correct number of layers specified if desired
        if head_mask is not None:
            if head_mask.size()[0] != (len(self.layers)):
                raise ValueError(
                    f"The head_mask should be specified for {len(self.layers)} layers, but it is for"
                    f" {head_mask.size()[0]}."
                )

        for idx, encoder_layer in enumerate(self.layers):
            if output_hidden_states:
                encoder_states = encoder_states + (hidden_states,)
            # add LayerDrop (see https://arxiv.org/abs/1909.11556 for description)
            dropout_probability = random.uniform(0, 1)
            if self.training and (dropout_probability < self.layerdrop):  # skip the layer
                layer_outputs = (None, None)
            else:
                if self.gradient_checkpointing and self.training:

                    def create_custom_forward(module):
                        def custom_forward(*inputs):
                            return module(*inputs, output_attentions)

View on GitHub (pinned to ddb1299bdd)

Solutions

  1. Convert gold labels to integer class indices (argmax if one-hot): gold.argmax(-1)
  2. Check shapes: gold.shape == predictions.shape[:-1]
  3. Reorder positional args if mask was passed in the gold slot

Example fix

# before
metric(predictions, gold_onehot)  # gold is (B, C)
# after
metric(predictions, gold_onehot.argmax(dim=-1))  # gold is (B,)
Defensive patterns

Strategy: validation

Validate before calling

assert gold_labels.dim() == predictions.dim() - 1, (gold_labels.shape, predictions.shape)

Type guard

import torch
def valid_gold(predictions: torch.Tensor, gold: torch.Tensor) -> bool:
    return gold.dim() == predictions.dim() - 1 and gold.dtype in (torch.long, torch.int)

Try / catch

try:
    metric(predictions, gold_labels)
except ValueError:
    if gold_labels.dim() == predictions.dim():
        metric(predictions, gold_labels.argmax(-1))
    else:
        raise

Prevention

When it happens

Trigger: Calling metric(predictions=[B, C], gold_labels=[B, C]) (one-hot gold) or passing logits/gold with equal dims; also 3-D token-level predictions with 3-D gold.

Common situations: Feeding one-hot encoded targets instead of class indices; datasets returning gold as probabilities; a mask arg mistakenly passed as gold_labels positionally.

Related errors


AI-assisted analysis of hankcs/HanLP@ddb1299bdd (2026-08-27). Data as JSON: /api/errors/f1a3b2399adab939. Report an issue: GitHub.