{"record":{"id":"7a56f8ae7e53b83f","repo":"invoke-ai/InvokeAI","slug":"lllite-target-for-m-lllite-name-is-type-targe","errorCode":null,"errorMessage":"LLLite target for '{m.lllite_name}' is {type(target).__name__}, expected nn.Linear","messagePattern":"LLLite target for '(.+?)' is (.+?), expected nn\\.Linear","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"invokeai/backend/anima/control_net_lllite.py","lineNumber":519,"sourceCode":"        cx = self.conditioning1(cond)  # (B, S, cond_emb_dim)\n        for m in self.lllite_modules:\n            m.cond_emb = cx\n\n    def clear_cond_image(self) -> None:\n        self.set_cond_image(None)\n\n    def set_multiplier(self, multiplier: float) -> None:\n        self.multiplier = multiplier\n        for m in self.lllite_modules:\n            m.multiplier = multiplier\n\n    def apply_to(self, transformer: nn.Module) -> None:\n        \"\"\"Swap the forward of each target Linear in ``transformer``. Idempotent.\"\"\"\n        self.restore()\n        for m in self.lllite_modules:\n            target = self._resolve_target(transformer, m.lllite_name)\n            if not isinstance(target, nn.Linear):\n                raise TypeError(f\"LLLite target for '{m.lllite_name}' is {type(target).__name__}, expected nn.Linear\")\n            if target.in_features != m.in_dim:\n                raise ValueError(\n                    f\"LLLite module '{m.lllite_name}' was trained for in_features={m.in_dim}, but the \"\n                    f\"target Linear has in_features={target.in_features}\"\n                )\n            m.bind(target)\n\n    def restore(self) -> None:\n        \"\"\"Undo :meth:`apply_to`. Safe to call when not applied.\n\n        LIFO contract: each bind saves the forward that was CURRENT at bind\n        time, so when multiple adapters are stacked on one transformer they\n        must be restored in reverse apply order. Restoring an earlier adapter\n        first would delete a later adapter's wrapper and re-pin the earlier\n        one's saved forward.\n        \"\"\"\n        for m in self.lllite_modules:\n            m.unbind()","sourceCodeStart":501,"sourceCodeEnd":537,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/backend/anima/control_net_lllite.py#L501-L537","documentation":"apply_to walks each LLLite module, resolves its named target layer in the transformer, and swaps that layer's forward. It raises TypeError when the resolved target is not an nn.Linear (e.g. a Conv2d, custom wrapper, or parallel/quantized linear), since LLLite can only patch Linear layers.","triggerScenarios":"Calling apply_to(transformer) where the name pattern resolves to a non-Linear module — a model whose blocks use Conv/Modulated projections, a quantized or fused-attention variant, or a wrapper module around the Linear.","commonSituations":"Applying a ControlNet trained for one model architecture to a different DiT whose block layer types differ, using quantized (bnb/torchao) linears that subclass differently, or model refactorings that wrapped projections.","solutions":["Verify the ControlNet matches the base model architecture it was trained against.","Ensure transformer layers at the target paths are plain nn.Linear (disable quantization/fusion for these modules).","Inspect with self._resolve_target(transformer, name) and check isinstance(target, nn.Linear) before apply_to.","Update the module name mapping if a refactor moved the Linear behind a wrapper."],"exampleFix":"# before\ncnet.apply_to(transformer)  # TypeError: target is FusedLinear\n# after\nfor name in [m.lllite_name for m in cnet.lllite_modules]:\n    t = cnet._resolve_target(transformer, name)\n    assert isinstance(t, torch.nn.Linear), (name, type(t))\ncnet.apply_to(transformer)","handlingStrategy":"type-guard","validationCode":"import torch.nn as nn\ndef validate_lllite_targets(cnet, transformer: nn.Module) -> None:\n    for m in cnet.lllite_modules:\n        target = cnet._resolve_target(transformer, m.lllite_name)\n        if not isinstance(target, nn.Linear):\n            raise TypeError(f\"{m.lllite_name} resolves to {type(target).__name__}, need nn.Linear\")\n        if target.in_features != m.in_dim:\n            raise ValueError(f\"{m.lllite_name}: in_features {target.in_features} != {m.in_dim}\")","typeGuard":"import torch.nn as nn\ndef is_compatible_lllite_target(target) -> bool:\n    return isinstance(target, nn.Linear)","tryCatchPattern":"try:\n    cnet.apply_to(transformer)\nexcept TypeError as e:\n    raise RuntimeError(f\"ControlNet incompatible with this model (non-Linear target): {e}\") from e","preventionTips":["Only apply ControlNets to the model family they were trained for.","Disable quantization/fused projections for patched layers or keep them as plain nn.Linear.","Call restore() before re-applying or switching models (apply_to already does).","Smoke-test apply_to/restore bit-exactness in CI for each supported model."],"tags":["controlnet","pytorch","type-mismatch","model-architecture"],"backgroundTag":"unsupported-layer-type","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}