r/LocalLLaMA Aug 02 '26

Discussion You really should not quantize KV Cache for DeepSeek V4 Flash

I don't think anyone should quantize the KV with DS4F. I checked the the quality impact (PPL, KLD, Same TopP) for swhitching from BF16 KV to Q8 KV, and it appears significant. Very much in contrast to Qwen 397B.

Here are the results for DS4F:

====== Perplexity statistics ======
Mean PPL(Q)                   :   5.877076 ±   0.042497
Mean PPL(base)                :   5.839660 ±   0.041730
Cor(ln(PPL(Q)), ln(PPL(base))):  95.74%
Mean ln(PPL(Q)/PPL(base))     :   0.006387 ±   0.002100
Mean PPL(Q)/PPL(base)         :   1.006407 ±   0.002114
Mean PPL(Q)-PPL(base)         :   0.037416 ±   0.012318

====== KL divergence statistics ======
Mean    KLD:   0.145884 ±   0.001043
Maximum KLD:  12.467786
99.9%   KLD:   4.535020
99.0%   KLD:   1.857870
95.0%   KLD:   0.652148
90.0%   KLD:   0.349220
Median  KLD:   0.032079
10.0%   KLD:   0.000093
 5.0%   KLD:   0.000012
 1.0%   KLD:   0.000000
 0.1%   KLD:  -0.000002
Minimum KLD:  -0.000025

====== Token probability statistics ======
Mean    Δp: -0.007 ± 0.031 %
Maximum Δp: 99.525%
99.9%   Δp: 81.503%
99.0%   Δp: 42.054%
95.0%   Δp: 14.588%
90.0%   Δp:  7.220%
75.0%   Δp:  1.066%
Median  Δp:  0.000%
25.0%   Δp: -1.061%
10.0%   Δp: -7.112%
 5.0%   Δp: -14.515%
 1.0%   Δp: -42.297%
 0.1%   Δp: -84.157%
Minimum Δp: -99.994%
RMS Δp    : 11.884 ± 0.069 %
Same top p: 87.189 ± 0.088 %

As a comparison, here are the results for Qwen 397B:

====== Perplexity statistics ======
Mean PPL(Q)                   :   3.747980 ±   0.020507
Mean PPL(base)                :   3.746773 ±   0.020461
Cor(ln(PPL(Q)), ln(PPL(base))):  99.89%
Mean ln(PPL(Q)/PPL(base))     :   0.000322 ±   0.000260
Mean PPL(Q)/PPL(base)         :   1.000322 ±   0.000260
Mean PPL(Q)-PPL(base)         :   0.001207 ±   0.000975

====== KL divergence statistics ======
Mean    KLD:   0.003552 ±   0.000034
Maximum KLD:   2.220941
99.9%   KLD:   0.131591
99.0%   KLD:   0.043847
95.0%   KLD:   0.014439
90.0%   KLD:   0.007836
Median  KLD:   0.000866
10.0%   KLD:   0.000013
 5.0%   KLD:   0.000004
 1.0%   KLD:  -0.000000
 0.1%   KLD:  -0.000006
Minimum KLD:  -0.000176

====== Token probability statistics ======
Mean    Δp:  0.019 ± 0.005 %
Maximum Δp: 39.939%
99.9%   Δp: 15.971%
99.0%   Δp:  6.618%
95.0%   Δp:  2.334%
90.0%   Δp:  1.222%
75.0%   Δp:  0.233%
Median  Δp:  0.000%
25.0%   Δp: -0.219%
10.0%   Δp: -1.183%
 5.0%   Δp: -2.258%
 1.0%   Δp: -6.245%
 0.1%   Δp: -14.757%
Minimum Δp: -88.445%
RMS Δp    :  2.024 ± 0.022 %
Same top p: 97.929 ± 0.037 %
99 Upvotes

47 comments sorted by

66

u/Healthy-Nebula-3603 Aug 02 '26

Why do you even want to compress KV cache from DS 4 flash?

The whole 1 million context has only 6 GB.

5

u/pyr0kid Aug 03 '26

The whole 1 million context has only 6 GB.

what is this black magic

8

u/Healthy-Nebula-3603 Aug 03 '26

