10.4 — Speculative decoding
Goal: Derive speculative decoding from a draft–target rejection-sampling argument; prove that the resulting distribution equals the target's distribution exactly; analyse the expected wall-clock speedup and when speculative decoding helps vs. hurts.
1. Why this session exists
Decoding from a B-parameter target model is slow: each token costs one full forward pass, memory-bound at batch (Cap 10.3 §3). The compute is spent moving the weights through HBM; the actual multiply-add work is cheap relative to the bandwidth bill.
A simple observation: at typical batch sizes, the GPU is idle most of the time. If we could verify multiple candidate tokens in one forward pass — and most of them turn out to be the same tokens the target would have produced — we'd amortise the per-step weight-read cost across multiple emitted tokens.
This is speculative decoding (Leviathan et al., 2023, arXiv:2211.17192[1]; also Chen et al., 2023[2], arXiv:2302.01318). The protocol:
- A cheap draft model proposes tokens autoregressively.
- The expensive target model runs one forward pass on the -token continuation, producing next-token distributions in parallel.
- A rejection-sampling rule accepts a prefix of the draft, then samples one extra token from a corrected distribution at the rejection point.
The miraculous property: the marginal distribution of the accepted output is exactly . No quality loss. The only thing that changes is wall-clock — typically – faster decode at no accuracy cost.
This session derives the algorithm, proves the correctness, and characterises when speculative decoding wins.
2. Setup
Let:
- be the target model's next-token distribution at step . Expensive to compute.
- be the draft model's distribution. Cheap (e.g., a B model proposing for a B target).
- the speculation length (typical –).
The goal is to produce a stream whose joint distribution equals , but with fewer wall-clock target-model invocations per emitted token.
3. The algorithm
SpeculativeDecode(x):
t = 1
while not done:
# Draft phase: cheap autoregressive sampling
draft tokens ỹ_{t}, ỹ_{t+1}, ..., ỹ_{t+k-1}
store draft probabilities p̃_j(ỹ_{t+j}) = π_draft(ỹ_{t+j} | ..., ỹ_{<t+j})
# Verification phase: one target forward over k tokens
target distributions q_j(·) = π_target(· | x, y_{<t}, ỹ_{t..t+j-1})
for j = 0, 1, ..., k
# Acceptance loop
for j = 0, 1, ..., k-1:
r ~ Uniform(0, 1)
if r < min(1, q_j(ỹ_{t+j}) / p̃_j(ỹ_{t+j})):
accept: y_{t+j} = ỹ_{t+j}
else:
# rejection: resample from corrected distribution
q̄(v) ∝ max(0, q_j(v) - p̃_j(v))
y_{t+j} ~ q̄
t = t + j + 1; goto outer while
# All k drafts accepted
# Bonus token: sample y_{t+k} from q_k (free — already computed)
y_{t+k} ~ q_k
t = t + k + 1
In words: walk down the draft, accept each token with probability . On the first rejection, resample from the residual distribution . If all are accepted, take one bonus token from the next target distribution (which we already computed for free during verification).
4. Correctness: the rejection-sampling argument
The key claim:
I.e., the distribution of the emitted token at each step is exactly the target's distribution , regardless of the draft.
4.1 Proof for a single step
Fix and write , for brevity, for the draft sample.
There are three ways the output takes value :
Case A. The draft proposes () and it is accepted (). Probability:
Case B. The draft proposes some () and it is rejected, after which we resample from .
The probability that any draft is rejected is
(Using .)
The corrected distribution is with . So
Case C. The draft proposes and it is rejected. Doesn't contribute to (rejection always leads to resampling from , which would be a different draw).
Sum. Adding Case A and Case B:
(The last equality is the elementary identity for non-negative .)
So a single rejection-sampling step yields a sample from — exactly, not approximately — regardless of . Iterating over gives the multi-step claim.
4.2 What if all drafts are accepted?
After accepting all tokens, we have the target distributions computed (one verification forward). We never sampled from . The "bonus token" step samples — this is an additional free token from the target distribution. So the all-accepted case emits tokens for the price of one target forward pass + draft forward passes.
5. The expected speedup
Let be the per-token acceptance probability — the probability that any given draft token is accepted:
A useful identity: . The more and agree, the higher .
5.1 Expected accepted tokens per round
In a round of drafts, the number of consecutive acceptances before the first rejection is a (truncated) geometric random variable. Its expectation:
(Sum of .) Plus one rejection-resampled token in the partial-rejection case, or one bonus token in the all-accepted case. Net:
5.2 Cost per round
One round costs:
- draft forwards:
- target forward over tokens (the verification): (the target forward over tokens is roughly the cost of one target forward — the prefill cost scales with but is bounded by memory traffic, not compute, at small ).
So
5.3 Worked numbers
Llama-3 70B target with Llama-3 8B draft. Approximate . For an aligned chat workload, – empirically.
At , :
- Numerator:
- Denominator:
- Speedup: .
A factor of wall-clock speedup with zero quality loss is the typical operational gain. Speedups of – are achievable with strong draft models or simple tasks (high ).
5.4 The acceptance-rate ceiling
. Equality requires — i.e., draft = target. So speculative decoding's ceiling speedup is . With and : ceiling .
In practice, the per-token acceptance rate depends on:
- How similar the draft and target are. Same family, same training data, smaller size: high .
- The distribution sharpness — sharp distributions ( small) are easier to predict, goes up.
- The task — code and structured output have low entropy and high ; open-ended chat has lower .
6. Drafting strategies
The draft model can be:
(a) A smaller model from the same family. Llama-3 70B target + Llama-3 8B draft. Trained on the same data, similar tokeniser, similar distribution. is typically high. The most common production setup.
(b) A self-distilled draft. Distil the target down to a -size draft. Highest but requires the extra training run.
(c) Medusa heads (Cai et al., 2024, arXiv:2401.10774)[3]. Instead of a separate draft model, attach extra prediction heads to the target model that predict in one pass. Zero extra model weights to load; lower than a dedicated draft (the heads are shallow) but , so the speedup arithmetic still favours it.
(d) EAGLE / EAGLE-2 (Li et al., 2024, arXiv:2401.15077)[4]. A small autoregressive draft head conditioned on the target's hidden states. Higher than Medusa; small constant draft cost. Currently (2026) the best published wall-clock results for general LLM inference.
(e) Tree-based / Lookahead decoding. Generalisations that propose a tree of possible continuations and verify the whole tree in parallel, accepting the deepest matching branch. Higher per-round emit at higher per-round verify cost; complex to implement.
7. Implementation details
Three details that catch implementers:
7.1 Parallel target verification
The target model's -token forward pass uses causal attention: position attends only to positions . The KV cache for the prefix is reused; the new keys/values for are computed once and tentatively appended. On a rejection at position , the tentative cache entries from position onwards are discarded — the cache after a round is truncated to whatever was actually accepted.
This is the single largest source of bugs in speculative-decode implementations. The cache must support truncation in .
7.2 Temperature handling
Both and should be evaluated at the same temperature — otherwise the acceptance rule samples from the wrong . The straightforward implementation evaluates both at the user-facing . Top- and top- truncation are applied to both in the same way.
(There is a variant — typical acceptance — where the acceptance rule accepts any draft token whose probability under exceeds a threshold rather than the strict ratio. This loosens the rule, raises , but slightly miscalibrates the output. Used in some production stacks for extra speedup.)
7.3 Greedy speculative decoding
At (greedy), the algorithm simplifies dramatically: accept iff . No randomness. The acceptance rate is the probability that draft argmax matches target argmax, position by position. This is often very high (– for similar models) — speculative decoding shines brightest at low temperature.
8. When speculative decoding doesn't help
Speculative decoding hurts when:
- Draft cost is high relative to target. If , the speculation overhead exceeds the savings even at high .
- Acceptance rate is low. Mismatched tokenisers, different model families, or tasks where the draft is consistently wrong. typically means net loss.
- Batch size is large. At batch , decode is compute-bound (Cap 10.3 §5.1), and adding speculation work makes throughput worse. Speculative decoding is primarily a latency optimisation for small-batch / single-stream serving. At high-throughput batched serving, continuous batching (10.8) is the better tool.
The clean rule: speculative decoding for latency-sensitive single-stream inference; continuous batching for throughput.
9. Connection to "test-time scaling"
Speculative decoding is a compute-saving technique that gives back wall-clock at no quality cost. Test-time scaling (10.7) is the opposite — spending more inference compute for higher quality.
Both can compose: a reasoning model uses test-time scaling to extend its chain-of-thought, and speculative decoding to make each token of that chain cheaper. The two operate at orthogonal layers (reasoning loop vs. per-token decode).
10. What we keep going forward
Three things.
- The protocol. Draft proposes , target verifies in parallel, rejection-sampling rule accepts a prefix. The acceptance distribution is exactly the target's — proved by the identity.
- The speedup formula. . Empirically – for chat workloads at –.
- Where it wins and where it doesn't. Small-batch latency-sensitive inference: yes, almost always. High-throughput batched serving: no, use continuous batching instead.
Cap 10.5 next: FlashAttention. With the KV-cache and speculative-decode mechanics in hand, we look at the attention kernel itself — and how an I/O-aware reformulation makes exact attention – faster on modern GPUs.
(a) Write the speculative-decoding algorithm in pseudocode. Identify exactly where the one target-model forward pass happens.
(b) Prove that for a single accepted-or-resampled step. Use the identity .
(c) State the expected-speedup formula. Compute the speedup for , , .
(d) Why does ? Sketch the derivation from .
(e) A team adds speculative decoding to their throughput-optimised serving stack (batch 128, continuous batching). They observe no speedup — sometimes a slowdown. Why?
(f) Greedy speculative decoding: state the simplified acceptance rule and why it almost always achieves higher than speculative decoding.
References
- [1]
Leviathan, Y., Kalman, M., & Matias, Y. (2023). "Fast inference from transformers via speculative decoding". arXiv:2211.17192 — Speculative decoding protocol and rejection-sampling correctness (10.4).
↩ - [2]
Chen, C., Borgeaud, S., Irving, G., et al. (2023). "Accelerating large language model decoding with speculative sampling". arXiv:2302.01318 — Parallel discovery of the same technique (10.4).
↩ - [3]
Cai, T., Li, Y., Geng, Z., et al. (2024). "Medusa: Simple LLM inference acceleration framework with multiple decoding heads". arXiv:2401.10774 — Medusa head-based drafting (10.4).
↩ - [4]
Li, Y., Wei, F., Zhang, C., & Zhang, H. (2024). "EAGLE: Speculative sampling requires rethinking feature uncertainty". arXiv:2401.15077 — EAGLE draft architecture (10.4).
↩