{"record":{"id":"5f40c1f31b2f3355","repo":"invoke-ai/InvokeAI","slug":"model-does-not-match-qwen-image-lora-heuristics","errorCode":null,"errorMessage":"model does not match Qwen Image LoRA heuristics","messagePattern":"model does not match Qwen Image LoRA heuristics","errorType":"exception","errorClass":"NotAMatchError","httpStatus":null,"severity":"error","filePath":"invokeai/backend/model_manager/configs/lora.py","lineNumber":858,"sourceCode":"        # text-fusion stage. Exclude them here so they route to LoRA_LyCORIS_Krea2_Config.\n        has_krea2_keys = _has_krea2_lora_keys(state_dict)\n        has_flux_keys = state_dict_has_any_keys_starting_with(\n            state_dict,\n            {\n                \"double_blocks.\",\n                \"single_blocks.\",\n                \"single_transformer_blocks.\",\n                \"transformer.single_transformer_blocks.\",\n                \"lora_unet_double_blocks_\",\n                \"lora_unet_single_blocks_\",\n                \"lora_unet_single_transformer_blocks_\",\n            },\n        )\n\n        if has_qwen_ie_keys and has_lora_suffix and not has_z_image_keys and not has_krea2_keys and not has_flux_keys:\n            return\n\n        raise NotAMatchError(\"model does not match Qwen Image LoRA heuristics\")\n\n    @classmethod\n    def _get_base_or_raise(cls, mod: ModelOnDisk) -> BaseModelType:\n        state_dict = mod.load_state_dict()\n        has_qwen_ie_keys = state_dict_has_any_keys_starting_with(\n            state_dict,\n            {\"transformer_blocks.\", \"transformer.transformer_blocks.\", \"lora_unet_transformer_blocks_\"},\n        )\n        has_z_image_keys = state_dict_has_any_keys_starting_with(state_dict, {\"diffusion_model.layers.\"})\n        has_krea2_keys = _has_krea2_lora_keys(state_dict)\n        has_flux_keys = state_dict_has_any_keys_starting_with(\n            state_dict,\n            {\n                \"double_blocks.\",\n                \"single_blocks.\",\n                \"single_transformer_blocks.\",\n                \"transformer.single_transformer_blocks.\",\n                \"lora_unet_double_blocks_\",","sourceCodeStart":840,"sourceCodeEnd":876,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/backend/model_manager/configs/lora.py#L840-L876","documentation":"NotAMatchError raised by LoRA_LyCORIS_QwenImage_Config._validate_looks_like_lora when the state dict fails the conjunctive Qwen Image Edit test: it must have transformer_blocks./transformer.transformer_blocks./lora_unet_transformer_blocks_ keys AND a LoRA suffix (lora_A/lora_B/lora_down/lora_up/dora_scale/lokr_w1/lokr_w2) AND must NOT contain Z-Image (diffusion_model.layers.), Krea-2 (text_fusion/txtfusion/time_mod_proj/attn.wq+attn.gate), or Flux (double_blocks/single_blocks/etc.) keys. Any failure of this combined condition rejects the file.","triggerScenarios":"from_model_on_disk probes a candidate Qwen Image LoRA and either the transformer_blocks prefixes are absent, no LoRA/LoKR suffix exists, or the file actually belongs to Z-Image, Krea-2, or Flux (excluded to prevent false routing).","commonSituations":"Importing a Flux LoRA whose transformer_blocks keys triggered the Qwen candidate (correctly rejected), a Krea-2 LoRA carrying transformer.transformer_blocks keys, a merged model with residual LoRA keys, or a genuinely broken/truncated Qwen LoRA missing its lora_A/lora_B weights.","solutions":["Determine which exclusions fired: if the file has diffusion_model.layers./double_blocks./Krea-2 keys, it belongs to another base — let the correct config claim it; the error may be an expected probe failure.","For a real Qwen Image LoRA, update InvokeAI so newer trainer formats and exclusions are recognized.","Verify file integrity — a truncated safetensors may have lost the lora_A/lora_B suffix keys; re-download.","Re-export in Kohya (lora_unet_transformer_blocks_...) or diffusers PEFT format matching the expected prefixes/suffixes.","Install with explicit base override (base=QwenImage) to bypass heuristics."],"exampleFix":"// before: Qwen LoRA whose keys also include Flux single_blocks (ambiguous)\n// after: strip the foreign keys before import\ntargeted = {k: v for k, v in sd.items() if not k.startswith((\"single_blocks.\", \"double_blocks.\"))}\nsave_file(targeted, \"qwen_lora.safetensors\")","handlingStrategy":"validation","validationCode":"sd = load_file(\"model.safetensors\")\nqwen_prefixes = (\"transformer_blocks.\", \"transformer.transformer_blocks.\", \"lora_unet_transformer_blocks_\")\nlora_suffixes = (\"lora_A.weight\", \"lora_B.weight\", \"lora_down.weight\", \"lora_up.weight\",\n                 \"dora_scale\", \"lokr_w1\", \"lokr_w2\")\nexcluded = (\"diffusion_model.layers.\", \"double_blocks.\", \"single_blocks.\",\n            \"single_transformer_blocks.\", \"transformer.single_transformer_blocks.\")\nok = (any(k.startswith(qwen_prefixes) for k in sd)\n      and any(k.endswith(lora_suffixes) for k in sd)\n      and not any(k.startswith(excluded) for k in sd)\n      and not any(\"text_fusion\" in k or \"txtfusion\" in k or \"time_mod_proj\" in k for k in sd))\nif not ok:\n    print(\"Will not match Qwen Image LoRA heuristics\")","typeGuard":"def is_qwen_image_lora_state_dict(state_dict: dict) -> bool:\n    qwen = (\"transformer_blocks.\", \"transformer.transformer_blocks.\", \"lora_unet_transformer_blocks_\")\n    lora = (\"lora_A.weight\", \"lora_B.weight\", \"lora_down.weight\", \"lora_up.weight\", \"dora_scale\", \"lokr_w1\", \"lokr_w2\")\n    flux_or_z = (\"diffusion_model.layers.\", \"double_blocks.\", \"single_blocks.\", \"single_transformer_blocks.\")\n    return (any(k.startswith(qwen) for k in state_dict)\n            and any(k.endswith(lora) for k in state_dict)\n            and not any(k.startswith(flux_or_z) for k in state_dict))","tryCatchPattern":"try:\n    config = LoRA_LyCORIS_QwenImage_Config.from_model_on_disk(mod, {})\nexcept NotAMatchError as e:\n    logger.warning(\"Qwen Image heuristic rejected file: %s\", e)\n    config = None  # allow other config classes (Flux/Krea2/ZImage) to claim it","preventionTips":["Strip foreign base-model keys (Flux/Z-Image/Krea-2) from mixed or merged files before importing as Qwen LoRAs.","Ensure the LoRA retains lora_A/lora_B/lora_down/lora_up weights — truncated files lose these suffixes first.","Re-export Krea-2 or Flux look-alike LoRAs under their own naming so routing isn't blocked by the exclusion checks.","Verify the model page actually says Qwen Image Edit before importing; look-alike DiT naming causes most rejections."],"tags":["lora","qwen-image","model-import","heuristic-matching","invokeai"],"backgroundTag":"unrecognized-model-format","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}