DeepSeek-V4.1-Flash-1017: what changed
DeepSeek calls it a minor update. The config is byte-identical and every tensor keeps its name and shape, yet all 48 shards changed. We diffed 2,421 tensors over HTTP range reads: the main model moved by about one percent, the draft model behind its speculative decoding was rebuilt.
- 4×B200·78 s·621 GiB·580
deepseek-v41-flash-1017Run01 · THE CLAIMA minor update with major gains
On October 17 DeepSeek published DeepSeek-V4.1-Flash-1017 and called it a minor update to V4.1-Flash, with “substantial improvements across reasoning, coding, agentic tasks, and visual benchmarks”, shorter outputs and faster task execution. These are the model card’s numbers, not ours:
Terminal-Bench 4.0 and ProgramBench gain 11 and 9 points, HLE without tools 5.8. A minor version label usually means a light fine-tune, so we looked at what actually changed between the two checkpoints.
02 · THE FILESSame architecture, new bytes everywhere
The two repositories agree on structure exactly. config.json is byte-identical, and both checkpoints hold 96,085 tensors with the same names, data types and shapes, laid out over the same 48 safetensors shards. Every one of the 48 shards has a different SHA-256, so no shard was carried over unchanged. Around the weights, 1017 recommends top_p 1.0 (V4.1-Flash said 0.95 or 1.0) and drops the Jinja chat_template.jinja, the technical report and the evaluation patch; prompts are encoded with encoding.py or DeepSeek’s new deepseek-recipe library.
Where the 475 GiB go also tells you which parts a fine-tune can afford to touch:
The 384 routed experts in each of 40 layers are FP4, packed two codes per byte with an E8M0 scale per block of 32, and take 57% of the checkpoint. The two Engram layers, lookup tables of 384 million FP8 rows each that the model reads from like a memory, take another 40%. Attention, the shared experts, the three MTP layers, the embeddings, the vision encoder and everything else fit in the remaining 17 GiB.
03 · METHODDiffing 950 GiB without downloading it
A safetensors file starts with a JSON header that gives every tensor’s type, shape and byte range, so an HTTP range read of the first few kilobytes of each shard maps the whole checkpoint. From there we read the same 16 KiB windows, at 25% and 75% into each tensor, from both releases and compared them. We sampled 2,421 tensors: every non-expert tensor of all 40 layers, 4 of the 384 experts in each layer and in each MTP layer, both Engram layers, and blocks 0, 16 and 31 of the vision encoder. That is about 110 MiB read instead of 950 GiB downloaded.
Two numbers per tensor. Codes changed is the share of stored values whose bits differ. Relative change is ‖Δ‖ / ‖W‖ over the decoded values. For BF16 and F32 tensors the relative change is the weight change itself. For FP4 and FP8 it is measured on the codes before their block scales, and quantization adds a floor: re-quantizing a slightly different weight flips a share of coarse FP4 codes even when the underlying weight barely moved. So the full-precision tensors give the clean picture, and the quantized ones are compared with each other.
04 · RESULTA light touch on the model, a new draft model
The main model moved by about one percent. Layer norms changed by 0.8%, the hyper-connection mixers by 1.5%, the token embeddings by 1.8% and the output head by 1.5%. That is the signature of post-training on top of the same base: every weight moves, none moves much. The parts that moved most are the ones that decide where computation goes: the expert router (5.0%) and the sparse-attention indexer (5.8%), which picks the tokens each query attends to.
Vision moved more. The encoder changed by 2.6% and the aligner that projects image features into the language model by 8.7%, consistent with the visual benchmarks on the card.
The draft stack was retrained. DeepSeek-V4.1-Flash speculates with three MTP layers and DSpark heads that propose tokens for the main model to verify. Their full-precision weights changed by 9.4% at the median and the DSpark heads by 37.3%; the MTP experts, below, look like new weights. A better drafter means more accepted tokens per step, which is one way to deliver the “faster task execution” the card promises without touching the main model’s quality.
| Weights | Format | Codes changed | Change in decoded values | Tensors sampled |
|---|---|---|---|---|
| routed experts | FP4 (E2M1) | 26.6% | 21.4% | 480 |
| MTP routed experts | FP4 (E2M1) | 88.0% | 98.5% | 36 |
| attention projections | FP8 (E4M3) | 64.4% | 8.3% | 200 |
| shared experts | FP8 (E4M3) | 74.1% | 17.6% | 120 |
| MTP attention and shared experts | FP8 (E4M3) | 94.9% | 56.6% | 24 |
| Engram tables | FP8 (E4M3) | 28.7% | 7.3% | 2 |
| expert block scales | E8M0 | 6.1% | 3.8% | 480 |
Read the quantized rows against each other. The main model’s FP4 experts flipped 26.6% of their codes; the MTP experts flipped 88.0%, with a decoded change of 98%: as different as two unrelated sets of weights. The Engram tables changed 28.7% of their entries by 7.3%, so the memory was updated too, while the projection that turns hidden states into Engram keys (97%) was replaced outright.
Where in depth
The norms changed most in the first eight layers, about 1.4%, and least in the middle of the stack, about 0.7%. The FP4 experts show the opposite shape, a few more codes flipped in the middle layers:
05 · SERVING ITSame engine, new weights
Because the architecture did not change, the vLLM settings carry over: the 1017 profile is our 4×B200 profile for V4.1-Flash at the new revision, with tensor parallelism and expert parallelism over four GPUs, 32 GiB of FP8 KV cache per GPU, DSpark with five draft tokens and a 192K context, on vLLM’s SM100 kernels for the FP4 experts. On 8×B200 (four GPUs used), NVIDIA driver 580.173.02:
A vLLM cold start takes 1,196 s before the first token. warmctl up restores the warmed engine in 78.4 s from page cache. CRIU is the largest step, 47.8 s, because the dump carries the Engram tables the engine keeps in pinned host memory: 326 GiB of process images next to 293 GiB of weights. The canary runs under a tolerance: FP4 experts are not bitwise repeatable, so the profile compares log-probabilities and warns rather than refusing to serve.
| Tokens in → out | Concurrent | Output tok/s | Total tok/s | TTFT p50 | TPOT p50 |
|---|---|---|---|---|---|
| 1K → 512 | 1 | 245 | 734 | 0.15 s | 3.2 ms |
| 1K → 512 | 32 | 1,757 | 5,270 | 2.41 s | 11.9 ms |
| 1K → 512 | 128 | 4,437 | 13,310 | 0.44 s | 24.7 ms |
| 1K → 2048 | 64 | 6,871 | 10,306 | 0.08 s | 7.4 ms |
| 8K → 512 | 1 | 204 | 3,471 | 0.18 s | 4.3 ms |
| 32K → 512 | 1 | 155 | 10,104 | 0.55 s | 5.3 ms |
Random-token prompts, medians per run. One request decodes at 316 tokens/s (3.2 ms per token with DSpark), 128 concurrent requests produce 4,437 output tokens/s, and 64 long generations 6,871. A 32K prompt gets its first token in 0.55 s.
06 · RUN ITBoth versions, side by side
The update is its own entry in the warmctl catalog, so warmctl up deepseek-v41-flash keeps serving the original while you compare:
$ curl -fsSL https://warmctl.io/install.sh | sh $ warmctl up deepseek-v41-flash-1017
The profile and the v2.0.0-beta.7 release that ships it are on GitHub. The diff itself is two short scripts, headers.py and diff.py: Python’s standard library and HTTP range requests, adaptable to any pair of safetensors checkpoints on Hugging Face.