{"record":{"id":"123a4b6d198affa1","repo":"lllyasviel/Fooocus","slug":"provide-num-res-blocks-either-as-an-int-globally","errorCode":null,"errorMessage":"provide num_res_blocks either as an int (globally constant) or as a list/tuple (per-level) with the same length as channel_mult","messagePattern":"provide num_res_blocks either as an int \\(globally constant\\) or as a list/tuple \\(per-level\\) with the same length as channel_mult","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"ldm_patched/controlnet/cldm.py","lineNumber":88,"sourceCode":"        if num_heads_upsample == -1:\n            num_heads_upsample = num_heads\n\n        if num_heads == -1:\n            assert num_head_channels != -1, 'Either num_heads or num_head_channels has to be set'\n\n        if num_head_channels == -1:\n            assert num_heads != -1, 'Either num_heads or num_head_channels has to be set'\n\n        self.dims = dims\n        self.image_size = image_size\n        self.in_channels = in_channels\n        self.model_channels = model_channels\n\n        if isinstance(num_res_blocks, int):\n            self.num_res_blocks = len(channel_mult) * [num_res_blocks]\n        else:\n            if len(num_res_blocks) != len(channel_mult):\n                raise ValueError(\"provide num_res_blocks either as an int (globally constant) or \"\n                                 \"as a list/tuple (per-level) with the same length as channel_mult\")\n            self.num_res_blocks = num_res_blocks\n\n        if disable_self_attentions is not None:\n            # should be a list of booleans, indicating whether to disable self-attention in TransformerBlocks or not\n            assert len(disable_self_attentions) == len(channel_mult)\n        if num_attention_blocks is not None:\n            assert len(num_attention_blocks) == len(self.num_res_blocks)\n            assert all(map(lambda i: self.num_res_blocks[i] >= num_attention_blocks[i], range(len(num_attention_blocks))))\n\n        transformer_depth = transformer_depth[:]\n\n        self.dropout = dropout\n        self.channel_mult = channel_mult\n        self.conv_resample = conv_resample\n        self.num_classes = num_classes\n        self.use_checkpoint = use_checkpoint\n        self.dtype = dtype","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/lllyasviel/Fooocus/blob/ae05379cc97bc4361ec8b4ec90193dab21be763f/ldm_patched/controlnet/cldm.py#L70-L106","documentation":"In the ControlNet/latent-diffusion UNet builder (cldm.py), num_res_blocks may be an int (same depth at every resolution level) or a per-level list whose length must equal len(channel_mult). A mismatched list raises ValueError at model construction. This validation precedes the asserts on disable_self_attentions/num_attention_blocks, which also index by level.","triggerScenarios":"Loading a SD1.5/SD2.x ControlNet config where num_res_blocks=[2,2,2,2] but channel_mult=[1,2,4,4,4] (5 levels), or vice versa; hand-edited config YAMLs that change one field without the other.","commonSituations":"Diffusion-model configs from different model families (SD1.x uses 4-level channel_mult, SD2.1/SDXL differ); copying a config from another repo (e.g. k-diffusion or original CompVis) with per-level block counts; custom training configs.","solutions":["If depth is uniform, use the int form: num_res_blocks: 2.","Otherwise make len(num_res_blocks) == len(channel_mult) — for SD1.x that is 4 entries, e.g. [2,2,2,2] with channel_mult [1,2,4,4].","Diff the failing config against the reference controlnet sd15 config shipped in the repo and align both fields.","Sanity-check any sibling per-level lists (disable_self_attentions, num_attention_blocks) against the same length."],"exampleFix":"# before\nchannel_mult=[1, 2, 4, 4, 5]\nnum_res_blocks=[2, 2, 2, 2]  # ValueError: len mismatch\n\n# after\nchannel_mult=[1, 2, 4, 4, 5]\nnum_res_blocks=[2, 2, 2, 2, 2]  # lengths match","handlingStrategy":"validation","validationCode":"if isinstance(num_res_blocks, int):\n    num_res_blocks = [num_res_blocks] * len(channel_mult)\nelse:\n    num_res_blocks = list(num_res_blocks)\n    if len(num_res_blocks) != len(channel_mult):\n        raise ValueError(f'len(num_res_blocks)={len(num_res_blocks)} != len(channel_mult)={len(channel_mult)}')","typeGuard":"def is_valid_res_blocks(nrb, channel_mult) -> bool:\n    return isinstance(nrb, int) or (isinstance(nrb, (list, tuple)) and len(nrb) == len(channel_mult))","tryCatchPattern":"try:\n    model = ControlNet(model_cfg)\nexcept ValueError as e:\n    if 'num_res_blocks' in str(e):\n        raise ValueError('Config error: num_res_blocks must be int or per-level list matching channel_mult') from e\n    raise","preventionTips":["Validate per-level lists (channel_mult, num_res_blocks, attention settings) together in a config linter.","Prefer the int form unless the model truly needs per-level depths.","Diff custom configs against the shipped reference config for the same model family."],"tags":["controlnet","unet-config","validation","stable-diffusion"],"backgroundTag":null,"analyzedSha":"ae05379cc97bc4361ec8b4ec90193dab21be763f","analyzedAt":"2026-08-15T04:23:59.533Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}