{"record":{"id":"20f4cafca6188724","repo":"invoke-ai/InvokeAI","slug":"state-dict-does-not-look-like-a-qwen3-model","errorCode":null,"errorMessage":"state dict does not look like a Qwen3 model","messagePattern":"state dict does not look like a Qwen3 model","errorType":"exception","errorClass":"NotAMatchError","httpStatus":null,"severity":"warning","filePath":"invokeai/backend/model_manager/configs/qwen3_encoder.py","lineNumber":233,"sourceCode":"\n    @classmethod\n    def _get_variant_or_default(cls, mod: ModelOnDisk) -> Qwen3VariantType:\n        \"\"\"Get the variant from state dict, raising NotAMatch when the size does not match a known Qwen3 variant.\n\n        We previously defaulted to 4B for unknown sizes, but that swallowed other causal-LM GGUFs\n        (Mistral, Llama, ...) which share llama.cpp tensor naming with Qwen3.\n        \"\"\"\n        state_dict = mod.load_state_dict()\n        variant = _get_qwen3_variant_from_state_dict(state_dict)\n        if variant is None:\n            raise NotAMatchError(\"hidden size does not match a known Qwen3 variant\")\n        return variant\n\n    @classmethod\n    def _validate_looks_like_qwen3_model(cls, mod: ModelOnDisk) -> None:\n        state_dict = mod.load_state_dict()\n        if not _has_qwen3_keys(state_dict):\n            raise NotAMatchError(\"state dict does not look like a Qwen3 model\")\n        # Reject T5 encoders: they share the token_embd.weight key with Qwen3 GGUFs but use the ``enc.``\n        # block prefix, and must be classified as T5Encoder (Qwen3 encoders never have ``enc.blk.*`` keys).\n        if _has_t5_encoder_keys(state_dict):\n            raise NotAMatchError(\"state dict looks like a T5 encoder (has 'enc.blk.*' keys), not a Qwen3 encoder\")\n        # Reject Gemma-2/3 encoders: their GGUFs also carry token_embd.weight + blk.* keys but use\n        # post-attention / post-feedforward norms a Qwen3 encoder never has; they must be classified as\n        # Gemma2Encoder (otherwise a Gemma GGUF matches both configs and can be re-identified wrongly).\n        if _has_gemma2_keys(state_dict):\n            raise NotAMatchError(\n                \"state dict looks like a Gemma-2 encoder (has post_attention_norm/post_ffw_norm keys), \"\n                \"not a Qwen3 encoder\"\n            )\n        # Reject Qwen2.5-VL / Qwen2-VL encoders: they carry a visual tower and must be\n        # classified as QwenVLEncoder (text-only Qwen3 encoders never have one).\n        if _has_qwen_vl_visual_tower(state_dict):\n            raise NotAMatchError(\n                \"state dict bundles a Qwen-VL visual tower; this is a Qwen-VL encoder, not a text-only Qwen3 encoder\"\n            )","sourceCodeStart":215,"sourceCodeEnd":251,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/backend/model_manager/configs/qwen3_encoder.py#L215-L251","documentation":"NotAMatchError raised by Qwen3Encoder._validate_looks_like_qwen3_model (qwen3_encoder.py:233) during model identification via from_model_on_disk. The state dict loaded from the candidate model folder lacks the keys that identify a Qwen3 model (e.g. token_embd.weight / blk.* for GGUF or Qwen3 transformer keys), so this config claims it is not a Qwen3 encoder and lets other configs match. It is a classification guard, not a fatal failure of your model.","triggerScenarios":"Calling ModelManager search/heuristic model install (Qwen3Encoder config's from_model_on_disk) on a folder whose state dict does not contain _has_qwen3_keys() matches — e.g. a safetensors folder of a non-Qwen model, a weights file missing blk/token_embd tensors, or a GGUF whose tensors were renamed/stripped.","commonSituations":"Installing a Llama/Mistral/T5 GGUF or safetensors folder into InvokeAI; downloading an incomplete/partial model snapshot (missing weight shards); pointing the scan at the wrong subdirectory so load_state_dict() sees unrelated files.","solutions":["Verify the model actually is a Qwen3 encoder (check config.json architectures or GGUF metadata); if not, install it under the correct model type/config.","Re-download the model — missing tensors mean an incomplete snapshot; confirm all safetensors/GGUF shards are present.","If it is a genuine Qwen3 encoder, ensure the state dict key names are standard (blk.*, token_embd.weight); re-convert with a current llama.cpp/convert script if keys were renamed.","Scan the correct folder: the config expects model_root/text_encoder/config.json or model_root/config.json with the weights alongside.","If identification should not be attempted for this file, exclude it from the scan directory or add an explicit type/override fields."],"exampleFix":"// before (wrong folder scanned)\nmodels/qwen3-encoder/  # contains unrelated Llama GGUF\n// after\nmodels/qwen3-encoder/text_encoder/token_embd.weight etc. (real Qwen3 tensors),\nmodels/llama/ (install as its own model type)","handlingStrategy":"validation","validationCode":"from safetensors import safe_open\nimport json, pathlib\ndef looks_like_qwen3_encoder(path: pathlib.Path) -> bool:\n    cfg = None\n    for cand in (path / 'text_encoder' / 'config.json', path / 'config.json'):\n        if cand.exists():\n            cfg = json.loads(cand.read_text())\n            break\n    if cfg is None:\n        return False\n    archs = cfg.get('architectures', [])\n    return any(a in {'Qwen3ForCausalLM', 'Qwen2ForCausalLM', 'Qwen2VLForConditionalGeneration'} for a in archs)","typeGuard":"def is_qwen3_state_dict(state_dict: dict) -> bool:\n    keys = set(state_dict)\n    has_qwen3 = 'token_embd.weight' in keys or any(k.startswith('blk.') or k.startswith('model.layers.') for k in keys)\n    not_t5 = not any(k.startswith('enc.blk.') for k in keys)\n    return has_qwen3 and not_t5","tryCatchPattern":"from invokeai.backend.model_manager.configs.qwen3_encoder import Qwen3Encoder_Qwen3Encoder_Config\nfrom invokeai.backend.model_manager.configs.base import NotAMatchError\ntry:\n    cfg = Qwen3Encoder_Qwen3Encoder_Config.from_model_on_disk(mod, overrides)\nexcept NotAMatchError as e:\n    logger.warning('Not a Qwen3 encoder: %s — trying other configs', e)\n    cfg = fallback_identify(mod, overrides)","preventionTips":["Check config.json architectures before installing a model into the encoder folder.","Verify GGUF/safetensors tensor names match Qwen3 conventions (blk.*, no enc.* prefix).","Re-download models whose snapshots may be incomplete.","Keep each model family in its own directory so scanners probe the right configs."],"tags":["model-identification","state-dict","qwen3","invokeai"],"backgroundTag":"model-not-a-match","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}