Instructions to use AnonimousA/Qwen3.8-Flash-Next-REAP-320-GGUF with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- llama.cpp
How to use AnonimousA/Qwen3.8-Flash-Next-REAP-320-GGUF with llama.cpp:
Install (macOS, Linux)
curl -LsSf https://llama.app/install.sh | sh # Start a local OpenAI-compatible server with a web UI: llama serve -hf AnonimousA/Qwen3.8-Flash-Next-REAP-320-GGUF:UD-Q2_K_XL # Run inference directly in the terminal: llama cli -hf AnonimousA/Qwen3.8-Flash-Next-REAP-320-GGUF:UD-Q2_K_XL
Install from WinGet (Windows)
winget install llama.cpp # Start a local OpenAI-compatible server with a web UI: llama serve -hf AnonimousA/Qwen3.8-Flash-Next-REAP-320-GGUF:UD-Q2_K_XL # Run inference directly in the terminal: llama cli -hf AnonimousA/Qwen3.8-Flash-Next-REAP-320-GGUF:UD-Q2_K_XL
Use pre-built binary
# Download pre-built binary from: # https://github.com/ggerganov/llama.cpp/releases # Start a local OpenAI-compatible server with a web UI: ./llama-server -hf AnonimousA/Qwen3.8-Flash-Next-REAP-320-GGUF:UD-Q2_K_XL # Run inference directly in the terminal: ./llama-cli -hf AnonimousA/Qwen3.8-Flash-Next-REAP-320-GGUF:UD-Q2_K_XL
Build from source code
git clone https://github.com/ggerganov/llama.cpp.git cd llama.cpp cmake -B build cmake --build build -j --target llama-server llama-cli # Start a local OpenAI-compatible server with a web UI: ./build/bin/llama-server -hf AnonimousA/Qwen3.8-Flash-Next-REAP-320-GGUF:UD-Q2_K_XL # Run inference directly in the terminal: ./build/bin/llama-cli -hf AnonimousA/Qwen3.8-Flash-Next-REAP-320-GGUF:UD-Q2_K_XL
Use Docker
docker model run hf.co/AnonimousA/Qwen3.8-Flash-Next-REAP-320-GGUF:UD-Q2_K_XL
- LM Studio
- Jan
- vLLM
How to use AnonimousA/Qwen3.8-Flash-Next-REAP-320-GGUF with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "AnonimousA/Qwen3.8-Flash-Next-REAP-320-GGUF" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "AnonimousA/Qwen3.8-Flash-Next-REAP-320-GGUF", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/AnonimousA/Qwen3.8-Flash-Next-REAP-320-GGUF:UD-Q2_K_XL
- Ollama
How to use AnonimousA/Qwen3.8-Flash-Next-REAP-320-GGUF with Ollama:
ollama run hf.co/AnonimousA/Qwen3.8-Flash-Next-REAP-320-GGUF:UD-Q2_K_XL
- Unsloth Desktop
- Pi
How to use AnonimousA/Qwen3.8-Flash-Next-REAP-320-GGUF with Pi:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf AnonimousA/Qwen3.8-Flash-Next-REAP-320-GGUF:UD-Q2_K_XL
Configure the model in Pi
# Install Pi: npm install -g @earendil-works/pi-coding-agent # Add to ~/.pi/agent/models.json: { "providers": { "llama-cpp": { "baseUrl": "http://localhost:8080/v1", "api": "openai-completions", "apiKey": "none", "models": [ { "id": "AnonimousA/Qwen3.8-Flash-Next-REAP-320-GGUF:UD-Q2_K_XL" } ] } } }Run Pi
# Start Pi in your project directory: pi
- Docker Model Runner
How to use AnonimousA/Qwen3.8-Flash-Next-REAP-320-GGUF with Docker Model Runner:
docker model run hf.co/AnonimousA/Qwen3.8-Flash-Next-REAP-320-GGUF:UD-Q2_K_XL
- Lemonade
How to use AnonimousA/Qwen3.8-Flash-Next-REAP-320-GGUF with Lemonade:
Pull the model
# Download Lemonade from https://lemonade-server.ai/ lemonade pull AnonimousA/Qwen3.8-Flash-Next-REAP-320-GGUF:UD-Q2_K_XL
Run and chat with the model
lemonade run user.Qwen3.8-Flash-Next-REAP-320-GGUF-UD-Q2_K_XL
List all available models
lemonade list
- Hermes Agent
How to use AnonimousA/Qwen3.8-Flash-Next-REAP-320-GGUF with Hermes Agent:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf AnonimousA/Qwen3.8-Flash-Next-REAP-320-GGUF:UD-Q2_K_XL
Configure Hermes
# Install Hermes: curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash hermes setup # Point Hermes at the local server: hermes config set model.provider custom hermes config set model.base_url http://127.0.0.1:8080/v1 hermes config set model.default AnonimousA/Qwen3.8-Flash-Next-REAP-320-GGUF:UD-Q2_K_XL
Run Hermes
hermes
- Atomic Chat
- OpenClaw
How to use AnonimousA/Qwen3.8-Flash-Next-REAP-320-GGUF with OpenClaw:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf AnonimousA/Qwen3.8-Flash-Next-REAP-320-GGUF:UD-Q2_K_XL
Configure OpenClaw
# Install OpenClaw: npm install -g openclaw@latest # Register the local server and set it as the default model: openclaw onboard --non-interactive --mode local \ --auth-choice custom-api-key \ --custom-base-url http://127.0.0.1:8080/v1 \ --custom-model-id "AnonimousA/Qwen3.8-Flash-Next-REAP-320-GGUF:UD-Q2_K_XL" \ --custom-provider-id llama-cpp \ --custom-compatibility openai \ --custom-text-input \ --accept-risk \ --skip-health
Run OpenClaw
openclaw agent --local --agent main --message "Hello from Hugging Face"
File size: 25,561 Bytes
b91c0e6 c2e411b b91c0e6 0d79102 b91c0e6 ba0dc6a b91c0e6 ba0dc6a b91c0e6 ba0dc6a 0d79102 4bc31ec 0d79102 4bc31ec 0d79102 5fb294f b91c0e6 5fb294f 4bc31ec 0d79102 b91c0e6 bbcebb1 0d79102 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 | ---
license: other
license_name: qwen-community-license-1.0
base_model: Qwen/Qwen3.8-Flash-Next
tags:
- llama.cpp
- moe
- pruning
- reap
- qwen
pipeline_tag: text-generation
---
# Qwen3.8-Flash-Next REAP-320 "multi-domain" β GGUF
The successor to [REAP-256 "duo"](https://huggingface.co/AnonimousA/Qwen3.8-Flash-Next-REAP-256-duo-GGUF): **512 β 320 experts per layer, 83.8 β 64.2 GiB** (64.2 GiB = **68.96 GB** decimal β the number HF's file listing shows; every size on this card is GiB, the same convention the compared models use), calibrated on a **multi-domain corpus** instead of code-only. Built directly in response to [this community critique](https://huggingface.co/AnonimousA/Qwen3.8-Flash-Next-REAP-256-duo-GGUF/discussions/2) β the full head-to-head against Unsloth's UD-IQ1_M, including where this build loses, is published in that thread.
**Not an official Qwen release.** Community derivative, unaffiliated with Alibaba/Qwen.
## Why K=320 and why multi-domain
- **K=320 sits above the reliability knee.** Two independent measurements (sh0wie's REAP ladder, and our own K=256 lineage) show rare-token reliability and clean termination degrading below ~K=288-320. At K=320: zero empty-content stalls and zero truncation across all our battery passes, 9/10 on the seeded rare-name probe.
- **Calibration is the product.** Salience was measured with `llama-imatrix` over a 525K-token corpus: 30% agentic / 30% code / 15% conversation / 12.5% math / 12.5% writing. The multi-domain build beat the code-only specialist **even at code** (HumanEval 96.3% vs 95.7%), and we have since reproduced the effect at K=256, where changing *only* the corpus moved HumanEval from 89.6% to 95.1% at identical size and identical bits.
> **Correction (2026-09-01).** An earlier version of this card claimed this selection "retains 82.7% of routing mass vs 75.3% for a code-only selection at the same K." That number is withdrawn. It was measured against a corpus drawn from the same mixture that produced this selection, and the metric turns out to be circular β **each selection wins when scored against the corpus that produced it.** We then ran it as a genuine prediction on a K=256 rebuild: retained routing mass said the new selection would be *worse* (82.7% vs 78.0% for the incumbent), and every behavioural probe said the opposite, decisively. Retained routing mass is useful for understanding a prune; it does not rank two prunes. The HumanEval, rare-name and fabrication numbers below are unaffected β those are measured on the model, not on the selection.
> β οΈ **Throughput figures in the tables below are superseded.** They have been corrected
> twice β once for a protocol error and once for a bug in the correction itself. Read
> [Corrections to this repository](#corrections-to-this-repository) at the bottom before
> citing any tok/s number from this card. Quality figures (HumanEval, rare-name,
> fabrication) are unaffected throughout.
## Measured (all on RTX 5090 32 GB, llama.cpp + expert-cache PR #27861 build)
| metric | this build | unpruned baseline |
|---|---|---|
| 6-task machine-verified battery (3 passes, effort medium) | **13.0 / 13.0 / 12.0** | 12 / 13 / 11 (UD-Q2_K_XL) |
| HumanEval-164 pass@1 (seed 42, effort low) | **96.3%** (158/164) | 95.7% (UD-IQ1_M) |
| Rare-name probe (10 seeded gens) | 9/10 | 8/10 (Q2), 5/10 (IQ1_M, truncation) |
| General-knowledge fabrication (12 questions) | **25%** | **0% (UD-IQ1_M)** |
| Decode with LRU-128 expert cache, 32 GB card | ~42-45 tok/s | ~42-46 (Q2 full, same cache) |
| Prefill, same regime | **337 tok/s (+23%)** | 273 tok/s |
**Honest limitation, stated loudly:** pruning experts costs world knowledge. On our 12-question fabrication probe this build fabricates 25% (the old K=256 duo: 42%; unpruned UD-IQ1_M: 0%). If you want a general-purpose assistant, take [Unsloth's UD-IQ1_M](https://huggingface.co/unsloth/Qwen3.8-Flash-Next-GGUF) β experts store knowledge, bits store precision. Take this build when **fit and speed in constrained VRAM** dominate: it is 5 GiB smaller than the 1-bit route, prefills ~23% faster under the same cache regime, and generates concisely.
## New: Q2 variant β same experts, fewer bits, fully GPU-resident on 32 GB
`Q2/` holds a second quant of the **same K=320 selection** (same manifest, same imatrix), pruned by binary copy from Unsloth's `UD-Q2_K_XL`: 2 shards, **57.3 GiB (61.5 GB decimal)**. That is the same disk footprint as the legacy [K=256 duo](https://huggingface.co/AnonimousA/Qwen3.8-Flash-Next-REAP-256-duo-GGUF) at Q3 (57.7 GiB) β which makes it a controlled bits-vs-experts comparison at constant size:
| metric (same battery, same rig) | **Q2 @ K=320** | Q3 @ K=256 (duo, same disk) | Q3 @ K=320 (main quant) |
|---|---|---|---|
| HumanEval-164 pass@1 | **95.1%** (156/164) | 89.6% | 96.3% |
| Rare-name probe | **9/10** | 7/10 | 9/10 |
| Fabrication (12 questions) | **25%** | 42% | 25% |
| Decode, `--n-cpu-moe 3` (30.3 GiB VRAM) | **86.9 tok/s** | β | doesn't fit |
| Decode, fully resident `--n-cpu-moe 0` | 98.5 tok/s (31.8 GiB β thin margin, see below) | β | doesn't fit |
| Decode, LRU-128 expert cache | 47.6 tok/s | β | ~42-45 |
At equal disk, **64 extra experts per layer beat 1 extra bit per weight on every knowledge metric**, and cost only 1.2 HumanEval points vs the Q3 build while freeing 7 GiB β enough to make the whole compute path GPU-resident on a 32 GB card. Recommended residency: `--n-cpu-moe 3` (leaves ~2 GiB VRAM margin; `--n-cpu-moe 0` measures faster but runs the card at ~98% and risks driver timeouts under load).
## Files
Main quant: `UD-Q3_K_XL`-lineage (pruned by binary copy from [Unsloth's quant](https://huggingface.co/unsloth/Qwen3.8-Flash-Next-GGUF) β surviving experts keep their original bits, no requantization). 2 shards, 64.2 GiB (68.96 GB) total. Plus the `Q2/` variant above: 2 shards, 57.3 GiB (61.5 GB).
`manifests/seleccion_mass_K320.json` ships the per-layer kept-expert manifest (`{"<layer>": [expert ids...]}`, stock ids 0-511) β the prune is reproducible from the source quant, and the manifest is directly usable by SSD-expert-streaming runtimes as a pinned set.
## Run it
Needs llama.cpp mainline β₯ 2026-08-27 (PR #27742, `qwen4exp` support):
```bash
llama-server -m Qwen3.8-Flash-Next-UD-Q3_K_XL-reap320-00001-of-00002.gguf \
-ngl 99 --cpu-moe -c 32768 -fa on --jinja --parallel 1 \
--temp 1.0 --top-p 0.95 --top-k 20 --min-p 0.0
```
On a 32 GB card, add the expert-cache from [PR #27861](https://github.com/ggml-org/llama.cpp/pull/27861) (`--moe-expert-cache 128`) for ~42-45 tok/s decode. Set reasoning effort explicitly (`"chat_template_kwargs": {"reasoning_effort": "low"}`) β the template defaults to `xhigh` and replies take minutes.
For the `Q2/` variant on a 32 GB card, skip the cache entirely and run near-resident β this is the fast path (86.9 tok/s decode, ~1000 tok/s prefill):
```bash
llama-server -m Q2/Qwen3.8-Flash-Next-UD-Q2_K_XL-reap320-00001-of-00002.gguf \
-ngl 99 --n-cpu-moe 3 -c 32768 -fa on --jinja --parallel 1 \
--temp 1.0 --top-p 0.95 --top-k 20 --min-p 0.0
```
## New: run the Q2 with Unsloth's MTP head (+32% decode, costs 3.2 GiB)
Unsloth published standalone MTP heads for Qwen3.8-Flash-Next on 2026-09-01. They work on
this pruned Q2 build β the head is not affected by expert pruning β and are the single
biggest speed lever we have found for it. Measured on the same 32 GB card, same GGUF,
same flags, paired:
| `--n-cpu-moe 8`, `-c 65536`, KV `q4_0` | VRAM | decode |
|---|---|---|
| no speculation | 28104 MiB (86.2%) | 73.6 tok/s |
| **`--spec-type draft-mtp`** | 31276 MiB (95.9%) | **97.5 tok/s** |
Draft acceptance is 76β81% (mean accepted length 2.5β2.6). Quality is preserved:
HumanEval-164 94.5% with MTP vs 95.1% without β Unsloth's verification is exact, and the
one-problem gap is sampling noise.
```bash
# Needs a build with the Flash-Next MTP graph, NOT stock mainline (see "Which build" below and trap 4)
llama-server -m Q2/Qwen3.8-Flash-Next-UD-Q2_K_XL-reap320-00001-of-00002.gguf \
-md mtp-Qwen3.8-Flash-Next-shared-Q8_0.gguf \
--spec-type draft-mtp --spec-draft-n-max 2 \
-ngl 99 --n-cpu-moe 8 -c 65536 -fa on --jinja --parallel 1 \
--cache-type-k q4_0 --cache-type-v q4_0 \
--temp 1.0 --top-p 0.95 --top-k 20 --min-p 0.0
```
**Which build.** Stock llama.cpp mainline has the `--spec-type draft-mtp` flag but not the
Qwen3.8-Flash-Next MTP graph, and not the loader that lets the *shared* heads borrow
`token_embd` / `output` from the main model. Any of these three works (same list as Unsloth's
`MTP/README.md`):
1. **Unsloth's fork, release tag `b10715-mix-86bd2d3` or newer** β https://github.com/unslothai/llama.cpp/releases.
The prebuilt binaries there are **CUDA and CPU only**. For **ROCm** (and for Windows) take the
*source tarball* of that tag and build it exactly like you build mainline (`-DGGML_HIP=ON` etc.).
This repository's numbers come from a `b10798-mix` source build on Windows/CUDA.
2. Upstream PR https://github.com/ggml-org/llama.cpp/pull/28243 (the same code on its way to mainline; still a draft as of 2026-09-09).
3. Unsloth fork PR #144.
On a correct build the shared head prints **one error line at startup about borrowing the
embeddings**. That line is normal; it works. The `shared-Q4_K_M` head (1.78 GiB) saves another
~840 MiB of VRAM versus `shared-Q8_0` at the same acceptance (0.70 vs 0.72 measured), useful on 24 GB cards.
The head costs **~3.2 GiB of VRAM, flat** β the same at every offload level we tried
(`--n-cpu-moe` 14 / 12 / 10 / 8), so budget for it once. On a 32 GB card at 96k context,
`--n-cpu-moe 10` is the balanced point (30578 MiB, 93.8%, 92.5 tok/s); `8` is the fast one
but leaves under 1 GiB free.
> **A note on how we measured this, because we got it wrong first.** Our initial harness
> reported 369 tok/s for this configuration β a 3.6Γ speedup. It was wrong. It timestamped
> only stream chunks carrying `content`, while this model emits its reasoning in
> `reasoning_content`; that time landed in "time to first token" while its tokens stayed in
> the numerator. The inflation scales with how much the model reasons, so it was invisible
> on a short prompt and enormous on a long one. The +32% above is wall-clock, cross-checked
> against the server's own `predicted_per_second`. **If you benchmark a reasoning model,
> make sure your timer sees the reasoning stream** β and require two independent clocks to
> agree before you believe a number.
## New (2026-09-06): prefill β the PLE table is why your prompt speed swings 3Γ, and `--lazy-mode on-direct` fixes it
Flash-Next carries a 26.8 GiB per-layer-embedding table (`per_layer_token_embd.weight`, 320M rows Γ 90 B) that
is untouched by expert pruning and stays on the host. llama.cpp reads it through `mmap`: one page fault per
~90-byte row, on every token of the prompt. Whether those pages are in the OS cache decides your prefill
speed β and on a machine that also loads other 20β60 GB models, they usually are not. Our production log
showed 245β2652 tok/s on 11β25k-token prompts for exactly this reason, and repetitive benchmark prompts
(few distinct rows) hide it completely.
[PR #28136](https://github.com/ggml-org/llama.cpp/pull/28136) adds `--lazy-mode on-direct`: positioned reads
from a worker pool instead of demand faults. Measured on the `Q2/` build (RTX 5090, Windows 11, 95 GB RAM,
NVMe) with a genuinely cold cache (`RAMMap -Et` + fresh process per arm), a real 25k-token mixed prose+code
prompt, `cache_prompt: false`, two cycles:
| prefill tok/s | cold | warm (same prompt) | different rows, warm process |
|---|---:|---:|---:|
| `--lazy-mode on` (mmap, the default) | **167** | 681 | 442 |
| **`--lazy-mode on-direct`** | **621** | 656 | 619 |
| `--lazy-mode off` (table resident, +26.8 GiB RAM) | 590 | 673 | 573 |
`on-direct` is the one that gives the same number every time; `off` is fast while the resident table
survives but loses it whenever Windows trims the working set. With Unsloth's MTP head loaded (same
protocol): 259 β 506 cold, 404 β 604 on new rows, decode unchanged (72 tok/s). A 28k-token prompt now
prefills cold in 44 s instead of 74β152 s.
To use it today: the PR is still open, it is **POSIX-only as written** (Windows prints
`--lazy-mode on-direct is not supported on this platform` and silently falls back to mmap β you need
[this Windows port](https://gist.github.com/mjungnickel18/083da5cde978ca3b102952029d4a991a) from the PR
thread), and the prebuilt Unsloth binaries reject the value. We build Unsloth's b10798 mix source + the PR +
the Windows port, which keeps the MTP head working. Full numbers, including the Windows-native table, are
[in the PR thread](https://github.com/ggml-org/llama.cpp/pull/28136). If you cannot build:
`--lazy-mode off` (mainline and Unsloth builds accept it) gets most of the cold gain for 26.8 GiB of RAM.
## Traps (measured, not theoretical)
1. `--parallel > 1` requires `--kv-unified`.
2. Empty `content` with tight `max_tokens`: reasoning burns the budget. Detect and retry with a higher cap.
3. First requests after a cold load pay disk; throughput climbs over ~3-4 requests to its warm ceiling. The disk cost is the PLE table (see the prefill section above); `--lazy-mode on-direct` removes it.
4. **`--spec-type draft-mtp` exists in llama.cpp mainline but does not work here.** Mainline has the flag and not the MTP graph for `qwen4exp`, nor the tensor borrowing the *shared* heads need. Symptoms on mainline: with a `shared-*` head, `tensor 'token_embd.weight' not found` β `failed to load draft model` (the head omits the embeddings on purpose, it is not a corrupt download); with a fused model, `model doesn't contain MTP layers`. The non-shared head is not a workaround: it gets past the missing tensor and fails later for the same reason. Use one of the builds listed under "Which build" above (ROCm users: build the Unsloth tag from source).
5. `"reasoning_effort": "none"` returns **HTTP 500** β the chat template accepts only `xhigh` / `medium` / `low`.
## Credits
- [Qwen](https://huggingface.co/Qwen) for Qwen3.8-Flash-Next (Qwen Community License 1.0).
- [Unsloth](https://huggingface.co/unsloth) for the UD-Q3_K_XL quant this was pruned from, and for UD-IQ1_M, the honest benchmark opponent.
- [Cerebras Research](https://github.com/CerebrasResearch/reap) for the REAP method.
- [sh0wie](https://huggingface.co/sh0wie) for independently mapping the pruning-reliability knee and publishing saliency manifests.
- The critic in [discussion #2](https://huggingface.co/AnonimousA/Qwen3.8-Flash-Next-REAP-256-duo-GGUF/discussions/2), whose pushback made this model exist.
---
## Corrections to this repository
**2026-08-31 β every throughput number in this card was measured with a flawed protocol, and
the context they were measured at was not stated. Both are corrected below. One correction
favours this build; the other does not.**
### What was wrong
**1. The decode rate included prefill.** Throughput was computed as *total wall time Γ· output
tokens*. That folds time-to-first-token into what was reported as a decode rate, so every decode
figure in this card was **too low**. The corrected protocol streams the response and measures only
the interval between the first and last token, with `ignore_eos` forcing a fixed output length so
the sample size cannot vary. Protocol borrowed from
[`jpezzulli/pennyroyal-validation`](https://github.com/jpezzulli/pennyroyal-validation).
Note for anyone reproducing this: `llama-server`'s own `timings.predicted_per_second` tracks the
**old, prefill-contaminated** figure, not the post-first-token decode rate. Do not use it.
**2. The numbers were measured at 8,192-token context, and this card recommends a configuration
that collapses at the context it is served at.** The context was never stated. For the
`--n-cpu-moe 4` configuration this turns out not to matter β 94.37 tok/s at 8k versus 93.45 at
98,304, inside noise. **But for the `--n-cpu-moe 0` "fast path" this card recommends, it matters
enormously**, and not in the way a reader would be able to detect:
| `--n-cpu-moe 0` | VRAM | decode | TTFT (code) |
|---|---|---|---|
| at 8,192 ctx | 31,658 MiB | 116.14 tok/s | 1.83 s |
| at 98,304 ctx | 32,168 MiB (**98.7%**) | **10.82 tok/s** | **17.83 s** |
**It does not fail. It loads, it answers, and it runs 10.7Γ slower.** At 98.7% of a 32 GB card the
driver begins paging and throughput collapses silently. The only trace is one warning that says
nothing about the consequence:
```
common_fit_params: failed to fit params to free device memory: n_gpu_layers already set by user to 99, abort
```
This card already warned that `--n-cpu-moe 0` *"runs the card at ~98% and risks driver timeouts
under load"*, and recommended `--n-cpu-moe 3` instead. That warning was **directionally right and
mechanically wrong**, in a way that makes it easy to ignore:
- it said **"under load"** β this happens at **one concurrent request**, with nothing else on the card;
- it said **"driver timeouts"** β there is no timeout. Nothing errors. It just gets 10.7Γ slower;
- it gave no magnitude, so "risks timeouts" reads like an edge case rather than a 10Γ cliff.
**Do not run `--n-cpu-moe 0` at long context on a 32 GB card.** Use `--n-cpu-moe 4`: it is slower
at short context and it is the only one measured here that holds its throughput at 98,304.
### Corrected table
All figures: post-first-token decode, `ignore_eos` with 1,024 forced output tokens, temperature
1.0 / top-p 0.95 / top-k 20 / min-p 0.0, `reasoning_effort: low`, warm-up pass discarded, single
RTX 5090 (32 GB) with no other process on the GPU.
Two prompts are reported because they differ a lot on this build: a **prose** prompt written to
force continuously distinct output (which suppresses n-gram draft hits), and a **code** prompt
(where the n-gram drafter earns its keep).
| configuration | context | VRAM | decode (prose) | decode (code) | TTFT | previously claimed |
|---|---|---|---|---|---|---|
| **`--n-cpu-moe 4` (as served, recommended)** | 98,304 | 30,730 MiB | **93.45** | **126.95** | 1.11 / 3.07 s | not listed |
| `--n-cpu-moe 4` | 8,192 | 29,552 MiB | 94.37 | 126.53 | 1.15 / 3.02 s | not listed |
| `--n-cpu-moe 3` | 8,192 | 30,108 MiB | 103.66 | 106.84 | 1.64 / 2.18 s | 86.9 tok/s |
| `--n-cpu-moe 0` (resident) | 8,192 | 31,658 MiB | 116.14 | 129.12 | 0.95 / 1.83 s | 98.5 tok/s |
| β οΈ `--n-cpu-moe 0` (resident) | 98,304 | 32,168 MiB (98.7%) | **10.82** | **12.08** | 8.92 / 17.83 s | β |
| `--cpu-moe --moe-expert-cache 128` | 8,192 | ~22 GB | 58.46 | 56.58 | 2.20 / 3.63 s | 47.6 tok/s |
| `--cpu-moe --moe-expert-cache 128` | 98,304 | ~22 GB | 61.31 | 58.21 | 2.34 / 3.60 s | β |
| **`--moe-expert-cache 192 --cache-reuse 256`** | 98,304 | ~22 GB | **70.52** | **71.68** | 2.12 / 3.80 s | β |
**Q3 main quant** (`UD-Q3_K_XL`-lineage, 64.2 GiB), same protocol. Note this build is served
**without** speculative decoding, where the Q2 rows above carry `--spec-type ngram-map-k4v`:
| configuration | context | decode (prose) | decode (code) | TTFT | previously claimed |
|---|---|---|---|---|---|
| `--cpu-moe --moe-expert-cache 128` | 8,192 | 54.09 | 53.89 | 2.40 / 4.69 s | ~42-45 tok/s |
| `--moe-expert-cache 192 --cache-reuse 256` | 98,304 | 66.59 | 66.22 | 2.74 / 3.97 s | β |
An earlier independent run of the `--n-cpu-moe 4` / 98,304 row two hours before this sweep gave
94.61 / 127.47 β 1.2% from the figure above, which is the reproducibility this protocol delivers.
### Two things the corrected numbers show that the old ones hid
**The expert cache is not the slow option β it is the option that holds.** At 8,192 tokens
`--n-cpu-moe 0` beats the cache almost 2:1 (116.14 vs 58.46). At the 98,304 this build is served
at, the cache is **6.5Γ faster** (70.52 vs 10.82), because it leaves ~10 GB of headroom instead of
running the card at 98.7%. The original table presents the cache as the bottom rung. At real
context it is the top one.
**`--cache-reuse` speeds up decode, not just prefill.** `--moe-expert-cache 192 --cache-reuse 256`
against `--moe-expert-cache 128` alone: **+15% prose, +23% code**, both at 98,304. It was adopted
here for time-to-first-token; the generation gain was not measured until now. If you run the
expert cache, run it with `--cache-reuse`.
### What this does and does not change
Nothing about the weights changed. No re-quantisation, no re-prune. This is a measurement
correction and a disclosure of a condition that should have been in the table from the start.
The quality claims in this card are **unaffected and unretracted**: 95.1% HumanEval, 9/10, and the
25% fabrication rate on the 12-question probe stand as published. The trade this build makes β
experts store knowledge, bits store precision β is not a throughput claim and does not move.
**If you are choosing between this and [Unsloth's UD-IQ1_M](https://huggingface.co/unsloth/Qwen3.8-Flash-Next-GGUF),
the corrected numbers do not change that advice.** That build fabricates 0% where this one
fabricates 25%. Take this one when fit and speed in constrained VRAM dominate; take theirs when
you want general knowledge.
---
**2026-09-01 β the correction above was itself measured wrong. The throughput numbers in
it are inflated; the advice it gives about `predicted_per_second` is backwards. The
`--n-cpu-moe 0` collapse it documents is real and stands.**
### The bug in our corrected harness
The 2026-08-31 protocol streams the response and measures the interval between the first
and last token. It timestamps a chunk only when that chunk carries `content`:
```python
delta = (ch.get("delta") or {}).get("content")
if delta:
if first_at is None: first_at = now
last_at = now
...
ct = usage["completion_tokens"] # ALL tokens, reasoning included
decode_tps = (ct - 1) / (last_at - first_at) # window of content only
```
This model emits its chain of thought in **`reasoning_content`**, a different field of the
delta. Those chunks are never timestamped, so the entire reasoning phase falls inside what
the harness calls "time to first token" β while its tokens remain in the numerator. The
numerator counts reasoning; the denominator excludes the time that produced it.
**The inflation scales with how much the model reasons**, which is why it was invisible to
us: our prose prompt reasons briefly and our code prompt reasons at length, and we read the
resulting gap as a code-versus-prose effect. It was not. It was the same server.
For the row this build is actually served at β `--n-cpu-moe 4`, 98,304 context, code prompt
β we published **126.95 tok/s**. Measured by wall clock: **85.0 tok/s**.
### And so: `predicted_per_second` is fine. Please disregard our warning about it.
The 2026-08-31 note told you that `llama-server`'s `timings.predicted_per_second` reports a
"prefill-contaminated" figure and to not use it. **That is wrong.** Re-measured today, that
counter agreed with wall-clock throughput to within 3% on every configuration we tried. It
was our harness that disagreed with reality, not the server.
The rule we should have followed, and now do: **a throughput number needs two independent
clocks that agree.** We report three β wall clock, post-first-token decode, and the server's
own counter β and treat any disagreement beyond ~10% as a measurement bug rather than a
finding. Had we done that in August, the harness would have failed its first run: it printed
`old method: 94.71` next to `decode: 369.09` and we read that as the old method having been
too conservative.
### What survives and what does not
**Survives.** The `--n-cpu-moe 0` collapse at long context β 10.7Γ is far too large to be a
metric artifact, and it reproduces in every clock. Do not run `--n-cpu-moe 0` at 98,304 on a
32 GB card. The relative ordering *within* a single prompt and a single speculation setting
is also roughly preserved, since the inflation factor is common to those rows: the expert
cache really does overtake `--n-cpu-moe 0` at long context, and `--cache-reuse` really does
help decode and not only prefill.
**Does not survive.** Every absolute tok/s figure in the 2026-08-31 table β inflated by
roughly 1.5Γ on the code prompt and less on prose. And any comparison **across** rows that
differ in speculation setting, including the Q3-without-spec against Q2-with-spec table,
because those rows produce different reasoning-to-content ratios and the inflation no longer
cancels.
**Unaffected, again.** No weights changed. The quality claims β 95.1% HumanEval, 9/10 on the
rare-name probe, 25% fabrication β are measured by counting correct answers, not by timing,
and do not move.
We are not republishing a full corrected table here until it has been re-run end to end with
the three-clock protocol. The honest anchor in the meantime: **as served
(`--n-cpu-moe 4`, `--spec-type ngram-map-k4v`, 98,304 context, KV `q4_0`), this build
generates 85 tok/s wall-clock on a code prompt**, and the MTP configuration described above
raises that to roughly 92-97 depending on offload.
*Two measurement corrections in two days, the second one correcting the first. The lesson we
are taking from it: a fix to a measurement does not validate itself. It has to be reconciled
against the method it replaces, and a large unexplained improvement in your own numbers is a
symptom before it is a result.*
|