benchmarks/stock: llama.cpp with its own DFlash2 drafter (and why it doesn't speed up here) - #52
Merged
Merged
Conversation
…doesn't speed up here The stock-engine table labelled llama.cpp's speculation "none for this model" and the docs said there was no DFlash2 head in GGUF form. Both stopped being true after the measured run: llama.cpp gained DFlash2 in build 10658 (#27816, the master landing of #27342), and incoai/Qwen3.8-27B-DFlash2-GGUF publishes the drafter. New `stock.py llama-dflash` arm: llama-server on the same UD-Q3_K_XL GGUF, serial and with the Q4_K_M DFlash2 drafter (--spec-type draft-dflash, draft width 7), same 512-token filler chad-bench tiles, greedy, cache_prompt off, 3 reps, plus a llama-bench verify-width probe. On build 10917, M4 Pro 24 GB: serial 97 tok/s prefill, 11.3 tok/s decode DFlash2 95 tok/s prefill, 11.1 tok/s decode, 96.5% of drafted tokens accepted batch of 1/2/4/8/16 tokens: 11.2 / 12.8 / 13.5 / 14.0 / 45.5 tok/s The drafter works; the 8-token verify costs ~6.4 serial steps on llama.cpp's Metal path for this quant, so acceptance cannot pay for the round. chad's whole round at that width costs ~2.2. The docs scope this to this GGUF on this Mac: llama.cpp's own PR reports ~1.8x on an M5 Pro with a Q4_K_M target. The build-10470 llama-bench row stays as recorded, relabelled "off in this benchmark". STOCK_LLAMA_BIN runs a newer build from an unpacked release without touching the brew install the matrix grid is pinned to. Closes #42. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Qsqne39Q9TQuEoKWukmSpT
The README footnote now states the result and links to docs/benchmarks.md, where the verify-width numbers already live. The drafter always downloads from the pinned repo, so the STOCK_DRAFT override and its one-use helper go. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Qsqne39Q9TQuEoKWukmSpT
nathansutton
marked this pull request as ready for review
September 11, 2026 21:43
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #42 — and instead of only relabelling the llama.cpp row, measures llama.cpp with its own DFlash2 drafter.
What was out of date
The stock-engine table said llama.cpp's speculation was "none for this model", and
docs/benchmarks.mdsaid there was no DFlash2 head in GGUF form. Both were true for build 10470, the build measured, and are not now:xsn/dflash2feature branch, notmaster(its commit is not an ancestor of any release). It reachedmasteras spec : add DFlash2 support (local convolution + candidate selector) (#27342) ggml-org/llama.cpp#27816 (b10f9ca58c), andb10658is the first release that contains it (b10657is one commit behind).incoai/Qwen3.8-27B-DFlash2-GGUFpublishes the drafter in BF16, Q8_0 and Q4_K_M.The new measurement
stock.py llama-dflashrunsllama-server(build 10917) on the sameUD-Q3_K_XLGGUF twice — serial, then with the Q4_K_M drafter (-md … --spec-type draft-dflash --spec-draft-n-max 7, chad's draft width) — on the same 512-token fillerchad-benchtiles (tokenized by the server itself), greedy,cache_promptoff, 3 reps each after a warmup. It also records allama-benchverify-width probe. M4 Pro 24 GB, nothing else resident, run twice (the numbers below are the committed second run; the first agreed within 0.1 tok/s).llama-bench(stock, build 10470)llama-server(build 10917), serialllama-server(build 10917)CHAD_NO_DFLASH=1)The drafter works and the speedup doesn't arrive. 96.5% of drafted tokens are accepted (110 / 114 per run, ~7.5 committed per round), and decode is 11.1 tok/s against 11.3 serial. The verify pass is why: llama.cpp's Metal path runs a batch of 1 / 2 / 4 / 8 / 16 tokens at 11.2 / 12.8 / 13.5 / 14.0 / 45.5 tok/s on this GGUF, so the 8-token verify alone costs ~6.4 serial steps and no acceptance rate can pay for the round. The jump at 16 is a kernel switch the round sits just below. chad's whole round at the same width, drafter included, costs ~2.2 serial steps (
mlx_dflash.BLOCK_ROUND_COSTS).I checked it isn't a measurement fault before writing it down: the drafter loaded and engaged (
common_speculative_impl_draft_dflash: n_max=7 … block_size=8, acceptance from the server's own counters), all 128 tokens were generated on every rep, and round time (~0.67 s) is the probe's 0.57 s verify plus ~0.1 s — not a CPU-bound drafter.Scope, as the docs now say it
This is this GGUF on this Mac, not llama.cpp's DFlash2 in general — llama.cpp's PR reports ~1.8× on an M5 Pro with a Q4_K_M target, and a different quant or chip can land on the other side of that kernel switch. Both drafted rows are ceilings on tiled code; the real-session numbers for chad stay in the footnote. Ollama is now described as measured without speculative decoding, not as lacking it.
Changes
README.md,docs/benchmarks.md: the two new rows, the relabelled build-10470 row, the Ollama wording, and the stale "no GGUF head" explanation replaced with the measurement.benchmarks/stock/stock.py: thellama-dflasharm,table()renders it and prints the llama-bench build,STOCK_LLAMA_BINso a newer build runs from an unpacked release without replacing the brew install the matrix grid's llama.cpp rows are pinned to. Server logs go to the temp dir, not_runs/.benchmarks/stock/_runs/llama-dflash.json: the record (per-rep timings, probe, flags).benchmarks/stock/README.md: the new command and how to point it at a build.The chad rows are unchanged (chad 2.0.0, same machine); nothing since touched the decode path.
ruffclean onstock.py.🤖 Generated with Claude Code
https://claude.ai/code/session_01Qsqne39Q9TQuEoKWukmSpT