Speculative Decoding Clearly Explained

(done right, it can make LLM inference 4x faster)

A local LLM typically produces one token per model pass. Each pass reads the model’s weights from memory, often leaving compute units waiting for data.

Generating a sentence means e process for every token.

Now introduce a smaller model that can predict the next token quickly. Let it make several predictions ahead while the larger model waits to check them.

The smaller model is the draft model. The larger model, called the target model, is the LLM whose output we want to preserve.

The draft model proposes. The target model verifies.

Because the guesses are already available, the target can check several positions in one pass instead of generating each token separately.

Here’s how that works.

→ Draft a possible continuation.

After “The cat sat,” the draft model proposes “on the red mat.” These tokens are provisional.

→ Check the guesses together.

The target model scores all four positions in one forward pass. Each position uses the preceding draft tokens as context.

→ Accept from left to right.

For sampling, let p be the target model’s probability for a guess and q the draft model’s probability. Accept it with probability min(1, p/q), stopping at the first rejection.

→ Correct and continue.

Discard the rejected token and all later guesses. Sample a replacement from the positive difference between the target and draft distributions, normalized into probabilities.

In the diagram, “on” and “the” are accepted. “Red” is rejected, and the replacement is “big.”

That produces three new tokens from one target-model pass. If every guess is accepted, the target can supply an additional token.

This acceptance and correction procedure preserves the target model’s output distribution. The speedup comes from replacing expensive passes with cheaper drafting and shared verification.

Uzu, an open-source engine for Apple Silicon, takes this further. DFlash proposes candidates in parallel, Weaver builds coherent draft paths, and rollback-free verification checks branches without repeatedly restoring the model’s running state.

In our base M5 coding test, 4-bit Qwen3.5 9B reached 92 to 117 tokens per second with Uzu, compared with 22 using plain llama.cpp. These complete engine results also reflect quantization and hardware-specific kernels.

Explore Uzu on GitHub: github.com/trymirai/uzu

(don't forget to star 🌟)

My quoted article explains how Uzu combines these techniques and how to benchmark the result on your own prompts.

Oct 11, 2026 · 4:33 PM UTC

42
45
265
19,333
RepliesRelevant
Replying to @akshay_pachaar
@akshay_pachaar red got rejected at p .10 and the whole tail got thrown out. brutal for the mat
0
0
1
149
Replying to @akshay_pachaar
@akshay_pachaar is the weight read the slow part in each pass?
1
0
0
149
Replying to @akshay_pachaar
@akshay_pachaar 🦾🦾🦾
0
0
0
12
Replying to @akshay_pachaar
@akshay_pachaar speculative decoding is one of those optimizations that feels like magic
0
0
0
35
Replying to @akshay_pachaar
@akshay_pachaar Great explainer. Spec decoding helps decode side. For long prompts the other half is prefill, and there reuse of the KV cache (prefix caching, or saving it to disk) often helps more than a faster forward pass.
0
0
0
37
Replying to @akshay_pachaar
@akshay_pachaar Does that 4× count the draft-model passes, or only the verified tokens? Rejected drafts are still compute, so I count discarded output in cost per request.
0
0
0
24
Replying to @akshay_pachaar
@akshay_pachaar The 4x hinges on acceptance rate. With per-token acceptance α and k drafted tokens, the expected tokens per target pass is (1−α^(k+1))/(1−α), about 3.4 at α=0.8 and k=4, before counting draft latency. Where does the break-even sit when the draft model isn't free?
0
0
0
17
Replying to @akshay_pachaar
@akshay_pachaar Good breakdown. The part people miss: the 4x only shows up when the draft model actually agrees with the big one. On high-entropy tasks the acceptance rate tanks and you're back near 1x. Have you found a draft/target pairing that holds up outside code and chat?
0
0
0
2
Replying to @akshay_pachaar
@akshay_pachaar watching token 3 get rejected and throw away the rest of the draft buffer hurts. still beats memory bandwidth choking every single forward pass though
0
0
0
40
Replying to @akshay_pachaar
@akshay_pachaar speculative decoding is how half of india wrote board exams. write the answer first, justify the steps later
0
0
0
37
Replying to @akshay_pachaar
@akshay_pachaar the part that always bites me is the acceptance rate in practice. 4x on paper, 1.7x on my prompts. do you gate the draft length or just let it run?
0
0
0
10
Replying to @akshay_pachaar
@akshay_pachaar Which draft model pairs best with a 26B? Gemma 4 26B on MLX is where I'd start.
0
0
0
68
Replying to @akshay_pachaar
@akshay_pachaar Speedup depends heavily on how predictable the output is. With 4 draft tokens, 80% acceptance gives roughly 3.0x and 40% gives about 1.8x. Coding sits near the top of that curve, but high-temperature creative writing lands much lower.
0
0
0
65
Replying to @akshay_pachaar
@akshay_pachaar Good explainer. The "done right" part matters. On DeepSeek-V4-Pro with one user I measured real text going from 43.93 to 77.56 tok/s, while random ids dropped from 37.58 to 21.62. Gains depend on how predictable the text is:

x.com/SJRonanMD/stat…
The same drafter made DeepSeek-V4-Pro 1.77x faster on real text and 0.58x as fast on random tokens. Why, how to predict it, and how to read speculative-decoding claims. x.com/i/article/2109…
0
0
0
89
Replying to @akshay_pachaar
@akshay_pachaar speculative decoding is the one trick that actually changed my local setup. small draft model + bigger verifier, watching per-token latency drop is so satisfying
0
0
0
10
Replying to @akshay_pachaar
@akshay_pachaar acceptance rate decides most of that 4x. drafts land often on code and boilerplate, they miss a lot more on open ended prose
0
0
0
84
Replying to @akshay_pachaar
@akshay_pachaar curious what acceptance rate you see from the draft model on code vs chat, since that's usually where the 4x lives or dies.
0
0
0
3