invoke-ai/InvokeAI · error · ValueError

Unmapped Gemma-2 GGUF tensor key '{key}'

Error message

Unmapped Gemma-2 GGUF tensor key '{key}'

What it means

Raised by _convert_gemma_llamacpp_to_pytorch for any GGUF tensor key that matches neither the blk.N block pattern nor the recognized top-level keys token_embd.weight and output_norm.weight. This catches global/extra tensors (e.g. output.weight, rope_freqs, per-layer norms outside blocks) that the converter has no rule for.

Source

Thrown at invokeai/backend/model_manager/load/model_loaders/gemma2_encoder.py:70

    out: dict[str, Any] = {}
    for key, value in sd.items():
        if not isinstance(key, str):
            out[key] = value
            continue
        m = _GEMMA_BLK_PATTERN.match(key)
        if m:
            idx, rest = m.group(1), m.group(2)
            component, _, suffix = rest.partition(".")
            mapped = _GEMMA_GGUF_KEY_MAP.get(component)
            if mapped is None:
                raise ValueError(f"Unmapped Gemma-2 GGUF tensor key component '{component}' (from '{key}')")
            out[f"layers.{idx}.{mapped}" + (f".{suffix}" if suffix else "")] = value
        elif key == "token_embd.weight":
            out["embed_tokens.weight"] = value
        elif key == "output_norm.weight":
            out["norm.weight"] = value
        else:
            raise ValueError(f"Unmapped Gemma-2 GGUF tensor key '{key}'")
    return out


@ModelLoaderRegistry.register(base=BaseModelType.Any, type=ModelType.Gemma2Encoder, format=ModelFormat.Gemma2Encoder)
class Gemma2EncoderLoader(ModelLoader):
    """Loads a Gemma-2 causal LM directory and exposes its decoder + tokenizer."""

    def _load_model(
        self,
        config: AnyModelConfig,
        submodel_type: Optional[SubModelType] = None,
    ) -> AnyModel:
        if not isinstance(config, Gemma2Encoder_Gemma2Encoder_Config):
            raise ValueError("Only Gemma2Encoder_Gemma2Encoder_Config models are supported here.")

        model_path = Path(config.path)

        match submodel_type:

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Inspect the offending key and add an explicit elif branch to _convert_gemma_llamacpp_to_pytorch mapping or intentionally skipping it
  2. Re-export the GGUF without the extraneous tensor (e.g. drop lm_head for encoder use)
  3. Verify the GGUF is truly Gemma-2 architecture via its metadata before loading

Example fix

# before
ValueError: Unmapped Gemma-2 GGUF tensor key 'output.weight'
# after
elif key == "output.weight":
    continue  # lm_head is not part of the encoder
else:
    raise ValueError(...)
Defensive patterns

Strategy: validation

Validate before calling

ALLOWED_TOP_LEVEL = {"token_embd.weight", "output_norm.weight"}
def has_unexpected_top_level_keys(keys):
    import re
    return [k for k in keys if not re.match(r"^blk\.\d+\.", k) and k not in ALLOWED_TOP_LEVEL]

Type guard

def is_supported_key(key: str) -> bool:
    import re
    return bool(re.match(r"^blk\.\d+\.[^.]+", key)) or key in {"token_embd.weight", "output_norm.weight"}

Try / catch

try:
    model = load_gemma2_model_from_gguf(gguf_path, dtype)
except ValueError as e:
    if "Unmapped Gemma-2 GGUF tensor key" in str(e):
        print(f"GGUF contains unsupported tensor '{e}'; re-export without it")
    else:
        raise

Prevention

When it happens

Trigger: load_gemma2_model_from_gguf on a GGUF containing top-level tensors like output.weight (tied lm_head not expected by the encoder), rope_freqs.weights, or any unexpected root-level key.

Common situations: Exporting a full causal-LM GGUF (with lm_head/output tensors) instead of an encoder-only export; GGUFs with extra metadata-like tensors; files converted by third-party scripts adding custom tensor names.

Related errors


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