Skip to content

About

llama.cpp fork tuned for speculative decoding on sm_86: int8 small-batch GEMM, fused q4 KV attention, GPU tool grammar, DFlash2

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

11,306 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

llama.cpp-opt: llama.cpp, tuned for speculative decode on sm_86

A llama.cpp fork that verifies 8 draft tokens in 33 ms instead of 54.
Qwen3.8-27B + DFlash2 speculative decoding on one RTX 3090. Kernel changes keep the output bit-identical.

BASED ON 8DF332DE1   CUDA / SM_86   OPT-IN FEATURES   MIT

What's different · Tested with · Build · Switches · Upstream llama.cpp

This is llama.cpp at upstream 8df332de1 (tag upstream-base) plus a linear series of commits on opt/main. They target one setup: a 27B hybrid Gated-DeltaNet/attention model (Qwen3.8-27B, IQ4_XS) drafting with DFlash2 on an RTX 3090, verifying 8 tokens per step at long context. On that setup a verify step drops from ~54 ms to ~33 ms.

Everything else is upstream llama.cpp. Its documentation lives in docs/, with build instructions and the server README.

What's different

Change Effect
MMSQ Small-batch (N <= 16) quantized GEMM on int8 tensor cores for IQ4_XS, Q4_K, Q5_K, Q6_K: split-K, activation reuse, occupancy-aware dispatch Weights stream at 750-830 GB/s of ~840; most of the speedup
Fused norm Residual add + RMS norm + weight + MMSQ activation quantization as one kernel 127 fewer kernels per step, bit-exact
Q4 MMA attention q4_0 K/V decoded straight into the 8-query MMA flash-attention tiles 95.8 -> 109.7 tok/s at 91K context
GPU grammar Tool-call grammars compiled to a DFA, masked and sampled on the GPU (Philox RNG) No logits copy to the host on tool requests
DFlash features Target features for the DFlash2 draft stay in a CUDA staging tensor No host round trip per step
Small kernels Small top-k, conv-state snapshot fusion, small F32 matmul Fewer, cheaper launches
Sleep cache Server snapshots KV and recurrent state to disk on idle unload and restores it on wake Long contexts survive idle sleep
Race fix Write-after-read race on KQ in flash_attn_ext_vec (fixed upstream in #30573, after upstream-base) racecheck 2.2M hazards -> 0

GPU sampling falls back to standard sampling for any request it can't serve (penalties, logprobs, reasoning budget, regex triggers), so no request is rejected.

Tested with

Target Qwen3.8-27B-Uncensored-HauhauCS-Aggressive-IQ4_XS.gguf (HauhauCS/Qwen3.8-27B-Uncensored-HauhauCS-Aggressive-MTP-GGUF @ 993a5971)
Draft stock Qwen3.8-27B-DFlash2-Q4_K_M.gguf (z-lab/Qwen3.8-27B-DFlash2-GGUF @ 2d9571f8), 7 drafted + 1 = 8 tokens verified per step
KV cache target q4_0 for K and V (3.6x smaller than f16, 1.7 GiB at 98K), draft f16
Context 98,304 tokens
GPU RTX 3090 24 GB (sm_86), eGPU on PCIe 4.0 x4 (OCuLink)
ms per verify step explanation python100 (tools) story
upstream 8df332de1 53.3 55.1 53.8
llama.cpp-opt 32.7 33.4 33.3

Same files, flags and sampling, run back to back. Every fork change since 2026-10-04 keeps the output bit-identical, checked by output hashes.

Model SHA-256 and revisions
target  034b4c6b7c5cd9f4a2f99570d5097698f9d1e265a0fb000207223cbf9f9bd0b0  rev 993a5971fda8f30dd1b7eb2654792ba4415c7460
draft   1a25c56858e1ebe93f2718ac1d49d1151f9323325c1bbfd6209370f4db131ebd  rev 2d9571f8ce46e151f61c6499c99dee6079e1d610

Build

git clone -b opt/main https://github.com/invaliddayta/llama.cpp-opt && cd llama.cpp-opt
cmake -S . -B build -G Ninja -DGGML_CUDA=ON -DCMAKE_CUDA_ARCHITECTURES=86 -DCMAKE_BUILD_TYPE=Release \
      -DGGML_CUDA_FA_QUANTS="q4_0-q4_0;q8_0-q8_0;f16-f16;bf16-bf16"
ninja -C build llama-server

Example server for the target setup:

GGML_CUDA_FATTN_Q4_MMA=1 LLAMA_GPU_SAMPLING=1 LLAMA_DFLASH_GPU_FEATURES=1 \
build/bin/llama-server -m target-IQ4_XS.gguf --ctx-size 98304 --gpu-layers 999 --flash-attn on \
  --cache-type-k q4_0 --cache-type-v q4_0 \
  --spec-draft-model DFlash2-Q4_K_M.gguf --spec-type draft-dflash --spec-draft-ngl 999 \
  --spec-draft-n-max 7 --spec-draft-p-min 0 --backend-sampling --jinja

The benchmarks also used --parallel 1 --split-mode none --spec-draft-device CUDA0 --spec-draft-poll 1 --spec-draft-type-k f16 --spec-draft-type-v f16 --threads 12 --threads-batch 16 --batch-size 2048 --ubatch-size 512 --reasoning-format deepseek --poll 10.

Switches

Env var Default Effect
GGML_CUDA_FATTN_Q4_MMA=1 off Fused q4_0 KV loader in MMA flash attention (sm86, head 256, 24/4 heads, 8 queries)
LLAMA_GPU_SAMPLING=1 off Sampling and tool grammar on the GPU, per-request fallback
LLAMA_DFLASH_GPU_FEATURES=1 off DFlash target features stay on the GPU
GGML_CUDA_MMSQ=0 on Turns MMSQ (and its fusions) off
GGML_CUDA_MMSQ_FUSE_NORM=0 on Turns only the fused norm/quantization off
LLAMA_SLEEP_CACHE_DIR unset Sleep cache: with --sleep-idle-seconds N, slots are written here on sleep and restored on wake
LLAMA_SLEEP_CACHE_KEY required with DIR Cache identity; change it whenever model, build or settings change
LLAMA_SLEEP_CACHE_MAX_MIB 16384 Size limit of the snapshot

MMSQ needs Ampere or newer. Shapes, types and batch sizes outside its range use upstream's kernels, and every opt-in leaves the upstream path untouched when off.

Staying close to upstream

opt/main is a linear series on top of upstream-base. The whole difference as one patch:

git diff upstream-base opt/main -- . ':!README.md' ':!media/llama-cpp-opt.svg'

License

MIT, like upstream llama.cpp (LICENSE). Not affiliated with ggml-org.

About

llama.cpp fork tuned for speculative decoding on sm_86: int8 small-batch GEMM, fused q4 KV attention, GPU tool grammar, DFlash2

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages