jon1012 commited on
Commit
f502798
·
verified ·
1 Parent(s): bb70bd3

Final card and build scripts: measured numbers, Engram caveat, pruning analysis

Browse files
Files changed (1) hide show
  1. README.md +140 -97
README.md CHANGED
@@ -15,10 +15,8 @@ tags:
15
 
16
  # DeepSeek-V4.1-Flash-NVFP4
17
 
18
- > **🚧 Coming soon this repository is a placeholder.** The weights are being built
19
- > right now and will land here shard by shard. The numbers below marked ⬜ are not
20
- > measured yet. Everything marked ✅ is already verified against the source checkpoint.
21
- > Watch this repo; the card is updated as each piece is uploaded.
22
 
23
  An FP4 re-pack of [`deepseek-ai/DeepSeek-V4.1-Flash`](https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash)
24
  by [LibertAI](https://libertai.io).
@@ -35,7 +33,7 @@ DeepSeek quantized V4.1-Flash themselves. From the upstream `config.json`:
35
  }
36
  ```
37
 
38
- Measured across all 48 upstream shards / 96,085 tensors (475.2 GiB):
39
 
40
  | component | size | share | dtype as shipped |
41
  |---|---:|---:|---|
@@ -45,124 +43,169 @@ DeepSeek quantized V4.1-Flash themselves. From the upstream `config.json`:
45
  | attention / dense | 4.9 GiB | 1.0% | E4M3, block 32×32 |
46
  | embeddings, head, vision | 4.0 GiB | 0.8% | BF16 |
47
 
48
- This is the break from V4-Flash. `DeepSeek-V4-Flash-0731` shipped FP8 block-128×128 with
49
- no FP4 anywhere — which is why the NVFP4 conversions of *that* model were worth ~2×. Here
50
- the 57% of the checkpoint that is routed experts is already at 4 bits, so quantizing it
51
- again buys nothing.
52
-
53
- ## What this repo actually does
54
-
55
- Two things, and it is worth being precise about which is a format change and which is a
56
- quantization.
57
-
58
- ### 1. Experts: MXFP4 → NVFP4, losslessly ✅
59
-
60
- The upstream experts are MX-style: 32-element blocks with a power-of-two E8M0 scale.
61
- NVFP4 is 16-element blocks with an E4M3 scale plus an FP32 per-tensor global scale.
62
-
63
- The transcode is **bit-exact**, and for a structural reason worth stating: NVFP4's
64
- 16-element blocks are a strict refinement of the source's 32-element blocks, so both
65
- NVFP4 half-blocks inherit one source scale `s`. Emit the nibbles **unchanged** and force
66
- `weight_scale × weight_scale_2 == s`, and every reconstructed value is identical to the
67
- source. E8M0 scales are powers of two, and E4M3 represents 2^k exactly for k ∈ [−9, 8],
68
- so the identity holds for every block whose scale lands in that window — the global scale
69
- is chosen per tensor to centre it. ⬜ Fraction of blocks outside the window: to be
70
- reported here per tensor (expected 0).
71
-
72
- ✅ Verified on shard 4: 1,152 expert weights transcoded, and an independent
73
- reconstruction from both representations found **0 mismatches over 2.36 billion elements,
74
- `max|delta| = 0` exactly**, with **0 of 849,346,560 block scales** falling outside E4M3's
75
- window.
76
-
77
- **This costs size.** NVFP4 is 4 + 8/16 = 4.5 bits/weight against MXFP4's 4 + 8/32 = 4.25,
78
- so the experts *grow*: shard 4 went from 7,389,759,032 to 7,814,559,376 bytes, **+5.75%**.
79
- Take this variant only if your engine's Blackwell MoE kernels want NVFP4 and have no MX
80
- path — it is a compatibility shim, not a compression win, and we would rather say so than
81
- let you find out from a disk-full error.
82
-
83
- To be clear about prior art: this losslessness is not something we invented, it is what
84
- any careful implementation of this transcode gets, for the structural reason above. We
85
- checked [`s-zaizen/DeepSeek-V4.1-Flash-NVFP4`](https://huggingface.co/s-zaizen/DeepSeek-V4.1-Flash-NVFP4),
86
- published the same day, by reconstructing `layers.1.ffn.experts.0.w1` from both their
87
- checkpoint and the source: **their nibbles are identical and all 11,796,480 elements match
88
- exactly too.** Their repo is **491.1 GiB — larger than the 475.2 GiB original** — because
89
- the expert transcode grows the file and the Engram tables are left at FP8. That is the gap
90
- this repo is trying to close, and it is the only thing that meaningfully separates the
91
- two.
92
-
93
- ### 2. Engram: FP8 → FP4, the one real size lever ⬜
94
-
95
- The Engram conditional-memory tables are 189.1 GiB — 39.8% of the checkpoint — and they
96
- are the only large block DeepSeek left at 8 bits. Two tables of ~384M rows × 256, at
97
- E4M3 with block-32 E8M0 scales.
98
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
  We take them to E2M1 **keeping the source's own block-32 / E8M0 scale layout**, so a table
100
- row ends up stored exactly the way DeepSeek stores an expert weight and any kernel that can
101
- dequantize an expert can dequantize the table. Scales are recomputed as a power of two
102
- ≥ amax/6 rather than reused, so no block clips.
103
 
104
- **189.1 ~97 GiB.** Accuracy impact is a real question and is being measured — this is
105
- a lossy step on a memory table, unlike step 1. Mean cosine similarity per row will be
106
- reported here before this variant is recommended for anything.
 
107
 
108
- Engram is a hashed n-gram **gather**, not a GEMM roughly 48 rows × 256 B12 KB per
109
- token so it dequantizes cheaply on lookup and is NVMe-friendly if you offload it.
110
- Upstream's own `convert.py` already shards `engram.embed` along dim 0 across ranks.
 
 
111
 
112
- ### Net effect
113
 
114
  | | upstream | s-zaizen NVFP4 | this repo |
115
  |---|---:|---:|---:|
116
  | routed experts + MTP | 276.3 GiB | ~292 GiB | ~292 GiB |
117
- | Engram | 189.1 GiB | 189.1 GiB | ~97 GiB |
118
  | everything else | 8.9 GiB | 8.9 GiB | 8.9 GiB |
119
- | **total** | **475.2 GiB** | **491.1 GiB** | **~398 GiB** |
120
 
121
- The Engram column is the whole point. If you need NVFP4 experts and do not care about
122
- Engram, s-zaizen's repo is a perfectly good checkpoint and was there first.
123
 
124
- ## Hardware notes
125
 
126
- Even at ~398 GiB this is a large model, and the Engram offload does not change the
127
- resident-weight picture as much as you would hope: the backbone alone (experts + MTP +
128
- attention + vision + embeddings) is ~301 GiB / 323 GB resident with the entire Engram
129
- table pushed to NVMe. Two 120 GB unified-memory boxes cannot hold it. A 4×B200 or
130
- 8×96 GB node can.
131
 
132
- A **REAP-pruned variant** targeting 2-node 120 GB-class hardware is in progress and will
133
- be published separately.
 
 
134
 
135
- ## About the base model
 
 
 
136
 
137
- DeepSeek-V4.1-Flash is a multimodal MoE with a **552B-parameter backbone** plus **196B of
138
- sparsely-accessed Engram memory**, activating **8B parameters per token during prefill and
139
- 16B during decode**, with a **1M-token** context.
140
 
141
- It uses a **Causal Encoder-Decoder** layout (40 layers = a 20-layer causal encoder feeding a
142
- 20-layer decoder, so the decoder's global KV is projected from final encoder states),
143
- **Compressed Sparse Attention 2** with per-layer Full/Reindex/Reuse modes and a hierarchical
144
- sparse indexer, **FP4 main KV caching** (E2M1, one E4M3 scale per 16 channels) for a global
145
- KV footprint of **890 bytes/token**, Single-Pass mHC, and **DSpark** speculative decoding.
146
- 384 routed experts + 1 shared, 6 routed per token. Reasoning effort is continuously
147
- controllable from 1 to 100.
148
 
149
- See the [technical report](https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash/blob/main/DeepSeek_V41_Tech_Report.pdf)
150
- and the upstream card for evaluations. We have run none of our own yet.
 
 
 
 
 
 
 
 
 
 
 
 
 
151
 
152
- ## Engine support
153
 
154
- As of 2026-09-10 no released engine serves `deepseek_v41`. vLLM has open PRs
155
  ([#56214](https://github.com/vllm-project/vllm/pull/56214),
156
  [#56228](https://github.com/vllm-project/vllm/pull/56228),
157
  [#56227](https://github.com/vllm-project/vllm/pull/56227),
158
  [#56208](https://github.com/vllm-project/vllm/pull/56208)) filed the morning the model
159
- dropped, and SGLang has merged a cookbook plus initial support. Serving instructions land
160
- here once we have actually served it.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
161
 
162
  ## Provenance
163
 
164
- Built with [`dsv41_fp4_stream.py`](./dsv41_fp4_stream.py), a shard-streaming re-packer that
165
- never holds more than one shard in RAM. The E2M1 table and nibble order are taken verbatim
166
- from the checkpoint's own `inference/convert.py`, not reconstructed from the spec.
 
 
 
 
 
 
167
 
168
  License: MIT, inherited from the base model.
 
15
 
16
  # DeepSeek-V4.1-Flash-NVFP4
17
 
18
+ **475.2 GiB 399.9 GiB (−15.8%)**, with the routed experts converted to NVFP4 **bit-exactly**
19
+ and the Engram memory tables taken from FP8 to FP4.
 
 
20
 
21
  An FP4 re-pack of [`deepseek-ai/DeepSeek-V4.1-Flash`](https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash)
22
  by [LibertAI](https://libertai.io).
 
33
  }
34
  ```
