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
- Make len(num_blocks), len(num_channels), len(num_in_chs) all equal num_branches
- Prefer timm's hrnet_w32/hrnet_w48 factories, which carry consistent stage configs
- 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
- Derive num_branches from len(num_channels) instead of stating it separately
- Validate stage config lists in a single config-loading function
- Use timm's hrnet factories for standard widths
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
- Token mixer type: {} not supported
- Input image must have positive dimensions, got H={height}, W
- Invalid class map file, expected a dict ({class_map_path}).
- Dataset length is unknown, please pass `num_samples` explici
- Found 0 images in subfolders of {root}. Supported image exte
AI-assisted analysis of huggingface/pytorch-image-models@9a5261e31b (2026-08-27).
Data as JSON: /api/errors/ac75f2e2b1169624.
Report an issue: GitHub.