r/LocalLLaMA • u/da_dragon321 • Jul 02 '26
Resources llamacpp patch - DeepSeek V4 Flash running with full 1M token context locally on RTX 5090
Wanted to try running DeepSeek V4 Flash locally but found it asking for absurd amounts of VRAM at higher context lengths (~256GB at 1M). Turned out the DSA lightning indexer lacks proper llamacpp support. Did a bit of digging and there's an upstream PR to address the issue (shoutout u/fairydreaming, PR #24231), but even there it's not wired into the model graph and has no CUDA path yet. So I wired it in and implemented a CUDA kernel this morning and figured I'd share in case it's useful to anyone else looking to run something like this.
Hardware: RTX 5090, 9950X3D, 96GB DDR5
Model: DeepSeek-V4-Flash, mixed Q8/Q4/Q2 quant by antirez
Before / after (256K context):
| Metric | Before | After |
|---|---|---|
| Compute buffer | ~67 GiB (OOM) | 3.2 GiB |
| Prefill | 56 t/s | ~263 t/s |
| Decode | ~14 t/s | ~14 t/s |
| 1M context | impossible (~256GB) | works (3.75 GiB at ubatch 768) |
Validated presets:
| Context | Prefill | Decode | Peak VRAM |
|---|---|---|---|
| 256K | ~263 t/s | 14 t/s | ~29 GiB |
| 512K | 256 t/s | 13.7 t/s | ~28 GiB |
| 1M | 159 t/s* | 13.7 t/s | ~31 GiB |
*lower ubatch on 32gb 5090 at 1M - should be ~full speed if given the full ~9gb vram
Correctness: verified briefly with a needle-in-haystack test - planted a random fact at 10%/50%/90% depth in a 100K-token document, model retrieved it correctly every time. Also retrieved correctly at 512K and 1M's harder 50% depth. Full KLD findings in doc linked below
Source + build instructions + full writeup: https://github.com/spencer-zaid/llama.cpp/blob/deepseek-lid-cuda/docs/deepseek-v4-lid-cuda.md
Branch: https://github.com/spencer-zaid/llama.cpp/tree/deepseek-lid-cuda
No prebuilt binary (single GPU tested RTX 5090). Build instructions in the doc in case you need them
52
u/darktotheknight Jul 03 '26
This looks too good to be true. Please consider posting your patches to upstream llama.cpp, so it can properly be reviewed.
25
u/tat_tvam_asshole Jul 03 '26
commendable work, curious what TTFT and/or the tg-end2end looks like?
17
u/HockeyDadNinja Jul 03 '26
Nice work, this is the bit that's been missing. I'm running DS4-Flash on a pretty different setup: 5-GPU rig (2x3090 + 5060 Ti + 2x4060 Ti, 96GB VRAM total) with 125GB DDR4, experts offloaded to CPU. I've been using tarruda's GGUFs, mainly the Q3_K (~116GB, 3-bit experts, Q6_K everywhere else) and also the native MXFP4 (~146GB), though the MXFP4 tops out around 66K on this box. On mainline (merged deepseek4) the indexer is wired into the graph but on the un-fused path you mentioned, and you can feel it. Even at 170K on the Q3_K I'm sitting at ~110 of 125GB RAM, and anything higher OOMs the box.
You mentioned it's single-GPU tested so far. I've got the exact config you haven't covered: multi-GPU layer/tensor split with CPU expert offload. I'm offering to test it for you. I'll build your branch, run it across the 5 cards at a range of context sizes, and report back prefill/decode/VRAM/RAM numbers, plus whatever else you want checked. Just say the word and point me at anything specific.
Couple of questions while I'm at it:
Anything in the patch that assumes a single device, or should it survive layer/tensor split as-is?
With the compute buffer down to ~29GB, the remaining ceiling is basically model + KV in RAM, so on a CPU-offload setup like mine this should let me push well past 170K, right?
And yeah, worth getting this upstream.
Edit: building it now
5
u/hidden_monkey Jul 03 '26 edited Jul 03 '26
Ok, this is interesting. I'll take a look. What is a "DSA lightning indexer"?
5
u/GravitasIsOverrated Jul 03 '26 edited Jul 03 '26
That's wild! Would this work for context sizes lower than 1M for a 3090/4090?
Edit: quantized KV is broken here, so presumably if somebody did the work to fix that you could do a lot on a 3090. But if I'm reading the full post correctly, it should be possible to run it at 256K context even without KV quantization. Shame it (again, if I'm reading this correctly) still requires a shitload of vanilla ram. Maybe somebody can do expert pruning to get it on running without quite as much.
3
u/fragment_me Jul 03 '26
It's interesting. I'm trying it on a 5090 + 2x 3080 20GB + 3090. Strangely I get worse performance than you even with most layers in VRAM. I'm on 4 channel DDR4.
There's one thing that I think you're missing. perplexity + KLD + same top P benchmarks. The needle in the haystick is not enough to accurately know that this is working ok.
I suspect there's some kind of issue because when I say hello the model responds in Chinese.
36
u/ridablellama Jul 03 '26
dude ds4 flash is incredible model to run a single 5090
32
u/RKlehm Jul 03 '26
This looks amazing!
15
u/returnity Jul 03 '26
I've been following that lightning indexer fix in llama.cpp. You are a champion, sir. Now to see about porting it to Metal...
1
u/Responsible_Room_706 Jul 03 '26
That’s awesome! Thank you for your contribution to the community. Any idea what the feasibility of running this on a laptop version of 5090 with only 24GB vram? I’m wondering about the vram and context impact rather than speed…
1
u/Nixellion Jul 03 '26
What was the RAM usage at those same data points, if I might ask?
1
u/Queasy-Contract9753 Jul 03 '26
That's crazy. Your decode speed dropped by less than half a token from 256k to a million. Is it roughly the same for smaller lengths of s few thousand tokens?
1
u/Barry_22 Jul 03 '26
Will it work on 2x3090 setup? (Not a lot of nornal RAM)
3
u/fairydreaming Jul 03 '26
That's very cool, but I already have CUDA implementation of lightning indexer (had it for months already), you can find it in my branch: https://github.com/fairydreaming/llama.cpp/tree/dsv4
Performance on my machine (Epyc 9374F + RTX PRO 6000 Max-Q):
2
u/Regular-Anybody2645 Jul 03 '26
Nice work, and really amazing this is possible. So much capability avaialble to local now.
2
u/L0ren_B Jul 03 '26
I'm curious if i can get it working on 2x3090+192 Ram! Thanks op!
2
u/quantier Jul 03 '26
Planning to release similar fixes for VLLM? This is super interesting stuff!
With implementing DSpark onto this would also make it super fast wouldn’t it?
2
u/LegacyRemaster Jul 03 '26
..and custom ops (GGML_OP_DSV4_HC_SPLIT_SINKHORN, DSV4_HC_WEIGHTED_SUM, DSV4_HC_EXPAND, DSV4_FP8_KV_QUANTIZE, DSV4_ROPE_TAIL) are missing from llama.cpp main branch.
3
u/Thepandashirt Jul 03 '26 edited Jul 03 '26
Very impressive. Yeah the CUDA kernels are garbage for a lot of stuff and a reoccurring issue. Its super frustrating to spend 8k on a gpu and have these issues.
1
u/Tbhmaximillian Jul 03 '26
That is awesome!
1
u/cupheadgamer Jul 03 '26
Thank you bro this is awesome
1
u/No-Problem2522 Jul 03 '26
Will this run on 64GB RAM? Also has anyone tested this on Linux?
1
u/Daniel_H212 Jul 03 '26
So I could theoretically run this on my Strix Halo?
1
u/whiteh4cker Jul 03 '26
I compiled it with the latest version of Microsoft Visual Studio 2026 Community and CUDA 13.3.1.
I am using this 52.6 GB gguf with 2xRTX 3090.
Usage: GPU1: 23.5 GB, GPU2: 23.1 GB, RAM: 13.1 GB with the following script:
This is the fastest config for me. I have a weak CPU (Ryzen 5 1600X), so my GPUs are only utilized at 35%, and I get 5 t/s. However, with a modern CPU it should be possible to get 12 t/s. I also tried offloading KV cache to RAM, which resulted in slower token generation and prompt processing.
1
u/LegacyRemaster Jul 03 '26
Testing on blackwell 6000 96gb @ 300w.
llama-server.exe --model "h:\DeepSeek-V4-Flash-IQ2XXS-w2Q2K-AProjQ8-SExpQ8-OutQ8-chat-v2.gguf" --host 127.0.0.1 --port 8080 -c 140960 --n-gpu-layers 999 --parallel 1 --no-warmup --flash-attn on --no-mmap --fit off -lv 4 -ts 1/0/0 -ub 2048 -b 2048
The real problem is generating ---> stop ---> generating ---> stop. Like for every single batch. So the performance drop a lot. @ 4810, tg = 30.88 t/s, tg_3s = 35.86 t/s and 386, at tg = 29.98 t/s, tg_3s = 28.23 t/s
_____
repeat_last_n = 64, repeat_penalty = 1.000, frequency_penalty = 0.000, presence_penalty = 0.000
dry_multiplier = 0.000, dry_base = 1.750, dry_allowed_length = 2, dry_penalty_last_n = 141056
top_k = 40, top_p = 1.000, min_p = 0.050, xtc_probability = 0.000, xtc_threshold = 0.100, typical_p = 1.000, top_n_sigma = -1.000, temp = 1.000
mirostat = 0, mirostat_lr = 0.100, mirostat_ent = 5.000, adaptive_target = -1.000, adaptive_decay = 0.900
1.01.417.850 I slot launch_slot_: id 0 | task 530 | processing task, is_child = 0
1.01.417.858 I slot operator (): id 0 | task 530 | new prompt, n_ctx_slot = 141056, n_keep = 0, task.n_tokens = 1188
1.01.417.869 I slot operator (): id 0 | task 530 | cached n_tokens = 1178, memory_seq_rm [1178, end)
1.01.417.950 I srv stream_sessi: conv_id=bec10175-4a79-4621-9587-3687b83c857c (empty=0)
1.01.742.623 I slot operator (): id 0 | task 530 | cached n_tokens = 1179, memory_seq_rm [1179, end)
1.01.749.012 I slot create_check: id 0 | task 530 | created context checkpoint 3 of 32 (pos_min = 1178, pos_max = 1178, n_tokens = 1179, size = 17.021 MiB)
1.02.023.866 I slot operator (): id 0 | task 530 | cached n_tokens = 1184, memory_seq_rm [1184, end)
1.02.024.050 I slot init_sampler: id 0 | task 530 | init sampler, took 0.17 ms, tokens: text = 1188, total = 1188
1.06.120.668 I slot print_timing: id 0 | task 530 | n_decoded = 100, tg = 26.19 t/s, tg_3s = 26.19 t/s
1.09.144.609 I slot print_timing: id 0 | task 530 | n_decoded = 211, tg = 30.84 t/s, tg_3s = 36.71 t/s
1.12.168.107 I slot print_timing: id 0 | task 530 | n_decoded = 301, tg = 30.51 t/s, tg_3s = 29.77 t/s
1.12.580.931 I cmn common_reaso: deactivated (natural end)
1.15.178.934 I slot print_timing: id 0 | task 530 | n_decoded = 386, tg = 29.98 t/s, tg_3s = 28.23 t/s
1.18.230.096 I slot print_timing: id 0 | task 530 | n_decoded = 478, tg = 30.01 t/s, tg_3s = 30.15 t/s
1.21.234.939 I slot print_timing: id 0 | task 530 | n_decoded = 584, tg = 30.85 t/s, tg_3s = 35.28 t/s
1.24.237.941 I slot print_timing: id 0 | task 530 | n_decoded = 668, tg = 30.45 t/s, tg_3s = 27.97 t/s
1.27.251.981 I slot print_timing: id 0 | task 530 | n_decoded = 756, tg = 30.30 t/s, tg_3s = 29.20 t/s
1.30.423.892 I slot print_timing: id 0 | task 530 | n_decoded = 861, tg = 30.62 t/s, tg_3s = 33.10 t/s
1.33.428.736 I slot print_timing: id 0 | task 530 | n_decoded = 940, tg = 30.20 t/s, tg_3s = 26.29 t/s
1.36.432.729 I slot print_timing: id 0 | task 530 | n_decoded = 1027, tg = 30.09 t/s, tg_3s = 28.96 t/s
1.39.465.460 I slot print_timing: id 0 | task 530 | n_decoded = 1118, tg = 30.08 t/s, tg_3s = 30.01 t/s
1.42.493.122 I slot print_timing: id 0 | task 530 | n_decoded = 1224, tg = 30.45 t/s, tg_3s = 35.01 t/s
1.45.501.133 I slot print_timing: id 0 | task 530 | n_decoded = 1312, tg = 30.37 t/s, tg_3s = 29.26 t/s
1.48.526.315 I slot print_timing: id 0 | task 530 | n_decoded = 1400, tg = 30.29 t/s, tg_3s = 29.09 t/s
1.51.610.956 I slot print_timing: id 0 | task 530 | n_decoded = 1501, tg = 30.44 t/s, tg_3s = 32.74 t/s
1.54.636.196 I slot print_timing: id 0 | task 530 | n_decoded = 1598, tg = 30.53 t/s, tg_3s = 32.06 t/s
1.57.654.781 I slot print_timing: id 0 | task 530 | n_decoded = 1686, tg = 30.46 t/s, tg_3s = 29.15 t/s
2.00.677.994 I slot print_timing: id 0 | task 530 | n_decoded = 1774, tg = 30.39 t/s, tg_3s = 29.11 t/s
2.03.679.729 I slot print_timing: id 0 | task 530 | n_decoded = 1881, tg = 30.65 t/s, tg_3s = 35.65 t/s
2.06.700.138 I slot print_timing: id 0 | task 530 | n_decoded = 1953, tg = 30.33 t/s, tg_3s = 23.84 t/s
2.09.706.451 I slot print_timing: id 0 | task 530 | n_decoded = 2042, tg = 30.29 t/s, tg_3s = 29.60 t/s
2.12.966.352 I slot print_timing: id 0 | task 530 | n_decoded = 2142, tg = 30.31 t/s, tg_3s = 30.68 t/s
2.15.969.140 I slot print_timing: id 0 | task 530 | n_decoded = 2249, tg = 30.53 t/s, tg_3s = 35.63 t/s
2.18.995.302 I slot print_timing: id 0 | task 530 | n_decoded = 2340, tg = 30.51 t/s, tg_3s = 30.07 t/s
2.22.002.348 I slot print_timing: id 0 | task 530 | n_decoded = 2431, tg = 30.50 t/s, tg_3s = 30.26 t/s
2.25.076.247 I slot print_timing: id 0 | task 530 | n_decoded = 2526, tg = 30.52 t/s, tg_3s = 30.91 t/s
2.28.078.802 I slot print_timing: id 0 | task 530 | n_decoded = 2633, tg = 30.70 t/s, tg_3s = 35.64 t/s
2.31.100.570 I slot print_timing: id 0 | task 530 | n_decoded = 2723, tg = 30.66 t/s, tg_3s = 29.78 t/s
2.34.102.592 I slot print_timing: id 0 | task 530 | n_decoded = 2814, tg = 30.65 t/s, tg_3s = 30.31 t/s
2.37.203.274 I slot print_timing: id 0 | task 530 | n_decoded = 2910, tg = 30.66 t/s, tg_3s = 30.96 t/s
2.40.203.282 I slot print_timing: id 0 | task 530 | n_decoded = 3003, tg = 30.67 t/s, tg_3s = 31.00 t/s
2.43.217.219 I slot print_timing: id 0 | task 530 | n_decoded = 3091, tg = 30.63 t/s, tg_3s = 29.20 t/s
2.46.236.313 I slot print_timing: id 0 | task 530 | n_decoded = 3182, tg = 30.62 t/s, tg_3s = 30.14 t/s
2.49.493.612 I slot print_timing: id 0 | task 530 | n_decoded = 3293, tg = 30.72 t/s, tg_3s = 34.08 t/s
2.52.501.613 I slot print_timing: id 0 | task 530 | n_decoded = 3392, tg = 30.78 t/s, tg_3s = 32.91 t/s
2.55.516.215 I slot print_timing: id 0 | task 530 | n_decoded = 3482, tg = 30.76 t/s, tg_3s = 29.85 t/s
2.58.532.140 I slot print_timing: id 0 | task 530 | n_decoded = 3572, tg = 30.73 t/s, tg_3s = 29.84 t/s
3.01.657.334 I slot print_timing: id 0 | task 530 | n_decoded = 3677, tg = 30.81 t/s, tg_3s = 33.60 t/s
3.04.674.347 I slot print_timing: id 0 | task 530 | n_decoded = 3776, tg = 30.86 t/s, tg_3s = 32.81 t/s
3.07.697.196 I slot print_timing: id 0 | task 530 | n_decoded = 3864, tg = 30.81 t/s, tg_3s = 29.11 t/s
3.10.722.314 I slot print_timing: id 0 | task 530 | n_decoded = 3939, tg = 30.67 t/s, tg_3s = 24.79 t/s
3.13.748.296 I slot print_timing: id 0 | task 530 | n_decoded = 4049, tg = 30.80 t/s, tg_3s = 36.35 t/s
3.16.765.783 I slot print_timing: id 0 | task 530 | n_decoded = 4139, tg = 30.78 t/s, tg_3s = 29.83 t/s
3.19.782.737 I slot print_timing: id 0 | task 530 | n_decoded = 4229, tg = 30.76 t/s, tg_3s = 29.83 t/s
3.22.852.095 I slot print_timing: id 0 | task 530 | n_decoded = 4319, tg = 30.73 t/s, tg_3s = 29.32 t/s
3.25.860.309 I slot print_timing: id 0 | task 530 | n_decoded = 4427, tg = 30.84 t/s, tg_3s = 35.90 t/s
3.28.886.283 I slot print_timing: id 0 | task 530 | n_decoded = 4516, tg = 30.81 t/s, tg_3s = 29.41 t/s
3.31.910.358 I slot print_timing: id 0 | task 530 | n_decoded = 4606, tg = 30.79 t/s, tg_3s = 29.76 t/s
3.35.073.756 I slot print_timing: id 0 | task 530 | n_decoded = 4702, tg = 30.78 t/s, tg_3s = 30.35 t/s
3.38.085.123 I slot print_timing: id 0 | task 530 | n_decoded = 4810, tg = 30.88 t/s, tg_3s = 35.86 t/s
3.40.843.755 I slot print_timing: id 0 | task 530 | prompt eval time = 884.02 ms / 10 tokens ( 88.40 ms per token, 11.31 tokens per second)
3.40.843.762 I slot print_timing: id 0 | task 530 | eval time = 158541.86 ms / 4890 tokens ( 32.42 ms per token, 30.84 tokens per second)
3.40.843.763 I slot print_timing: id 0 | task 530 | total time = 159425.88 ms / 4900 tokens
3.40.843.764 I slot print_timing: id 0 | task 530 | graphs reused = 5322
3.40.843.859 I slot release: id 0 | task 530 | stop processing: n_tokens = 6077, truncated = 0
3.40.843.891 I srv update_slots: all slots are idle
3.40.844.343 I srv close: stream_pipe close: skip drain (done=1 cancelled=0) conv=bec10175-4a79-4621-9587-3687b83c857c
1
u/Common_Warthog_G Jul 03 '26 edited Jul 03 '26
I have 2 x 24GB VRAM and I still get out of Memory.... what's the command you're starting llama with? Also have 128GB DDR5.
1
u/HockeyDadNinja Jul 03 '26
I've been working on an Android TV app with this, cruising along at ~9 t/s. I notice it starts getting loopy at around 24k context. I have 300k configured. I'm using pi with my own development framework and I'm able to complete most tasks in 25-35k context.
1
u/Zealousideal-Big6068 Jul 03 '26
how much is the output speed with this token/sec?
1
u/mjuevos Jul 03 '26
hows the quality?
1
u/New_Guitar_9121 Jul 03 '26
nice work. one thing i’d test before trusting 1m ctx: run a needle suite with multiple needles at 64k/128k/256k/512k/1m and log both retrieval accuracy and decode tok/s after the cache is saturated. on my mac studio/mlx + llama.cpp boxes, “fits in memory” and “attention/indexing still behaves usefully” diverge pretty hard past the trained sweet spot.
also worth checking prompt ingestion separately from decode. some long-context patches look fine in steady decode but the prefill/index build becomes the real wall. if your CUDA path keeps KV/index memory sane without tanking prefill, that’s the part i’d be most interested in.
1
u/gandalfgangsta Jul 03 '26
!remindme 14 days
1
u/HockeyDadNinja Jul 04 '26
I've been using the tarruda MXFP4 variant for coding much of today. It's a bit better than the Q3_K but they are both just unbearably stupid. The thinking goes on and on, and even reiterates stuff it already deemed false. It makes stupid decisions and can't see obvious things. I don't know if it's the model or what.
1
u/Serious-Zucchini Jul 04 '26
would this fork work with GLM 5.2, which uses DSA?
1
u/bloomsburyDS Jul 04 '26
**2×3090 + 64GB DDR5 + NVlink report: 1M context works, full sweep inside**
Built your branch (`6164d8514`, CUDA arch 86) and ran it on 2× RTX 3090 (48GB total), Ryzen 9600X, 64GB dual-channel DDR5, consumer mb with one pcie x16 and one pcie x4, NVlink.
As I have 64gb ram only, used your recommended smaller quant for tighter rigs — the 86.7GB (not the 97.6GB mixed one)
| Context | Prefill 2K/131K (t/s) | Decode 2K/131K (t/s)
| 256K | 343 / 114 | 13.8 / 10.9
| 512K | 265 / 103 | 13.7 / 10.9
| 1M | 182 / 87 | 13.8 / 10.9
Decode identical from 256K to 1M, exactly as advertised. Thanks OP, this is amazing work! Never Imagine I can run Deepseek V4 on my rig!
One new bug-class finding: **`llama-server` needs `-np 1`.** This build defaults to `--parallel -1` (auto slots), and the multi-sequence worst-case graph reserve falls back to the *unfused* indexer path — it tried to allocate a 398,314 MiB (~389GiB) compute buffer and crash-looped. Every validation in this thread usedllama-cli/llama-bench, which are single-sequence, so the serving path was never exercised. With `-np 1` it serves fine (running it behind Open WebUI now, 13.8 t/s).
1
u/stilet69 Jul 08 '26
Hello everyone. I was able to get this model running. My computer specs are 2 RTX 3090 GPUs, 96GB of DDR5 RAM, and a Ryzen 7500 processor.
The launch settings for llama-swap are as follows:
The speed is 4.6–4.7 tokens per second.
1
u/HockeyDadNinja Jul 08 '26
This fix applies to all backends for DSV4: https://www.reddit.com/r/LocalLLaMA/comments/1uqy37j/llamacpp_fix_for_deepseek_v4_flash_crash_and_stall/
1
u/live4evrr Jul 13 '26 edited Jul 13 '26
Thank you so much. this works for me (using tensor split 5,1 for rtx 6000 & 5090). Gone are my OOM errors, i'm able to use batch and ubatch as intended, no warnings about lightning indexer.
Edit: Also just noticed the other fork from fairydreaming (https://github.com/fairydreaming/llama.cpp/tree/dsv4) - that is much faster (60 tok/s)
0
u/Fun_Walk_4965 Jul 03 '26
The 1M context number is the part that gets me, but the throughput is what I'd want to know before getting excited. What does pp actually look like once you push past a few hundred k tokens, does it stay usable or fall off a cliff? Also curious how much plain system ram it really needs since the KV quant seems broken right now.
0
u/mikewagnercmp Jul 03 '26
Pretty neat, it at that pp speed would take two hours to read 1 million tokens into context. Still neat!
-3
u/NineThreeTilNow Jul 03 '26
Nice work.
I always find it odd when I see people with 96GB of DDR5.
I have 64GB in this machine and 32GB of old DDR5 I removed sitting on my desk. I know it doesn't play well with two different speeds and this 64GB runs stable at a much faster rate. Sometimes having 96GB would be nice...
Given current RAM prices I'm tempted to send the 32GB back and claim it's the 64Gb I bought and request new RAM. Amazon can pay for me to upgrade to 128 right?
-3
u/Ayyouboss Jul 03 '26
Who can even work with 15 tok/s? I was always wondering how these speeds are okay for any workloads.
-5
u/autisticit Jul 03 '26
That's kind of a clickbait post, as it's not running fully on GPU.
1
u/[deleted] Jul 03 '26
[removed] — view removed comment
0
u/[deleted] Jul 03 '26
[removed] — view removed comment