open-mmlab/mmdetection · error · ValueError

The hidden size ({config.hidden_size}) is not a multiple of

Error message

The hidden size ({config.hidden_size}) is not a multiple of the number of attention heads ({config.num_attention_heads})

What it means

BertSelfAttention-style attention in GLIP/grounding configs requires hidden_size divisible by num_attention_heads so each head gets an integer head size. This check is copied from HuggingFace BERT; configs with embedding_size (ALBERT-style) are exempt.

Source

Thrown at mmdet/models/utils/vlfuse_helper.py:565

        config (:class:`~transformers.BertConfig`):
            The configuration object that
            contains various parameters for the model.
        clamp_min_for_underflow (bool, optional):
            Whether to clamp the minimum value of the hidden states
             to prevent underflow. Defaults to `False`.
        clamp_max_for_overflow (bool, optional):
            Whether to clamp the maximum value of the hidden states
            to prevent overflow. Defaults to `False`.
    """

    def __init__(self,
                 config: BertConfig,
                 clamp_min_for_underflow: bool = False,
                 clamp_max_for_overflow: bool = False):
        super().__init__()
        if config.hidden_size % config.num_attention_heads != 0 and \
                not hasattr(config, 'embedding_size'):
            raise ValueError(f'The hidden size ({config.hidden_size}) is '
                             'not a multiple of the number of attention '
                             f'heads ({config.num_attention_heads})')

        self.num_attention_heads = config.num_attention_heads
        self.attention_head_size = int(config.hidden_size /
                                       config.num_attention_heads)
        self.all_head_size = self.num_attention_heads * \
            self.attention_head_size

        self.query = nn.Linear(config.hidden_size, self.all_head_size)
        self.key = nn.Linear(config.hidden_size, self.all_head_size)
        self.value = nn.Linear(config.hidden_size, self.all_head_size)

        self.dropout = nn.Dropout(config.attention_probs_dropout_prob)
        self.position_embedding_type = getattr(config,
                                               'position_embedding_type',
                                               'absolute')
        if self.position_embedding_type == 'relative_key' or \

View on GitHub (pinned to cfd5d3a985)

Solutions

  1. Fix the text encoder config so hidden_size is divisible by num_attention_heads (e.g. 768/12)
  2. Load a stock bert config instead of hand-editing
  3. If porting ALBERT-like models, keep embedding_size set (the code exempts it)

Example fix

# before
BertConfig(hidden_size=768, num_attention_heads=14)
# after
BertConfig(hidden_size=768, num_attention_heads=12)
Defensive patterns

Strategy: validation

Validate before calling

assert config.hidden_size % config.num_attention_heads == 0 or hasattr(config, 'embedding_size')

Prevention

When it happens

Trigger: Loading a modified BERT text encoder config where hidden_size % num_attention_heads != 0 and no embedding_size attribute is present, e.g. hidden_size=768 with num_attention_heads=14.

Common situations: Custom/trimmed text backbones for GLIP/GroundingRCNN, hand-edited bert-base-uncased config.json values, or a config pulled from an incompatible transformers version.

Related errors


AI-assisted analysis of open-mmlab/mmdetection@cfd5d3a985 (2026-08-27). Data as JSON: /api/errors/eb244c69229a1bbb. Report an issue: GitHub.