invoke-ai/InvokeAI · error · RuntimeError

PiD checkpoint is missing {len(missing)} keys required by Pi

Error message

PiD checkpoint is missing {len(missing)} keys required by PidNet{detail}: {missing[:5]}

What it means

After a strict=False load, load_pid_decoder checks the reported missing keys. If the checkpoint lacks any parameter the PidNet requires, it raises RuntimeError with the count and first 5 missing keys. If every missing key is part of lq_proj, the message additionally explains that the file looks like a base PixDiT_T2I checkpoint rather than a PiD super-resolution decoder — since the model cache skips weight init, missing keys would otherwise leave uninitialized garbage weights.

Source

Thrown at invokeai/backend/pid/decode.py:289

    # strict=False so we can report missing and unexpected keys separately; both are fatal. The model
    # cache builds loaders under `skip_torch_weight_init()`, which no-ops every `reset_parameters()`,
    # so a key the checkpoint does not supply is left as uninitialised memory rather than a sane
    # default — a partial checkpoint would decode to garbage / NaNs instead of failing.
    missing, unexpected = net.load_state_dict(state_dict, strict=False)
    if unexpected:
        raise RuntimeError(
            f"PiD checkpoint has unexpected keys not present in PidNet: {unexpected[:5]}"
            + (f" (+ {len(unexpected) - 5} more)" if len(unexpected) > 5 else "")
        )
    if missing:
        lq = [k for k in missing if k.startswith("lq_proj.")]
        detail = (
            " (the LQ projection is incomplete — this looks like a base PixDiT_T2I checkpoint rather than a "
            "PiD super-resolution decoder)"
            if lq and len(lq) == len(missing)
            else ""
        )
        raise RuntimeError(
            f"PiD checkpoint is missing {len(missing)} keys required by PidNet{detail}: {missing[:5]}"
            + (f" (+ {len(missing) - 5} more)" if len(missing) > 5 else "")
        )
    return net


# ---------------------------------------------------------------------------
# Sampling
# ---------------------------------------------------------------------------


def _get_t_list(device: torch.device, *, num_steps: Optional[int] = None) -> Tensor:
    """Distill-student sigma schedule.

    When *num_steps* differs from the trained 4 steps, linearly sub-sample
    the canonical 5-point list (mirrors `PidDistillModel._get_t_list`).
    """
    full = torch.tensor(_STUDENT_T_LIST, device=device, dtype=torch.float32)

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Use the correct PiD super-resolution decoder checkpoint (one containing lq_proj.* keys), not the base PixDiT_T2I checkpoint
  2. Re-download the checkpoint if the file is truncated; verify its size/checksum
  3. Match the backbone argument to the checkpoint so the expected key set aligns
Defensive patterns

Strategy: validation

Validate before calling

sd = torch.load(path, map_location="cpu")
missing = set(build_pid_net(backbone).state_dict()) - set(sd)
assert not missing, f"missing keys: {sorted(missing)[:5]}"

Try / catch

try:
    net = load_pid_decoder(path, backbone=backbone)
except RuntimeError as e:
    if "missing" in str(e):
        logger.error(f"Incomplete checkpoint: {e}")
    raise

Prevention

When it happens

Trigger: Calling load_pid_decoder with a checkpoint that omits required parameters: an incomplete save, a base PixDiT_T2I checkpoint lacking lq_proj.*, or a backbone mismatch that changes the expected parameter set.

Common situations: Downloading a truncated/partial file, confusing the base model checkpoint with the PiD SR decoder checkpoint, or loading a checkpoint saved before a module was added.

Related errors


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