invoke-ai/InvokeAI · error · ValueError
Unexpected missing keys loading SDNQ Qwen3 text encoder: {mi
Error message
Unexpected missing keys loading SDNQ Qwen3 text encoder: {missing} What it means
After loading the SDNQ Qwen3 text encoder, missing keys are tolerated only for lm_head.weight, which may be tied to model.embed_tokens.weight and re-shared after load. Any other set of missing keys raises this ValueError, indicating the checkpoint lacks required Qwen3 weights.
Source
Thrown at invokeai/backend/model_manager/load/model_loaders/z_image.py:640
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,
config: Main_SDNQ_ZImage_Config,
) -> AnyModel:View on GitHub (pinned to 0b6a024f2f)
Solutions
- Read the reported missing-key names and re-download/re-export the text_encoder so all Qwen3 parameters are present.
- Verify file integrity (sizes/hashes) of the SDNQ checkpoint — a partial file is the most common cause.
- Align the transformers version with the one used at quantization time so parameter names match.
- If a legitimately tied weight is reported, extend the loader's expected-tied-keys handling (like the existing lm_head.weight case) rather than loosening strict=False.
Example fix
// before
missing, unexpected = model.load_state_dict(sd, assign=True, strict=False)
if missing and missing != ["lm_head.weight"]:
raise ValueError(...) # fires on any other missing key
// after
print(sorted(missing)) # diagnose which params are absent, then re-export/re-download the text_encoder
assert not [k for k in missing if k != "lm_head.weight"], f"checkpoint incomplete: {missing}" Defensive patterns
Strategy: validation
Validate before calling
model_keys = set(model.state_dict().keys())
missing = [k for k in model_keys if k not in sd and k != "lm_head.weight"]
if missing:
raise ValueError(f"checkpoint is incomplete, missing: {missing[:5]}...") Type guard
def state_dict_is_complete(sd: dict, model, allowed_tied=("lm_head.weight",)) -> bool:
model_keys = set(model.state_dict().keys())
return all(k in sd or k in allowed_tied for k in model_keys) Try / catch
try:
te = loader._load_model(config, SubModelType.TextEncoder)
except ValueError as e:
if "Unexpected missing keys loading SDNQ Qwen3 text encoder" in str(e):
redownload_text_encoder(config) # incomplete/corrupt checkpoint
te = loader._load_model(config, SubModelType.TextEncoder)
else:
raise Prevention
- Verify download completeness (file sizes/hashes) for text_encoder weights.
- Never hand-prune state dicts; re-quantize instead.
- Keep transformers versions consistent between export and load.
- Fail fast on incomplete downloads with a checksum step before registering the model.
When it happens
Trigger: The SDNQ state dict is missing parameters of Qwen3ForCausalLM other than lm_head.weight — partial export, pruned/truncated checkpoint, or key renaming from a transformers version change — so `missing` is non-empty and not exactly ['lm_head.weight'] at z_image.py:640.
Common situations: Incomplete download of the text_encoder folder; an export script dropped layers or quant blocks; a transformers upgrade renamed modules so keys no longer line up; corruption during SDNQ quantization.
Related errors
- Unexpected keys loading SDNQ Qwen3 text encoder: {unexpected
- 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/653e2082e48c3099.
Report an issue: GitHub.