deepseek-ai/DeepSeek-V3 · warning
Warning: Missing scale_inv tensor for ${weight_name}, skippi
Error message
Warning: Missing scale_inv tensor for ${weight_name}, skipping conversion What it means
This is a printed WARNING (not an exception) from fp8_cast_bf16.py:82: a weight with element_size()==1 (FP8) had no matching '{weight}_scale_inv' tensor findable via get_tensor (which raises KeyError when the name is absent from weight_map or from the loaded file). The except KeyError path keeps the raw FP8 bytes in the BF16 output and continues — downstream code then silently loads a mixed-precision checkpoint, which will produce garbage activations.
Source
Thrown at inference/fp8_cast_bf16.py:82
safetensor_files.sort()
for safetensor_file in tqdm(safetensor_files):
file_name = os.path.basename(safetensor_file)
current_state_dict = load_file(safetensor_file, device="cuda")
loaded_files[file_name] = current_state_dict
new_state_dict = {}
for weight_name, weight in current_state_dict.items():
if weight_name.endswith("_scale_inv"):
continue
elif weight.element_size() == 1: # FP8 weight
scale_inv_name = f"{weight_name}_scale_inv"
try:
# Get scale_inv from the correct file
scale_inv = get_tensor(scale_inv_name)
fp8_weight_names.append(weight_name)
new_state_dict[weight_name] = weight_dequant(weight, scale_inv)
except KeyError:
print(f"Warning: Missing scale_inv tensor for {weight_name}, skipping conversion")
new_state_dict[weight_name] = weight
else:
new_state_dict[weight_name] = weight
new_safetensor_file = os.path.join(bf16_path, file_name)
save_file(new_state_dict, new_safetensor_file)
# Memory management: keep only the 2 most recently used files
if len(loaded_files) > 2:
oldest_file = next(iter(loaded_files))
del loaded_files[oldest_file]
torch.cuda.empty_cache()
# Update model index
new_model_index_file = os.path.join(bf16_path, "model.safetensors.index.json")
for weight_name in fp8_weight_names:
scale_inv_name = f"{weight_name}_scale_inv"
if scale_inv_name in weight_map:View on GitHub (pinned to 9b4e9788e4)
Solutions
- Re-verify the download: compare model.safetensors.index.json weight_map against actual files; re-download incomplete shards (huggingface-cli download --resume)
- Check the actual scale naming in the checkpoint and, if different (e.g. ...scale or ...scale_weight), adjust scale_inv_name or pre-rename keys
- Treat this warning as fatal for correctness — grep the output for 'Missing scale_inv' and fail the run instead of shipping mixed FP8/BF16 weights
- Confirm you are converting the official DeepSeek-V3/R1 FP8 checkpoint that this script was written for
Example fix
# before (fp8_cast_bf16.py)
except KeyError:
print(f"Warning: Missing scale_inv tensor for {weight_name}, skipping conversion")
new_state_dict[weight_name] = weight
# after — fail fast on missing scales
except KeyError:
raise RuntimeError(
f"Missing scale_inv for {weight_name}: FP8 checkpoint is incomplete or "
f"uses different scale naming; re-download or fix the index"
) Defensive patterns
Strategy: try-catch
Validate before calling
import json, os
from glob import glob
fp8_path = "hf/deepseek-ai/DeepSeek-V3"
with open(os.path.join(fp8_path, "model.safetensors.index.json")) as f:
weight_map = json.load(f)["weight_map"]
# Every FP8 weight must have a scale_inv entry mapped to an existing file
all_keys = set()
for shard in glob(os.path.join(fp8_path, "*.safetensors")):
from safetensors import safe_open
with safe_open(shard, framework="pt") as sf:
all_keys.update(sf.keys())
missing = [k for k in all_keys
if not k.endswith("_scale_inv") and f"{k}_scale_inv" not in all_keys]
# element_size check happens at runtime; approximate by name for FP8 checkpoints
assert not missing, f"weights missing scale_inv (incomplete download?): {missing[:5]}" Type guard
def has_scale_inv(weight_name: str, weight_map: dict, loaded_keys: set) -> bool:
scale = f"{weight_name}_scale_inv"
return scale in weight_map and scale in loaded_keys Try / catch
# Fail fast instead of printing a warning and emitting mixed-precision weights
try:
scale_inv = get_tensor(scale_inv_name)
except KeyError:
raise RuntimeError(
f"Missing {scale_inv_name}: the FP8 checkpoint is incomplete or its scale "
f"tensors use different naming. Re-download the checkpoint or fix the index; "
f"continuing would silently keep FP8 bytes in the BF16 output."
) Prevention
- Grep conversion logs for 'Missing scale_inv' and treat any hit as a failed run
- Verify download completeness with huggingface-cli download (resumable) and check index.json entry counts
- Only feed this script the official DeepSeek FP8 checkpoints; other quantization schemes name scales differently
- After conversion, sanity-check output dtypes: no tensor in the BF16 output should have element_size()==1
When it happens
Trigger: Running fp8_cast_bf16.py on a checkpoint where: the scale tensor is named differently (e.g. 'weight_scale' without _inv), the model.safetensors.index.json weight_map lacks the scale entry (corrupt/partial download), or the scale lives in a file whose name differs from the map. The per-file iteration reads via load_file (KeyError on missing key) and get_tensor (KeyError on missing weight_map entry).
Common situations: Incomplete interrupted downloads from HF hub (missing shard scale entries); checkpoints from quantizers other than the official FP8 recipe (e.g. compressed-tensors uses weight_scale/axis-ep names); index.json from a different revision than the shard files.
Related errors
- Input tensors must be contiguous
- Input tensors must have 2 dimensions
- Key ${key} not found in mapping
- Input tensor must be contiguous
- Last dimension size must be divisible by block_size (block_s
AI-assisted analysis of deepseek-ai/DeepSeek-V3@9b4e9788e4 (2026-08-14).
Data as JSON: /api/errors/996a3ef3448d0bbb.
Report an issue: GitHub.