{"record":{"id":"9249fcc87ac7247c","repo":"sgl-project/sglang","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":"python/sglang/multimodal_gen/runtime/models/vaes/autoencoder.py","lineNumber":236,"sourceCode":"    def set_attn_processor(\n        self, processor: Union[AttentionProcessor, Dict[str, AttentionProcessor]]\n    ):\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.unets.unet_2d_condition.UNet2DConditionModel.set_default_attn_processor","sourceCodeStart":218,"sourceCodeEnd":254,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/multimodal_gen/runtime/models/vaes/autoencoder.py#L218-L254","documentation":"When you pass a dict to set_attn_processor, its keys must cover every attention layer in the autoencoder exactly. The method counts registered processors via self.attn_processors and rejects a dict whose length differs, because some layers would be left without a processor.","triggerScenarios":"Calling autoencoder.set_attn_processor({'block_0': AttnProcessor()}) when the model has more attention layers than dict entries, or passing a dict with extra entries. Also reached indirectly via set_default_attn_processor or fuse_qkv_projections.","commonSituations":"Porting a diffusers-style snippet that hardcodes processor names from a different architecture; adding/removing layers in a config without regenerating the processor dict; assuming a single processor instance is enough while passing it wrapped in a dict.","solutions":["Pass a single processor instance instead of a dict if all layers should use the same processor: set_attn_processor(AttnProcessor())","If per-layer processors are needed, build the dict from self.attn_processors.keys(): dict(self.attn_processors) then modify values","Print list(model.attn_processors.keys()) to get the exact layer names/count your dict must match"],"exampleFix":"# before\nvae.set_attn_processor({\"mid_block.attn1\": AttnProcessor()})\n# after\nvae.set_attn_processor(AttnProcessor())\n# or per-layer:\nprocs = {k: AttnProcessor() for k in vae.attn_processors}\nvae.set_attn_processor(procs)","handlingStrategy":"validation","validationCode":"if isinstance(procs, dict):\n    assert set(procs) == set(vae.attn_processors), (\n        f\"need {len(vae.attn_processors)} processors, got {len(procs)}\")\nvae.set_attn_processor(procs)","typeGuard":"def is_complete_processor_dict(model, procs) -> bool:\n    return isinstance(procs, dict) and len(procs) == len(model.attn_processors)","tryCatchPattern":"try:\n    vae.set_attn_processor(procs)\nexcept ValueError as e:\n    if \"number of processors\" in str(e):\n        vae.set_attn_processor(next(iter(procs.values())))  # uniform fallback\n    else:\n        raise","preventionTips":["Prefer passing a single processor instance for uniform setups","Derive processor dicts from model.attn_processors.keys() rather than hardcoding names"],"tags":["attention","processor","autoencoder","value-error"],"backgroundTag":"dict-length-mismatch","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}