Skip to content

dflash: rotate injected K/V cache when using K/V quantization#25823

Merged
ruixiang63 merged 4 commits into
ggml-org:masterfrom
ruixiang63:dflash_quant_perf
Jul 18, 2026
Merged

dflash: rotate injected K/V cache when using K/V quantization#25823
ruixiang63 merged 4 commits into
ggml-org:masterfrom
ruixiang63:dflash_quant_perf

Conversation

@ruixiang63

Copy link
Copy Markdown
Member

Overview

Fix issue: #25725

Resolved by @ggerganov 's suggestion: Simply applying the rotation during injection should fix the problem.

Additional information

Requirements

Comment thread src/models/dflash.cpp Outdated
ruixiang63 and others added 2 commits July 17, 2026 15:26
Co-authored-by: Georgi Gerganov <ggerganov@gmail.com>
@ruixiang63

Copy link
Copy Markdown
Member Author

Looks better now :)

@ggerganov ggerganov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, can merge after @HermiG confirms it fixes the issue.

@HermiG

HermiG commented Jul 17, 2026

Copy link
Copy Markdown

Confirmed fixed. I launched the server with LLAMA_ATTN_ROT_DISABLE=0 and --cache-type-k-draft q8_0 --cache-type-v-draft q5_1. Acceptance rate appears to match f16/bf16 levels.

Draft acceptance: 0.97159

cclecle pushed a commit to cclecle/llama-cpp-turboquant that referenced this pull request Jul 17, 2026
Cherry-pick of ggml-org#25823 (squashed; original 4 commits touch
only src/models/dflash.cpp). Fixes ggml-org#25725: DFlash draft
acceptance rate collapses to zero with quantized cache types because the
injected K/V is not rotated into the cache's rotated space. Apply the Hadamard
rotation (llama_mul_mat_hadamard with self_k_rot/self_v_rot, and the _swa
variants on the iSWA path) during injection, restoring acceptance to parity
with f16/bf16 cache. Prerequisite rotation infra already present in our fork.

Co-authored-by: Georgi Gerganov <ggerganov@gmail.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@ruixiang63
ruixiang63 merged commit 571d0d5 into ggml-org:master Jul 18, 2026
37 of 45 checks passed
@ruixiang63
ruixiang63 deleted the dflash_quant_perf branch July 18, 2026 21:26
fewtarius added a commit to fewtarius/CachyLLama that referenced this pull request Jul 19, 2026
…, OpenCL Q6_K/Adreno, CORS, checkpoint min-step, prompt cache refactor, MoE expert API stays)

