Files
deepseek-v4-quant/memory/2026-05-08.md
biondizzle f63eed5cfd Purge INT4 references — expert weights are FP4 (E2M1), not INT4
All docs and scripts updated. Historical memory entries annotated.
2026-05-08 02:33:46 +00:00

72 lines
5.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 2026-05-08 DeepSeek V4 Pro NVFP4 Quantization
## Status: Blocked on mixed-precision model's deeply non-standard weight format
The mixed-precision `DeepSeek-V4-Pro` model has three levels of compression:
- **Attention layers**: FP8 (float8_e4m3fn + float8_e8m0fnu scales) — our `dequant_fp8_to_bf16.py` handles these ✅
- **Routed experts**: INT8 at **half dimensions** — e.g. `w1: int8 [3072, 3584]` instead of expected `[3072, 7168]`, with separate scale factors. Our dequant script does NOT handle these ❌
- **Shared experts**: FP8 (float8_e4m3fn) — also not dequantized ❌
Result: `from_pretrained` sees shape mismatches on expert weights because the INT8 expert tensors are at half the expected dimensions. `ignore_mismatched_sizes` won't help — it'd reinitialize with random weights.
## What needs to happen
A **complete dequantization** script that handles ALL compressed tensor types:
1. FP8 attention weights (weight × block_scale → BF16) — already working
2. INT8 routed expert weights (weight × scale → BF16, expand dimensions back) — need to find scale tensors
3. FP8 shared expert weights — same as attention dequant
Then produce a truly pure-BF16 model with standard dimensions.
## Attempt history on B200 node (45.76.247.107)
1. **Custom quantizer (Path A)**: Output 840GB, wrong format — rejected
2. **FP8 model + modelopt**: DeepGEMM crashes on Blackwell (SM100 unsupported), Triton finegrained FP8 matmul has K mismatch
3. **Naive upcast (upcast_to_bf16.py)**: Just cast FP8 scales to BF16 without dequantizing — broken, FP8Linear.forward still tries FP8 kernel path
4. **Proper dequant (dequant_fp8_to_bf16.py)**: Handles FP8 attention ✅, but missed INT8 experts and FP8 shared experts — shape mismatch on load
5. **nvfp4_experts_only on mixed-precision**: Crashes in calibration forward pass (FP8Linear kernel issues)
6. **nvfp4_experts_only on dequantized BF16**: OOM killed during quantizer setup (94% RAM with seq_device_map)
7. **nvfp4_experts_only, 128 calib, gpu_max_mem_percentage 0.9**: Shape mismatch — INT8 expert weights at half dimensions
## Repo
- Branch: `modelopt-nvfp4` on `https://sweetapi.com/biondizzle/deepseek-v4-quant.git`
- Auth: user `biondizzle`, password `Gold1234@x`
- Scripts: `scripts/dequant_fp8_to_bf16.py`, `scripts/upcast_to_bf16.py`, `scripts/model_opt_nvfp4_experts_only.py`
- Patches: `patches/patch_finegrained_fp8_blackwell.py`, `patches/quant_module_patched.py`
## Key learnings
- Mixed-precision DeepSeek-V4-Pro is NOT just "BF16 with some FP8" — it has INT8 expert weights at half dimensions too
- DeepGEMM only supports SM90 (Hopper), not SM100 (Blackwell)
- FP8Linear.forward() has an escape hatch: `if self.weight.element_size() > 1: return F.linear(...)` — if weight is BF16, it skips the FP8 kernel
- `--use_seq_device_map` causes OOM on 2.8TB RAM with 782GB model + quantizer overhead
- `--gpu_max_mem_percentage 0.9` is the right approach — fits ~1.3TB on 8×B200 GPUs
- Calibration size (256 vs 128) only affects scale quality, not model format or inference
## Mike's preferences
- Name output dirs with strategy: `DeepSeek-V4-Pro_NVFP4-<strategy>_kv_fp8_cast`
- One script per strategy, copy and tweak for each
- Track everything in git, don't lose working code
- Target output: ~600GB NVFP4
## 01:37 UTC - Complete dequant script updated, strategy pivot to full NVFP4
### Script update: `dequant_fp8_to_bf16.py` now handles ALL compressed types:
1. **FP8 weights** (attention + shared experts): block-wise (128×128) dequant via float8_e4m3fn × float8_e8m0fnu scale → BF16
2. **FP4 (E2M1) expert weights**: Unpack 2 FP4 values per int8 byte (lower nibble first, upper second), E2M1 LUT lookup × E8M0 scale, per-row 32-column block scaling (MXFP4 microscaling), output dimensions 2× stored dimensions → BF16
3. **Scale tensors removed** after dequantization
4. Progress output per shard with ETA
### Mike's directive: strategy change
- **Drop `nvfp4_experts_only`** — go full `nvfp4` quantization on the properly dequantized BF16 model
- Need to create `scripts/model_opt_nvfp4_full.py` (copy from experts_only, change `--quantization` from `nvfp4_experts_only` to `nvfp4`)
- Steps: (1) Run complete dequant to get true BF16 model, (2) Run full nvfp4 quantization on it
### FP4 (E2M1) expert weight format confirmed (was incorrectly assumed INT4)
- `w1: int8 [3072, 3584]` with scale `float8_e8m0fnu [3072, 224]` → output `[3072, 7168]` (224 * 32 = 7168)
- `w2: int8 [7168, 1536]` with scale `float8_e8m0fnu [7168, 96]` → output `[7168, 3072]` (96 * 32 = 3072)
- `w3: int8 [3072, 3584]` with scale `float8_e8m0fnu [3072, 224]` → output `[3072, 7168]`
- **Proof**: nibble index 0 (+0.0) vs index 8 (-0.0) ratio = 0.996. INT4 would have -8 at index 8 (rare). FP4 has -0.0 at index 8 (same as +0.0).
### Previous BF16 model is WRONG
- The `/root/nvidia-meeting/DeepSeek-V4-Pro-BF16` (782GB) only dequantized FP8 attention weights
- FP4 expert weights and FP8 shared experts were left compressed → shape mismatches on load
- Must re-run complete dequant, output will likely be larger (~1.1-1.2TB?)