deepseek-ai/DeepSeek-V3 · error · AssertionError
Key ${key} not found in mapping
Error message
Key ${key} not found in mapping What it means
Thrown in convert.py's main loop (inference/convert.py:63): after renaming HF-style parameter names (self_attn→attn, mlp→ffn, weight_scale_inv→scale, e_score_correction_bias→bias), it takes the second-to-last dot component (key = name.split('.')[-2]) and looks it up in the hardcoded `mapping` dict (embed_tokens, q_proj, kv_a_proj_with_mqa, gate, down_proj, ...). Any checkpoint whose module names differ from the expected HF DeepSeek-V3 layout fails here.
Source
Thrown at inference/convert.py:63
"""
torch.set_num_threads(8)
n_local_experts = n_experts // mp
state_dicts = [{} for _ in range(mp)]
for file_path in tqdm(glob(os.path.join(hf_ckpt_path, "*.safetensors"))):
with safe_open(file_path, framework="pt", device="cpu") as f:
for name in f.keys():
if "model.layers.61" in name:
continue
param: torch.Tensor = f.get_tensor(name)
if name.startswith("model."):
name = name[len("model."):]
name = name.replace("self_attn", "attn")
name = name.replace("mlp", "ffn")
name = name.replace("weight_scale_inv", "scale")
name = name.replace("e_score_correction_bias", "bias")
key = name.split(".")[-2]
assert key in mapping, f"Key {key} not found in mapping"
new_key, dim = mapping[key]
name = name.replace(key, new_key)
for i in range(mp):
new_param = param
if "experts" in name and "shared_experts" not in name:
idx = int(name.split(".")[-3])
if idx < i * n_local_experts or idx >= (i + 1) * n_local_experts:
continue
elif dim is not None:
assert param.size(dim) % mp == 0, f"Dimension {dim} must be divisible by {mp}"
shard_size = param.size(dim) // mp
new_param = param.narrow(dim, i * shard_size, shard_size).contiguous()
state_dicts[i][name] = new_param
os.makedirs(save_path, exist_ok=True)
for i in trange(mp):
save_file(state_dicts[i], os.path.join(save_path, f"model{i}-mp{mp}.safetensors"))View on GitHub (pinned to 9b4e9788e4)
Solutions
- Inspect the failing key: print the original tensor name that produced it (add logging before the assert) and compare with mapping's keys
- Extend the mapping dict in convert.py with the missing key: 'new_module_name': ('target_name', shard_dim_or_None)
- Verify you are converting a checkpoint with the exact naming this script targets (DeepSeek-V3 HF format); for other revisions use the upstream repo's matching convert script
- Check for rename collisions: name.replace('gate', ...) style substring bugs — prefer exact component replaces
Example fix
# before (convert.py)
mapping = {
...
"gate": ("gate", None),
}
# AssertionError: Key xxx not found in mapping
# after — add the missing module key with its new name and shard dim
mapping = {
...
"gate": ("gate", None),
"xxx": ("yyy", 0), # shard dim 0 for column-parallel, 1 for row-parallel, None for replicated
} Defensive patterns
Strategy: validation
Validate before calling
from safetensors import safe_open
from convert import mapping
with safe_open("model-00001-of-000163.safetensors", framework="pt") as f:
bad = set()
for name in f.keys():
n = name[len("model."):] if name.startswith("model.") else name
n = n.replace("self_attn", "attn").replace("mlp", "ffn") \
.replace("weight_scale_inv", "scale").replace("e_score_correction_bias", "bias")
key = n.split(".")[-2]
if key not in mapping:
bad.add((name, key))
assert not bad, f"unmapped keys: {sorted(bad)[:10]}" Type guard
def key_is_mapped(name: str, mapping: dict) -> bool:
key = name.split(".")[-2]
return key in mapping Try / catch
try:
main(hf_ckpt_path, save_path, n_experts, mp)
except AssertionError as e:
if "not found in mapping" in str(e):
raise SystemExit(
"Checkpoint naming differs from expected HF DeepSeek-V3 layout. "
"Inspect the key in the message and extend `mapping` in convert.py."
)
raise Prevention
- Only convert checkpoints with the exact HF naming this script targets
- Dry-run the key rename over all safetensors keys before a long conversion
- When HF releases new model revisions, diff tensor names first: safetensors safe_open keys vs mapping
When it happens
Trigger: Running convert.py --hf-ckpt-path with: a checkpoint from a different/newer HF model revision that renamed modules (e.g. new attention or quantization keys), a DeepSeek-R2/other-variant checkpoint with keys like xxx not in mapping, a plain (non-HF) safetensors file, or names where the replacement chain produces an unexpected second-to-last token (e.g. after 'mlp'→'ffn', 'gate_proj'→... the split lands on something unmapped like 'e_score_correction_bias' paths where key becomes 'bias' before mapping).
Common situations: Upgrading transformers/HF checkpoint revisions where naming changed; converting V2/V3.1/V3.2-Exp checkpoints whose router or expert-parallel keys differ; scale tensors named differently (weight_scale vs weight_scale_inv) so 'scale' key never appears or an unknown key appears.
Related errors
- Warning: Missing scale_inv tensor for ${weight_name}, skippi
- Dimension ${dim} must be divisible by ${mp}
- Number of experts must be divisible by model parallelism
- Vocabulary size must be divisible by world size (world_size=
- Output features must be divisible by world size (world_size=
AI-assisted analysis of deepseek-ai/DeepSeek-V3@9b4e9788e4 (2026-08-14).
Data as JSON: /api/errors/8703f7b4d1e39362.
Report an issue: GitHub.