{"record":{"id":"5a9d9b510554d3f9","repo":"invoke-ai/InvokeAI","slug":"model-does-not-match-lycoris-lora-heuristics","errorCode":null,"errorMessage":"model does not match LyCORIS LoRA heuristics","messagePattern":"model does not match LyCORIS LoRA heuristics","errorType":"exception","errorClass":"NotAMatchError","httpStatus":null,"severity":"warning","filePath":"invokeai/backend/model_manager/configs/lora.py","lineNumber":636,"sourceCode":"\n        has_key_with_lora_suffix = state_dict_has_any_keys_ending_with(\n            mod.load_state_dict(),\n            {\n                \"to_k_lora.up.weight\",\n                \"to_q_lora.down.weight\",\n                \"lora_A.weight\",\n                \"lora_B.weight\",\n                # LyCORIS LoKR suffixes\n                \"lokr_w1\",\n                \"lokr_w2\",\n                # LyCORIS LoHA suffixes\n                \"hada_w1_a\",\n                \"hada_w2_a\",\n            },\n        )\n\n        if not has_key_with_lora_prefix and not has_key_with_lora_suffix:\n            raise NotAMatchError(\"model does not match LyCORIS LoRA heuristics\")\n\n    @classmethod\n    def _get_base_or_raise(cls, mod: ModelOnDisk) -> BaseModelType:\n        if _get_flux_lora_format(mod):\n            if _is_flux2_lora(mod):\n                return BaseModelType.Flux2\n            return BaseModelType.Flux\n\n        state_dict = mod.load_state_dict()\n        str_keys = [k for k in state_dict.keys() if isinstance(k, str)]\n\n        # Rule out Anima LoRAs — their lora_te_ keys have shapes that\n        # lora_token_vector_length() misidentifies as SD2/SDXL.\n        if has_cosmos_dit_kohya_keys(str_keys) or has_cosmos_dit_peft_keys(str_keys):\n            raise NotAMatchError(\"model looks like an Anima LoRA, not a Stable Diffusion LoRA\")\n\n        # If we've gotten here, we assume that the model is a Stable Diffusion model\n        token_vector_length = lora_token_vector_length(state_dict)","sourceCodeStart":618,"sourceCodeEnd":654,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/backend/model_manager/configs/lora.py#L618-L654","documentation":"The LyCORIS config class uses heuristics: it expects at least one state-dict key with a LoRA prefix (e.g. `lora_`) or LoRA suffix (e.g. `.lora_down/.lora_up`) and LyCORIS-specific keys like `hada_w1_a`/`hada_w2_a`. If the file has neither prefix-style nor suffix-style LoRA keys, it cannot be a LyCORIS LoRA and `NotAMatchError` is raised so other config classes can be tried.","triggerScenarios":"`from_model_on_disk` probing a checkpoint that lacks both `lora_`-prefixed keys and `lora`-suffixed keys — e.g. a full checkpoint, a text-encoder-only patch, or a LoCON/other format with unrecognized key naming.","commonSituations":"Trying to load a full fine-tuned checkpoint as a LyCORIS; a LoRA saved with nonstandard key names (custom trainer); files that are DoRA/other experimental formats not matching LyCORIS heuristics.","solutions":["Verify the file is actually a LyCORIS/LoCon file and re-export it in Kohya or diffusers LoRA format","If it's a full checkpoint, import it as a main model, not a LoRA","Rename/convert keys with a conversion script so they carry `lora_` prefix or `lora` suffix","Upgrade InvokeAI if the format is a newly supported LyCORIS variant"],"exampleFix":"// before: checkpoint keys\n{\"transformer.blocks.0.attn.qkv.weight\": ...}\n// after: convert to LyCORIS keys\n{\"lora_unet_blocks_0_attn_qkv.hada_w1_a\": ..., \"lora_unet_blocks_0_attn_qkv.hada_w2_b\": ...}","handlingStrategy":"validation","validationCode":"from safetensors import safe_open\nwith safe_open(file, framework=\"pt\") as f:\n    keys = list(f.keys())\nif not any(k.startswith(\"lora_\") for k in keys) and not any(k.endswith(\".lora_down.weight\") for k in keys):\n    print(\"not a LyCORIS/LoRA state dict — full checkpoint or unknown format\")","typeGuard":"def looks_like_lycoris(keys: list[str]) -> bool:\n    return any(k.startswith(\"lora_\") for k in keys) or any(\"lora\" in k and (\"down\" in k or \"up\" in k) for k in keys)","tryCatchPattern":"try:\n    cfg = LoRALyCORISConfig.from_model_on_disk(mod)\nexcept NotAMatchError:\n    if looks_like_full_checkpoint(mod):\n        import_as_main_model(mod)","preventionTips":["Only import LyCORIS files exported with standard key naming","Distinguish full checkpoints from LoRA files before import","Use standard trainers (kohya_ss) that emit recognizable keys"],"tags":["lora","lycoris","heuristics","not-a-match"],"backgroundTag":"lora-format-not-recognized","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}