hankcs/HanLP · error · ValueError

`attn_output` should be of size {(bsz, self.num_heads, tgt_l

Error message

`attn_output` should be of size {(bsz, self.num_heads, tgt_len, self.head_dim)}, but is {attn_output.size()}

What it means

WeightNormalization (Keras-style) needs to reparameterize the layer's weight matrix, which it locates via the kernel attribute (or layer.cell.kernel for RNNs). Wrapping a layer type that stores weights under a different attribute (e.g. Embedding or custom layers) raises this ValueError in build().

Source

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

            attn_weights = layer_head_mask.view(1, -1, 1, 1) * attn_weights.view(bsz, self.num_heads, tgt_len, src_len)
            attn_weights = attn_weights.view(bsz * self.num_heads, tgt_len, src_len)

        if output_attentions:
            # this operation is a bit awkward, but it's required to
            # make sure that attn_weights keeps its gradient.
            # In order to do so, attn_weights have to be reshaped
            # twice and have to be reused in the following
            attn_weights_reshaped = attn_weights.view(bsz, self.num_heads, tgt_len, src_len)
            attn_weights = attn_weights_reshaped.view(bsz * self.num_heads, tgt_len, src_len)
        else:
            attn_weights_reshaped = None

        attn_probs = nn.functional.dropout(attn_weights, p=self.dropout, training=self.training)

        attn_output = torch.bmm(attn_probs, value_states)

        if attn_output.size() != (bsz * self.num_heads, tgt_len, self.head_dim):
            raise ValueError(
                f"`attn_output` should be of size {(bsz, self.num_heads, tgt_len, self.head_dim)}, but is"
                f" {attn_output.size()}"
            )

        attn_output = attn_output.view(bsz, self.num_heads, tgt_len, self.head_dim)
        attn_output = attn_output.transpose(1, 2)

        # Use the `embed_dim` from the config (stored in the class) rather than `hidden_state` because `attn_output` can be
        # partitioned aross GPUs when using tensor-parallelism.
        attn_output = attn_output.reshape(bsz, tgt_len, self.embed_dim)

        attn_output = self.out_proj(attn_output)

        return attn_output, attn_weights_reshaped, past_key_value


class BartEncoderLayer(nn.Module):
    def __init__(self, config: BartConfig):

View on GitHub (pinned to ddb1299bdd)

Solutions

  1. Wrap only kernel-based layers (Dense, Conv1D/2D, RNN cells)
  2. For custom layers, expose the weight matrix as self.kernel so the wrapper can find it
  3. Use torch's built-in torch.nn.utils.weight_norm for PyTorch modules instead of this Keras-style wrapper

Example fix

# before
wn = WeightNormalization(MyCustomLayer(...))
# after
class MyCustomLayer(nn.Module):
    def __init__(...):
        self.kernel = nn.Parameter(...)  # expose kernel
wn = WeightNormalization(MyCustomLayer())
Defensive patterns

Strategy: type-guard

Validate before calling

assert hasattr(layer.cell if is_rnn else layer, 'kernel'), 'layer must expose .kernel for WeightNormalization'

Type guard

def wrappable(layer, is_rnn=False) -> bool:
    return hasattr(layer.cell if is_rnn else layer, 'kernel')

Try / catch

try:
    wn = WeightNormalization(layer); wn.build(input_shape)
except ValueError as e:
    raise ValueError(f'cannot weight-normalize {type(layer).__name__}: {e}') from e

Prevention

When it happens

Trigger: Wrapping a Keras layer without a kernel attribute (many custom layers, Embedding in some versions) with WeightNormalization and calling build/forward on it.

Common situations: Porting weight-norm configs between layer types; wrapping Lambda/custom layers; Keras version changes where layer internals moved off .kernel; wrapping RNNs where cell detection (is_rnn) fails so it looks for kernel on the wrong object.

Related errors


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