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

  1. Re-verify the download: compare model.safetensors.index.json weight_map against actual files; re-download incomplete shards (huggingface-cli download --resume)
  2. 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
  3. 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
  4. 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

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


AI-assisted analysis of deepseek-ai/DeepSeek-V3@9b4e9788e4 (2026-08-14). Data as JSON: /api/errors/996a3ef3448d0bbb. Report an issue: GitHub.