One model, three stacks, and numbers that do not compare
Qwen 3.8 27B is the same 27.8B model in all three setups below, and the numbers people quote for it are not the same kind of number. Stock llama.cpp reads the Q4_K_M file once per token. DSpine keeps that file and adds a small drafter that guesses tokens ahead. tqLLM replaces the weights with its own TurboQuant file and runs them in its own C++ engine, with a drafter and a long-context cache. One of those is a drafter, one is an engine plus a weight format, and one is the baseline.
That matters because the headlines are now 28, about 90 to 129, and 273.1 tokens a second for the same model. They are not three measurements of one thing. This page separates the layers, gives each claim its source, and says what we are measuring ourselves.
Stock llama.cpp: the baseline
The baseline is llama.cpp with the Unsloth UD-Q4_K_M file, 16.46 GB, no drafting. On an RTX 3090 it is about 28 tok/s in the DSpine author's own test. On our L4 it is 14.90 tok/s at 32K, 12.98 at 64K and 10.11 at 128K, which is the floor the other two stacks beat. With DFlash2, the drafter this site has written about, the same card reaches 50.6 tok/s in the same test. Those two numbers are the reference points for everything below.
The 27B is a hybrid model: 64 layers, 48 of them Gated DeltaNet and 16 full attention, with trained MTP heads. The Q4_K_M file fits a 24 GB card with room for context; the DFlash2 drafter adds 1.14 GB, and the target's built-in MTP path costs about 1.4 GB. This is the setup most readers already have.
DSpine: a drafter, same weights
DSpine is Tencent's new drafter for Qwen 3.8 27B, and it is a different bet from DFlash2. The weights are Tencent's, published as tencent/Qwen3.8-27B-DSpine-b16 under Apache-2.0 with the paper (arXiv 2609.36173). The runtime is not. Upstream llama.cpp has no DSpine support, so the GGUF conversions and the only llama.cpp backend come from Ajay9o9's dspine branch; stock llama.cpp refuses the files rather than running them wrong. That is why every DSpine row here runs on a fork and not on mainline.
It is a five-layer draft model that reads hidden states from five layers of the target and drafts a block of 16 tokens in parallel. Each draft position attends only to earlier positions in the block, and a code bridge after every layer passes the predecessor's predicted token back through the depth of the drafter. Tencent's model card says it accepts 7.20 tokens per round on GSM8K against 5.69 for DFlash2.
On one RTX 3090, with the same UD-Q4_K_M target, the author's fork reports:
| Context | DSpine | DFlash2 | No drafting |
|---|---|---|---|
| 8K | 35.6 | 26.6 | 28.1 |
| 32K | 31.1 | 28.0 | 23.8 |
| 64K | 35.5 | 23.0 | 19.5 |
| 128K | does not fit | does not fit | 14.6 |
The pattern is not a flat 3.2 times. At 8K DSpine is 1.34 times DFlash2 and 1.27 times no drafting. At 64K it is 1.54 times DFlash2 and 1.82 times no drafting. The long-context advantage is larger than the short one, and at 128K the drafter no longer fits on the author's 24 GB 3090 while plain decoding still does.
The same drafter looks different on other engines. On TensorFold, @lasse_ai measured +19% across eight agent settings, with a best case of +50% (234.7 to 352.8 tok/s at 7,700 prompt tokens, thinking off), and 8 of 8 settings faster. On chat it is slower: 0.78 times at temperature 0 (156.3 to 121.7), and 0.88 times overall. Code at temperature 1 is level (250.4 to 249.9). All 20 benchmark token hashes matched DFlash2 and undrafted output, though the chart marks cache-resume parity as unverified. On one H100 in SGLang, @fahdmirza reports 33 to 156 tok/s, about 4.8 times, on short prompts and one request at a time.
The longest-context public test is @bnjmn_marie's: DSpine leads DFlash2 by 13%. On one RTX PRO 6000, with Qwen3.8-27B and four DeepSWE 1.1 agent runs restarted at about 100K tokens and carried to 262K, batch 1: DSpine 89.9 tok/s, DFlash2 79.5, and no speculation 21 to 24. MTP-5 sits at 61.4 and DSpark at 65.6. That is 3.98 times no speculation and 13% over DFlash2. The paper reports +27.8% accepted tokens per round against DFlash and +10% against DFlash2 on Qwen3-8B, but it evaluates short tasks (GSM8K, HumanEval, MT-Bench), and the released drafters show +4% over DFlash2 in the repository's own benchmarks. His read is that the method is stronger than the released drafter, and that SpecForge's training code may produce better ones.
He ran it in SGLang, and vLLM support is still a pull request. Tencent evaluated its 27B drafter at concurrency 8 on Hopper GPUs; his run is one user, batch 1, on one RTX PRO 6000, which is the regime a coding agent works in. The public part of his write-up does not state the SGLang version or the quant, so that figure carries the gap.
So the honest DSpine line is: strong on agent and code, weaker on chat, and the gain depends on the GPU, the context and the drafter you compare against. The long-context agent run puts the gain over DFlash2 at 13%, not the paper's 27.8%. The author says 15 is best on CUDA, 2 on an RX 7800 XT, and that DFlash2 or MTP is faster for chat on some cards. This is not a universal 3.2 times.
On our L4 the same drafter does more, not less: 47.25 tok/s at 32K and 27.09 at 64K against stock's 14.90 and 12.98, or 3.17 and 2.09 times. The card is weaker and more bandwidth-bound than a 3090, which is exactly where a draft block pays: one read of the weights serves several tokens. That is a direction, not a new universal ratio.
tqLLM: an engine and a weight format
tqLLM is not a drafter bolted onto llama.cpp. It is a C++ inference engine with its own TurboQuant weights, its own exact speculative decoding and a long-context cache. The 27B fits in 11.85 GB as TQ3; the recommended TQ3_4S-v2 file is 14.5 GB. It runs on NVIDIA RTX 30, 40 and 50 cards and the GB10, and on Apple Silicon through Metal. It serves an OpenAI-compatible API and ships as a Docker image or a source build.
Its claims on one RTX 3090:
| Test | Plain | With DFlash2 drafter |
|---|---|---|
| 2K summary | 55.5 | 155.2 |
| 32K summary | 50.6 | 131.0 |
| LocalMaxxing reasoning-v1 | 273.1 | |
| LocalMaxxing code-v1 | 199.5 |
Those are the project's own numbers, and the RTX 3090 pair was submitted and approved on the board; the 5060 Ti pair is marked not submitted. On a 16 GB RTX 5060 Ti it reports 175.9 reasoning and 109 code, and on one 24 GB RTX 3090 it runs the 27B at 32K context with a 16-bit KV cache. With TQ4_L, the tq3 KV cache and DFlash2, it reports 140 tok/s at 256K and a 1M context with YaRN and TqCache, where the oldest KV sits in system RAM. The drafter is DFlash2, and the engine says its speculative output is exact. tqLLM 1.5.0 shipped on 2026-11-10, the same day as our run; these rows are 1.4.4, engine 9a9e7e5.
On our L4 the engine is the fastest stack at 32K and 64K: 66.97 and 61.59 tok/s against stock's 14.90 and 12.98, or 4.49 and 4.74 times. At 128K it falls to 20.94, level with DSpine at 7, because this 23,034 MiB card cannot keep the model and the 128K KV resident. A full 24 GiB consumer card might; we did not run one. The engine log puts the int8 LM head and token embeddings in host memory and 3.09 GB of the KV there, with 5.50 GB on the device. The long-context number is real, and it is a memory limit, not an engine limit.
Two caveats matter more than the headline.
First, the weights are different. tqLLM's TQ3_4S is a 4-bit TurboQuant build, not the Q4_K_M file in the stock and DSpine rows. A speed comparison is stack against stack, not bytes against bytes, and this page cannot tell you whether TQ3_4S answers as well as Q4_K_M.
Second, the hardware list is narrow. tqLLM lists CUDA architectures 86, 89, 120 and 121: RTX 30, 40 and 50, the GB10 and the DGX Spark. It does not list the A100 (sm_80). An A100 source build would be an unsupported configuration. That is why our first notebook runs stock and DSpine on the A100, and tqLLM in a separate L4 session.
The project also compares itself with other engines: on a DGX Spark, up to 1.42x faster prompts than TensorFold 1.2.3 with the 27B in TensorFold's own record setup, and on an RTX 3090, up to 34% more total output than Strata 0.2.12 with Qwen3.8-Flash-Next at 2 to 12 users. Those are the project's own comparisons, on its own files and settings, and one of them is not even about this model. They are leads, not independent rows.
Why the three numbers disagree
- Stock is one stack: the Q4_K_M file, llama.cpp, no drafts. It is the floor.
- DSpine is the same file plus a drafter. The gain is the draft acceptance rate, so it rises on code and agent work and can fall on chat. It never changes the weights.
- tqLLM is a different file, a different engine and a different drafter. Its 155.2 and 273.1 are not the same bytes as the 28 and 50. It can be faster because the weights are smaller and the engine is tuned for one user, not because the drafter is better.
- On our L4 the split is clean: prefill barely moves across the stacks (within about 5%, and tqLLM at 64K is the 10% exception), and only decode separates them, 14.90 for stock, 47.25 for DSpine and 66.97 for tqLLM at 32K.
The fair questions are therefore: on the same GPU, with the same prompt and the same output length, how much does each stack gain over stock? And does the answer hold when the output is checked, not just timed?
What we measured on an L4
One NVIDIA L4, 24 GB nominal, 23,034 MiB usable with ECC on, 72 W. The ECC reserve is why this card has about 1.5 GiB less than its 24 GiB label, and the calculator already charges it. A consumer 24 GB card does not carry that reserve; we did not run one here. Stock and DSpine use Unsloth UD-IQ4_XS, 14.25 GB with q8_0 KV; tqLLM uses TQ3_4S, 14.5 GB with its DFlash2 drafter. Three runs per row, greedy, answers capped at 256 tokens that stopped on their own between 31 and 138. Decode medians use all three runs; prefill and TTFT use the fresh runs where there are any (all three on stock and tqLLM, one on the 32K and 128K DSpine rows), and on the 64K DSpine row, where every repeat carries the 42-token cached template, they are medians over the three. The TTFTs, 33.55 to 228.69 seconds, show those prefills are real. The L4 is the card that runs all three, which is why it is the comparison and the A100 is not.
| Context | Stack | Prefill tok/s | Decode tok/s |
|---|---|---|---|
| 32K | stock | 729.1 | 14.90 |
| 32K | DSpine, n-max 15 | 718.1 | 47.25 |
| 32K | tqLLM, TQ3_4S | 690.8 | 66.97 |
| 64K | stock | 583.9 | 12.98 |
| 64K | DSpine, n-max 15 | 577.9 | 27.09 |
| 64K | tqLLM, TQ3_4S | 642.4 | 61.59 |
| 128K | stock | 422.0 | 10.11 |
| 128K | DSpine, n-max 7 | 420.2 | 21.18 |
| 128K | tqLLM, TQ3_4S | 415.6 | 20.94 |
Three things stand out.
Prefill barely moves. At a given context the two llama.cpp stacks prefill within 1.5% of stock at all three sizes. tqLLM is about 5% slower at 32K (690.8 against 729.1), 10% faster at 64K (642.4 against 583.9), and 1.5% slower at 128K. TTFT follows it: 33.04 s at 32K, 82.36 s at 64K, 227.73 s at 128K on stock. The stacks differ in generation, not in reading.
DSpine gains more on a weak card. Against stock it is 3.17 times at 32K, 2.09 times at 64K and 2.09 times at 128K. The author's 3090 rows show 1.27 to 1.82 times from 8K to 64K. That is not a contradiction: on a 23,034 MiB 72 W L4 the target is more bandwidth-bound, so one weight read serving a draft block is worth more. The author's rows are a different corpus, so compare the direction, not the exact ratio.
tqLLM does not hold 128K on this card. It is the fastest stack at 32K and 64K, 4.49 and 4.74 times stock. At 128K it falls to 20.94, level with DSpine at 7 and still 2.07 times stock. The engine log explains it: on 23,034 MiB it moves the int8 LM head and token embeddings to host memory and keeps 3.09 GB of the 128K KV in host, with 5.50 GB on the device. The 32K and 64K rows use the device part. That row is the price of 128K in 23,034 MiB, not a fair device-resident comparison.
The speed is rented from memory. Stock is 14.25 GB of weights. DSpine adds 1.26 GB of drafter. tqLLM is 14.5 GB of different weights plus a 0.79 GB drafter, and on this card it moves 2.47 GB of LM head and embeddings to host at every context. At 128K it also moves 3.09 GB of KV to host. On a 23,034 MiB card that price is visible. A full 24 GiB consumer card has about 1.5 GiB more to work with, so 128K might stay resident there; we did not run one. Even so, the fall is not a loss: at 128K DSpine is 21.18 and tqLLM 20.94 against stock 10.11, 2.09 and 2.07 times.
Power did not separate the arms: median draw 71.4 to 71.9 W against a 72 W limit, peak 78.03 W. The card is at its ceiling in every row.
What this cannot say: three runs of one prompt per size are not a quality test, the tqLLM arm uses different weights, and the 128K DSpine row is n-max 7 while the shorter rows are 15. The A100 run at 128K and 256K is still pending; tqLLM is not supported there.
What to choose, today
The first question is whether the model fits, and the VRAM calculator answers it before speed matters.
- You have a 24 GB card, code or agent work, and a Q4_K_M file: DSpine is the cheapest experiment. It is a drafter and a fork, and the author's own 3090 rows show the largest gain at 64K.
- You have a 24 GB card and mostly chat: DFlash2 or MTP is still the safer default; DSpine's own TensorFold numbers are slower on chat.
- You want one card to hold a long context, and you accept a new weight format: tqLLM is the one to read. It is the only stack here that claims 256K to 1M on a 3090, and it is the only one whose weights are part of the product. On this 23,034 MiB L4 at 128K it falls back to DSpine's level because the KV moves to host memory; a full 24 GiB card might hold it, but we did not test one. Above 64K, treat it as a different product.
- You have an A100: tqLLM is not listed for it. Stock and DSpine are the supported arms; a tqLLM source build is an experiment, not a recommendation.
FAQ
Is DSpine faster than DFlash2?
On the author's RTX 3090, at 8K to 64K, yes: 35.6 against 26.6 at 8K and 35.5 against 23.0 at 64K. On TensorFold's chat test it is slower, 0.78 times at temperature 0. The answer depends on the workload and the engine.
Does DSpine change the model's output?
Not by design, but it is not always byte-identical either. A draft is accepted only when it equals the token the model would have produced serially, and TensorFold matched 20 of 20 token hashes. The DSpine model card is more careful: verification processes several tokens in one batch, which rounds slightly differently from one token at a time, so near-tied tokens can flip. Code and tool calls usually match; prose and image descriptions can diverge. Our notebooks keep the generated text so we can say which happened on our runs.
Why is tqLLM slower at 128K?
On this 23,034 MiB L4 it is not slower by design, it is out of room. The engine keeps the int8 LM head and token embeddings in host memory and 3.09 GB of the 128K KV in host, with 5.50 GB on the device, so decode reads part of the cache over PCIe. At 32K and 64K the used positions are in the device part, where it was the fastest stack we measured.
What is tqLLM?
A C++ inference engine for Qwen models and TurboQuant GGUF weights, with exact speculative decoding and a long-context cache. It is not a llama.cpp fork and not a drafter you add to an existing setup.
Can I run tqLLM on an A100?
Its support table lists sm_86, 89, 120 and 121, not sm_80. Use an L4, an RTX 30, 40 or 50 card, or a GB10. An A100 source build is unsupported.
Are these numbers independent?
No. The DSpine rows are the author's and two testers'; the tqLLM rows are the project's own. The LocalMaxxing figures for the 3090 were submitted and approved, which is a check on the harness, not an independent replication of every claim, and the 5060 Ti pair was not submitted at all. Our L4 rows are first-party and marked as such; the A100 run is still pending.