invoke-ai/InvokeAI · error · ValueError
Expected 2D embed_tokens weight tensor, got shape {embed_sha
Error message
Expected 2D embed_tokens weight tensor, got shape {embed_shape}. The model file may be corrupted or incompatible. What it means
Raised when 'model.embed_tokens.weight' exists in the GGUF state dict but is not a 2D (vocab, hidden) tensor. Because GGUF tensors carry GGML shapes, the loader reads .shape (or .tensor_shape) to derive vocab_size; a malformed or quantized-off embedding tensor yields an unexpected rank, so the file is treated as corrupted/incompatible.
Source
Thrown at invokeai/backend/model_manager/load/model_loaders/z_image.py:1243
for key in sd.keys():
if isinstance(key, str) and key.startswith("model.layers."):
parts = key.split(".")
if len(parts) > 2:
try:
layer_idx = int(parts[2])
layer_count = max(layer_count, layer_idx + 1)
except ValueError:
pass
# Get vocab size from embed_tokens weight shape
embed_weight = sd.get("model.embed_tokens.weight")
if embed_weight is None:
raise ValueError("Could not find model.embed_tokens.weight in state dict")
# Handle GGMLTensor shape access
embed_shape = embed_weight.shape if hasattr(embed_weight, "shape") else embed_weight.tensor_shape
if len(embed_shape) != 2:
raise ValueError(
f"Expected 2D embed_tokens weight tensor, got shape {embed_shape}. "
"The model file may be corrupted or incompatible."
)
vocab_size = embed_shape[0]
# Detect attention configuration from layer weights
# IMPORTANT: Use layer 1 (not layer 0) because some models like FLUX 2 Klein have a special
# first layer with different dimensions (input projection layer) while the rest of the
# transformer layers have a different hidden_size. Using a middle layer ensures we get
# the representative hidden_size for the bulk of the model.
# Fall back to layer 0 if layer 1 doesn't exist.
q_proj_weight = sd.get("model.layers.1.self_attn.q_proj.weight")
k_proj_weight = sd.get("model.layers.1.self_attn.k_proj.weight")
gate_proj_weight = sd.get("model.layers.1.mlp.gate_proj.weight")
# Fall back to layer 0 if layer 1 doesn't exist (single-layer model edge case)
if q_proj_weight is None:
q_proj_weight = sd.get("model.layers.0.self_attn.q_proj.weight")View on GitHub (pinned to 0b6a024f2f)
Solutions
- Re-download or re-convert the GGUF with an up-to-date converter that preserves 2D embedding shapes.
- Verify the tensor rank with gguf-dump; if it is 1D/3D, re-export from the original safetensors checkpoint.
- If quantization packs the tensor, load a F16/FP32 variant of the text-encoder GGUF instead.
- Check disk/full-download health: a truncated file can corrupt tensor headers producing wrong shapes.
Example fix
// before: hand-rolled conversion flattened embeddings tensor 'model.embed_tokens.weight' shape [2315296] // after: re-convert preserving rank tensor 'model.embed_tokens.weight' shape [151669, 2048]
Defensive patterns
Strategy: validation
Validate before calling
import gguf
reader = gguf.GGUFReader(path)
for t in reader.tensors:
if t.name == "model.embed_tokens.weight":
shape = t.shape
if shape is None or len(shape) != 2:
raise ValueError(f"Bad embed shape {shape} in {path}; re-convert the GGUF.") Type guard
def has_2d_embedding(path: str) -> bool:
try:
import gguf
for t in gguf.GGUFReader(path).tensors:
if t.name == "model.embed_tokens.weight":
return len(t.shape) == 2
except Exception:
pass
return False Try / catch
try:
model = load_text_encoder(cfg)
except ValueError as e:
if "Expected 2D embed_tokens" in str(e):
raise ModelValidationError(f"GGUF {cfg.path} corrupt; re-download/re-convert.") from e
raise Prevention
- Only use GGUFs converted with maintained converter versions.
- Sanity-check shapes via gguf-dump after conversion.
- Prefer official F16 releases over hand-quantized files.
- Verify downloads complete (size + hash).
When it happens
Trigger: Loading a GGUF text encoder where the embed_tokens tensor was flattened (1D), stored transposed with extra dims (3D), or quantized to a format whose metadata loses the 2D shape during conversion.
Common situations: Hand-converted GGUF from safetensors with a broken conversion script; corrupted download where tensor metadata is garbled; incompatible model generation whose embed tensor was fused or reshaped.
Understand the failure class
Background: Tensor shape mismatch errors ("must have shape", "expected shape ... got ..."): when tensor dimensions disagree with what an op or layer was told to expect — this error's family across 6 libraries.
Related errors
- Cannot split QKV tensor '{key}': first dimension ({tensor.sh
- Expected 2D embed_tokens weight tensor, got shape {embed_sha
- not a readable GGUF file: {e}
- Only MistralEncoder_GGUF_Config models are supported here.
- Expected Main_GGUF_Wan_Config, got {type(config).__name__}.
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/af4a9228d1c6479b.
Report an issue: GitHub.