huggingface/pytorch-image-models · error · ValueError

num_branches({}) <> num_blocks({})

Error message

num_branches({}) <> num_blocks({})

What it means

HRNet's high-resolution module validates that num_branches matches the lengths of num_blocks, num_channels, and num_in_chs. The message shows the specific mismatch (here num_branches vs len(num_blocks)); any inconsistency raises ValueError after logging the error.

Source

Thrown at timm/models/hrnet.py:406

            block_types,
            num_blocks,
            num_channels,
            **dd,
        )
        self.fuse_layers = self._make_fuse_layers(**dd)
        self.fuse_act = nn.ReLU(False)

    def _check_branches(self, num_branches, block_types, num_blocks, num_in_chs, num_channels):
        error_msg = ''
        if num_branches != len(num_blocks):
            error_msg = 'num_branches({}) <> num_blocks({})'.format(num_branches, len(num_blocks))
        elif num_branches != len(num_channels):
            error_msg = 'num_branches({}) <> num_channels({})'.format(num_branches, len(num_channels))
        elif num_branches != len(num_in_chs):
            error_msg = 'num_branches({}) <> num_in_chs({})'.format(num_branches, len(num_in_chs))
        if error_msg:
            _logger.error(error_msg)
            raise ValueError(error_msg)

    def _make_one_branch(self, branch_index, block_type, num_blocks, num_channels, stride=1, device=None, dtype=None):
        dd = {'device': device, 'dtype': dtype}
        downsample = None
        if stride != 1 or self.num_in_chs[branch_index] != num_channels[branch_index] * block_type.expansion:
            downsample = nn.Sequential(
                nn.Conv2d(
                    self.num_in_chs[branch_index],
                    num_channels[branch_index] * block_type.expansion,
                    kernel_size=1,
                    stride=stride,
                    bias=False,
                    **dd,
                ),
                nn.BatchNorm2d(num_channels[branch_index] * block_type.expansion, momentum=_BN_MOMENTUM, **dd),
            )

        layers = [block_type(self.num_in_chs[branch_index], num_channels[branch_index], stride, downsample, **dd)]

View on GitHub (pinned to 9a5261e31b)

Solutions

  1. Make len(num_blocks), len(num_channels), len(num_in_chs) all equal num_branches
  2. Prefer timm's hrnet_w32/hrnet_w48 factories, which carry consistent stage configs
  3. Add an assert in your config loader: all(num_branches == len(l) for l in (num_blocks, num_channels, num_in_chs))

Example fix

# before
HighResolutionModule(num_branches=3, num_blocks=[4,4,4,4], num_channels=[32,64,128], num_in_chs=[32,64,128])
# after
HighResolutionModule(num_branches=3, num_blocks=[4,4,4], num_channels=[32,64,128], num_in_chs=[32,64,128])
Defensive patterns

Strategy: validation

Validate before calling

lens = {len(num_blocks), len(num_channels), len(num_in_chs)}
assert len(lens) == 1 and num_branches == len(num_blocks), \
    f'inconsistent HRNet config: branches={num_branches}, blocks={len(num_blocks)}, chs={len(num_channels)}'
mod = HighResolutionModule(num_branches, num_blocks, num_channels, num_in_chs, ...)

Type guard

def is_consistent_hrnet_cfg(num_branches, num_blocks, num_channels, num_in_chs) -> bool:
    return num_branches == len(num_blocks) == len(num_channels) == len(num_in_chs)

Prevention

When it happens

Trigger: Constructing HighResolutionModule directly (or a custom HRNet config) where e.g. num_branches=3 but num_blocks=[4,4,4,4] has 4 entries; usually when hand-modifying stage definitions.

Common situations: Customizing HRNet stage depths/widths for experiments and forgetting to update one of the parallel lists; merging HRNet configs from different variants (hrnet_w32 vs hrnet_w48); yaml-driven model builders that populate the lists independently.

Related errors


AI-assisted analysis of huggingface/pytorch-image-models@9a5261e31b (2026-08-27). Data as JSON: /api/errors/ac75f2e2b1169624. Report an issue: GitHub.