{"record":{"id":"170030a0524571f8","repo":"invoke-ai/InvokeAI","slug":"state-dict-does-not-look-like-a-single-file-qwen3","errorCode":null,"errorMessage":"state dict does not look like a single-file Qwen3-VL encoder","messagePattern":"state dict does not look like a single-file Qwen3-VL encoder","errorType":"validation","errorClass":"NotAMatchError","httpStatus":null,"severity":"error","filePath":"invokeai/backend/model_manager/configs/qwen3_vl_encoder.py","lineNumber":192,"sourceCode":"    \"\"\"\n\n    base: Literal[BaseModelType.Any] = Field(default=BaseModelType.Any)\n    type: Literal[ModelType.Qwen3VLEncoder] = Field(default=ModelType.Qwen3VLEncoder)\n    format: Literal[ModelFormat.Checkpoint] = Field(default=ModelFormat.Checkpoint)\n    cpu_only: bool | None = Field(default=None, description=\"Whether this model should run on CPU only\")\n\n    @classmethod\n    def from_model_on_disk(cls, mod: ModelOnDisk, override_fields: dict[str, Any]) -> Self:\n        raise_if_not_file(mod)\n\n        raise_for_override_fields(cls, override_fields)\n\n        if mod.path.suffix.lower() != \".safetensors\":\n            raise NotAMatchError(f\"expected a .safetensors file, got {mod.path.suffix or '(no suffix)'}\")\n\n        state_dict = mod.load_state_dict()\n        if not _is_qwen3_vl_encoder_state_dict(state_dict):\n            raise NotAMatchError(\"state dict does not look like a single-file Qwen3-VL encoder\")\n        _validate_krea2_qwen3_vl_checkpoint_shape(state_dict)\n\n        return cls(**override_fields)\n","sourceCodeStart":174,"sourceCodeEnd":196,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/backend/model_manager/configs/qwen3_vl_encoder.py#L174-L196","documentation":"Raised as a NotAMatchError by Qwen3VLEncoder_Checkpoint_Config.from_model_on_disk when a .safetensors file loads but _is_qwen3_vl_encoder_state_dict() returns False — i.e. the key layout does not contain both a language-model decoder (keys with '.layers.' and 'model.' prefix) and a Qwen3-VL visual tower (keys starting with 'visual.', 'model.visual.', or containing '.visual.'). The visual tower is what distinguishes Qwen3-VL from the text-only Qwen3 encoder, so a text-only checkpoint is rejected.","triggerScenarios":"Importing a single .safetensors file that is a text-only Qwen3 encoder (Z-Image / FLUX.2 Klein), a stripped/comfied checkpoint with renamed or pruned vision keys, or a diffusers-format tensor bundle whose keys use a naming scheme with no visual.* / .visual.* entries.","commonSituations":"Grabbing the wrong companion file (text-only qwen3 encoder instead of qwen3_vl_4b); a checkpoint re-exported with keys stripped of the vision tower; custom merges that rename visual.* keys; using a partial checkpoint containing only language-model layers.","solutions":["Inspect keys with `safetensors.safe_open(path).keys()` and confirm both language-model layer keys and visual-tower keys exist.","Download the correct single-file Qwen3-VL checkpoint (e.g. a qwen3vl_4b_* safetensors that includes the vision tower).","If you have a text-only Qwen3 encoder, let it match the text-only Qwen3Encoder config instead of forcing the Qwen3-VL checkpoint type.","Re-export the checkpoint preserving original visual.* key names; restore missing vision-tower weights from the base repo."],"exampleFix":"// before: text-only checkpoint -> rejected\nkeys: ['model.embed_tokens.weight', 'model.layers.0...']  # no visual.*\n\n// after: correct Qwen3-VL checkpoint\nkeys: ['model.layers.35...', 'visual.patch_embed.proj.weight', ...]","handlingStrategy":"validation","validationCode":"from safetensors import safe_open\n\ndef looks_like_qwen3vl_checkpoint(path) -> bool:\n    with safe_open(str(path), framework=\"pt\", device=\"cpu\") as f:\n        keys = list(f.keys())\n    has_text = any(\".layers.\" in k and (\"model.\" in k or k.startswith(\"layers.\")) for k in keys)\n    has_visual = any(k.startswith((\"visual.\", \"model.visual.\")) or \".visual.\" in k for k in keys)\n    return has_text and has_visual","typeGuard":"def is_qwen3vl_state_dict(keys: list[str]) -> bool:\n    has_text_decoder = any(\".layers.\" in k and (\"model.\" in k or k.startswith(\"layers.\")) for k in keys)\n    has_visual_tower = any(k.startswith((\"visual.\", \"model.visual.\")) or \".visual.\" in k for k in keys)\n    return has_text_decoder and has_visual_tower","tryCatchPattern":"try:\n    invokeai_model_manager.probe(file_path)\nexcept NotAMatchError as e:\n    if \"does not look like a single-file Qwen3-VL encoder\" in str(e):\n        # likely a text-only Qwen3 encoder or wrong checkpoint; inspect keys and re-source the file\n        inspect_and_relocate_checkpoint(file_path)\n    else:\n        raise","preventionTips":["Download checkpoints from the official qwen3vl_4b safetensors releases, not ad-hoc re-exports.","Inspect safetensors headers (keys only) before importing large files to confirm visual.* keys exist.","Don't prune or rename keys when converting checkpoints between formats.","Keep text-only Qwen3 encoders and Qwen3-VL checkpoints clearly separated by filename."],"tags":["invokeai","model-import","state-dict","checkpoint","not-a-match"],"backgroundTag":"checkpoint-key-mismatch","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}