invoke-ai/InvokeAI · warning · NotAMatchError
state dict does not look like a PiD decoder (no 'lq_proj.*'
Error message
state dict does not look like a PiD decoder (no 'lq_proj.*' keys)
What it means
This is the identification gate: a state dict must contain a key containing `lq_proj` (the diagnostic marker of PidDistillModel's `net.lq_proj...` weights) for the file to be considered a PiD decoder at all. If no such key exists, `NotAMatchError` is raised — a normal 'not this model type' signal, letting the factory try other config classes.
Source
Thrown at invokeai/backend/model_manager/configs/pid_decoder.py:287
`PidNet` contract — the same keys and shapes `load_pid_decoder` demands — and the backbone then
comes from the latent channel count in the weights, with an explicit override or the name as the
tie-breaker for the architecturally identical FLUX.1 / SD3 / Qwen-Image family. `variant` is
carried as data without participating in the discriminator tag (one config class per backbone).
"""
type: Literal[ModelType.PiDDecoder] = Field(default=ModelType.PiDDecoder)
format: Literal[ModelFormat.Checkpoint] = Field(default=ModelFormat.Checkpoint)
@classmethod
def from_model_on_disk(cls, mod: ModelOnDisk, override_fields: dict[str, Any]) -> Self:
raise_if_not_file(mod)
# An explicit `base` is validated against this class's Literal here, so it already narrows
# identification to exactly one of the five PiD config classes.
raise_for_override_fields(cls, override_fields)
state_dict = mod.load_state_dict()
if not _looks_like_pid_decoder(state_dict):
raise NotAMatchError("state dict does not look like a PiD decoder (no 'lq_proj.*' keys)")
# Imported lazily: it pulls in the vendored PiD network stack, which model identification has
# no reason to load for the overwhelming majority of files.
from invokeai.backend.pid.decode import required_pid_net_shapes
contract = required_pid_net_shapes()
shapes = pid_net_shapes(state_dict)
# Everything from here to `_validate_base` is backbone-independent: each of these rejects a file
# *every* PiD config class would reject for the same reason, which is exactly the case the plain
# no-match signal cannot carry — no class matches, and the factory registers the file through its
# `Unknown_Config` fallback. See `_raise_if_no_backbone_can_accept`.
#
# The latent projection carries both the architecture version and the backbone, so the checks
# that read it can only speak when it is there. When it is not, the file is truncated, and the
# contract check diagnoses that far better than a guess about the architecture would.
if _LATENT_PROJ_KEY in shapes:
_raise_if_discriminator_malformed(shapes, contract)View on GitHub (pinned to 0b6a024f2f)
Solutions
- Verify you downloaded the PiD decoder weights (PiD_res2k*/... model_ema_bf16.pth), not the base PixDiT_T2I checkpoint
- Load the checkpoint and check `any('lq_proj' in k for k in sd)` to confirm it is a PiD decoder
- Let InvokeAI auto-identify the correct model type; do not force a PiD decoder registration for a non-PiD file
- Re-download if the file may be wrong/corrupted from the source repo
Example fix
// sanity check before installing
import torch
sd = torch.load('model_ema_bf16.pth', map_location='cpu')
assert any('lq_proj' in k for k in sd), 'not a PiD decoder' Defensive patterns
Strategy: validation
Validate before calling
import torch
sd = torch.load(ckpt_path, map_location='cpu')
if not any(isinstance(k, str) and 'lq_proj' in k for k in sd):
raise SystemExit('Not a PiD decoder (no lq_proj keys); check you downloaded the decoder, not base PixDiT weights.') Type guard
def looks_like_pid_decoder(sd: dict) -> bool:
return any(isinstance(k, str) and 'lq_proj' in k for k in sd) Try / catch
try:
install_model(path)
except NotAMatchError:
logger.info('File is not a PiD decoder; letting other model configs identify it.') Prevention
- Download the PiD_res2k*/... decoder .pth, not the base PixDiT_T2I checkpoint
- Sanity-check keys with `any('lq_proj' in k for k in sd)` before installing
- Let auto-identification pick the model type instead of forcing PiD
When it happens
Trigger: `from_model_on_disk` calls `_looks_like_pid_decoder(state_dict)` and finds no key with the `lq_proj` substring — e.g. installing a base PixDiT_T2I checkpoint, a VAE, or any non-PiD .pth that the router still offered to the PiD config classes.
Common situations: Installing the wrong artifact from the nvidia/PiD repo (base PixDiT weights have no lq_proj); pointing the installer at an unrelated diffusion model checkpoint; single-file install where the router mislabels the model.
Related errors
- The Wan T5 Encoder must resolve to a standalone Wan T5 encod
- The {label} model must resolve to a Wan main model.
- The Component Source model must resolve to a Wan main model.
- The VAE must resolve to a standalone Wan VAE model.
- Unrecognized LLLite module name: '{name}'
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/2c530726c1d22f9d.
Report an issue: GitHub.