invoke-ai/InvokeAI · error · TypeError

LLLite target for '{m.lllite_name}' is {type(target).__name_

Error message

LLLite target for '{m.lllite_name}' is {type(target).__name__}, expected nn.Linear

What it means

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.

Source

Thrown at invokeai/backend/anima/control_net_lllite.py:519

        cx = self.conditioning1(cond)  # (B, S, cond_emb_dim)
        for m in self.lllite_modules:
            m.cond_emb = cx

    def clear_cond_image(self) -> None:
        self.set_cond_image(None)

    def set_multiplier(self, multiplier: float) -> None:
        self.multiplier = multiplier
        for m in self.lllite_modules:
            m.multiplier = multiplier

    def apply_to(self, transformer: nn.Module) -> None:
        """Swap the forward of each target Linear in ``transformer``. Idempotent."""
        self.restore()
        for m in self.lllite_modules:
            target = self._resolve_target(transformer, m.lllite_name)
            if not isinstance(target, nn.Linear):
                raise TypeError(f"LLLite target for '{m.lllite_name}' is {type(target).__name__}, expected nn.Linear")
            if target.in_features != m.in_dim:
                raise ValueError(
                    f"LLLite module '{m.lllite_name}' was trained for in_features={m.in_dim}, but the "
                    f"target Linear has in_features={target.in_features}"
                )
            m.bind(target)

    def restore(self) -> None:
        """Undo :meth:`apply_to`. Safe to call when not applied.

        LIFO contract: each bind saves the forward that was CURRENT at bind
        time, so when multiple adapters are stacked on one transformer they
        must be restored in reverse apply order. Restoring an earlier adapter
        first would delete a later adapter's wrapper and re-pin the earlier
        one's saved forward.
        """
        for m in self.lllite_modules:
            m.unbind()

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Verify the ControlNet matches the base model architecture it was trained against.
  2. Ensure transformer layers at the target paths are plain nn.Linear (disable quantization/fusion for these modules).
  3. Inspect with self._resolve_target(transformer, name) and check isinstance(target, nn.Linear) before apply_to.
  4. Update the module name mapping if a refactor moved the Linear behind a wrapper.

Example fix

# before
cnet.apply_to(transformer)  # TypeError: target is FusedLinear
# after
for name in [m.lllite_name for m in cnet.lllite_modules]:
    t = cnet._resolve_target(transformer, name)
    assert isinstance(t, torch.nn.Linear), (name, type(t))
cnet.apply_to(transformer)
Defensive patterns

Strategy: type-guard

Validate before calling

import torch.nn as nn
def validate_lllite_targets(cnet, transformer: nn.Module) -> None:
    for m in cnet.lllite_modules:
        target = cnet._resolve_target(transformer, m.lllite_name)
        if not isinstance(target, nn.Linear):
            raise TypeError(f"{m.lllite_name} resolves to {type(target).__name__}, need nn.Linear")
        if target.in_features != m.in_dim:
            raise ValueError(f"{m.lllite_name}: in_features {target.in_features} != {m.in_dim}")

Type guard

import torch.nn as nn
def is_compatible_lllite_target(target) -> bool:
    return isinstance(target, nn.Linear)

Try / catch

try:
    cnet.apply_to(transformer)
except TypeError as e:
    raise RuntimeError(f"ControlNet incompatible with this model (non-Linear target): {e}") from e

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29). Data as JSON: /api/errors/7a56f8ae7e53b83f. Report an issue: GitHub.