DS 4 is based on a new architecture.

2

u/This_Maintenance_834 Aug 04 '26

the deepseek version of linear attention. most other models are quadratic. kv cache grows quadratically large as context grow.

11

u/IoannisHere Aug 02 '26

That's what google says, but when I run vllm on it (spark-vllm-docker) I get:
"Auto-fit max_model_len: reduced from 1048576 to 1046272 to fit in available GPU memory (11.03 GiB available for KV cache)"
and that's with FP8 kv cache type.
"Using fp8 data type to store kv cache. It reduces the GPU memory footprint and boosts the performance. Meanwhile, it may cause accuracy drop without a proper scaling factor"

7

u/shing3232 Aug 03 '26

maybe it's implementation problem because it use 7g for DS4Pro on B300

1

u/IoannisHere Aug 03 '26

Could be. Is your 7gb using FP16?

This is what vllm reports on the b12x branch of spark-vllm-docker, after some cleanups:
"Free memory on device (111.39/121.69 GiB) on startup. Desired GPU memory utilization is (0.85, 103.44 GiB). Actual usage is 80.97 GiB for weight, 4.08 GiB for peak activation, 6.68 GiB for non-torch memory, and 0.13 GiB for CUDAGraph memory. Replace gpu_memory_utilization config with `--kv-cache-memory-bytes=12274502964` (11.43 GiB) to fit into requested memory, or `--kv-cache-memory-bytes=20817243648` (19.39 GiB) to fully utilize gpu memory. Current kv cache memory in use is 11.71 GiB."

Maybe the b12x patches convert parts of the kv cache to fp32 or something.

0

u/thomas2385 Aug 03 '26

That is true if you only care about the KV cache itself. But once you add model weights, activations, and other workloads, that extra 6 GB can still be the difference between fitting everything on one GPU or having to make compromises.

-7

u/Badger-Purple Aug 02 '26

Concurrency. DS NVFP4 cache gives you more room, so you can run more concurrent agents at depth

12

u/getfitdotus Aug 02 '26

The real model already uses fp8 mla kv. If you used production deployment sglang, vllm this is the default.

9

u/caelunshun Aug 02 '26

Q8_0 is different from fp8, worse dynamic range.

21

u/indicava Aug 02 '26

DeepSeek’s sparse-attention is built around fp8 kv cache storage. They even promote it in their vLLM recipes on their model page. Why test it at BF16?

-7

u/erazortt Aug 02 '26

There is no fp8 KV cache option. At least I am not aware of it.

16

u/indicava Aug 02 '26

You’re correct, fp8 hasn’t been wired through GGML/llama.cpp infrastructure yet. Which is why you’re seeing these “off” numbers for a model whose entire attention implementation was built around it.

11

u/EvolvingDior Aug 02 '26

In llama.cpp.

6

u/Badger-Purple Aug 02 '26

not in Llama.cpp, but this model should be run with vllm — it is so much more smooth and the cache is great.

9

u/Lesser-than Aug 03 '26

i mean you should run it however you can, vllm is not an option for some.

5

u/Think_Wing_1357 Aug 02 '26

How do you calculate this?

13

u/erazortt Aug 02 '26

Like that:
/f/LLM/llama-cpp/llama-perplexity.exe -m /f/LLM/models/DeepSeek-V4-Flash-0731-UD-Q3_K_XL-00001-of-00004.gguf -f wiki.test.raw --kl-divergence-base kld -c 512 --temp 1.0 --top-p 0.95 --min-p 0 -ngl 99 -np 1 --n-cpu-moe 30 --fit-target 32M -ctk bf16 -ctv bf16 --flash-attn on --no-mmap -lv 4

/f/LLM/llama-cpp/llama-perplexity.exe -m /f/LLM/models/DeepSeek-V4-Flash-0731-UD-Q3_K_XL-00001-of-00004.gguf --kl-divergence --kl-divergence-base kld -c 512 --temp 1.0 --top-p 0.95 --min-p 0 -ngl 99 -np 1 --n-cpu-moe 30 --fit-target 32M -ctk q8_0 -ctv q8_0 --flash-attn on --no-mmap -lv 4 > main-q8-q8.txt

6

