invoke-ai/InvokeAI · error · InvalidMatchError
PiD checkpoint has {len(mismatched)} weights whose shape Pid
Error message
PiD checkpoint has {len(mismatched)} weights whose shape PidNet cannot accept (e.g. {k}: {got}, expected {want}); loading it would fail with a size mismatch What it means
Beyond key presence, each weight's shape is compared to the contract; `lq_proj.latent_proj.0.weight` is excluded because its shape legitimately varies by backbone (it has its own dedicated checks). Any other mismatch means `load_pid_decoder` would fail with a torch size-mismatch error, so identification raises `InvalidMatchError` naming an example key, its got shape, and the expected shape.
Source
Thrown at invokeai/backend/model_manager/configs/pid_decoder.py:171
# the `Unknown_Config` registration these checks exist to prevent, so the crash fails as a silent
# accept rather than loudly. Only `unexpected` can hold one today; sorting both the same way keeps
# that from depending on which set is on which side of the subtraction.
if missing := sorted(contract.keys() - shapes.keys(), key=str):
raise InvalidMatchError(
f"PiD checkpoint is missing {len(missing)} of the weights required by PidNet; the file is "
f"incomplete and cannot be used as a PiD decoder: {missing[:5]}{_and_more(missing)}"
)
if unexpected := sorted(shapes.keys() - contract.keys(), key=str):
raise InvalidMatchError(
f"PiD checkpoint has {len(unexpected)} keys PidNet does not expect, which `load_pid_decoder` "
f"rejects too: {unexpected[:5]}{_and_more(unexpected)}"
)
mismatched = [(k, shapes[k], want) for k, want in contract.items() if k != _LATENT_PROJ_KEY and shapes[k] != want]
if mismatched:
k, got, want = mismatched[0]
raise InvalidMatchError(
f"PiD checkpoint has {len(mismatched)} weights whose shape PidNet cannot accept "
f"(e.g. {k}: {got}, expected {want}); loading it would fail with a size mismatch"
)
def _name_components(mod: ModelOnDisk, override_fields: dict[str, Any]) -> tuple[str, ...]:
"""The name evidence for backbone and variant, most specific first.
NVIDIA distributes PiD checkpoints as
``PiD_res2k_sr4x_official_<backbone>_distill_4step/model_ema_bf16.pth``, so the backbone and the
preset usually live in the *directory* name rather than the weights filename. A direct
single-file install stores the checkpoint as ``<uuid>/model_ema_bf16.pth`` and drops that
directory, which is why the install source is consulted at all: for an HF or URL install it still
carries NVIDIA's name.
These used to be concatenated into one string and substring-matched, which let a fixed backbone
precedence decide cases the name had already answered — `/flux/model_sd3.pth` matched `flux`
first and was registered as FLUX although the file itself says sd3. Matching component byView on GitHub (pinned to 0b6a024f2f)
Solutions
- Obtain the unmodified official checkpoint matching InvokeAI's `build_pid_net` legacy configuration
- If it's a fine-tune with different dims, it is incompatible — request support or use the original architecture
- Re-download; compare the reported example shape against the official file to confirm corruption vs intentional change
Defensive patterns
Strategy: validation
Validate before calling
from invokeai.backend.pid.decode import required_pid_net_shapes
from invokeai.backend.pid.state_dict_utils import pid_net_shapes
import torch
sd = torch.load(ckpt_path, map_location='cpu')
contract = required_pid_net_shapes(); shapes = pid_net_shapes(sd)
bad = [(k, shapes[k], w) for k, w in contract.items()
if k != 'lq_proj.latent_proj.0.weight' and shapes[k] != w]
if bad:
raise SystemExit(f'Shape mismatches, e.g. {bad[0]}') Type guard
def shapes_match_pid_net(sd: dict) -> bool:
from invokeai.backend.pid.decode import required_pid_net_shapes
from invokeai.backend.pid.state_dict_utils import pid_net_shapes
shapes = pid_net_shapes(sd)
return all(shapes[k] == w for k, w in required_pid_net_shapes().items()
if k != 'lq_proj.latent_proj.0.weight') Try / catch
try:
install_model(path)
except InvalidMatchError as e:
if 'whose shape PidNet cannot accept' in str(e):
logger.error('Incompatible/fine-tuned PidNet dims: %s', e)
else:
raise Prevention
- Avoid third-party PidNet fine-tunes with modified dimensions
- Compare reported shapes against the official release when diagnosing
- Never splice weights from different PiD releases into one file
When it happens
Trigger: `_raise_if_pid_net_contract_unmet` in `from_model_on_disk` finds contract keys present with wrong shapes — e.g. a decoder trained with modified PidNet hyperparameters, or a spliced checkpoint mixing tensors from different releases.
Common situations: Third-party fine-tunes of PidNet with changed dims; checkpoints converted between formats incorrectly; mixing weights from different PiD releases into one file.
Related errors
- PiD checkpoint has {channels} latent channels; no supported
- PiD decoder has lq_proj hidden dim {lq_hidden_dim}, but Invo
- Only CheckpointConfigBase models are currently supported her
- Expected QwenVLEncoder_Checkpoint_Config, got {type(config).
- Incompatible 'noise' and 'latents' shapes: ${latents.shape=}
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/dd23be714a69a261.
Report an issue: GitHub.