Turbo dflash#219
Conversation
* tests : add support for qwen3 SSM archs * arch : add LLM_KV_ATTENTION_RECURRENT_LAYERS * cont : naming + TODOs
* cuda: reserve space for quantize kv-cache at startup * address review comments * remove forward decl Co-authored-by: Johannes Gäßler <johannesg@5d6.de> * remove assert in ggml-cuda.cu Co-authored-by: Johannes Gäßler <johannesg@5d6.de> --------- Co-authored-by: Johannes Gäßler <johannesg@5d6.de>
…gml-org#24030) * Removes __restrict__ from PDL kernel headers due to incompatibility with PDL. Adds preprocessor directives based on arch in kernel body to add __restrict__ to retain performance on older architectures. * Simplifies new __restrict__ usage via macro * Add hopper to PDL __restrict__ fix. Co-authored-by: Oliver Simons <osimons@nvidia.com> --------- Co-authored-by: Oliver Simons <osimons@nvidia.com>
* add model * nits
* qwen35: use post-norm hidden state for MTP * rename pre_norm to nextn * fix step35
* Tidy up SYCL doc a bit - Add explicit links to referenced items - Fix spelling errors Signed-off-by: Todd Malsbary <todd.malsbary@intel.com> * Correct documented default for GGML_SYCL_GRAPH The default is ON, not OFF: $ cmake -LAH -B build | grep GGML_SYCL_GRAPH ... GGML_SYCL_GRAPH:BOOL=ON Signed-off-by: Todd Malsbary <todd.malsbary@intel.com> * Move docker instructions from SYCL.md to docker.md This makes them directly accesible from the Quick Start section of the top-level README.md. Signed-off-by: Todd Malsbary <todd.malsbary@intel.com> * Refer to intel.Dockerfile for ARGs and their defaults The defaults are always changing; this avoids accuracy errors from duplicating the information. Signed-off-by: Todd Malsbary <todd.malsbary@intel.com> * Remove mention of Nvidia in SYCL row of backend table This support was removed in 2026.02 - refer to the SYCL.md News. Signed-off-by: Todd Malsbary <todd.malsbary@intel.com> --------- Signed-off-by: Todd Malsbary <todd.malsbary@intel.com>
…2754) * ggml-cpu: add rvv 512b,1024b impls for iq4_xs * ggml-cpu: refactor; add rvv 512b, 1024b impls for q6_K, i-quants * ggml-cpu: refactor; add 512 and 1024 implementations of tq3_s, iq3_xxs, iq2_s, iq2_xs, iq2_xxs improve iq2_xs impl for rvv 256 Co-authored-by: Rehan Qasim <rehan.qasim@10xengineers.ai> --------- Co-authored-by: taimur-10x <taimur.ahmad@10xengineers.ai> Co-authored-by: Rehan Qasim <rehan.qasim@10xengineers.ai>
…rt (ggml-org#23834) * Start work on flash_attn refactor * Refactor * Split k/v quantization * Refactor and abstract quantization logic for flash_attn and mul_mat * Add quantization support to tile path * formatting * Move to functions, add a check
…#24073) * tests : refactor test-save-load-state to accept token input - Default prompt is now empty; when not provided, generate n_batch random tokens (useful for models without a tokenizer) - Tokenization happens once upfront; pass token vector to test functions - generate_tokens prints token IDs instead of decoded pieces - Use llama_model_get_vocab / llama_vocab_n_tokens API - Upgrade log level from LOG_TRC to LOG_INF for visibility Assisted-by: llama.cpp:local pi * cont : use llama_tokens alias
…ml-org#23974) The XCFramework generated by build-xcframework.sh creates a module map that manually lists public headers. That list can fall out of sync with the framework's Headers directory. The module map is currently missing ggml-opt.h, which is present in the framework headers. This can cause downstream Apple builds to fail with: Include of non-modular header inside framework module 'llama' Use the framework's Headers directory itself as the module map umbrella instead of maintaining a manual header list. This makes all public headers under the generated framework's Headers directory part of the llama module.
…ggml-org#24065) * webui: fix tool selector toggle/counter, key tools by stable identity Key the disabled set, counts and toggles by a stable per-tool key instead of bare function name, deduped from one canonical list. Per-tool checkboxes become presentational (single row handler, no nested button), category checkboxes drop the tristate (n/total carries partial). One getEnabledToolsForLLM keeps normalized MCP schemas and dedupes by name. * ui: use SvelteSet and SvelteMap for local tool collections to satisfy svelte/prefer-svelte-reactivity
* agents: refactor, include more guidelines * better example * rephrase a bit * add more examples * nits
…ent (ggml-org#24110) * server: avoid unnecessary checkpoint restore when new tokens are present The pos_min_thold calculation unconditionally subtracts 1 to ensure at least one token is evaluated for logits when no new tokens exist. However, when the request contains new tokens beyond the cached prefix, this -1 is overly conservative and may trigger an unnecessary checkpoint restore. Conditionally apply the -1 only when n_past >= task.n_tokens() (no new tokens), avoiding redundant KV state restoration when there is actual work to do. * cont : add ref --------- Co-authored-by: Georgi Gerganov <ggerganov@gmail.com>
) * ggml: vectorize ggml_vec_dot_q4_1_q8_1 with WASM SIMD128 Optimize the inner loop of ggml_vec_dot_q4_1_q8_1_generic using WASM SIMD128 intrinsics, gated behind #ifdef __wasm_simd128__ so non-wasm builds are completely unaffected. Approach: - single wasm_v128_load covers all 32 packed 4-bit weights - nibbles unpacked via AND/SHR into two u8x16 registers - widened to i16 before multiply (WASM SIMD has no i8*i8 instruction) - 4x wasm_i32x4_dot_i16x8 calls accumulate all 32 element pairs - horizontal reduce via 4x wasm_i32x4_extract_lane Benchmark (node v25, emcc -O3 -msimd128, 64 blocks x QK8_1=32, 200k iterations): | impl | ns/call | speedup | |--------|---------|---------| | scalar | 880.7 | 1.00x | | simd | 257.8 | 3.42x | Correctness verified against scalar reference across 10 random seeds with exact output match. * ggml: move q4_1_q8_1 WASM SIMD implementation to wasm backend Relocate the SIMD128 implementation of ggml_vec_dot_q4_1_q8_1 to ggml/src/ggml-cpu/arch/wasm/quants.c to follow architecture-specific layout. Restore the generic implementation in ggml/src/ggml-cpu/quants.c. Move for loop in the else block. * ggml: use generic q4_1_q8_1 fallback in wasm backend
* Fix Gemma 4 Unified conversion * Set audio hidden size to audio_embed_dim
Co-authored-by: lvyichen <lvyichen@stepfun.com>
* webui: added single line reasoning preview. * patch: reduce width slightly for the previewing section * refactor: move formatter constants to the right file * feat: reimplement reasoning preview with throttled dynamic per-line rendering * chore: fix spacing Co-authored-by: Aleksander Grygier <aleksander.grygier@gmail.com> * chore: refactor to requested changes * refactor: grouped by capture pattern instead of block-level + inline * ui: fax interrupt state only trigger for 1st reasoning message * chore: make reasoning preview respects showThoughtInProgress setting * chore; newline at EOF Co-authored-by: Aleksander Grygier <aleksander.grygier@gmail.com> * fix: thread rawContent so collapsible content can handle compute preview * patch: showThoughtInProgress accidentally blocks rawContent being passed * chore: fix lint * chore: change smoke test --------- Co-authored-by: Aleksander Grygier <aleksander.grygier@gmail.com>
* chore(ui): pin package versions to currently installed - Update all dependencies and devDependencies to match exactly what's in package-lock.json - This ensures reproducible builds by locking to specific versions rather than semver ranges * chore: Update packages * chore: Move remaining dependencies to devDependencies * fix: Add missing `mermaid` package * chore: Update `cookie` package to `v1.1.1` * chore: Formatting * test: Update test configs
…gml-org#22445) * Deduplicate imatrix loading code * Add back LLAMA_TRACE, early exit on quantize missing metadata
…debar (ggml-org#23132) * use child snippets for landing and chat message elements * make ... icon visible in conversation history menu * conversation history forward tab fix * add snippet fix for fork icon in conversation history * focus/keyboard fix for attachment x icon and scroll left/right * formatting * fix scroll down issue * simply Statistics and pointer events in scrolldown * create storybook tests and move to folder * improve tests to actually assert on element
…o4 dequant for ne=8 Assisted-by: Claude
Assisted-by: Claude
Speculative Decoding (Draft Model Enabled)Standard Decoding (No Draft Model) |
Assisted-by: Claude
|
Okay got server up and running |
Gemma 4 Speculative Decoding BenchmarksA performance comparison of Gemma 4 (26B and 31B parameter models, including QAT variants) running baseline vs. speculative decoding via DFlash. Summary of Results
Detailed Benchmark Logs1. Gemma4-26BBaseline (Standard Decoding)Command: Metrics:
DFlash (Speculative Decoding)Command: Metrics:
2. Gemma4-26B-QATBaseline (Standard Decoding)Command: Metrics:
DFlash (Speculative Decoding)Command: Metrics:
3. Gemma4-31BBaseline (Standard Decoding)Command: Metrics:
DFlash (Speculative Decoding)Command: Metrics:
4. Gemma4-31B-QATBaseline (Standard Decoding)Command: Metrics:
DFlash (Speculative Decoding)Command: Metrics:
|
Batch encoder outputs and defer KV cache injection to draft() time instead of injecting per-ubatch. Improves Qwen DFlash throughput by 14-29%, but Gemma4's lower acceptance rate (~43%) causes regression by concentrating wasted work in draft(). Gate by target model type: enable deferred injection for most models, disable for Gemma4. Assisted-by: Claude
Deferred KV Injection Optimization for DFLASH Speculative DecodingThe ProblemDFLASH is a block-diffusion drafting method for speculative decoding. It uses a small "draft" model alongside the big "target" model. The draft model has two parts:
The connection between these two: every time the target model processes a token, DFLASH needs to encode that token through the draft encoder, then inject the encoder output into the draft decoder's KV cache so the decoder can attend to it. In the original implementation, this injection happened immediately inside the
Each injection decode is cheap -- it's just K/V projections (Wk, Wv matmuls) plus a cache write -- but it still takes GPU time, and it's serialized with the target model's own work. The Optimization: Deferred InjectionThe insight: we don't actually need to inject each encoder output into the KV cache right away. The draft decoder only reads the cache when it's time to generate drafts (the So instead of injecting immediately, we stash the encoder output and wait. When the orchestrator calls This turns: Into: The total work is the same, but batching the injection improves GPU utilization (larger matmuls) and removes serialization overhead between the target and draft GPU operations. A safety cap ( Benchmark ResultsTwo model families told opposite stories: Qwen3.6 models (big improvement)
These models have near-100% draft acceptance rate. Every stashed encoder output gets used by the decoder, and batching the injection is a pure win. Gemma4 models (regression)
Acceptance rate is the root cause. Gemma4 accepts only ~43% of draft tokens, versus Qwen's near-100%. These low rates mean most tokens the target verifies are rejected, but they still trigger The GateRather than applying the optimization universally, we detect the target model type and disable deferred injection for Gemma4 models. When disabled, the code falls back to the original per-chunk immediate injection behavior. The detection is a simple substring check on if (strstr(model_desc, "gemma")) {
m_use_deferred = false;
}When
When
Verified After Gating
What's in the Code
|
The speculative checkpoint save/restore condition excluded RS mode when the rollback fit within the RS window. In RS mode, llama_memory_seq_rm does not actually remove individual positions from the KV cache, so stale rejected-token positions persisted and caused every subsequent llama_decode to fail with: the tokens of sequence 0 in the input batch have inconsistent sequence positions ... Y = X + 1 Fix: always save and restore speculative checkpoints for RS mode, not only when the draft size exceeds the RS limit. Assisted-by: Claude
When deferred KV injection is enabled, the stash accumulates encoder outputs across process() calls. After checkpoint restoration (partial draft acceptance), the stash retains entries with positions past the restored prefix. The next flush_injection would inject stale positions into the draft cache. Fix: check if the incoming batch starts at or before the last stashed position; if so, the sequence was rolled back, so clear the stash. Assisted-by: Claude
This reverts commit cb71353.
This reverts commit 05fc3a0.
|
@giveen — thanks again for the DFlash work and the benches on #219. We could not land #219 as-is: base was Tom rebased your intended CL onto current He tried to keep your intended changes (content from your Only small tip-preserving tweaks on top:
We do not have your DFlash draft GGUFs here. Could you please re-test that PR branch the same way you did on #219 (5090, Once that looks good we can merge the rebased PR and close this one as superseded. Appreciate you driving this. |
Hardware: RTX 5090 (32GB) · Intel Core Ultra 9 285K
Target model: Qwen3.6-35B-A3B-UD-Q4_K_S.gguf
Draft model: Qwen3.6-35B-A3B-DFlash-Q8_0.gguf
Prompt: "Write a quicksort algorithm in Python. Write code only."
Sampling:
--temp 0 --top-k 1 --seed 42Overview
Port DFlash speculative decoding (block-diffusion drafting with KV cache injection, from (#103)) onto
feature/turboquant-kv-cache. DFlash uses a lightweight draft model to propose blocks of tokens by encoding target model hidden states and conditioning on noise latents, then validates against the target model.Key changes
llama_model_dflashandllama_model_eagle3model architectures (encoder/decoder graph builders, tensor loader, hparams)--dflashflag in CLI/server, with speculative type auto-detectionctx_otherfor target model embedding/output sharing in DFlash decoderembeddings_layer_inp+t_layer_inppopulation) needed by the DFlash encoderoutput_reservesizing for target contexts when draft flags are active (server_n_outputs_maxnow accounts for--dflash/--eagle3)Results
Baseline (no speculation)
q8_0cache, 1024 ctxDFlash On
Summary
turbo4K /q8_0V, 64k context) vs 237.4 t/s baseline — 1.67x speedupq8_0both)turbo4KV cache works with DFlash and can improve generation speed in mixed configurationsRequirements