invoke-ai/InvokeAI · error · ValueError
Unexpected keys loading SDNQ Qwen3 text encoder: {unexpected
Error message
Unexpected keys loading SDNQ Qwen3 text encoder: {unexpected} What it means
When loading the SDNQ-quantized Qwen3 text encoder, load_state_dict(strict=False) reports keys in the checkpoint that do not match any Qwen3ForCausalLM parameter. Any unexpected key is treated as a fatal mismatch and raises this ValueError, because unexpected keys mean the weights file does not correspond to the expected Qwen3 architecture.
Source
Thrown at invokeai/backend/model_manager/load/model_loaders/z_image.py:638
)
def _load_text_encoder(self, config: Main_SDNQ_Diffusers_ZImage_Config) -> AnyModel:
from transformers import AutoConfig, Qwen3ForCausalLM
te_dir = resolve_submodel_path(config, SubModelType.TextEncoder, Path(config.path) / "text_encoder")
target_device = TorchDevice.choose_torch_device()
compute_dtype = TorchDevice.choose_bfloat16_safe_dtype(target_device)
te_config = AutoConfig.from_pretrained(te_dir, local_files_only=True)
with accelerate.init_empty_weights():
model = Qwen3ForCausalLM(te_config)
sd = sdnq_sd_loader(te_dir, compute_dtype=compute_dtype)
# Qwen3ForCausalLM may share lm_head.weight with model.embed_tokens.weight; missing keys
# for that tie are expected and handled by re-sharing post-load.
missing, unexpected = model.load_state_dict(sd, assign=True, strict=False)
if unexpected:
raise ValueError(f"Unexpected keys loading SDNQ Qwen3 text encoder: {unexpected}")
if missing and missing != ["lm_head.weight"]:
raise ValueError(f"Unexpected missing keys loading SDNQ Qwen3 text encoder: {missing}")
if missing == ["lm_head.weight"]:
model.lm_head.weight = model.model.embed_tokens.weight
return model
def _load_tokenizer(self, config: Main_SDNQ_Diffusers_ZImage_Config) -> AnyModel:
tok_dir = resolve_submodel_path(config, SubModelType.Tokenizer, Path(config.path) / "tokenizer")
return AutoTokenizer.from_pretrained(tok_dir, local_files_only=True)
def _load_vae(self, config: Main_SDNQ_Diffusers_ZImage_Config) -> AnyModel:
from diffusers import AutoencoderKL
vae_dir = resolve_submodel_path(config, SubModelType.VAE, Path(config.path) / "vae")
return AutoencoderKL.from_pretrained(vae_dir, local_files_only=True)
def _load_from_singlefile(
self,View on GitHub (pinned to 0b6a024f2f)
Solutions
- Verify the text_encoder/ folder actually contains SDNQ-quantized Qwen3 weights matching Qwen3ForCausalLM; re-export or re-download it.
- Inspect the reported unexpected key names to identify the mismatch (prefixes, quant-metadata keys, renamed modules).
- Upgrade/downgrade transformers and the SDNQ tooling so parameter naming matches the checkpoint's export version.
- If keys are harmless quant-metadata, strip them before load_state_dict or update the loader's expected-key filter.
Example fix
// before
model.load_state_dict(sd, assign=True, strict=False) # ValueError on unexpected keys
// after
sd = {k: v for k, v in sd.items() if k in dict(model.named_parameters()) or k in dict(model.named_buffers())}
missing, unexpected = model.load_state_dict(sd, assign=True, strict=False)
if unexpected:
raise ValueError(f"Unexpected keys loading SDNQ Qwen3 text encoder: {unexpected}") Defensive patterns
Strategy: validation
Validate before calling
model_keys = set(model.state_dict().keys())
extra = [k for k in sd if k not in model_keys]
if extra:
raise ValueError(f"checkpoint has keys unknown to Qwen3ForCausalLM: {extra[:5]}...") Type guard
def state_dict_matches_architecture(sd: dict, model) -> bool:
model_keys = set(model.state_dict().keys())
return all(k in model_keys for k in sd) Try / catch
try:
te = loader._load_model(config, SubModelType.TextEncoder)
except ValueError as e:
if "Unexpected keys loading SDNQ Qwen3 text encoder" in str(e):
te = reexport_or_redownload_text_encoder(config) # fix weights, then retry
te = loader._load_model(config, SubModelType.TextEncoder)
else:
raise Prevention
- Keep the text_encoder folder from the same release/quantization run as the rest of the model.
- Pin the transformers version used at quantization time.
- Verify hashes of downloaded text_encoder files before first use.
- Log unexpected key names to spot architecture drift early.
When it happens
Trigger: Loading a text_encoder subfolder whose SDNQ state dict contains keys absent from Qwen3ForCausalLM — wrong model in text_encoder/, an architecture change across Qwen3 revisions, extra buffers/quant metadata keys the loader doesn't strip, or a truncated/corrupted export.
Common situations: Mixing text-encoder folders from different model families into an SDNQ ZImagePipeline; a diffusers/transformers version changed parameter naming so checkpoint keys no longer match; hand-edited or repackaged SDNQ exports leaving stray keys.
Related errors
- Unexpected missing keys loading SDNQ Qwen3 text encoder: {mi
- state dict has Anima ControlNet-LLLite keys but no lllite_co
- state dict does not look like a Qwen3 model
- state dict bundles a Qwen-VL visual tower; this is a Qwen-VL
- folder is SDNQ-quantized; use Qwen3Encoder_SDNQ_Folder_Confi
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/ff88e1e103d5989f.
Report an issue: GitHub.