invoke-ai/InvokeAI · warning · NotAMatchError
state dict does not look like a Qwen3 model
Error message
state dict does not look like a Qwen3 model
What it means
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.
Source
Thrown at invokeai/backend/model_manager/configs/qwen3_encoder.py:233
@classmethod
def _get_variant_or_default(cls, mod: ModelOnDisk) -> Qwen3VariantType:
"""Get the variant from state dict, raising NotAMatch when the size does not match a known Qwen3 variant.
We previously defaulted to 4B for unknown sizes, but that swallowed other causal-LM GGUFs
(Mistral, Llama, ...) which share llama.cpp tensor naming with Qwen3.
"""
state_dict = mod.load_state_dict()
variant = _get_qwen3_variant_from_state_dict(state_dict)
if variant is None:
raise NotAMatchError("hidden size does not match a known Qwen3 variant")
return variant
@classmethod
def _validate_looks_like_qwen3_model(cls, mod: ModelOnDisk) -> None:
state_dict = mod.load_state_dict()
if not _has_qwen3_keys(state_dict):
raise NotAMatchError("state dict does not look like a Qwen3 model")
# Reject T5 encoders: they share the token_embd.weight key with Qwen3 GGUFs but use the ``enc.``
# block prefix, and must be classified as T5Encoder (Qwen3 encoders never have ``enc.blk.*`` keys).
if _has_t5_encoder_keys(state_dict):
raise NotAMatchError("state dict looks like a T5 encoder (has 'enc.blk.*' keys), not a Qwen3 encoder")
# Reject Gemma-2/3 encoders: their GGUFs also carry token_embd.weight + blk.* keys but use
# post-attention / post-feedforward norms a Qwen3 encoder never has; they must be classified as
# Gemma2Encoder (otherwise a Gemma GGUF matches both configs and can be re-identified wrongly).
if _has_gemma2_keys(state_dict):
raise NotAMatchError(
"state dict looks like a Gemma-2 encoder (has post_attention_norm/post_ffw_norm keys), "
"not a Qwen3 encoder"
)
# Reject Qwen2.5-VL / Qwen2-VL encoders: they carry a visual tower and must be
# classified as QwenVLEncoder (text-only Qwen3 encoders never have one).
if _has_qwen_vl_visual_tower(state_dict):
raise NotAMatchError(
"state dict bundles a Qwen-VL visual tower; this is a Qwen-VL encoder, not a text-only Qwen3 encoder"
)View on GitHub (pinned to 0b6a024f2f)
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.
Example fix
// before (wrong folder scanned) models/qwen3-encoder/ # contains unrelated Llama GGUF // after models/qwen3-encoder/text_encoder/token_embd.weight etc. (real Qwen3 tensors), models/llama/ (install as its own model type)
Defensive patterns
Strategy: validation
Validate before calling
from safetensors import safe_open
import json, pathlib
def looks_like_qwen3_encoder(path: pathlib.Path) -> bool:
cfg = None
for cand in (path / 'text_encoder' / 'config.json', path / 'config.json'):
if cand.exists():
cfg = json.loads(cand.read_text())
break
if cfg is None:
return False
archs = cfg.get('architectures', [])
return any(a in {'Qwen3ForCausalLM', 'Qwen2ForCausalLM', 'Qwen2VLForConditionalGeneration'} for a in archs) Type guard
def is_qwen3_state_dict(state_dict: dict) -> bool:
keys = set(state_dict)
has_qwen3 = 'token_embd.weight' in keys or any(k.startswith('blk.') or k.startswith('model.layers.') for k in keys)
not_t5 = not any(k.startswith('enc.blk.') for k in keys)
return has_qwen3 and not_t5 Try / catch
from invokeai.backend.model_manager.configs.qwen3_encoder import Qwen3Encoder_Qwen3Encoder_Config
from invokeai.backend.model_manager.configs.base import NotAMatchError
try:
cfg = Qwen3Encoder_Qwen3Encoder_Config.from_model_on_disk(mod, overrides)
except NotAMatchError as e:
logger.warning('Not a Qwen3 encoder: %s — trying other configs', e)
cfg = fallback_identify(mod, overrides) Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- state dict bundles a Qwen-VL visual tower; this is a Qwen-VL
- LoRA "{lora_key}" already applied to Qwen3 encoder.
- Expected PreTrainedModel for text encoder, got {type(text_en
- Expected PreTrainedTokenizerBase for tokenizer, got {type(to
- No Qwen3 Encoder source provided. Standalone safetensors/GGU
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/20f4cafca6188724.
Report an issue: GitHub.