35
 
36
+ Measured across all 48 upstream shards / 96,085 tensors (475.2 GiB):
37
 
38
  | component | size | share | dtype as shipped |
39
  |---|---:|---:|---|
 
43
  | attention / dense | 4.9 GiB | 1.0% | E4M3, block 32×32 |
44
  | embeddings, head, vision | 4.0 GiB | 0.8% | BF16 |
45
 
46
+ This is the break from V4-Flash. `DeepSeek-V4-Flash-0731` shipped FP8 block-128×128 with no
47
+ FP4 anywhere — which is why the NVFP4 conversions of *that* model were worth ~2×. Here the
48
+ 57% of the checkpoint that is routed experts is already at 4 bits, so quantizing it again
49
+ buys nothing. **The Engram tables are the only large block left at 8 bits, and they are what
50
+ this repo is really about.**
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
 
52
+ ## What this repo does
53
+
54
+ ### 1. Experts: MXFP4 → NVFP4, bit-exactly
55
+
56
+ Upstream experts are MX-style: 32-element blocks with a power-of-two E8M0 scale. NVFP4 is
57
+ 16-element blocks with an E4M3 scale plus an FP32 per-tensor global scale.
58
+
59
+ The transcode is **lossless**, for a structural reason: NVFP4's 16-element blocks are a
60
+ strict refinement of the source's 32-element blocks, so both NVFP4 half-blocks inherit one
61
+ source scale `s`. Emit the nibbles **unchanged** and force `weight_scale × weight_scale_2 == s`,
62
+ and every reconstructed value is identical. E8M0 scales are powers of two, and E4M3
63
+ represents 2^k exactly for k ∈ [−9, 8], so the identity holds for every block whose scale
64
+ lands in that window. The global scale is chosen per tensor to centre it.
65
+
66
+ Measured over the **whole checkpoint**:
67
+
68
+ | | |
69
+ |---|---|
70
+ | expert weights transcoded | **47,232** |
71
+ | block scales inside E4M3's exact window | **34,823,208,960 / 34,823,208,960 (100%)** |
72
+ | independent reconstruction check | **0 mismatches over 2.36 × 10⁹ elements, `max\|delta\| = 0`** |
73
+
74
+ **This costs size.** NVFP4 is 4 + 8/16 = 4.5 bits/weight against MXFP4's 4 + 8/32 = 4.25, so
75
+ the experts *grow* — one shard went 7,389,759,032 → 7,814,559,376 bytes, **+5.75%**. Take
76
+ the expert half only if your engine's Blackwell MoE kernels want NVFP4 and have no MX path.
77
+
78
+ Prior art: this losslessness is not something we invented, it is what any careful
79
+ implementation gets. We checked
80
+ [`s-zaizen/DeepSeek-V4.1-Flash-NVFP4`](https://huggingface.co/s-zaizen/DeepSeek-V4.1-Flash-NVFP4),
81
+ published the same day, by reconstructing `layers.1.ffn.experts.0.w1` from their checkpoint
82
+ and from the source: **their nibbles are identical and all 11,796,480 elements match
83
+ exactly.** Their repo is **491.1 GiB — larger than the 475.2 GiB original** — because the
84
+ expert transcode grows the file and Engram is left at FP8.
85
+
86
+ ### 2. Engram: FP8 → FP4 — the actual size lever
87
+
88
+ The Engram conditional-memory tables are two tensors of ~384M rows × 256, 94.6 GiB each.
89
  We take them to E2M1 **keeping the source's own block-32 / E8M0 scale layout**, so a table
90
+ row is stored exactly the way DeepSeek stores an expert weight and any kernel that
91
+ dequantizes an expert can dequantize the table. Scales are recomputed as a power of two
92
+ ≥ amax/6 rather than reused, so **no block clips**.
93
 
94
+ | table | source | output | mean cosine (1.5M sampled rows) |
95
+ |---|---:|---:|---:|
96
+ | `layers.1.engram.embed` | 94.6 GiB | **48.8 GiB** | **0.993415** |
97
+ | `layers.14.engram.embed` | 94.6 GiB | **48.8 GiB** | **0.993445** |
98
 
99
+ ⚠️ **This half is lossy and has not been evaluated end-to-end.** Cosine0.9934 is lower
100
+ than we would accept on expert weights, and no benchmark has been run — no engine can run
101
+ this architecture yet (see below). If you need a checkpoint with untouched Engram, use
102
+ upstream or s-zaizen's repo. We publish this because the size and I/O win is large and the
103
+ measurement is stated honestly, not because the quality is established.
104
 
105
+ ## Net effect
106
 
107
  | | upstream | s-zaizen NVFP4 | this repo |
108
  |---|---:|---:|---:|
109
  | routed experts + MTP | 276.3 GiB | ~292 GiB | ~292 GiB |
110
+ | Engram | 189.1 GiB | 189.1 GiB | **97.6 GiB** |
111
  | everything else | 8.9 GiB | 8.9 GiB | 8.9 GiB |
112
+ | **total** | **475.2 GiB** | **491.1 GiB** | **399.9 GiB** |
113
 
114
+ 143,317 tensors across 48 shards. The index is rebuilt from the shard headers, and every
115
+ tensor the source had is present.
116
 
117
+ ## Running Engram off SSD
118
 
119
+ Engram is a hashed n-gram **gather**, not a GEMM. With `engram_layer_ids [1,14]`,
120
+ `engram_max_ngram_size 4` and `engram_n_heads 8`, each position looks up 3 n-gram sizes ×
121
+ 8 heads = 24 rows per Engram layer, so **48 rows per token**:
 
 
122
 
123
+ | | per row | per token |
124
+ |---|---:|---:|
125
+ | upstream FP8 | 264 B | 12.4 KB |
126
+ | this repo FP4 | 136 B | **6.4 KB** |
127
 
128
+ At decode that is ~48 random reads per token — trivial for an NVMe. Prefill is where it
129
+ bites: a 64K-token prompt is ~3.1M small random reads. **So the FP4 Engram halves the SSD
130
+ traffic per token as well as the footprint.** Upstream anticipates this: their `convert.py`
131
+ already shards `engram.embed` along dim 0 across ranks.
132
 
133
+ **But it does not make small boxes work.** Everything except the two Engram tables is
134
+ **302.3 GiB (324.6 GB)** and must be resident. Two 120 GB unified-memory boxes cannot hold
135
+ it, with or without Engram on disk. A 4×B200 or an 8×96 GB node can.
136
 
137
+ ## On pruning
 
 
 
 
 
 
138
 
139
+ We looked at whether V4.1-Flash could be expert-pruned to fit smaller hardware without
140
+ calibration data. **It cannot**, and the checkpoint says so three ways:
141
+
142
+ * the `noaux_tc` router bias is nearly uniform — **std 0.0627** against absolute values of
143
+ 9–57, top/bottom-decile gap ~0.13. Load balancing has equalised expert usage, so there
144
+ are no cold experts to drop.
145
+ * router directions are not redundant — nearest-neighbour cosine averages **0.32–0.45**,
146
+ and 0–2 experts per layer exceed 0.9. Nothing to merge.
147
+ * ⚠️ **`gate.bias` and `gate.bias_vl` are effectively uncorrelated** (mean **−0.05**, min
148
+ −0.45, mean absolute difference 6.4). The model carries a *separate* router bias for
149
+ vision-language tokens, so expert specialisation is modality-dependent and **a text-only
150
+ REAP calibration would prune the vision path.** If you are pruning this model, calibrate
151
+ on multimodal data.
152
+
153
+ Any real prune needs activation-based REAP, which needs a working engine.
154
 
155
+ ## Engine support
156
 
157
+ As of 2026-09-10 **no released engine serves `deepseek_v41`.** vLLM has open PRs
158
  ([#56214](https://github.com/vllm-project/vllm/pull/56214),
159
  [#56228](https://github.com/vllm-project/vllm/pull/56228),
160
  [#56227](https://github.com/vllm-project/vllm/pull/56227),
161
  [#56208](https://github.com/vllm-project/vllm/pull/56208)) filed the morning the model
162
+ dropped; SGLang has merged a cookbook plus initial support.
163
+
164
+ ⚠️ **DeepSeek's own `inference/` stack is bundled here for reference but will NOT load this
165
+ checkpoint as-is.** It expects the upstream layout: `convert.py` asserts routed experts are
166
+ `torch.int8` and reads their scales from `<name>.scale`, whereas this repo stores them as
167
+ `uint8` with `<name>.weight_scale` (E4M3, block 16) plus a `<name>.weight_scale_2` global
168
+ scale, and stores the Engram tables at E2M1 rather than E4M3. Loading it needs a reader that
169
+ understands the `quantization_config` below. We ship the reference code unmodified so the
170
+ delta is inspectable, not because it works out of the box.
171
+
172
+ Because nothing reads this architecture yet, the `quantization_config` in `config.json`
173
+ **describes** what we did rather than matching an existing convention:
174
+
175
+ ```json
176
+ "expert_dtype": "nvfp4", "expert_block_size": 16, "expert_scale_fmt": "e4m3",
177
+ "expert_global_scale": true,
178
+ "engram_dtype": "fp4", "engram_block_size": 32, "engram_scale_fmt": "ue8m0"
179
+ ```
180
+
181
+ Dense/attention weights are untouched (fp8, block 32×32, ue8m0). **No throughput, latency
182
+ or quality numbers are published here, because we have not been able to run the model.**
183
+
184
+ ## About the base model
185
+
186
+ DeepSeek-V4.1-Flash is a multimodal MoE with a **552B-parameter backbone** plus **196B of
187
+ sparsely-accessed Engram memory**, activating **8B parameters per token during prefill and
188
+ 16B during decode**, with a **1M-token** context.
189
+
190
+ It uses a **Causal Encoder-Decoder** layout (40 layers = a 20-layer causal encoder feeding a
191
+ 20-layer decoder), **Compressed Sparse Attention 2** with per-layer Full/Reindex/Reuse modes
192
+ and a hierarchical sparse indexer, **FP4 main KV caching** for a global KV footprint of
193
+ **890 bytes/token**, Single-Pass mHC, and **DSpark** speculative decoding. 384 routed experts
194
+ + 1 shared, 6 routed per token. Reasoning effort is continuously controllable from 1 to 100.
195
+
196
+ See the [technical report](https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash/blob/main/DeepSeek_V41_Tech_Report.pdf)
197
+ for evaluations. We have run none of our own.
198
 
199
  ## Provenance
200
 
201
+ Built with [`dsv41_fp4_stream.py`](./dsv41_fp4_stream.py), a shard-streaming re-packer.
202
+ The E2M1 table and nibble order are taken verbatim from the checkpoint's own
203
+ `inference/convert.py`, not reconstructed from the spec. The Engram shards are written as
204
+ hand-built safetensors containers so a 94.6 GiB table is never held in RAM.
205
+
206
+ Also included: [`verify_transcode.py`](./verify_transcode.py) (the bit-exactness check),
207
+ [`test_engram_path.py`](./test_engram_path.py) and
208
+ [`test_engram_shard.py`](./test_engram_shard.py) (cpu/cuda agreement and container
209
+ round-trip), and [`analyze_router.py`](./analyze_router.py) (the pruning analysis above).
210
 
211
  License: MIT, inherited from the base model.