invoke-ai/InvokeAI · error · NotAMatchError

state dict does not look like a single-file Qwen3-VL encoder

Error message

state dict does not look like a single-file Qwen3-VL encoder

What it means

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.

Source

Thrown at invokeai/backend/model_manager/configs/qwen3_vl_encoder.py:192

    """

    base: Literal[BaseModelType.Any] = Field(default=BaseModelType.Any)
    type: Literal[ModelType.Qwen3VLEncoder] = Field(default=ModelType.Qwen3VLEncoder)
    format: Literal[ModelFormat.Checkpoint] = Field(default=ModelFormat.Checkpoint)
    cpu_only: bool | None = Field(default=None, description="Whether this model should run on CPU only")

    @classmethod
    def from_model_on_disk(cls, mod: ModelOnDisk, override_fields: dict[str, Any]) -> Self:
        raise_if_not_file(mod)

        raise_for_override_fields(cls, override_fields)

        if mod.path.suffix.lower() != ".safetensors":
            raise NotAMatchError(f"expected a .safetensors file, got {mod.path.suffix or '(no suffix)'}")

        state_dict = mod.load_state_dict()
        if not _is_qwen3_vl_encoder_state_dict(state_dict):
            raise NotAMatchError("state dict does not look like a single-file Qwen3-VL encoder")
        _validate_krea2_qwen3_vl_checkpoint_shape(state_dict)

        return cls(**override_fields)

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Inspect keys with `safetensors.safe_open(path).keys()` and confirm both language-model layer keys and visual-tower keys exist.
  2. Download the correct single-file Qwen3-VL checkpoint (e.g. a qwen3vl_4b_* safetensors that includes the vision tower).
  3. If you have a text-only Qwen3 encoder, let it match the text-only Qwen3Encoder config instead of forcing the Qwen3-VL checkpoint type.
  4. Re-export the checkpoint preserving original visual.* key names; restore missing vision-tower weights from the base repo.

Example fix

// before: text-only checkpoint -> rejected
keys: ['model.embed_tokens.weight', 'model.layers.0...']  # no visual.*

// after: correct Qwen3-VL checkpoint
keys: ['model.layers.35...', 'visual.patch_embed.proj.weight', ...]
Defensive patterns

Strategy: validation

Validate before calling

from safetensors import safe_open

def looks_like_qwen3vl_checkpoint(path) -> bool:
    with safe_open(str(path), framework="pt", device="cpu") as f:
        keys = list(f.keys())
    has_text = any(".layers." in k and ("model." in k or k.startswith("layers.")) for k in keys)
    has_visual = any(k.startswith(("visual.", "model.visual.")) or ".visual." in k for k in keys)
    return has_text and has_visual

Type guard

def is_qwen3vl_state_dict(keys: list[str]) -> bool:
    has_text_decoder = any(".layers." in k and ("model." in k or k.startswith("layers.")) for k in keys)
    has_visual_tower = any(k.startswith(("visual.", "model.visual.")) or ".visual." in k for k in keys)
    return has_text_decoder and has_visual_tower

Try / catch

try:
    invokeai_model_manager.probe(file_path)
except NotAMatchError as e:
    if "does not look like a single-file Qwen3-VL encoder" in str(e):
        # likely a text-only Qwen3 encoder or wrong checkpoint; inspect keys and re-source the file
        inspect_and_relocate_checkpoint(file_path)
    else:
        raise

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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