invoke-ai/InvokeAI · error · NotAMatchError

model does not match Anima LoRA heuristics

Error message

model does not match Anima LoRA heuristics

What it means

The Anima LoRA config's _validate_looks_like_lora accepts a file only when it has Cosmos DiT block keys (blocks.X.mlp, blocks.X.adaln_modulation, blocks.X.cross_attn.q_proj, etc.) AND those keys carry a LoRA suffix; both `has_cosmos_keys and has_lora_suffix` must hold. Files matching the block layout but missing LoRA suffixes — or with LoRA suffixes but no Cosmos block structure — raise this NotAMatchError.

Source

Thrown at invokeai/backend/model_manager/configs/lora.py:1063

        # Also check for LoRA/LoKR weight suffixes
        has_lora_suffix = state_dict_has_any_keys_ending_with(
            state_dict,
            {
                "lora_A.weight",
                "lora_B.weight",
                "lora_down.weight",
                "lora_up.weight",
                "dora_scale",
                ".lokr_w1",
                ".lokr_w2",
            },
        )

        if has_cosmos_keys and has_lora_suffix:
            return

        raise NotAMatchError("model does not match Anima LoRA heuristics")

    @classmethod
    def _get_base_or_raise(cls, mod: ModelOnDisk) -> BaseModelType:
        """Anima LoRAs target Cosmos DiT blocks (blocks.X.mlp, blocks.X.adaln_modulation,
        blocks.X.cross_attn.q_proj, etc.).

        Uses the strict Cosmos-DiT detectors to be mutually exclusive with
        Wan-LoRA detection — see ``_validate_looks_like_lora`` for rationale.
        """
        state_dict = mod.load_state_dict()
        str_keys = [k for k in state_dict.keys() if isinstance(k, str)]

        if has_cosmos_dit_kohya_keys_strict(str_keys) or has_cosmos_dit_peft_keys_strict(str_keys):
            return BaseModelType.Anima

        raise NotAMatchError("model does not look like an Anima LoRA")

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Confirm the file's role: if it is a full Anima checkpoint, install it as a main/checkpoint model, not a LoRA.
  2. Dump keys and verify both the blocks.X.* pattern and a lora suffix; if suffixes were stripped, re-export with standard LoRA naming.
  3. If it targets a different DiT, let the matching config class claim it (or choose the model type manually in the installer).
  4. Update InvokeAI if the Anima/Cosmos export naming is newer than the installed heuristic table.

Example fix

// before: full checkpoint hits the LoRA probe and raises
installer.install_as_lora(path="anima_v1.safetensors")  # NotAMatchError
// after: verify Cosmos block keys + lora suffix first
from safetensors import safe_open
import re
with safe_open("anima_v1.safetensors", framework="pt") as f:
    ks = list(f.keys())
cosmos = [k for k in ks if re.search(r"blocks\.\d+\.(mlp|adaln_modulation|cross_attn\.)", k)]
has_lora_suffix = any(k.endswith(("lora_A", "lora_B", "lora_down", "lora_up")) or ".lora_" in k for k in ks)
if cosmos and has_lora_suffix:
    installer.install_as_lora(path="anima_v1.safetensors")
else:
    installer.install_as_checkpoint(path="anima_v1.safetensors")
Defensive patterns

Strategy: validation

Validate before calling

import re
from safetensors import safe_open

def looks_like_anima_lora(path):
    with safe_open(path, framework="pt") as f:
        ks = list(f.keys())
    cosmos = any(re.search(r"blocks\.\d+\.(mlp|adaln_modulation|cross_attn\.)", k) for k in ks)
    suffix = any(k.endswith(("lora_A", "lora_B", "lora_down", "lora_up")) or ".lora_" in k for k in ks)
    return cosmos and suffix

assert looks_like_anima_lora("model.safetensors"), "not an Anima LoRA — likely a checkpoint or another format"

Type guard

def is_anima_lora_state_dict(keys: list[str]) -> bool:
    import re
    cosmos = any(re.search(r"blocks\.\d+\.(mlp|adaln_modulation|cross_attn\.)", k) for k in keys)
    suffix = any(k.endswith(("lora_A", "lora_B", "lora_down", "lora_up")) or ".lora_" in k for k in keys)
    return cosmos and suffix

Try / catch

try:
    installer.install_as_lora(path="model.safetensors")
except NotAMatchError as e:
    if "Anima LoRA heuristics" in str(e):
        log.warning("not an Anima LoRA (%s); retrying as checkpoint/main model", e)
        installer.install_as_checkpoint(path="model.safetensors")
    else:
        raise

Prevention

When it happens

Trigger: from_model_on_disk validation of a candidate Anima LoRA where the state dict either lacks blocks.X.* Cosmos DiT keys entirely (e.g. a transformer_blocks/h--style naming from another DiT) or has Cosmos keys without lora/lora_A/lora_down style suffixes (e.g. a full Anima checkpoint probed as a LoRA).

Common situations: Installing an Anima full-model checkpoint through the LoRA config class by mistake; downloading a similarly-named LoRA trained for another Cosmos-variant model; key-renaming tools or ComfyUI exports that strip the standard suffixes; the file simply is not an Anima LoRA at all and auto-detection is just cycling through config classes.

Related errors


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