DEV Community

frank chu
frank chu

Posted on

DeepSeek swapped its Flash model overnight. I pulled the new config and did the cache math.

On October 17, DeepSeek replaced the model behind its deepseek-flash API endpoint. Same name, same price, no changelog entry you had to go read — if your agent called deepseek-flash on Friday and again on Saturday, it talked to two different checkpoints and nobody sent you an email about it.

The new checkpoint is DeepSeek-V4.1-Flash-1017, on Hugging Face under MIT, and it was the top story on Hacker News this morning (903 points when I checked). DeepSeek calls it "a minor update." Its own benchmark table disagrees with the adjective: all 11 reported benchmarks went up, Terminal-Bench 4.0 by 11.1 points, ProgramBench by 8.8. Those are DeepSeek's numbers on DeepSeek's harnesses, and I can't reproduce DeepSWE from my desk. What I can do is pull the primary artifacts — the actual config.json and the actual file sizes — and check the part of the story that is arithmetic: the KV cache paper is titled "Pushing the Limits of KV Cache Compression," and a figure of 890 bytes per token of cache has been circulating in the coverage. So I did the math from the config.

What the config actually says

curl -s https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash-1017/raw/main/config.json
Enter fullscreen mode Exit fullscreen mode

The fields that matter:

num_hidden_layers      40
len(compress_ratios)   43        <- three more than the layer count
compress_ratios        {0: 5 layers, 2: 18 layers, 1: 20 layers}
num_attention_heads    64
num_key_value_heads    1
head_dim               512
sliding_window         128
max_position_embeddings  1,048,576
kv_source_layer_ids    [2, 8, 14, 20]   <- only four layers source long-range KV
index_topk             512
n_routed_experts       384,  num_experts_per_tok  6
Enter fullscreen mode Exit fullscreen mode

And the weights, summed from the Hugging Face blob sizes rather than anyone's summary of them:

48 safetensors shards
510,296,708,312 bytes total = 510.3 GB (475.3 GiB)
downloads at fetch time: 10,233   likes: 1,216   created: 2026-10-17T02:40Z
Enter fullscreen mode Exit fullscreen mode

Three things in there are doing the real work. One KV head, shared. A sliding window of 128 tokens, which means a windowed layer's cache stops growing after 128 positions no matter how long your context gets. And only four source layers feeding long-range KV, with per-layer compression ratios on top.

The cache math, with the assumptions on the table

Here is the whole experiment. Every number below is a bound under a stated assumption, because the config tells you the geometry, not the serving stack's exact layout:

L = 43            # len(compress_ratios) from the config
head_dim = 512

# [A] every layer stores its own 512-dim latent KV per token, bf16
A = L * head_dim * 2
# [B] a vanilla MHA transformer of the same width, for scale
B = L * 64 * 80 * 2 * 2     # 64 heads x 80 dim, K and V, bf16
# [C] only the 4 kv_source layers store long-range KV, ratio-2 compressed
C = 4 * head_dim * 2 // 2
Enter fullscreen mode Exit fullscreen mode
[A] every layer, 512-dim latent, bf16:  44,032 bytes/token -> 46.2 GB at 1M tokens
[B] vanilla MHA, same width:           880,640 bytes/token -> 923.4 GB at 1M tokens
[C] only 4 source layers, compressed:   2,048 bytes/token -> 2.15 GB at 1M tokens
[claim] 890 bytes/token:                                    -> 0.93 GB at 1M tokens
Enter fullscreen mode Exit fullscreen mode

The circulating 890 figure sits below even my most aggressive bound, which means quantization below bf16 and the sparse index (index_topk: 512 — the model attends to a selected subset, not everything it stores) are doing the rest. Fine. Plausible. But here is the part nobody in the coverage mentioned: bytes per token is not a constant for this architecture, and quoting it as one is a category error. A window-128 layer costs 128 positions whether your prompt is 8,000 tokens or a million. Run the amortization:

window-only effective bytes/token at ctx=8,192:     688.0
window-only effective bytes/token at ctx=131,072:    43.0
window-only effective bytes/token at ctx=1,048,576:   5.4
Enter fullscreen mode Exit fullscreen mode

Same model, same code, and the "per-token" cache cost swings by two orders of magnitude depending on the length you measured at. Whoever produced 890 measured at some specific length, on some specific mix of layers, and the number travels without either. That doesn't make it wrong. It makes it incomplete in exactly the way a benchmark score is incomplete — and this one at least ships with a config file you can check it against, which is more than the 11 benchmark rows give you.

The price is the other half of the paper

DeepSeek's published API prices, checked today: $0.15 per million uncached input tokens, $0.60 per million output, and $0.003 per million cached input reads. That last ratio is the tell:

1M uncached input: $0.15 | 1M output: $0.60 | 1M cached input: $0.003
cached input is 50x cheaper than uncached input
Enter fullscreen mode Exit fullscreen mode

A 50x discount on cache reads is a vendor telling you, in prices, that its cache is genuinely cheap to serve — that's the KV compression work showing up in the rate card, not the press release. DeepSeek's own DeepSWE chart (via The Decoder's summary) puts the new model at just under $0.20 per task at its top setting against $2–$10 for rivals on the same chart: 10x to 50x. Vendor chart, vendor harness, treat accordingly. But the direction is consistent with the config, and the config is public.

There is also a Search and Fetch API in this release at $0.75 per 1,000 successful requests, free through server-side tools in DeepSeek Harness, Claude Code and Codex until billing starts on October 31 at 16:00 UTC. DeepSeek is no longer just selling the model; it's selling the agent's eyes.

The part I actually don't like

None of the above is the problem. The problem is the delivery mechanism: a silent swap under an unchanged model name. Every evaluation you ran against deepseek-flash last week now describes a checkpoint that no longer serves traffic. DeepSeek did publish the weights and a dated checkpoint name — ...-1017 is right there in the repo name — so the pinned, self-hosted path is fully reproducible. It's only the convenient path, the API alias, that moved underneath you. If you pin versions for your database and your base images but let your model float on a vendor's alias, this release is what that policy costs you: not a worse model — by every published measure it's a better one — just a different one than the one you tested.

Pin the checkpoint. Read the config. The arithmetic is the announcement.

Top comments (0)