{"record":{"id":"c0f0cacdd74e129f","repo":"invoke-ai/InvokeAI","slug":"a-dict-of-processors-was-passed-but-the-number-of","errorCode":null,"errorMessage":"A dict of processors was passed, but the number of processors {len(processor)} does not match the number of attention layers: {count}. Please make sure to pass {count} processor classes.","messagePattern":"A dict of processors was passed, but the number of processors (.+?) does not match the number of attention layers: (.+?)\\. Please make sure to pass (.+?) processor classes\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"invokeai/backend/util/hotfixes.py","lineNumber":475,"sourceCode":"\n    # Copied from diffusers.models.unet_2d_condition.UNet2DConditionModel.set_attn_processor\n    def set_attn_processor(self, processor: Union[AttentionProcessor, Dict[str, AttentionProcessor]]):\n        r\"\"\"\n        Sets the attention processor to use to compute attention.\n\n        Parameters:\n            processor (`dict` of `AttentionProcessor` or only `AttentionProcessor`):\n                The instantiated processor class or a dictionary of processor classes that will be set as the processor\n                for **all** `Attention` layers.\n\n                If `processor` is a dict, the key needs to define the path to the corresponding cross attention\n                processor. This is strongly recommended when setting trainable attention processors.\n\n        \"\"\"\n        count = len(self.attn_processors.keys())\n\n        if isinstance(processor, dict) and len(processor) != count:\n            raise ValueError(\n                f\"A dict of processors was passed, but the number of processors {len(processor)} does not match the\"\n                f\" number of attention layers: {count}. Please make sure to pass {count} processor classes.\"\n            )\n\n        def fn_recursive_attn_processor(name: str, module: torch.nn.Module, processor):\n            if hasattr(module, \"set_processor\"):\n                if not isinstance(processor, dict):\n                    module.set_processor(processor)\n                else:\n                    module.set_processor(processor.pop(f\"{name}.processor\"))\n\n            for sub_name, child in module.named_children():\n                fn_recursive_attn_processor(f\"{name}.{sub_name}\", child, processor)\n\n        for name, module in self.named_children():\n            fn_recursive_attn_processor(name, module, processor)\n\n    # Copied from diffusers.models.unet_2d_condition.UNet2DConditionModel.set_default_attn_processor","sourceCodeStart":457,"sourceCodeEnd":493,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/backend/util/hotfixes.py#L457-L493","documentation":"`set_attn_processor` verifies that when a dict of attention processors is supplied, its number of entries equals the number of attention layers reported by `self.attn_processors`. A mismatch means the caller supplied processors for the wrong set of module names (or wrong model), so mapping modules to processors would silently skip or fail; the library raises this ValueError instead. This is standard diffusers `ModelMixin.set_attn_processor` behavior in InvokeAI's hotfixed copy.","triggerScenarios":"Calling `unet.set_attn_processor(processor_dict)` where processor_dict keys/size don't match `unet.attn_processor` — e.g. building a dict for a different model, reusing an IP-Adapter processor dict across differently-patched UNets, or patching after LoRA/extension code changed the attention module set. Raised from set_attn_processor, invoked by _run_diffusion, patch_unet_attention_processor, apply_ip_adapter_attention, patch_extension, and set_default_attn_processor.","commonSituations":"IP-Adapter application to a UNet whose attention layer names differ from the ones the adapter bundle was built for (different SD1.5 vs SDXL UNets, or xformers/PyTorch 2.0 renaming); mixing processors computed before and after another patch pass; setting default processors on a model with extra controlnet attention modules.","solutions":["Print `len(unet.attn_processors)` and `list(processor.keys())`; rebuild the dict so it has exactly one processor per key returned by `unet.attn_processors` (keys must match exactly).","Build the dict programmatically from `unet.named_modules()` / `unet.attn_processors.keys()` instead of hardcoding names, e.g. `{k: MyAttnProcessor() for k in unet.attn_processors.keys()}`.","Pass a single processor instance (or list) instead of a dict if you want the same processor applied to all layers — the count check only applies to dicts.","Ensure IP-Adapter cross-attention processors are applied to the same UNet variant (SD1.5 vs SDXL) they were exported for; regenerate the processor dict if the base model changed.","If a prior patch pass (LoRA/extension) altered the attention set, recompute processors after all other patches rather than caching them."],"exampleFix":"// before\nproc = {\"down_blocks.0.attentions.0.transformer_blocks.0.attn1.processor\": AttnProcessor2_0()}\nunet.set_attn_processor(proc)\n// after\nfrom invokeai.backend.util.hotfixes import AttnProcessor2_0\nproc = {name: AttnProcessor2_0() for name in unet.attn_processors.keys()}\nassert len(proc) == len(unet.attn_processors)\nunet.set_attn_processor(proc)","handlingStrategy":"validation","validationCode":"expected = set(unet.attn_processors.keys())\nif isinstance(processor, dict) and set(processor.keys()) != expected:\n    missing = expected - set(processor.keys())\n    extra = set(processor.keys()) - expected\n    raise ValueError(f\"processor keys mismatch; missing={sorted(missing)} extra={sorted(extra)}\")","typeGuard":"def processors_match(unet, processor) -> bool:\n    return not isinstance(processor, dict) or set(processor.keys()) == set(unet.attn_processors.keys())","tryCatchPattern":"try:\n    unet.set_attn_processor(processor)\nexcept ValueError as e:\n    if \"number of processors\" in str(e):\n        from invokeai.backend.util.hotfixes import AttnProcessor2_0\n        processor = {name: AttnProcessor2_0() for name in unet.attn_processors.keys()}\n        unet.set_attn_processor(processor)\n    else:\n        raise","preventionTips":["Always build processor dicts from `unet.attn_processors.keys()`, never hardcoded layer names.","Recompute the processor dict after any other patching (LoRA, xformers, extensions) changes the UNet.","Only reuse IP-Adapter processor dicts with the exact UNet variant they were exported for (SD1.5 vs SDXL).","Before calling set_attn_processor, assert set equality of dict keys against attn_processors keys to get a precise diff instead of a count mismatch."],"tags":["attention-processors","count-mismatch","valueerror","ip-adapter","diffusers"],"backgroundTag":"processor-count-mismatch","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}