{"record":{"id":"fe27aec2118dd479","repo":"invoke-ai/InvokeAI","slug":"state-dict-appears-to-be-in-a-legacy-controlnet-ll","errorCode":null,"errorMessage":"State dict appears to be in a legacy ControlNet-LLLite weight format (keys starting with '{_LEGACY_MODULES_PREFIX}'). Only the v2 named-key format is supported.","messagePattern":"State dict appears to be in a legacy ControlNet-LLLite weight format \\(keys starting with '(.+?)'\\)\\. Only the v2 named-key format is supported\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"invokeai/backend/anima/control_net_lllite.py","lineNumber":423,"sourceCode":"            if MODULE_NAME_PATTERN.match(name) is None:\n                raise ValueError(f\"Unrecognized LLLite module name: '{name}'\")\n            modules.append(LLLiteModuleDiT(name, in_dim, cond_emb_dim, mlp_dim, multiplier=multiplier))\n        self.lllite_modules = nn.ModuleList(modules)\n\n    @classmethod\n    def from_state_dict(\n        cls, state_dict: dict[str, torch.Tensor], metadata: dict[str, str] | None\n    ) -> AnimaControlNetLLLite:\n        \"\"\"Build the adapter from a saved v2 named-key state dict.\n\n        Hyperparams come from ``lllite.*`` metadata when present, with\n        state-dict-shape fallbacks. ``inpaint_masked_input`` is metadata-only\n        (not derivable from shapes; defaults to False).\n        \"\"\"\n        meta = metadata or {}\n\n        if any(k.startswith(_LEGACY_MODULES_PREFIX) for k in state_dict):\n            raise ValueError(\n                f\"State dict appears to be in a legacy ControlNet-LLLite weight format (keys starting \"\n                f\"with '{_LEGACY_MODULES_PREFIX}'). Only the v2 named-key format is supported.\"\n            )\n\n        module_names: set[str] = set()\n        for key in state_dict:\n            head, dot, _tail = key.partition(\".\")\n            if dot and MODULE_NAME_PATTERN.match(head):\n                module_names.add(head)\n        if not module_names:\n            raise ValueError(\"State dict contains no LLLite modules (no 'lllite_dit_blocks_*' keys).\")\n\n        def sort_key(name: str) -> tuple[int, int]:\n            match = MODULE_NAME_PATTERN.match(name)\n            assert match is not None\n            return int(match.group(1)), _SUFFIX_ORDER.index(match.group(2))\n\n        sorted_names = sorted(module_names, key=sort_key)","sourceCodeStart":405,"sourceCodeEnd":441,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/backend/anima/control_net_lllite.py#L405-L441","documentation":"from_state_dict only supports the v2 named-key ControlNet-LLLite format. If any key starts with _LEGACY_MODULES_PREFIX (the legacy 'lllite_modules.' layout), it raises ValueError telling you to convert the checkpoint. Legacy keys lack the per-module names needed to resolve injection targets.","triggerScenarios":"Loading an old ControlNet-LLLite checkpoint saved with keys like 'lllite_modules.0.down.weight' instead of named keys like 'lllite_dit_blocks_0_down.down.weight'.","commonSituations":"Using checkpoints trained/saved with an earlier version of the training code, or downloading community models created before the v2 format was introduced.","solutions":["Re-export the checkpoint with a current version of the training script (v2 named keys).","Write a one-time conversion script renaming legacy 'lllite_modules.<i>.' keys to 'lllite_dit_blocks_<n>_<suffix>.' using the original module ordering.","Obtain a v2-format version of the model from its source.","Pin/upgrade library versions so trainer and loader formats match."],"exampleFix":"# before\ncontrolnet = ControlNetLLLiteDiT.from_state_dict(torch.load(\"old.safetensors\"), meta)\n# after\nsd = convert_legacy_lllite_state_dict(torch.load(\"old.safetensors\"))  # rename lllite_modules.<i>.* -> named keys\ncontrolnet = ControlNetLLLiteDiT.from_state_dict(sd, meta)","handlingStrategy":"validation","validationCode":"LEGACY_PREFIX = \"lllite_modules\"\ndef reject_legacy_format(state_dict: dict) -> None:\n    legacy = [k for k in state_dict if k.startswith(LEGACY_PREFIX)]\n    if legacy:\n        raise ValueError(\n            f\"legacy LLLite format detected ({len(legacy)} keys, e.g. '{legacy[0]}'); \"\n            \"convert to v2 named-key format first\"\n        )","typeGuard":"def is_v2_lllite_state_dict(sd: dict) -> bool:\n    keys = list(sd)\n    return not any(k.startswith(\"lllite_modules\") for k in keys) and any(\n        k.split(\".\")[0].startswith(\"lllite_dit_blocks_\") for k in keys\n    )","tryCatchPattern":"try:\n    cnet = ControlNetLLLiteDiT.from_state_dict(sd, metadata)\nexcept ValueError as e:\n    if \"legacy\" in str(e):\n        sd = convert_legacy_lllite_state_dict(sd)\n        cnet = ControlNetLLLiteDiT.from_state_dict(sd, metadata)\n    else:\n        raise","preventionTips":["Re-export old checkpoints with current training code.","Keep a one-time legacy->v2 conversion script handy.","Check safetensors metadata for a format/version field before loading.","Document which model files are legacy in your model registry."],"tags":["controlnet","checkpoint","legacy-format","migration"],"backgroundTag":"legacy-checkpoint-format","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}