lllyasviel/Fooocus · critical · Exception

CORRUPTED MODEL: one of the q-k-v values for the text encode

Error message

CORRUPTED MODEL: one of the q-k-v values for the text encoder was missing

What it means

diffusers_convert.convert_text_enc_state_dict collects q_proj/k_proj/v_proj weights for the CLIP text encoder and merges them into a single in_proj_weight tensor. If, for any captured prefix, one of the three projection weights is still None (i.e. one of q/k/v was never seen in the state dict), the checkpoint is considered structurally broken and this exception is raised. It protects against building a malformed in_proj_weight full of holes.

Source

Thrown at ldm_patched/modules/diffusers_convert.py:245

        if (
                k.endswith(".self_attn.q_proj.bias")
                or k.endswith(".self_attn.k_proj.bias")
                or k.endswith(".self_attn.v_proj.bias")
        ):
            k_pre = k[: -len(".q_proj.bias")]
            k_code = k[-len("q_proj.bias")]
            if k_pre not in capture_qkv_bias:
                capture_qkv_bias[k_pre] = [None, None, None]
            capture_qkv_bias[k_pre][code2idx[k_code]] = v
            continue

        relabelled_key = textenc_pattern.sub(lambda m: protected[re.escape(m.group(0))], k)
        new_state_dict[relabelled_key] = v

    for k_pre, tensors in capture_qkv_weight.items():
        if None in tensors:
            raise Exception("CORRUPTED MODEL: one of the q-k-v values for the text encoder was missing")
        relabelled_key = textenc_pattern.sub(lambda m: protected[re.escape(m.group(0))], k_pre)
        new_state_dict[relabelled_key + ".in_proj_weight"] = torch.cat(tensors)

    for k_pre, tensors in capture_qkv_bias.items():
        if None in tensors:
            raise Exception("CORRUPTED MODEL: one of the q-k-v values for the text encoder was missing")
        relabelled_key = textenc_pattern.sub(lambda m: protected[re.escape(m.group(0))], k_pre)
        new_state_dict[relabelled_key + ".in_proj_bias"] = torch.cat(tensors)

    return new_state_dict


def convert_text_enc_state_dict(text_enc_dict):
    return text_enc_dict


View on GitHub (pinned to ae05379cc9)

Solutions

  1. Re-download the checkpoint from the original source and verify its file size/SHA
  2. If the file was self-merged or pruned, re-export it keeping ALL text encoder q/k/v projection keys
  3. Inspect keys: torch / safetensors load and list keys matching *.q_proj.* / *.k_proj.* / *.v_proj.* to find which projection is missing
  4. As a workaround, load the model without the text encoder and pair it with a separate standalone CLIP file

Example fix

from safetensors import safe_open

with safe_open('model.safetensors', framework='pt') as f:
    keys = list(f.keys())
qkv = {p: [k for k in keys if p in k] for p in ('q_proj', 'k_proj', 'v_proj')}
# before: one of the lists empty -> 'CORRUPTED MODEL' at conversion
# after: all three non-empty -> conversion succeeds
assert all(len(v) > 0 for v in qkv.values()), qkv
Defensive patterns

Strategy: validation

Validate before calling

from safetensors import safe_open

def has_full_qkv_weights(path):
    with safe_open(path, framework='pt') as f:
        keys = [k for k in f.keys() if k.endswith(('.q_proj.weight', '.k_proj.weight', '.v_proj.weight'))]
    prefixes = {k.rsplit('.', 2)[0] for k in keys}
    ok = {k.rsplit('.', 2)[0] for k in keys if k.endswith('.q_proj.weight')}
    # every prefix that has any projection must have all three weights
    have = {}
    for k in keys:
        have.setdefault(k.rsplit('.', 2)[0], set()).add(k.rsplit('.', 1)[1])
    return all(v == {'weight'} and p in ok for p, v in have.items()) and len(ok) == len(prefixes)

Try / catch

try:
    sd_out = ldm_patched.modules.diffusers_convert.convert_text_enc_state_dict(sd)
except Exception as e:
    if 'CORRUPTED MODEL' in str(e):
        raise SystemExit('Checkpoint text encoder is incomplete (missing q/k/v projection); re-download it') from e
    raise

Prevention

When it happens

Trigger: Calling load_checkpoint_guess_config (or any path that converts an SD2.x-style text encoder) on a .safetensors/.ckpt whose text encoder section contains q_proj.weight but is missing k_proj.weight or v_proj.weight (or vice versa). Happens when a checkpoint was pruned, hand-edited, merged incorrectly, or truncated during download.

Common situations: Users re-saving a checkpoint with a script that filters keys by substring and accidentally drops one projection; interrupted downloads (file parses but keys incomplete); mixing SD1.5 CLIP weights into an SD2.1 checkpoint manually.

Related errors


AI-assisted analysis of lllyasviel/Fooocus@ae05379cc9 (2026-08-15). Data as JSON: /api/errors/a5034aa6fc12e184. Report an issue: GitHub.