invoke-ai/InvokeAI · error · RuntimeError

unexpected keys loading Ideogram 4 text encoder: {unexpected

Error message

unexpected keys loading Ideogram 4 text encoder: {unexpected[:10]}

What it means

The Ideogram 4 text encoder loads its state dict with strict=False (so tied-weight omissions don't fail), but unexpected keys indicate the checkpoint contains tensors that do not exist in the model — evidence of a wrong or contaminated checkpoint. Because these cannot be resolved by tying or verification, the loader hard-fails immediately with the first 10 unexpected key names.

Source

Thrown at invokeai/backend/model_manager/load/model_loaders/ideogram4.py:208

                swap_linears_to_fp8(model, sd, compute_dtype=compute_dtype)
            load_fp8_state_dict(model, sd, device=torch.device("cpu"), dtype=compute_dtype, assign=True, strict=False)
            _verify_encoder_fully_materialized(model, context="Ideogram 4 fp8 text encoder")
            model.eval()
            return model

        is_bnb_nf4 = "quantization_config" in raw_cfg and bool(raw_cfg["quantization_config"].get("load_in_4bit"))

        with accelerate.init_empty_weights():
            model = AutoModel.from_config(cfg)
            if is_bnb_nf4:
                model = quantize_model_nf4(model, modules_to_not_convert=set(), compute_dtype=compute_dtype)

        _, unexpected = model.load_state_dict(sd, strict=False, assign=True)
        # Unexpected keys signal a wrong or contaminated checkpoint and must hard-fail. Missing keys are
        # acceptable only for tied weights (resolved by _verify_encoder_fully_materialized via
        # tie_weights); any genuinely missing non-tied weight is caught there as a leftover meta tensor.
        if unexpected:
            raise RuntimeError(f"unexpected keys loading Ideogram 4 text encoder: {unexpected[:10]}")
        _verify_encoder_fully_materialized(model, context="Ideogram 4 text encoder")
        if not is_bnb_nf4:
            model = model.to(compute_dtype)
        model.eval()
        return model

    def _load_vae(self, model_path: Path) -> AnyModel:
        from invokeai.backend.ideogram4.autoencoder import (
            AutoEncoder,
            AutoEncoderParams,
            convert_diffusers_state_dict,
        )

        target_device = TorchDevice.choose_torch_device()
        model_dtype = TorchDevice.choose_bfloat16_safe_dtype(target_device)

        sd = load_file(model_path / "vae" / "diffusion_pytorch_model.safetensors")
        sd = convert_diffusers_state_dict(sd)

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Compare the listed unexpected keys against the model's named parameters and strip/re-map the prefix or stale keys in the checkpoint.
  2. Verify the checkpoint is the correct text-encoder variant for the Ideogram 4 pipeline; re-download the correct one.
  3. Check that the checkpoint is from the repo's text_encoder directory, not the transformer or VAE.
  4. If the keys are from a renamed module, write a conversion function that renames them before load_state_dict.

Example fix

// before
_, unexpected = model.load_state_dict(sd, strict=False, assign=True)
// after: strip known foreign prefix
sd = {k.removeprefix("text_model."): v for k, v in sd.items()}
_, unexpected = model.load_state_dict(sd, strict=False, assign=True)
Defensive patterns

Strategy: validation

Validate before calling

model_keys = {k for k, _ in model.state_dict().items()}
unexpected = set(sd.keys()) - model_keys
if unexpected:
    raise ValueError(f"checkpoint has foreign keys: {sorted(unexpected)[:10]}")

Type guard

def keys_compatible(sd: dict, model) -> bool:
    model_keys = set(model.state_dict().keys())
    return not (set(sd.keys()) - model_keys)

Try / catch

try:
    encoder = loader._load_model(cfg, SubModelType.TextEncoder)
except RuntimeError as e:
    if "unexpected keys loading Ideogram 4" in str(e):
        sd = remap_or_redownload_checkpoint(cfg.path)
    else:
        raise

Prevention

When it happens

Trigger: In _load_text_encoder, model.load_state_dict(sd, strict=False, assign=True) returns a non-empty `unexpected` list — the checkpoint has keys that don't match the text-encoder architecture (wrong variant, extra modules, or stale key layout).

Common situations: Pointing the loader at the wrong subfolder of a multi-model repo; using a text encoder from a different model version; checkpoints saved with prefixed keys (e.g. 'text_model.') not present in the target architecture.

Related errors


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