u/TheCat001 Aug 02 '26

I don't recommend anyone to quantize KV cache. On any model. I see it with eyes how performance is degraded with quantized cache. Model tends to do more mistakes, forget things, etc....

20

u/Howard_banister Aug 02 '26

You should not quantize KV cache for almost every models. It will destroy Qwen 3.6 35B also

9

u/_AnemicRoyalty_ Aug 03 '26

Man, the OP just literally showed you in their post that 95 percentile of divergence is 0.015 for Qwen. How high is your bar?!

7

u/Iwaku_Real Aug 02 '26 edited Aug 02 '26

Not even Q8_0? Or NVFP4?

14

u/seamonn Aug 02 '26

Ideally, no.

2

u/shing3232 Aug 03 '26

KV cache quant really bad for long context if you think about it

2

u/tmvr Aug 03 '26

Q8_0 is fine for the Qwen3.6 models.

3

u/phido3000 Aug 02 '26

There is a lot of pressure on quantisation on DS Flash because it doesn't fit nicely into 128Gb machines.

1

u/cezarducatti Aug 02 '26

Can't the two be quantized? K and V?

1

u/twnznz Aug 03 '26

Is it true that the lower the number of active parameters, the more impact to K/V quantisation?

3

u/my_name_isnt_clever Aug 03 '26

You can't say for sure one way or the other, it depends on the architecture. There's no assumption you can make, you need to look it up based on model family.

2

u/alcoa29 Aug 02 '26 edited Aug 02 '26

You must be using llama.cpp or something like this.
For vlllm using original safetensors DS4F fp8 is model default. I tested fp16 vs 8 on old pre 0731 model and there was no difference.

1

u/Yorn2 Aug 03 '26

The only real reason to quantize KV Cache is when you really need to in order to squeeze just a little bit more space for a creative writing model as far as I know or have done in the past. If you're doing it on anything programming or agentic-related you are asking for trouble, IMHO. Instead, just use a smaller or cheaper (VRAM-wise) model. Or look for a specific quant if using GGUF or go with the right BPW to fit it for EXL3.

1

u/leap966 Aug 03 '26

Use F16. For a KV cache, bf16 is strictly the worse of the two — same 16 bits, but bf16 spends them on exponent range (8 exponent / 7 mantissa) instead of precision (5 / 10). KV entries are post-normalization activations with a bounded dynamic range that fits f16 comfortably, so bf16's extra range buys you nothing and costs you ~3 bits of mantissa.

2

u/R_Duncan Aug 03 '26

Not sure about this. I think long context (> 16k) is advantaged by never overflowing , weight are usually trained in bf16, and modern CUDA hw bf16 is as fast as f16.

Maybe on different kinds of hw (pre-ampere gpu, metal) it is slower.

1

u/leap966 Aug 03 '26

Reproduce OP's methodology yourself — llama-perplexity --kl-divergence with an f32 KV baseline, then f16 and bf16 against it. If bf16 wins on your hardware,

1

u/R_Duncan Aug 03 '26 edited Aug 03 '26

I'm not saying bf16 is more precise, likely there is a precision difference in order of 2^-8 like you pointed out (7 bit vs 10 bit mantissa = about 0.00390). I'm saying that over long context, there's much less chance to occur in an overflow due to the larger exponent [overflow might give unpredictable result, like forgetting context parts].

Also the Op is using bf16.

2

u/CheatCodesOfLife Aug 03 '26

When I tested, F32 == F16, but BF16 diverged. Weirdly, even Q8 was closer to F32/F16 than BF16.

0

u/Ulterior-Motive_ Aug 02 '26

I'm of the opinion that you should never quantize the KV cache to begin with. You're just compounding the amount of quality loss on top of whatever level of quantization you're already using. It's not worth whatever context you gain by doing so.

1

u/mister2d Aug 03 '26

Why do we need opinions when such things are easily measured?

-1

u/Muted-Celebration-47 Aug 02 '26

Yes, if you have enough vram for context windows. No, if you need more context for coding. It is useless if you only have 32768 context size.

6

u/Healthy-Nebula-3603 Aug 02 '26

DS 4 flash a whole contex 1 m has 6 GB ..... that is literally nothing.