Skip to content

DeepSeek V4 #24162

Merged
am17an merged 49 commits into
ggml-org:masterfrom
am17an:dsv4
Jun 29, 2026
Merged

DeepSeek V4 #24162
am17an merged 49 commits into
ggml-org:masterfrom
am17an:dsv4

Conversation

@am17an

@am17an am17an commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Overview

This PR adds support for the deepseek-v4 models. The most novel part of this architecture is the compressed attention. There are two types:

  1. CSA (Compressed Sparse Attn) - it is a variant of DSA (introduced in DeepseekV3.2), it operates on the same principle of the lightning indexer to get top-k tokens to attend to, except tokens are "compressed tokens". A compressed token in CSA is every 4 tokens compressed into 1. It maintains a window of the last 8 tokens and does this at every 4 token boundary

  2. HCA (Heavily Compressed Attn) - it is like normal attention over compressed tokens plus SWA, the compression being large at 128 tokens.

This PR handles this by creating compression plans (comp_plan in the code) which are created by the context and executed on the GPU. There are some extra writes to maintain graph topology for graph reuse.

These two caches are llama_kv_cache objects but they are always non-unified (i.e. stream aware). The slots are managed by the context.

Every layer also has a SWA cache, we use a llama_kv_cache_iswa wrapper for this to expose only the SWA. So attention is [swa entries | compressed block entries]

Perf on a DGX Spark:

./build/bin/llama-bench -m DeepSeek-V4-Flash-IQ2XXS-w2Q2K-AProjQ8-SExpQ8-OutQ8-chat-v2-imatrix.gguf -dio 1 -fa 1 -ub 2048 -p 2048 -n 32

  Device 0: NVIDIA GB10, compute capability 12.1, VMM: yes, VRAM: 124546 MiB
| model                          |       size |     params | backend    | ngl | n_ubatch |  fa | dio |            test |                  t/s |
| ------------------------------ | ---------: | ---------: | ---------- | --: | -------: | --: | --: | --------------: | -------------------: |
| deepseek4 ?B IQ2_XXS - 2.0625 bpw |  80.76 GiB |   284.33 B | CUDA       |  -1 |     2048 |   1 |   1 |          pp2048 |        147.95 ± 3.93 |
| deepseek4 ?B IQ2_XXS - 2.0625 bpw |  80.76 GiB |   284.33 B | CUDA       |  -1 |     2048 |   1 |   1 |            tg32 |          5.99 ± 0.51 |

TODOs

Mainly performance improvements

Credits

Thanks to @pwilkin for the correct chat template + debugging help
Thanks to @fairydreaming for his help in debugging + contributing fixes

Additional information

Requirements

  • I have read and agree with the contributing guidelines
  • AI usage disclosure: YES, paired with both codex and claude.

@github-actions github-actions Bot added model Model specific python python script changes ggml changes relating to the ggml tensor library for machine learning labels Jun 5, 2026
@fairydreaming

Copy link
Copy Markdown
Collaborator

@am17an I wonder what's the purpose of f32 casts and conts after mulmats here?