Upstream highlights since 6be7459:
- model: DFlash speculative with KV rotation (ggml-org#25823)
- model: Hy3 (hy_v3) with MTP speculative decoding (ggml-org#25395)
- model: DeepseekV4 with fused hyper-connection ops (ggml-org#25585)
- ggml: 0.17.0, LIGHTNING_INDEXER, out_prod, f16 set_rows
- vulkan: Q2_0 support, native e2m1/e4m3 conversions, transfer-queue race fix
- CUDA: MMQ kernel config refactor (ggml-org#24127), tighter MMQ src1 buffer for fp4 (ggml-org#25613), CUDA graphs on Volta/Turing, MoE gate/up dedup, CUDA Virtual Devices
- ROCm: hexagon L2 cache rework, native fp4, FP16/INT8 coopmat on AMD
- SYCL: Battlemage flash attention via oneDNN XMX, XIELU op, fp16 conv2d_dw
- OpenCL: Q6_K GEMM/GEMV fix, ragged-tile MoE prefill FP16, Adreno vectorized LD/ST, A7x optimizations, ABS op
- kleidiai: SME2 f32 kernel, SME vs SME2 dispatch
- server: refactor prompt cache state ownership (ggml-org#25649) - new server_prompt_cache_state separates prompt metadata from KV data
- server: evict checkpoints within min-step (ggml-org#25472)
- server: text-only slot save/restore with mtmd (ggml-org#25076)
- server: --cors-* options (ggml-org#25655)
- server: refactored server_stream (ggml-org#25541)
- server: respect min-step when splitting prompt batches (ggml-org#25420)
- server: move chat-template thinking probe inside init try/catch (ggml-org#24093)
- common: auto-download dflash/eagle3 HF sidecars (ggml-org#25811), drop --stdin mutual-exclusion, align tokenize usage
- conversion: BitNetForCausalLM, dflash tokenizer fix, split MTP export for HY V3
- llama-quant: exclude i32 ffn_gate_tid2eid routing table, allow manual tensor types with --pure
- llama-batch: fix allowed decreasing pos in a seq (ggml-org#25449), n_keep_tail in split_equal for recurrent
- llama: refactor fused ops (ggml-org#24646), TP fix for Phi3/Bert/Plamo2/3/ChatGLM
- ui: agentic content UX, reasoning effort on mobile add sheet, MCP panel fixes, thinking menu fix
- vendor: BoringSSL 0.20250713.0
- tests: actually exercise test-recurrent-state-rollback, ds_v4_hc sentinel init, export-graph-ops graceful exit

CachyLLama preservation work (conflict resolution):

1. tools/server/server-task.h: Accept upstream's server_prompt refactor (no data member, clear() method).
   Move our t_last_used field from server_prompt to server_prompt_cache_state (where it now lives
   after the refactor). server_prompt_cache_state already has the size() method, so our old
   size() on server_prompt is no longer needed.

2. tools/server/server-context.cpp (create_checkpoint): Take upstream's min-step eviction
   pre-filter as the FIRST pass, then keep our existing highest-pos_min eviction as the
   capacity overflow fallback. These are complementary: min-step removes redundant checkpoints
   from the same task; highest-pos_min keeps the rec-window-friendly checkpoints when at cap.

3. tools/server/server-context.cpp (handle_completions_impl): Keep our std::vector<server_task>
   tasks batching for multi-prompt requests and per-user concurrency check, AND take upstream's
   res->set_req(&req) for spipe ownership transfer.

4. tools/server/server-task.cpp: Fix references to entry.tokens -> entry.prompt.tokens,
   entry.checkpoints -> entry.prompt.checkpoints, entry.n_tokens() -> entry.prompt.n_tokens().
   Update find_eviction_candidate return type from list<server_prompt>::iterator to
   list<server_prompt_cache_state>::iterator.

5. ggml/src/ggml-cuda/mmq.cuh + new mmq-config-rdna3_5.cuh: Upstream's massive MMQ refactor
   moved per-architecture config into separate files but did NOT add RDNA3.5 (gfx1150/1/2/3,
   Strix Halo). Create mmq-config-rdna3_5.cuh (231 CASE entries) derived from rdna2 with
   nthreads=128 (4 warps) and I=48 (smaller X tile) matching our original Strix Halo tuning.
   Wire into both host and device dispatch paths before the RDNA4 / RDNA2 fallback.

6. README.md and AGENTS.md: Keep CachyLLama-specific links and project context where upstream
   added parallel content.

Verified:
- cmake --build builds clean (Release, CPU-only)
- llama-server starts, --help shows all CachyLLama flags preserved:
  --cache-ssd-hot-ram, --cache-ssd-warm-ram, --cache-ssd-system-prompts,
  --cache-ssd-system-max-days, --cache-ssd-no-fsync, --cache-ssd-max-conversations,
  --max-concurrent-per-user
- /expert-stats and /expert-tracking endpoints preserved
- 55/58 tests pass; 3 failures unrelated to merge:
  - test-tokenizers-ggml-vocabs: missing model downloads
  - test-jinja-py: missing jinja2 Python module
  - test-quant-type-selection: snapshot mismatch on upstream's new MXFP4_MOE heuristic

Custom CachyLLama files untouched (no upstream conflicts):
- common/kv-ssd-cache.{cpp,h}, common/kv-ssd-posix.h, common/kv-ssd-system-cache.{cpp,h}
- common/kv_page_manager.{cpp,h}
- tools/server/server-context-page-manager.{cpp,h}
- tools/server/server-context-ssd-cache.{cpp,h}
- test_kv_page_manager.cpp, tests/test-ssd-cache-caps.cpp
- STRIX_HALO_NOTES.md, docs/development/user-isolation-design.md
- .github/workflows/build-cpu.yml, build-cuda-windows.yml, build-vulkan.yml
@flashburns

flashburns commented Jul 19, 2026

Copy link
Copy Markdown

This broke Step 3.7 Flash for me. When using without KV cache quantization. The model spams a single token no matter the prompt. I was using a custom quant when I ran into this but I also tested this with the official ggufs at IQ4_XS and both are effected.

I am using ROCm 7.2.1/HIP on a gfx1151 (strix halo 128gb unified ram style PC).
4937ca8 works fine.

Let me know if I need to provide more info or can help with this somehow, not sure if this is the right place to report my issue.

@ruixiang63

Copy link
Copy Markdown
Member Author

This broke Step 3.7 Flash for me. When using without KV cache quantization. The model spams a single token no matter the prompt. I was using a custom quant when I ran into this but I also tested this with the official ggufs at IQ4_XS and both are effected.

I am using ROCm 7.2.1/HIP on a gfx1151 (strix halo 128gb unified ram style PC). 4937ca8 works fine.

Let me know if I need to provide more info or can help with this somehow, not sure if this is the right place to report my issue.

Why does this break Step 3.7 Flash? The patch only applies to the DFlash file and should not affect any other models. And it only works when doing quantization for DFlash draft models.

If you’re unable to resolve it, please open an issue.

@flashburns

flashburns commented Jul 20, 2026

Copy link
Copy Markdown

I am digging deeper and the issue is not this patch, sorry for blaming this one. I have now found that the bug is not consistent and so other commits fail before the one that merged this.

To make the tests consistent I cooked up a long one that takes about 30 min and fills up context. I then had an agent bisected commits overnight for me. What actually seemed to cause it is c7d8722 undoing this change in the latest version of llama.cpp fixes it for me.

Sorry for jumping the gun, I have been at this for a few days now and just want it to end.
Whats worse is that it seems someone else already ran into this, fixed it and then it never got merged and the PR is now closed, given I would be a new contributor anything I will submit will not be taken seriously #24172

Edit, never mind it looks like it is getting addressed #25863 so I guess I just need to wait for this to merge :)

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

Labels

model Model specific

Projects

None yet

Development

Successfully merging this pull request may close these issues.

DFlash draft acceptance rate collapses to zero when using quantized --cache-type-k-draft (or v)

5 participants