Stability-AI/generative-models · error · ValueError
provide num_res_blocks either as an int (globally constant)
Error message
provide num_res_blocks either as an int (globally constant) or as a list/tuple (per-level) with the same length as channel_mult
What it means
UNetModel validates that num_res_blocks is either a single int (broadcast to all levels) or a list/tuple whose length equals len(channel_mult). A mismatched list length raises ValueError during model construction.
Source
Thrown at sgm/modules/diffusionmodules/openaimodel.py:606
), "Either num_heads or num_head_channels has to be set"
if num_head_channels == -1:
assert (
num_heads != -1
), "Either num_heads or num_head_channels has to be set"
self.in_channels = in_channels
self.model_channels = model_channels
self.out_channels = out_channels
if isinstance(transformer_depth, int):
transformer_depth = len(channel_mult) * [transformer_depth]
transformer_depth_middle = transformer_depth[-1]
if isinstance(num_res_blocks, int):
self.num_res_blocks = len(channel_mult) * [num_res_blocks]
else:
if len(num_res_blocks) != len(channel_mult):
raise ValueError(
"provide num_res_blocks either as an int (globally constant) or "
"as a list/tuple (per-level) with the same length as channel_mult"
)
self.num_res_blocks = num_res_blocks
if disable_self_attentions is not None:
assert len(disable_self_attentions) == len(channel_mult)
if num_attention_blocks is not None:
assert len(num_attention_blocks) == len(self.num_res_blocks)
assert all(
map(
lambda i: self.num_res_blocks[i] >= num_attention_blocks[i],
range(len(num_attention_blocks)),
)
)
logpy.info(
f"Constructor of UNetModel received num_attention_blocks={num_attention_blocks}. "
f"This option has LESS priority than attention_resolutions {attention_resolutions}, "View on GitHub (pinned to e8cd657656)
Solutions
- Make the num_res_blocks list the same length as channel_mult
- Replace the list with a single int to broadcast it to every level
- Regenerate the config from the reference model definition
Example fix
// before (yaml) channel_mult: [1, 2, 4, 4] num_res_blocks: [2, 2, 2] // after (yaml) channel_mult: [1, 2, 4, 4] num_res_blocks: [2, 2, 2, 2] # or just 2
Defensive patterns
Strategy: validation
Validate before calling
if not isinstance(num_res_blocks, int) and len(num_res_blocks) != len(channel_mult):
raise ValueError(
f"num_res_blocks has length {len(num_res_blocks)} but channel_mult has {len(channel_mult)} levels"
) Type guard
def num_res_blocks_ok(nrb, channel_mult) -> bool:
return isinstance(nrb, int) or (isinstance(nrb, (list, tuple)) and len(nrb) == len(channel_mult)) Try / catch
try:
model = UNetModel(**unet_config)
except ValueError as e:
if "num_res_blocks" in str(e):
unet_config["num_res_blocks"] = unet_config["channel_mult"].__len__() * [2]
model = UNetModel(**unet_config)
else:
raise Prevention
- Always change channel_mult and num_res_blocks lists together
- Prefer a scalar num_res_blocks unless per-level control is needed
- Schema-validate UNet configs (length constraints) before instantiation
When it happens
Trigger: Passing num_res_blocks as a list of length != len(channel_mult), e.g. [2,2,2] with channel_mult [1,2,4,4] in the UNet config.
Common situations: Hand-edited diffusion model YAMLs where resolution/channel_mult was changed but num_res_blocks list not updated; porting configs from UNet variants with different level counts.
Related errors
- rearranging not available for {len(in_shape)}-dimensional in
- unknown merge strategy {self.merge_strategy}
- Unknown loss type {self.loss_type}
- NotImplementedError
- need either 'input_key' or 'input_keys' for embedder {embedd
AI-assisted analysis of Stability-AI/generative-models@e8cd657656 (2026-08-29).
Data as JSON: /api/errors/70581882b18f3f2c.
Report an issue: GitHub.