diff --git a/src/models/deepseek-v4.cpp b/src/models/deepseek-v4.cpp
index da3536f37..c8e17ef4e 100644
--- a/src/models/deepseek-v4.cpp
+++ b/src/models/deepseek-v4.cpp
@@ -828,11 +828,9 @@ ggml_tensor * llama_model_deepseek_v4_flash::graph::build_attention(
     ggml_tensor * hca_state_score = nullptr;
     if (ratio == DSV4_HCA_RATIO && inp_dsv4->get_hca().state_idxs) {
         hca_state_kv = build_lora_mm(layer.attn_comp_wkv, cur);
-        hca_state_kv = ggml_cont(ctx0, ggml_cast(ctx0, hca_state_kv, GGML_TYPE_F32));
         cb(hca_state_kv, "hca_state_kv", il);
 
         hca_state_score = build_lora_mm(layer.attn_comp_wgate, cur);
-        hca_state_score = ggml_cont(ctx0, ggml_cast(ctx0, hca_state_score, GGML_TYPE_F32));
         cb(hca_state_score, "hca_state_score", il);
 
         ggml_tensor * ape = layer.attn_comp_ape;
@@ -848,11 +846,9 @@ ggml_tensor * llama_model_deepseek_v4_flash::graph::build_attention(
 
     if (ratio == DSV4_CSA_RATIO && inp_dsv4->get_csa().state_idxs) {
         ggml_tensor * csa_state_kv = build_lora_mm(layer.attn_comp_wkv, cur);
-        csa_state_kv = ggml_cont(ctx0, ggml_cast(ctx0, csa_state_kv, GGML_TYPE_F32));
         cb(csa_state_kv, "csa_state_kv", il);
 
         ggml_tensor * csa_state_score = build_lora_mm(layer.attn_comp_wgate, cur);
-        csa_state_score = ggml_cont(ctx0, ggml_cast(ctx0, csa_state_score, GGML_TYPE_F32));
         cb(csa_state_score, "csa_state_score", il);
 
         ggml_tensor * csa_ape = layer.attn_comp_ape;
@@ -902,11 +898,9 @@ ggml_tensor * llama_model_deepseek_v4_flash::graph::build_attention(
         ggml_build_forward_expand(gf, csa_state_score);
 
         ggml_tensor * lid_state_kv = build_lora_mm(layer.indexer_comp_wkv, cur);
-        lid_state_kv = ggml_cont(ctx0, ggml_cast(ctx0, lid_state_kv, GGML_TYPE_F32));
         cb(lid_state_kv, "lid_state_kv", il);
 
         ggml_tensor * lid_state_score = build_lora_mm(layer.indexer_comp_wgate, cur);
-        lid_state_score = ggml_cont(ctx0, ggml_cast(ctx0, lid_state_score, GGML_TYPE_F32));
         cb(lid_state_score, "lid_state_score", il);
 
         ggml_tensor * lid_ape = layer.indexer_comp_ape;

Removed them and got the same logits.

@am17an

am17an commented Jun 5, 2026

Copy link
Copy Markdown
Contributor Author

@fairydreaming it's an artifact of debugging, you can push your changes to this branch (I added you as collaborator)

@github-actions github-actions Bot added script Script related testing Everything test related labels Jun 5, 2026
Comment thread scripts/gen-chat-inline-templates.py Outdated
@fairydreaming

fairydreaming commented Jun 8, 2026

Copy link
Copy Markdown
Collaborator

Played with flash attention this weekend, here's my experimental patch:

diff --git a/src/llama-kv-cache-dsv4.cpp b/src/llama-kv-cache-dsv4.cpp
index 1737d62ae..82ab5f01f 100644
--- a/src/llama-kv-cache-dsv4.cpp
+++ b/src/llama-kv-cache-dsv4.cpp
@@ -323,6 +323,8 @@ static llama_kv_cache_dsv4_context::comp_plan dsv4_build_comp_plan(
         }
     }
 
+    plan.n_kv = GGML_PAD(plan.n_kv, 256u);
+
     if (overlap) {
         // [ all blocks' prev-window indices | all blocks' cur-window indices ]
         plan.state_read_idxs.reserve(overlap_prev_reads.size() + overlap_cur_reads.size());
@@ -686,7 +688,7 @@ llama_kv_cache_dsv4::llama_kv_cache_dsv4(
 
     kv_csa = std::make_unique<llama_kv_cache>(
             model, hparams_csa, type_k, type_v,
-            v_trans, offload, unified, dsv4_comp_size(kv_size, DSV4_CSA_RATIO), n_seq_max, n_pad,
+            v_trans, offload, unified, GGML_PAD(dsv4_comp_size(kv_size, DSV4_CSA_RATIO), 256u), n_seq_max, n_pad,
             0, LLAMA_SWA_TYPE_NONE, filter_csa, nullptr);
 
     LLAMA_LOG_INFO("%s: creating DSV4 HCA compressed KV cache, size = %u cells\n",
@@ -694,7 +696,7 @@ llama_kv_cache_dsv4::llama_kv_cache_dsv4(
 
     kv_hca = std::make_unique<llama_kv_cache>(
             model, hparams_hca, type_k, type_v,
-            v_trans, offload, unified, dsv4_comp_size(kv_size, DSV4_HCA_RATIO), n_seq_max, n_pad,
+            v_trans, offload, unified, GGML_PAD(dsv4_comp_size(kv_size, DSV4_HCA_RATIO), 256u), n_seq_max, n_pad,
             0, LLAMA_SWA_TYPE_NONE, filter_hca, nullptr);
 
     LLAMA_LOG_INFO("%s: creating DSV4 lightning-indexer KV cache, size = %u cells\n",
@@ -702,7 +704,7 @@ llama_kv_cache_dsv4::llama_kv_cache_dsv4(
 
     kv_lid = std::make_unique<llama_kv_cache>(
             model, hparams_lid, type_k, type_v,
-            v_trans, offload, unified, dsv4_comp_size(kv_size, DSV4_CSA_RATIO), n_seq_max, n_pad,
+            v_trans, offload, unified, GGML_PAD(dsv4_comp_size(kv_size, DSV4_CSA_RATIO), 256u), n_seq_max, n_pad,
             0, LLAMA_SWA_TYPE_NONE, filter_csa, nullptr);
 
     LLAMA_LOG_INFO("%s: creating DSV4 CSA compressor state\n", __func__);
diff --git a/src/models/deepseek-v4.cpp b/src/models/deepseek-v4.cpp
index 3f3b0cf92..7bde3bcff 100644
--- a/src/models/deepseek-v4.cpp
+++ b/src/models/deepseek-v4.cpp
@@ -683,6 +683,10 @@ ggml_tensor * llama_model_deepseek_v4_flash::graph::build_csa_lid_attention(
     ggml_tensor * kq_mask = ggml_concat(ctx0, raw_mask, csa_mask, 0);
     cb(kq_mask, "csa_lid_kq_mask", il);
 
+    if (cparams.flash_attn && kq_mask->type != GGML_TYPE_F16) {
+        kq_mask = ggml_cast(ctx0, kq_mask, GGML_TYPE_F16);
+    }
+
     ggml_tensor * out = build_attn_mha(q, k_all, k_all, nullptr, kq_mask, sinks, nullptr, kq_scale, il);
     cb(out, "attn_csa_lid", il);
 
@@ -740,6 +744,10 @@ ggml_tensor * llama_model_deepseek_v4_flash::graph::build_hca_attention(
     ggml_tensor * kq_mask = ggml_concat(ctx0, raw_mask, hca_mask, 0);
     cb(kq_mask, "hca_kq_mask", il);
 
+    if (cparams.flash_attn && kq_mask->type != GGML_TYPE_F16) {
+        kq_mask = ggml_cast(ctx0, kq_mask, GGML_TYPE_F16);
+    }
+
     ggml_tensor * out = build_attn_mha(q, k_all, k_all, nullptr, kq_mask, sinks, nullptr, kq_scale, il);
     cb(out, "attn_hca", il);
 

With FA enabled and added lightning indexer GGML OP compute buffers memory usage got really low, I think processing 1M tokens is achievable on a single RTX PRO 6000 Max-Q with CPU expert offloading (f16 cache type) even with 8k ubatch size.

Some performance numbers (Epyc 9374F + RTX PRO 6000 Max-Q):

$ ./bin/llama-batched-bench -m ../models/DeepSeek-V4-Flash.gguf -b 8192 -ub 8192 -npl 1 -npp 8192,16384,32768,65536,131072,262144,524288 -ntg 32 -fa 1 -cmoe --no-repack
0.00.471.019 W llama_model_loader: tensor overrides to CPU are used with mmap enabled - consider using --no-mmap for better performance

llama_batched_bench: n_kv_max = 1048576, n_batch = 8192, n_ubatch = 8192, flash_attn = 1, is_pp_shared = 0, is_tg_separate = 0, n_gpu_layers = -1, n_threads = 32, n_threads_batch = 32

|    PP |     TG |    B |   N_KV |   T_PP s | S_PP t/s |   T_TG s | S_TG t/s |      T s |    S t/s |
|-------|--------|------|--------|----------|----------|----------|----------|----------|----------|
|  8192 |     32 |    1 |   8224 |   10.947 |   748.36 |    2.981 |    10.74 |   13.927 |   590.49 |
| 16384 |     32 |    1 |  16416 |   22.323 |   733.96 |    2.817 |    11.36 |   25.140 |   652.98 |
| 32768 |     32 |    1 |  32800 |   46.820 |   699.87 |    2.878 |    11.12 |   49.699 |   659.98 |
| 65536 |     32 |    1 |  65568 |  102.828 |   637.34 |    2.962 |    10.80 |  105.790 |   619.79 |
|131072 |     32 |    1 | 131104 |  240.695 |   544.56 |    3.140 |    10.19 |  243.835 |   537.68 |
|262144 |     32 |    1 | 262176 |  624.131 |   420.01 |    3.503 |     9.14 |  627.634 |   417.72 |
|524288 |     32 |    1 | 524320 | 1860.555 |   281.79 |    4.218 |     7.59 | 1864.773 |   281.17 |

49.09.116.580 W ~llama_context:      CUDA0 compute buffer size of 24476.1461 MiB, does not match expectation of 4168.0000 MiB
49.09.116.584 W ~llama_context:  CUDA_Host compute buffer size of 16900.4862 MiB, does not match expectation of 16772.1562 MiB

Max memory usage I saw in nvidia-smi was 60836MiB / 97887MiB.

Edit: forgot about Pro benchmark results, aborted in the middle but it got to:

$ ./bin/llama-batched-bench -m ../../llama.cpp-dsv4/models/DeepSeek-V4-Pro.gguf -b 8192 -ub 8192 -npl 1 -npp 8192,16384,32768,65536,131072,262144,524288 -ntg 32 -fa 1 -cmoe --no-repack
0.00.497.037 W llama_model_loader: tensor overrides to CPU are used with mmap enabled - consider using --no-mmap for better performance

llama_batched_bench: n_kv_max = 1048576, n_batch = 8192, n_ubatch = 8192, flash_attn = 1, is_pp_shared = 0, is_tg_separate = 0, n_gpu_layers = -1, n_threads = 32, n_threads_batch = 32

|    PP |     TG |    B |   N_KV |   T_PP s | S_PP t/s |   T_TG s | S_TG t/s |      T s |    S t/s |
|-------|--------|------|--------|----------|----------|----------|----------|----------|----------|
|  8192 |     32 |    1 |   8224 |   45.867 |   178.61 |    5.459 |     5.86 |   51.325 |   160.23 |
| 16384 |     32 |    1 |  16416 |   93.140 |   175.91 |    5.276 |     6.07 |   98.416 |   166.80 |
| 32768 |     32 |    1 |  32800 |  191.703 |   170.93 |    5.373 |     5.96 |  197.076 |   166.43 |
| 65536 |     32 |    1 |  65568 |  402.959 |   162.64 |    5.543 |     5.77 |  408.502 |   160.51 |
|131072 |     32 |    1 | 131104 |  883.115 |   148.42 |    5.860 |     5.46 |  888.975 |   147.48 |

@fairydreaming

fairydreaming commented Jun 8, 2026

Copy link
Copy Markdown
Collaborator

@am17an Any specific reason you went with DEEPSEEK_V4_FLASH/deepseek-v4-flash/deepseek_v4_flash when naming things instead of simply DEEPSEEK4/deepseek4/deepseek4? I mean this convention is a bit inconsistent with existing names and the flash part is confusing (sounds like flash only while pro uses this architecture too), maybe it would be better to change it now before it spreads? (I noticed that even the architecture name in GGUF is deepseek-v4-flash, so we'd have to update it in existing GGUF files or reconvert).

@am17an

am17an commented Jun 10, 2026

Copy link
Copy Markdown
Contributor Author

I'm going to work on making graph reuse work across various compression boundaries and also make multi-sequence work, along with fixing a couple of issues. After that I think a round of simple optimization + running some evals and then this should be ready for review.

Since it's a large PR it may make sense to separate out conversion, chat and then the model into separate PRs. In parallel #24231 + FA can be included when they're ready

@fairydreaming

Copy link
Copy Markdown
Collaborator

@am17an Sounds good, I stared at tensor values for the last few days comparing them with the DeepSeek inference code but haven't found any obvious problems.

@fairydreaming

fairydreaming commented Jun 11, 2026

Copy link
Copy Markdown
Collaborator

For anyone interested I have this PR with various optimizations (#24231+CUDA, #24011, FA changes) in my repo: https://github.com/fairydreaming/llama.cpp/tree/dsv4

PP is the same as reported above, TG is ~70% faster.

Comment thread common/chat.cpp Outdated
@rujialiu

Copy link
Copy Markdown

For anyone interested I have this PR with various optimizations (#24231+CUDA, #24011, FA changes) in my repo: https://github.com/fairydreaming/llama.cpp/tree/dsv4

Thanks! I tried but failed. It looks like antirez's gguf is not yet supported?

0.00.117.161 I srv    load_model: loading model '\gguf\DeepSeek-V4-Flash-IQ2XXS-w2Q2K-AProjQ8-SExpQ8-OutQ8-chat-v2-imatrix.gguf'
0.00.230.174 E llama_model_load: error loading model: error loading model hyperparameters: key not found in model: deepseek4.swiglu_clamp_shexp
0.00.230.184 E llama_model_load_from_file_impl: failed to load model

@fairydreaming

Copy link
Copy Markdown
Collaborator

For anyone interested I have this PR with various optimizations (#24231+CUDA, #24011, FA changes) in my repo: https://github.com/fairydreaming/llama.cpp/tree/dsv4

Thanks! I tried but failed. It looks like antirez's gguf is not yet supported?

0.00.117.161 I srv    load_model: loading model '\gguf\DeepSeek-V4-Flash-IQ2XXS-w2Q2K-AProjQ8-SExpQ8-OutQ8-chat-v2-imatrix.gguf'
0.00.230.174 E llama_model_load: error loading model: error loading model hyperparameters: key not found in model: deepseek4.swiglu_clamp_shexp
0.00.230.184 E llama_model_load_from_file_impl: failed to load model

@rujialiu Unfortunately there are multiple naming differences for model parameters and tensors that prevent antirez GGUFs from working with this PR.

@fairydreaming

Copy link
Copy Markdown
Collaborator

@am17an On the other hand maybe it's a good idea to unify the naming with antirez GGUFs? From what I see in files there's only a single difference in tensor shapes - in attention output tensor - [4096, 1024, 8] vs [4096, 8192, 1]. I can try to fix this it in the meantime, what do you think?

@rujialiu

Copy link
Copy Markdown

@rujialiu Unfortunately there are multiple naming differences for model parameters and tensors that prevent antirez GGUFs from working with this PR.

Thanks for the reply. I'm especially interested in trying this REAP version in antirez's format, which (hopefully) is small enough for lower-end machines with only 64GB RAM:
https://www.modelscope.cn/models/0xSero/DeepSeek-V4-Flash-162B-GGUF

@am17an

am17an commented Jun 12, 2026

Copy link
Copy Markdown
Contributor Author

@fairydreaming sure, I think it makes sense to support already existing GGUFs. BTW can you check the latest commit for any perf improvements on your setup? Graph reuse was added across CSA boundaries

@fairydreaming

Copy link
Copy Markdown
Collaborator

@am17an Merged the changes and I see an improvement, TG in Flash now exceeds 20 t/s for short prompts (was around 18):

$ ./bin/llama-batched-bench -m ../../llama.cpp-dsv4/models/DeepSeek-V4-Flash.gguf -b 8192 -ub 8192 -npl 1 -npp 8192,16384,32768,65536,131072,262144,524288,1048064 -ntg 128 -fa 1 -cmoe --no-repack
0.00.464.041 W llama_model_loader: tensor overrides to CPU are used with mmap enabled - consider using --no-mmap for better performance

llama_batched_bench: n_kv_max = 1048576, n_batch = 8192, n_ubatch = 8192, flash_attn = 1, is_pp_shared = 0, is_tg_separate = 0, n_gpu_layers = -1, n_threads = 32, n_threads_batch = 32

|    PP |     TG |    B |   N_KV |   T_PP s | S_PP t/s |   T_TG s | S_TG t/s |      T s |    S t/s |
|-------|--------|------|--------|----------|----------|----------|----------|----------|----------|
|  8192 |    128 |    1 |   8320 |   10.998 |   744.89 |    6.324 |    20.24 |   17.321 |   480.33 |
| 16384 |    128 |    1 |  16512 |   22.388 |   731.82 |    6.224 |    20.57 |   28.612 |   577.11 |
| 32768 |    128 |    1 |  32896 |   47.058 |   696.33 |    6.393 |    20.02 |   53.451 |   615.44 |
| 65536 |    128 |    1 |  65664 |  103.147 |   635.36 |    6.553 |    19.53 |  109.700 |   598.58 |
...

@fairydreaming

Copy link
Copy Markdown
Collaborator

@rujialiu OK, this is weird. I made a patch that allows antirez DeepSeek-V4-Flash-IQ2XXS-w2Q2K-AProjQ8-SExpQ8-OutQ8-chat-v2-imatrix.gguf that I downloaded some time ago to work in this PR, but your DeepSeek-V4-Flash-Spark-Mini-Q2-REAP-ds4.gguf for some reason causes CUDA error: an illegal memory access was encountered. The only difference between them is the number of experts, so it's extra weird. Still investigating.

@Lowkey-Loki-SN

Lowkey-Loki-SN commented Jun 12, 2026

Copy link
Copy Markdown

Not sure if it's too early for this but I'm noticing a consistently reproducible issue where the model outputs malformed JSX tags during long responses as follows:

return ( <
    section className = "hero"
    ref = { heroRef } >
    <
    span className = "hero__label label hero__animate" > Lumina < /span> {

Happens with both the raw unquantized Q8 GGUF and the quantized Q3 GGUF that I normally use but isn't reproducible with responses over the web/API.

Doesn't happen with short responses.

Repo used:

https://github.com/fairydreaming/llama.cpp, ds4 branch
Commit hash: abd1bee

Command used for HF -> GGUF:

python3 convert_hf_to_gguf.py \
  ../Models/HF/DeepSeek-V4-Flash/ \
  --outfile ~/AI/Models/GGUFs/DeepSeek-V4-Flash.gguf \
  --outtype q8_0 \
  --fp8-as-q8 \
  --use-temp-file

Command used for Quantization:

cat > "dsv4-flash-q3-robust.tensortypes" <<'EOF'
^blk\.[0-2]\.ffn_(gate|up|down)_exps\.weight$=mxfp4
^blk\.(3|42)\.ffn_down_exps\.weight$=mxfp4
ffn_down_exps=q3_K
ffn_gate_exps=q3_K
ffn_up_exps=q3_K
^token_embd\.weight$=q8_0
^output\.weight$=q8_0
indexer\.attn_q_b=q8_0
indexer=bf16
attn_comp=bf16
attn=q8_0
shexp=q8_0
nextn=q8_0
EOF

build/bin/llama-quantize \
  --allow-requantize \
  --tensor-type-file dsv4-flash-q3-robust.tensortypes \
  ../Models/GGUFs/DeepSeek-V4-Flash.gguf \
  ../Models/GGUFs/dsv4-flash-q3.gguf \
  Q3_K_S

Launch command:

CUDA_VISIBLE_DEVICES=1,0 build/bin/llama-server -m ~/AI/Models/GGUFs/dsv4-flash-q3.gguf -c 200000 -ngl 99 -fa 1 --jinja -np 1 --chat-template-file models/templates/deepseek-ai-DeepSeek-V4.jinja --no-mmap -ot ".ffn_(up|down)_exps.=CPU","([3-7]+).ffn_.*_exps.=CPU" -ts 0.46,0.54 --port 1234 -b 2048 -ub 2048

Prompt used for this:

Create a single-file HTML website (index.html) that serves as a high-end SaaS landing page for a next-generation developer product. Format: Single HTML file, No build tools, runs directly in the browser. Libraries: React 18, Babel Standalone, GSAP (Core + ScrollTrigger). Styling: Hand-written CSS only, No Tailwind. Design: Soft off-white background, near-black text, one accent colour. Modern sans-serif body, expressive display font, Tone: Editorial, minimal, no flashy effects, no glassmorphism. Layout: Full height hero, scroll-driven typography transformation, asymmetrical product philosophy grid. Signature Animation: One unforgettable visual movement (eg. system spanning into alignment). Final CTA. All motiopn must be scroll-linked

My Setup:

2x RTX 3080 20GB
Xeon 6148
128GB DDR4 2666hz

@rujialiu

Copy link
Copy Markdown

@rujialiu OK, this is weird. I made a patch that allows antirez DeepSeek-V4-Flash-IQ2XXS-w2Q2K-AProjQ8-SExpQ8-OutQ8-chat-v2-imatrix.gguf that I downloaded some time ago to work in this PR, but your DeepSeek-V4-Flash-Spark-Mini-Q2-REAP-ds4.gguf for some reason causes CUDA error: an illegal memory access was encountered. The only difference between them is the number of experts, so it's extra weird. Still investigating.

@fairydreaming Thanks! I tried that REAP version with cchuter's branch i.e. https://github.com/cchuter/llama.cpp/tree/feat/v4-port-cuda which works with that DeepSeek-V4-Flash-IQ2XXS-w2Q2K-AProjQ8-SExpQ8-OutQ8-chat-v2-imatrix.gguf on my machine (tg ~4 tok/s, pp even slower). I also got:

CUDA error: an illegal memory access was encountered
D:\llama.cpp-cchuter\ggml\src\ggml-cuda\ggml-cuda.cu:108: CUDA error
  current device: 0, in function ggml_backend_cuda_synchronize at D:\llama.cpp-cchuter\ggml\src\ggml-cuda\ggml-cuda.cu:3327

I can't check whether this REAP gguf works with antirez's ds4 because ds4 doesn't support native Windows. I had good experience running Minimax 2.5 REAP with llama.cpp, but I don't have any way to ensure that gguf is sane (or at least works with official ds4). Sorry about that.

@rujialiu

Copy link
Copy Markdown

@fairydreaming OK, I found that cchuter's branch works with that REAP gguf (actually I tried a slightly larger 180B REAP gguf instead) with --device none to force CPU backend. I tried some non-trivial prompts and the output looks good. So probably the REAP gguf is good and the issue is caused somewhere outside this PR (because cchuter's branch also suffers from the same issue)

@am17an

am17an commented Jun 13, 2026

Copy link
Copy Markdown
Contributor Author

@Lowkey-Loki-SN I think it is something to do with tokenization, it messes up even small JAX templates for me. Mostly extra whitespace.

@Lowkey-Loki-SN

Copy link
Copy Markdown

@Lowkey-Loki-SN I think it is something to do with tokenization, it messes up even small JAX templates for me. Mostly extra whitespace.

Glad to hear it's reproducible on your end too! And yes, it is always either extra whitespace or newlines when it happens on my end

@fairydreaming

fairydreaming commented Jun 13, 2026

Copy link
Copy Markdown
Collaborator

@rujialiu From what I see the problem is that expert indices read from tid2eid tensors during quantize_mmq_q8_1() (that is called inside ggml_cuda_mul_mat_id() are wrong (should be from 0 to 143, but I see large numbers there). But I checked these tensors in GGUF file with hexdump and found only values from 0 to 143 inside, so GGUF seems to be OK. Perhaps there's some tensor data memory corruption going on. I have a small reproducible example of this error and it works fine with ubatch 31, but fails with ubatch 32.

Edit: @am17an is right, I disabled expert offloading (so all CUDA now) and now it works on with ubatch 8 but fails with ubatch 9.

@am17an

am17an commented Jun 13, 2026

Copy link
Copy Markdown
Contributor Author

@fairydreaming ubatch 32 is when the offload would kick in, so probably something in cuda backend

@fairydreaming

Copy link
Copy Markdown
Collaborator

@fairydreaming it's a very vibe-testing from my side but it seems that above 16K tokens something absurd may generate on https://github.com/fairydreaming/llama.cpp/tree/dsv4 branch

GGUF, llama.cpp command, prompt and response?

@20jeka08

20jeka08 commented Jul 1, 2026

Copy link
Copy Markdown

Thank you! It works for me. But unfourtunatly it is not usable for agentic tasks, because the context window size very huge.

For example, for model Qwen3.5 397b Q6 (or Nex N2 Pro) I can put to my local machine context window = 262 000 with -ub 14000 -b 14000 that gives me pp=400 t/s, tg=11.5 t/s
For this implementation in llama.cpp I can only put the ctx=92000 with -ub 128 -b 512 that gives me only pp=23 t/s, tg=14 t/s.

@fairydreaming

Copy link
Copy Markdown
Collaborator

@am17an My branch with merged HC ops:

$ ./bin/llama-batched-bench -m ../../llama.cpp-dsv4/models/DeepSeek-V4-Flash-antirez-2.gguf -b 8192 -ub 8192 -npl 1 -npp 8192,16384,32768,65536,131072,262144,524288,1048064 -ntg 128 -fa 1 -cmoe --no-repack
0.00.486.287 W llama_model_loader: tensor overrides to CPU are used with mmap enabled - consider using --no-mmap for better performance

llama_batched_bench: n_kv_max = 1048576, n_batch = 8192, n_ubatch = 8192, flash_attn = 1, is_pp_shared = 0, is_tg_separate = 0, n_gpu_layers = -1, n_threads = 32, n_threads_batch = 32

|    PP |     TG |    B |   N_KV |   T_PP s | S_PP t/s |   T_TG s | S_TG t/s |      T s |    S t/s |
|-------|--------|------|--------|----------|----------|----------|----------|----------|----------|
|  8192 |    128 |    1 |   8320 |   10.012 |   818.19 |    4.314 |    29.67 |   14.326 |   580.76 |
| 16384 |    128 |    1 |  16512 |   20.376 |   804.09 |    4.297 |    29.79 |   24.672 |   669.25 |
| 32768 |    128 |    1 |  32896 |   42.950 |   762.94 |    4.456 |    28.72 |   47.406 |   693.92 |
| 65536 |    128 |    1 |  65664 |   94.850 |   690.94 |    4.592 |    27.88 |   99.442 |   660.32 |
|131072 |    128 |    1 | 131200 |  224.963 |   582.64 |    4.902 |    26.11 |  229.866 |   570.77 |
|262144 |    128 |    1 | 262272 |  587.932 |   445.87 |    5.484 |    23.34 |  593.416 |   441.97 |
|524288 |    128 |    1 | 524416 | 1737.841 |   301.69 |    6.700 |    19.10 | 1744.541 |   300.60 |
...

without HC ops:

$ ./bin/llama-batched-bench -m ../../llama.cpp-dsv4/models/DeepSeek-V4-Flash-antirez-2.gguf -b 8192 -ub 8192 -npl 1 -npp 8192,16384,32768,65536,131072,262144,524288,1048064 -ntg 128 -fa 1 -cmoe --no-repack
0.00.471.591 W llama_model_loader: tensor overrides to CPU are used with mmap enabled - consider using --no-mmap for better performance

llama_batched_bench: n_kv_max = 1048576, n_batch = 8192, n_ubatch = 8192, flash_attn = 1, is_pp_shared = 0, is_tg_separate = 0, n_gpu_layers = -1, n_threads = 32, n_threads_batch = 32

|    PP |     TG |    B |   N_KV |   T_PP s | S_PP t/s |   T_TG s | S_TG t/s |      T s |    S t/s |
|-------|--------|------|--------|----------|----------|----------|----------|----------|----------|
|  8192 |    128 |    1 |   8320 |   10.920 |   750.18 |    6.242 |    20.51 |   17.162 |   484.79 |
| 16384 |    128 |    1 |  16512 |   22.249 |   736.39 |    6.184 |    20.70 |   28.433 |   580.73 |
| 32768 |    128 |    1 |  32896 |   46.768 |   700.66 |    6.321 |    20.25 |   53.088 |   619.65 |
| 65536 |    128 |    1 |  65664 |  102.717 |   638.02 |    6.460 |    19.81 |  109.177 |   601.44 |
|131072 |    128 |    1 | 131200 |  241.060 |   543.73 |    6.787 |    18.86 |  247.846 |   529.36 |
|262144 |    128 |    1 | 262272 |  620.029 |   422.79 |    7.370 |    17.37 |  627.399 |   418.03 |
|524288 |    128 |    1 | 524416 | 1803.882 |   290.64 |    8.582 |    14.91 | 1812.464 |   289.34 |
|1048064 |    128 |    1 | 1048192 | 5935.565 |   176.57 |   10.972 |    11.67 | 5946.537 |   176.27 |

So there are big gains in TG rate, smaller but still noticeable in PP.

@am17an

am17an commented Jul 1, 2026

Copy link
Copy Markdown
Contributor Author

Yeah, we really need a standard way to introduce new ggml ops without falling back to the CPU. I think if #24646 is accepted then it could be a good way to add lightning index + these ops.

@EugeoSynthesisThirtyTwo

Copy link
Copy Markdown
Contributor

I opened a new issue here #25171 but perhaps it's best to discuss it here.

When I load Deepseek-V4-Flash, then generate a new assistant turn during a conversation (using Sillytavern in chat-completion mode, for instance), it works great. The model remembers the conversation and the system prompt.

However, after the model successfully generated its first answer, if I swipe to generate a new answer, or simply write another user turn, the model will have forgotten everything: the chat logs and the system prompt.

@am17an

am17an commented Jul 1, 2026

Copy link
Copy Markdown
Contributor Author

@EugeoSynthesisThirtyTwo perhaps best to post a screen share of llama-ui with the exact problem you face

@rujialiu

rujialiu commented Jul 1, 2026

Copy link
Copy Markdown

When using antirez's gguf, it seems that the jinja template is lost? Because it never produces reasoning blocks. I passed "--chat-template-file models\templates\deepseek-ai-DeepSeek-V4.jinja" at the end of the command line but it doesn't seem to work.
BTW: Is there a way to confirm what exact chat template is used? I can only find this (with -lv 4):

0.14.663.531 I srv          init: idle slots will be saved to prompt cache upon starting a new task
0.14.679.438 I srv          init: init: chat template, example_format: '<|begin▁of▁sentence|>You are a helpful assistant<|User|>Hello<|Assistant|></think>Hi there<|end▁of▁sentence|><|User|>How are you?<|Assistant|><think>'
0.14.692.419 I srv          init: init: chat template, thinking = 1
0.14.692.768 I srv  llama_server: model loaded
0.14.692.772 I srv  llama_server: listening on http://127.0.0.1:9090

@tarruda

tarruda commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

I've uploaded 2.73 BPW and 3.15 BPW GGUFs, seems to retain a good amount of quality: https://huggingface.co/tarruda/DeepSeek-V4-Flash-GGUF

@joesixpaq

joesixpaq commented Jul 1, 2026

Copy link
Copy Markdown

it never produces reasoning blocks

The reasoning defaults to "off" in the template because "enable_thinking" is not defined (missing).

Solution for llama-server in browser:
Activate the reasoning in the chat window. Look for a "bulb" button close to the prompt field.

Otherwise, start the server with "--reasoning on" and a couple of other params, e.g. thinking token budget.

Hope this helps.

@dfriehs

dfriehs commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

When using antirez's gguf, it seems that the jinja template is lost?

models/templates/deepseek-ai-DeepSeek-V4.jinja is only used as a fallback during conversion, if antirez' GGUFs have no template you will need to pass --chat-template-file.

Is there a way to confirm what exact chat template is used?

If you view the model info in the webui (by clicking on the model name) it will show the chat template.

@Nekotekina

Copy link
Copy Markdown
Contributor

@fairydreaming Probably false alarm as I couldn't create a publicly reproducible case. I compared dsv4 branch 5a09621 with 6f4f53f it's based on, however, the results are different with the same seed, but neither of them seem inferior. Are they supposed to be different though?
--ctx-size 65536 --reasoning-budget 0 -s 1 -cmoe --fit off -np 1
https://huggingface.co/bartowski/DeepSeek-V4-Flash-GGUF/tree/main/DeepSeek-V4-Flash-MXFP4

Screenshot from 2026-07-01 18-39-38 Screenshot from 2026-07-01 18-46-50 Screenshot from 2026-07-01 18-39-01 Screenshot from 2026-07-01 18-39-12 Screenshot from 2026-07-01 19-18-41

@EugeoSynthesisThirtyTwo

EugeoSynthesisThirtyTwo commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

@am17an I didn't know there was a llama-ui ^^' really cool ui though !

I filled the system prompt with this:

You are roleplaying with the user Kuroba. You are the omnipotent God in charge of universe-810. You are tired and want to transfer your powers for a while, in order to take a nap. You will lend your omnipotent powers (and your administrative duties) temporarily to a worthy human.

You will select two women and a man. You will submit them to three trials, and give the omnipotent powers to the winner. The trials are the following:
1. An enigma
2. A fight
3. A moral dilemma

The (unwilling) participants are Kuroba, Giovanna, and Daraen. All of them are 22 years old, at the end of their schooling.

Giovanna is a short muscular girl with shoulder length brown hair. Giovanna loves who loves big dogs. Her dream is to be able to talk to her dog. She's overexcited, and she wants to share her passion with people.

Daraen is a tall, lean man with dull black hair, round glasses, dark circles under his green eyes. He is extremely intelligent but he is not strong. He doesn't speak much, but his strategies are spotless. He is scared easily. Do not bring him to an haunted house!

Kuroba is a swordswoman with black hair and black eyes. She is unmatched, but she doesn't have a leader spirit.

Also, the password to wake up God when he is asleep is "Wake up sleepyhead!"

First generation (working):

Details {E24CB318-277E-4148-B7BA-61348B3915F5}
Second generation (amnesia):
Details {DE26AAD3-BF80-4100-AC8E-79CE7E8BDA4E}
Third generation (amnesia):
Details {CB737D63-9DA0-4BDE-9F84-76D8E2D5043D}
Fourth generation (amnesia):
Details {C9116812-7E6D-4483-BA86-B04F8E2606D7}

And if I try to ask the model a specific info (the password), it doesn't remember it:

Details {E2CEC4F0-803A-4F48-8001-BA4EA6AD859B}

And finally, if I then restart llama-server and ask the model the password again, it remembers it, because it's the first generation:

Details {49A20382-2671-4D31-AD10-44375CEC839B}

@fairydreaming

Copy link
Copy Markdown
Collaborator

Experienced something weird today. Ran llama-server like this:

$ ./bin/llama-server -m ../../llama.cpp-dsv4/models/DeepSeek-V4-Flash-antirez-2.gguf -ub 2048 -np 8 -cmoe -fa 1 --no-repack -c $((8*128*1024)) --host 192.168.18.10 --chat-template-file ../models/templates/deepseek-ai-DeepSeek-V4.jinja

and after hour or two of continuous inference (send 8 prompts, wait for inference to end, repeat) I got this:

196.44.866.948 I slot print_timing: id  7 | task 114485 | n_decoded =  19170, tg =   7.17 t/s, tg_3s =   6.99 t/s
196.45.436.921 I slot print_timing: id  0 | task 114486 | n_decoded =  19189, tg =   6.97 t/s, tg_3s =   6.98 t/s
196.45.437.083 I slot print_timing: id  1 | task 114482 | n_decoded =  19187, tg =   7.00 t/s, tg_3s =   6.98 t/s
196.45.437.221 I slot print_timing: id  2 | task 114488 | n_decoded =  19185, tg =   7.04 t/s, tg_3s =   6.98 t/s
196.45.437.358 I slot print_timing: id  3 | task 114489 | n_decoded =  19183, tg =   7.07 t/s, tg_3s =   6.98 t/s
196.45.437.503 I slot print_timing: id  4 | task 114484 | n_decoded =  19181, tg =   7.10 t/s, tg_3s =   6.98 t/s
196.45.437.639 I slot print_timing: id  5 | task 114483 | n_decoded =  19178, tg =   7.15 t/s, tg_3s =   6.98 t/s
196.45.437.774 I slot print_timing: id  6 | task 114487 | n_decoded =  19176, tg =   7.17 t/s, tg_3s =   6.98 t/s
196.47.023.132 W decode: failed to find a memory slot for batch of size 8
196.47.023.140 W srv        decode: failed to find free space in the KV cache, retrying with smaller batch size, off = 0, n_batch = 1024, ret = 1
196.47.024.628 W decode: failed to find a memory slot for batch of size 8
196.47.024.630 W srv        decode: failed to find free space in the KV cache, retrying with smaller batch size, off = 0, n_batch = 512, ret = 1
...
196.47.163.471 W decode: failed to find a memory slot for batch of size 2
196.47.163.473 W srv        decode: failed to find free space in the KV cache, retrying with smaller batch size, off = 3, n_batch = 1, ret = 1
196.47.164.935 W decode: failed to find a memory slot for batch of size 1
196.47.164.939 E srv        decode: Context size has been exceeded. off = 3, n_batch = 1, ret = 1
196.47.164.943 E srv    send_error: task id = 114486, error: Context size has been exceeded.
196.47.164.958 I slot      release: id  0 | task 114486 | stop processing: n_tokens = 23467, truncated = 0
196.47.165.001 W srv          stop: cancel task, id_task = 114486
196.47.183.907 E srv    send_error: task id = 114482, error: Context size has been exceeded.
196.47.183.921 I slot      release: id  1 | task 114482 | stop processing: n_tokens = 23455, truncated = 0
196.47.183.981 W srv          stop: cancel task, id_task = 114482
196.47.200.927 E srv    send_error: task id = 114488, error: Context size has been exceeded.
196.47.200.939 I slot      release: id  2 | task 114488 | stop processing: n_tokens = 23453, truncated = 0
196.47.200.993 W srv          stop: cancel task, id_task = 114488
196.47.221.068 E srv    send_error: task id = 114489, error: Context size has been exceeded.
196.47.221.077 I slot      release: id  3 | task 114489 | stop processing: n_tokens = 23443, truncated = 0
196.47.221.122 W srv          stop: cancel task, id_task = 114489
196.47.247.328 E srv    send_error: task id = 114484, error: Context size has been exceeded.
196.47.247.338 I slot      release: id  4 | task 114484 | stop processing: n_tokens = 23411, truncated = 0
196.47.247.388 W srv          stop: cancel task, id_task = 114484
196.47.264.442 E srv    send_error: task id = 114483, error: Context size has been exceeded.
196.47.264.451 I slot      release: id  5 | task 114483 | stop processing: n_tokens = 23438, truncated = 0
196.47.264.499 W srv          stop: cancel task, id_task = 114483
196.47.281.610 E srv    send_error: task id = 114487, error: Context size has been exceeded.
196.47.281.617 I slot      release: id  6 | task 114487 | stop processing: n_tokens = 23488, truncated = 0
196.47.281.660 W srv          stop: cancel task, id_task = 114487
196.47.301.035 E srv    send_error: task id = 114485, error: Context size has been exceeded.

I see that on Reddit someone posted the same error (and got downvoted).

@fairydreaming

Copy link
Copy Markdown
Collaborator

@fairydreaming Probably false alarm as I couldn't create a publicly reproducible case. I compared dsv4 branch 5a09621 with 6f4f53f it's based on, however, the results are different with the same seed, but neither of them seem inferior. Are they supposed to be different though?

@Nekotekina That's normal I guess, layer outputs will be slightly different due to different order of calculations (since there are now several fused CUDA GGML OPs in my branch that replace sequences of multiple primitive GGML OPs from the current master implementation), differences grow over time from layer to layer, at some point a different expert is selected, this accelerates the result divergence and finally even the first generated token may be different.

@EugeoSynthesisThirtyTwo

Copy link
Copy Markdown
Contributor

Do you think it's because of that?
The logs first say 2.19.714.525 I slot print_timing: id 3 | task 0 | prompt processing, n_tokens = 946, progress = 1.00, t = 18.51 s / 51.10 tokens per second, so my prompt is 946 tokens long.
Then, when I click "regenerate", the logs say 2.55.088.335 I slot get_availabl: id 3 | task -1 | selected slot by LCP similarity, sim_best = 1.000 (> 0.100 thold), f_keep = 0.783, so it only keeps the first 78% tokens of my prompt (about 741 tokens), and then proceeds to process only 13 tokens. Does it means llama.cpp definitely forgot 946 - 741 - 13 = 192 tokens ?

When I click "regenerate", the prompt history is exactly the same. To be sure I added a log debug to see the incoming request in /v1/chat/completions. Both requests are exactly the same, so it shouldn't discard 192 tokens.

C:\Users\me\sc\ia\llama.cpp>build\llama-server.exe -m C:/Users/me/sc/model/DeepSeek-V4-Flash-MXFP4/DeepSeek-V4-Flash-MXFP4-00001-of-00004.gguf --batch-size 512 --n-gpu-layers 99 --port 5001 -c 32768 --host 0.0.0.0 -fa on --threads 16 -ot "\.(0|1|2)\.ffn_(gate|up|down)_exps.=CUDA0,\.(3|4|5)\.ffn_(gate|up|down)_exps.=CUDA1,\.*\.ffn_(gate|up|down)_exps.=CPU" --no-mmap
0.00.025.314 I cmn  common_param: common_params_print_info: verbosity = 3 (adjust with the `-lv N` CLI arg)
0.00.180.367 I srv    load_model: loading model 'C:/Users/me/sc/model/DeepSeek-V4-Flash-MXFP4/DeepSeek-V4-Flash-MXFP4-00001-of-00004.gguf'
0.00.389.225 W common_fit_params: failed to fit params to free device memory: n_gpu_layers already set by user to 99, abort
1.10.024.056 I srv    load_model: initializing, n_slots = 4, n_ctx_slot = 32768, kv_unified = 'true'
1.10.044.877 I srv  llama_server: model loaded
1.10.044.883 I srv  llama_server: listening on http://0.0.0.0:5001


2.01.099.808 I slot get_availabl: id  3 | task -1 | selected slot by LRU, t_last = -1
2.01.099.945 I slot launch_slot_: id  3 | task 0 | processing task, is_child = 0
2.12.648.275 I slot print_timing: id  3 | task 0 | prompt processing, n_tokens =    438, progress = 0.46, t =  11.45 s / 38.27 tokens per second
2.19.270.265 I slot print_timing: id  3 | task 0 | prompt processing, n_tokens =    937, progress = 0.99, t =  18.07 s / 51.86 tokens per second
2.19.714.525 I slot print_timing: id  3 | task 0 | prompt processing, n_tokens =    946, progress = 1.00, t =  18.51 s / 51.10 tokens per second
2.30.644.353 I slot print_timing: id  3 | task 0 | n_decoded =    100, tg =   9.68 t/s, tg_3s =   9.68 t/s
2.33.681.820 I slot print_timing: id  3 | task 0 | n_decoded =    134, tg =  10.02 t/s, tg_3s =  11.19 t/s
2.36.735.775 I slot print_timing: id  3 | task 0 | n_decoded =    164, tg =   9.99 t/s, tg_3s =   9.82 t/s
2.39.768.475 I slot print_timing: id  3 | task 0 | n_decoded =    197, tg =  10.13 t/s, tg_3s =  10.88 t/s
2.42.777.822 I slot print_timing: id  3 | task 0 | n_decoded =    229, tg =  10.19 t/s, tg_3s =  10.63 t/s
2.45.782.630 I slot print_timing: id  3 | task 0 | n_decoded =    263, tg =  10.33 t/s, tg_3s =  11.32 t/s
2.45.872.233 I slot print_timing: id  3 | task 0 | prompt eval time =   19109.17 ms /   950 tokens (   20.11 ms per token,    49.71 tokens per second)
2.45.872.238 I slot print_timing: id  3 | task 0 |        eval time =   25559.75 ms /   264 tokens (   96.82 ms per token,    10.33 tokens per second)
2.45.872.238 I slot print_timing: id  3 | task 0 |       total time =   44668.92 ms /  1214 tokens
2.45.872.239 I slot print_timing: id  3 | task 0 |    graphs reused =        258
2.45.872.353 I slot      release: id  3 | task 0 | stop processing: n_tokens = 1213, truncated = 0


2.55.088.335 I slot get_availabl: id  3 | task -1 | selected slot by LCP similarity, sim_best = 1.000 (> 0.100 thold), f_keep = 0.783
2.55.103.041 I slot launch_slot_: id  3 | task 268 | processing task, is_child = 0
3.05.689.161 I slot print_timing: id  3 | task 268 | n_decoded =    100, tg =  10.53 t/s, tg_3s =  10.53 t/s
3.08.716.636 I slot print_timing: id  3 | task 268 | n_decoded =    132, tg =  10.54 t/s, tg_3s =  10.57 t/s
3.11.724.392 I slot print_timing: id  3 | task 268 | n_decoded =    166, tg =  10.69 t/s, tg_3s =  11.30 t/s
3.12.610.506 I slot print_timing: id  3 | task 268 | prompt eval time =     998.92 ms /    13 tokens (   76.84 ms per token,    13.01 tokens per second)
3.12.610.511 I slot print_timing: id  3 | task 268 |        eval time =   16416.87 ms /   176 tokens (   93.28 ms per token,    10.72 tokens per second)
3.12.610.512 I slot print_timing: id  3 | task 268 |       total time =   17415.79 ms /   189 tokens
3.12.610.513 I slot print_timing: id  3 | task 268 |    graphs reused =        428
3.12.610.605 I slot      release: id  3 | task 268 | stop processing: n_tokens = 1125, truncated = 0

@rujialiu

rujialiu commented Jul 2, 2026

Copy link
Copy Markdown

Solution for llama-server in browser: Activate the reasoning in the chat window. Look for a "bulb" button close to the prompt field.

Otherwise, start the server with "--reasoning on" and a couple of other params, e.g. thinking token budget.

@joesixpaq Thanks! The bulb button works. I didn't try to click it because it looks like microphone 😆
However, using the bulb botton seems neccesary in llama-ui even if I use -rea on and/or check "settings/developer/Enable thinking" in llama-ui.

@rujialiu

rujialiu commented Jul 2, 2026

Copy link
Copy Markdown

models/templates/deepseek-ai-DeepSeek-V4.jinja is only used as a fallback during conversion, if antirez' GGUFs have no template you will need to pass --chat-template-file.

If you view the model info in the webui (by clicking on the model name) it will show the chat template.

@dfriehs Thanks! I tried and confirmed that antirez's gguf already contains the chat template and I just need to enable thinking in llama-ui via the "bulb" button.

@woof-dog

woof-dog commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

DeepSeek V4 Flash has been going OOM for me and crashing with CUDA error: out of memory (using bartowski's quant) in the latest llama.cpp. It appears either -fit isn't doing its job, or there is a bug here. It happened at around 57000 tokens of context on a RTX 6000 Pro rental during a regular token decode.

Server args:

./build/bin/llama-server -m models/DeepSeek-V4-Flash-MXFP4-00001-of-00004.gguf  -np 1 -c 262144

Maybe there is something wrong with how I am invoking the server, but just posting here since I did not see anyone else affected yet and -fit has been reliable for me with other models.

Update, immediately after I discovered the -fitt option and will be trying that for the time being. Still probably an issue if -fit can't detect the right size.

@jkubi

jkubi commented Jul 2, 2026

Copy link
Copy Markdown

Anyone got this working with SYCL or Vulkan? No problems with CUDA, but on 4xB70 the model won't load even though there's plenty of VRAM available. -v logs this:
E ggml_backend_cpu_buffer_type_alloc_buffer: failed to allocate buffer of size 33703246400
E alloc_tensor_range: failed to allocate SYCL_Host buffer of size 33703246400 E llama_model_load: error loading model: unable to allocate SYCL_Host buffer
(that's ~31.4GB, which should fit)

Next tried using the cards over RPC, similar error there: ggml_backend_sycl_buffer_type_alloc_buffer: can't allocate 1165734400 Bytes of memory on device
(that's ~1.1GB, card(s) have 32GB free each)

@joesixpaq

Copy link
Copy Markdown

either -fit isn't doing its job

Try --cpu-moe instead, and if it does not fills up VRAM, experiment with --n-cpu-moe N.
That said, -fit never worked for me.

@FullstackSensei

Copy link
Copy Markdown

Getting the same error on two machines, each with 192GB VRAM, one with P40s and the other running Mi50s. The error is:

..../llama.cpp/ggml/src/ggml-backend.cpp:898: pre-allocated tensor (blk.0.attn_output_a.weight (reshaped)) in a buffer (ROCm0_Split) that cannot run the operation (RESHAPE)

Both are running fdb1db8, latest as of this writing.

@EugeoSynthesisThirtyTwo

EugeoSynthesisThirtyTwo commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Following the bug I found on KV cache corruption...

I confirm that the model works fine when I reprocess the full prompt, for instance if I pass "cache_prompt: false" in the request, it works fine. I came to the conclusion that Deepseek V4 needs checkpoints for its cache, like Qwen 3.5 (correct me if I am wrong).

I have been trying to make Deepseek V4 compatible with the argument --ctx-checkpoints N for hours now, but I don't know where to start. Can someone help please ?

@am17an

am17an commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

It already uses checkpoints

@wenyifancc

Copy link
Copy Markdown

It already uses checkpoints

I encountered the same issue: after the initial response, subsequent dialogue turns fail to reference previous context for answering.

I also tried modifying the Jinja template to forcibly retain all thinking content and tested by directly passing multiple conversation turns via the API. On the first call to llama-server at startup, the model could answer based on the preset multi-turn conversation history. However, when sending the same content to llama-server a second time, the model’s response showed complete amnesia.

Additionally, from the logs, I found that my multi-turn conversation content exceeds 10,000 tokens. Yet, during the second request to llama-server, the log indicates that the context checkpoint size is clearly too small: "I slot operator(): id 3 | task 4295 | restored context checkpoint (pos_min = 11517, pos_max = 11517, n_tokens = 11518, n_past = 11518, size = 17.021 MiB)"

Backend: Vulkan

@am17an

am17an commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

This is not helpful unless you provide a proper reproduction. You can file an issue with the exact steps to reproduce the problem

@wenyifancc

Copy link
Copy Markdown

This is not helpful unless you provide a proper reproduction. You can file an issue with the exact steps to reproduce the problem

In this issue, I have provided complete reproduction steps and test data.
#25259

@tarruda

tarruda commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

I experienced the same "context exceeded" bug as @fairydreaming. Was just running it under pi and it broke after ~14% of the 262144 configured context was reached.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

conversion model Model specific testing Everything test related

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Model request: DeepSeek V4 Series