TAI BUI
Back to curriculum
BuildPython

Speculative Decoding and EAGLE

A frontier LLM spends a full forward pass over billions of parameters on every token it emits, and that pass is mostly wasted effort. A much smaller model can often guess the next 3-5 tokens correctly, so the big model only has to *verify* the guess. When the guess is right you get several tokens for the price of one. Speculative decoding (Leviathan et al. 2023) made this exact, and EAGLE-3 (2025) pushed acceptance to about 4.5 tokens per verify, a 4-5x speedup at matched output distribution.

TIME: ~75 minutesPREREQUISITES: Phase 10 Lesson 12 (Inference Optimization), Phase 10 Lesson 04 (Pre-training Mini-GPT)

Learning Objectives

  • Explain why autoregressive decoding is bound by memory bandwidth, and how verifying K drafted tokens in one target pass gets more than one token per weight read.
  • Apply the exact accept/reject rule with the residual distribution `(p - q)+` and state why the output still follows the target distribution.
  • Compute expected tokens per target forward from `α` and K, and measure both quantities in the toy harness.
  • Describe how EAGLE, EAGLE-2, EAGLE-3 and Medusa change the draft, and build the tree attention mask for a drafted tree.
  • Decide from workload type, temperature and batch size whether speculative decoding will pay off.

The Problem

Decode throughput for a 70B-class model on H100 is typically 40-80 tokens/second. Each token needs a full forward pass that reads all the model weights from HBM. You can't make the model smaller without changing its output, and you can't push batch size past what memory allows. The only way out is to get more than one token per forward pass.

Autoregressive generation looks inherently serial: x_{t+1} = sample(p(· | x_{1:t})). But there is room for concurrency. Suppose a cheap predictor says "the next 4 tokens are probably [a, b, c, d]". You can verify all 5 positions in a single forward pass of the big model and accept the longest matching prefix.

Leviathan, Kalai, Matias (2023, "Fast Inference from Transformers via Speculative Decoding") made this exact with an accept/reject rule that preserves the target model's sampling distribution. Same output distribution, 2-4× faster.

Warm-up0/3
1. Why is single-stream decoding of a large LLM on a modern GPU usually memory-bound rather than compute-bound?Warm-up
A token t box feeding into a box for this step, which reads the whole model from memory, feeding into token t+1. A note says each new token repeats this same whole-model read. A question asks what usually limits how fast this runs.
Setup only, from the stem; the limiting resource is the question.
2. What does the KV cache save during autoregressive generation?Warm-up
Five token boxes in a row, tok 1 through tok 5, each with an arrow down into a single dashed KV cache box marked with a question mark. A question asks what the cache holds and what that saves from being redone on the next step.
Setup only; the stem itself names the KV cache, but what it stores is the question.
3. Why does batching several requests together raise decode throughput on a memory-bound GPU?Warm-up
Three request boxes, A, B, and C, each with an arrow converging into a single one-batch-step box. A question asks why grouping requests this way raises throughput on a memory-bound GPU.
Batching several requests into one step is the stem's own setup; why it helps is the question.
Check: The Problem0/1
1. Why can verifying K drafted tokens in one target pass yield more than one token per weight read?Explain
Two boxes: a plain decode step producing 1 new token with a full weight read, and a verify pass scoring K+1 positions with the same weight read. A question asks why the verify pass yields more than one token per weight read.
Both steps reading the weights once is the Concept section's own step 2; what the extra positions buy is the question.

The Concept

The Two-Model Setup

  • Target model M_p: the big, slow, high-quality model you actually want samples from. Distribution: p(x).
  • Draft model M_q: a small, fast, lower-quality model with distribution q(x). It is roughly 10-70× smaller than the target (about 1B for a 70B target, 0.6B for a 32B one, 500M for a 7B one).

Per step:

  1. Draft model proposes K tokens autoregressively: x_1, x_2, ..., x_K ~ q.
  2. The target model runs one forward pass over all K+1 positions in parallel and produces p(x_k) for each proposed token.
  3. Accept/reject each token left-to-right via the modified rejection-sampling rule below. Accept the longest matching prefix.
  4. If any token is rejected, sample the replacement from the corrected distribution and stop. Otherwise sample one bonus token from p(· | x_1...x_K).

If the draft matches the target perfectly, you get K+1 tokens per target forward. If the draft is wrong at position 1, you get 1 token.

The Exactness Rule

Speculative decoding produces samples with the same distribution as sampling from p directly, and the rejection rule below is what guarantees it.

For each drafted token x_t:
    r ~ Uniform(0, 1)
    if r < p(x_t) / q(x_t):
        accept x_t
    else:
        sample replacement from residual: (p - q)+ / ||(p - q)+||_1
        stop

where (p - q)+ denotes the positive part of the pointwise difference. When the draft and target agree (p ≈ q) acceptance is close to 1. When they disagree, the residual distribution is built so the overall sample still follows p.

Greedy case. For temperature=0 sampling, check argmax(p) == x_t. If it matches, accept. If not, output argmax(p) and stop.

Expected Speedup

If the draft model's token-level acceptance rate is α, the expected number of tokens per target forward pass is:

E[tokens] = (1 - α^{K+1}) / (1 - α)        # K = draft length, α in [0, 1]

At α = 0.8, K = 4: (1 - 0.8^5)/(1 - 0.8) = 3.36 tokens per forward. One round costs roughly cost_q * K + cost_p: K draft steps plus one target verify. If cost_p >> cost_q * K, the speedup is about 3.36× / 1 = 3.36× on throughput.

The parameter that matters is α, and it comes from how well the draft is aligned with the target. A good draft is what makes the whole thing pay off.

Training the Draft: Distillation

A randomly initialized small model makes a poor draft. The standard recipe is to distill from the target:

  1. Pick a small architecture (~1B for a 70B target, ~500M for a 7B target).
  2. Run the target model on a large text corpus; store its next-token distributions.
  3. Train the draft with KL divergence against the target's distribution (not against ground-truth tokens).

The result is α of 0.6-0.8 on coding and 0.7-0.85 on natural-language chat, which gives 2-3× speedups in production.

EAGLE: Tree Drafting + Feature Reuse

Li, Wei, Zhang, Zhang (2024, "EAGLE: Speculative Sampling Requires Rethinking Feature Uncertainty") spotted two inefficiencies in standard speculative decoding:

  1. The draft does K serial steps, each through its full stack. It could instead reuse the target's features (hidden states) from the most recent verify, since the target already computed rich representations that the draft re-derives from scratch.
  2. The draft outputs a linear chain. If it output a tree of candidates instead (multiple guesses per node), the target's single forward pass could verify several paths in parallel via a tree attention mask and pick the longest accepted branch.

EAGLE-1 changes:

  • The draft takes the target's final hidden state at position t as input, not raw tokens.
  • The draft is one transformer decoder layer rather than a separate small model.
  • The output is a tree of K = 4-8 candidates per depth, with depth 4-6.

EAGLE-2 (2024) adds dynamic tree topology. The tree grows wider where the draft is uncertain and stays narrow where it is confident, which raises α_effective without raising verify cost.

EAGLE-3 (Li et al. 2025, "EAGLE-3: Scaling up Inference Acceleration of Large Language Models via Training-Time Test") removes the fixed top-layer feature dependency and trains the draft with a new "test-time simulation" loss. The draft learns on outputs that match the target's test-time distribution instead of the teacher-forced training distribution. Acceptance rate rises from 0.75 (EAGLE-2) to 0.82 (EAGLE-3), and mean tokens/verify from 3.0 to 4.5.

Tree Attention Verification

When the draft outputs a tree, the target model verifies it in a single forward pass using a tree attention mask, a causal mask that encodes the tree topology rather than a pure line. Each token attends only to its ancestors in the tree. The verify pass is still one forward and one matmul, and the topological mask costs only a few extra KV entries.

        root
       /    \
      a      b
     / \    / \
    c  d   e   f

If a, b are competing first-token candidates and c, d, e, f are second-token candidates, all six positions get verified in one forward pass. The output is the longest prefix along any accepted path.

When It Wins, When It Doesn't

Wins:

  • Chat and completion with predictable text (code, common English, structured output), where α is high.
  • Setups with idle GPU compute during decode (the memory-bound phase). Tree drafting puts the spare FLOPs to work.

Loses / no win:

  • Highly stochastic outputs (creative writing at high temperature), where α drops toward 1/|vocab|.
  • Batch serving at very high concurrency. Batching already fills the FLOPs, so there is little room for tree verification.
  • Very small target models, where the draft isn't much smaller.

Production deployments typically report 2-3× wall-clock speedup on chat, 3-5× on code generation, and close to none on creative writing.

Check: The Concept0/26
1. In speculative decoding, what is the target model?Define
A term card reading Target model, from the Concept section (Two-Model Setup), with a context note: Context: speculative decoding pairs two models of different sizes. A question asks: What is the target model, M_p?
The term as the lesson names it; its mechanism is the question.
2. In speculative decoding, what is the draft model?Define
A term card reading Draft model, from the Concept section (Two-Model Setup), with a context note: Context: speculative decoding pairs two models of different sizes. A question asks: What is the draft model, M_q?
The term as the lesson names it; its mechanism is the question.
3. What does K, the draft length, count?Define
A term card reading K (draft length), from the Concept section (Two-Model Setup), with a context note: Context: each round has a drafting stage and a checking stage. A question asks: What does K count?
The term as the lesson names it; its mechanism is the question.
4. What does the acceptance rate α measure?Define
A term card reading alpha (acceptance rate), from the Concept section (Expected Speedup), with a context note: Context: some drafted tokens are kept by the check, others are swapped out. A question asks: What does alpha measure?
The term as the lesson names it; its mechanism is the question.
5. What is the exact rejection rule for a drafted token x_t?Define
A drafted-token box carrying probability q(x_t), feeding into a target's-check box that computes p(x_t) for the same token. A question asks what rule decides whether to keep x_t and what happens if it's dropped.
The two probabilities being compared are given by the Exactness Rule; the rule itself is the question.
6. What does the residual distribution (p - q)+ put its probability on?Define
Three pairs of bars, p and q, for tok A, tok B and tok C, with p and q values marked above each bar. A question asks which tokens keep positive probability under the residual, the positive part of p minus q.
Illustrative target and draft values for three tokens, not captured from a real run.
7. What is tree drafting?Define
A term card reading Tree drafting, from the Concept section (EAGLE: Tree Drafting + Feature Reuse), with a context note: Context: a draft's guesses can be shaped as a straight line or as a branching structure. A question asks: What is tree drafting?
The term as the lesson names it; its mechanism is the question.
8. Under a tree attention mask, which positions may a drafted node attend to?Define
A tree of seven labeled nodes, root, a, b, c, d, e and f, with root branching to a and b, a branching to c and d, and b branching to e and f. A question asks which positions node d may attend to under the tree attention mask.
This is the lesson's own example tree from Tree Attention Verification, topology only, no mask drawn.
9. What does EAGLE feature reuse change about the draft's input and structure?Define
A term card reading EAGLE feature reuse, from the Concept section (EAGLE: Tree Drafting + Feature Reuse), with a context note: Context: EAGLE changes what the draft receives as input and how it is built. A question asks: What does EAGLE feature reuse change about the draft's input and structure?
The term as the lesson names it; its mechanism is the question.
10. What is the test-time simulation loss used to train the EAGLE-3 draft?Define
A term card reading Test-time simulation loss, from the Concept section (EAGLE: Tree Drafting + Feature Reuse), with a context note: Context: EAGLE-3 trains its draft with a different loss than earlier EAGLE versions. A question asks: What is the test-time simulation loss?
The term as the lesson names it; its mechanism is the question.
11. If all K drafted tokens are accepted, why does the round still return a (K+1)th token?Explain
Two boxes: K drafted tokens, all passing the accept test, and position K+1, already scored by the target in the same pass. A question asks why the round still returns a K+1th token when nothing needed replacing.
The target's single pass covering K+1 positions is the Concept section's own step 2; what happens to the extra one is the question.
12. Why is the replacement token drawn from the residual rather than from p after a rejection?Explain
Two boxes: a rejected token, drawn from q and failing the check, and a replacement, sampled from the residual (p - q)+ rather than from p. A question asks why using the residual here keeps the overall output following p.
That the replacement comes from (p - q)+ is the Exactness Rule's own stated step; why it must be that source is the question.
13. For temperature = 0 (greedy) sampling, how does the acceptance test simplify?Explain
Two boxes: an ordinary case drawing a uniform r to accept or reject, and a greedy case at temperature 0 with its simplified test left as a question mark. A question asks how the test changes at temperature 0.
The ordinary accept/reject test is the Exactness Rule's own description; how it simplifies at T=0 is the question.
14. A round costs about cost_q * K + cost_p. When does a gain of 3.36 tokens per forward turn into about a 3.36x throughput gain?Explain
A formula panel reading round cost is about cost_q times K plus cost_p, labeled K draft steps and one target verify. A question asks when a gain in tokens per forward becomes about the same gain in throughput.
The round-cost formula is given directly in Expected Speedup; the condition under which the token gain becomes a throughput gain is the question.
15. How should a draft model be trained so that its acceptance rate α is high?Explain
A three-line recipe panel: pick a small architecture, run the target on a corpus and store its distributions, then train the draft with a loss left as a question mark.
Steps 1 and 2 are the lesson's own Distillation recipe, given directly; step 3's loss is the question.
16. Which two inefficiencies in standard speculative decoding does EAGLE target?Explain
Two boxes side by side, inefficiency 1 and inefficiency 2, both left as question marks. A question asks which two inefficiencies in standard speculative decoding EAGLE targets.
The lesson frames EAGLE as targeting exactly two inefficiencies in the standard setup; what they are is the question.
17. What does EAGLE-2 add on top of EAGLE-1?Explain
Two boxes: EAGLE-1's tree, with a fixed branching factor per depth, and EAGLE-2, with its change to the tree left as a question mark. A question asks what EAGLE-2 adds on top of EAGLE-1.
EAGLE-1's fixed-branching tree is the lesson's own description; EAGLE-2's addition is the question.
18. How do the three EAGLE versions differ from one another?Explain
A horizontal chain of three boxes, EAGLE-1 dated 2024, EAGLE-2 dated 2024, and EAGLE-3 dated 2025, connected by arrows. A question asks what changes at each step from one version to the next.
The version names and years are given in the lesson's EAGLE section and Further Reading; what changes at each step is the question.
19. How does tree attention verification let the target check a whole drafted tree in one forward pass?Explain
A panel listing seven positions, root, a, b, c, d, e and f, against one target forward pass. A question asks what lets one pass score every branching path correctly.
The six drafted positions and single-pass count come from the lesson's own Tree Attention Verification example; the mechanism is the question.
20. Where does speculative decoding give little or no benefit?Explain
A dial running from low temperature, predictable text, on the left, to high temperature, unpredictable text, on the right. A question asks what happens to speculative decoding's benefit as output gets less predictable.
Temperature's link to predictability is the lesson's own framing; where the benefit disappears is the question.
21. Expected tokens per target forward is (1 - α^(K+1)) / (1 - α). What does it give at α = 0.8 and K = 4?Apply
A formula panel: alpha 0.8 and K 4 plugged into 1 minus alpha to the K+1, over 1 minus alpha, with the result left as a question mark.
The formula is given directly in Expected Speedup; alpha and K come from the stem.
22. Using E[tokens] = (1 - α^(K+1)) / (1 - α), what is the expected tokens per target forward at α = 0.5 and K = 4?Apply
A formula panel: alpha 0.5 and K 4 plugged into 1 minus alpha to the K+1, over 1 minus alpha, with the result left as a question mark.
The formula is given directly in Expected Speedup; alpha and K come from the stem.
23. A team builds a draft by initializing a small model at random and runs it as the draft. Throughput ends up below plain decode. Which ingredient was missing?Analyze
Two boxes: a draft model with weights initialized at random, and a measured result showing throughput below plain decode. A question asks which ingredient from the lesson's draft-training recipe was missing.
Both the random initialization and the below-plain-decode result are given directly in the stem.
24. At temperature 1.5 a team sees α collapse and speculative decoding run slower than plain decode. Why slower rather than merely equal?Analyze
Two boxes: draft and target, both running every round regardless, and a measured result showing speculative decoding slower than plain decode. A question asks why slower rather than merely equal.
The temperature, the alpha collapse, and the slower-than-plain result are all given directly in the stem.
25. You serve a 7B chat model at batch size 256 and decode already keeps the GPU's compute near saturation. A teammate proposes adding EAGLE tree drafting. What should you expect?Analyze
Two boxes: a current setup at batch 256 with compute already near full, and a proposal to add EAGLE tree drafting on top. A question asks what to expect from adding tree drafting here.
The batch size and near-saturated compute are given directly in the stem.
26. You serve a 70B target for single-user code completion at low concurrency. Which setup fits best?Design
Two boxes: a target, a 70B model serving code completion, and a workload, single user at low concurrency. A question asks which setup fits best here.
The target size, workload type, and concurrency are all given directly in the stem.

Build It

main.py runs on synthetic toy distributions so the math stays visible. It needs only numpy. There is no neural network in it and no GPT-2 distillation; the target is a fixed distribution over a small vocabulary, and the draft is that target blended with a uniform distribution.

  • speculative_step(target, draft, K, rng) implements the exact rejection rule. The harness compares the empirical total-variation distance from the target for plain sampling and for speculative sampling, using the first token of each round.
  • measure_alpha measures the acceptance rate of the draft. The alpha flag is only a hint for how make_draft blends, so the measured value comes out different.
  • measure_throughput counts tokens per round at draft length K and prints it next to expected_tokens(alpha, K), the closed form from The Concept.
  • build_tree and tree_attention_mask construct a depth-3 tree with branching (3, 2, 2), and validate_tree_mask checks that every node attends to its ancestors and nothing else. The tree here is topology only. There is no draft model filling it in.

The snippet below is illustrative. It compresses the same idea and adds a temperature argument that main.py does not have.

python
def speculative_step(p_target, q_draft, K, temperature=1.0):
    """One round of speculative decoding. Returns list of accepted tokens."""
    # 1. Draft K tokens
    draft_tokens = []
    q_probs = []
    state = draft_state_init()
    for _ in range(K):
        probs = softmax(q_draft(state) / temperature)
        t = np.random.choice(len(probs), p=probs)
        draft_tokens.append(t)
        q_probs.append(probs[t])
        state = draft_step(state, t)
 
    # 2. Target computes p at every drafted position + 1 extra
    p_probs_all = target_forward_batched(p_target, draft_tokens, temperature)
 
    # 3. Accept/reject left-to-right
    accepted = []
    for k, tok in enumerate(draft_tokens):
        r = np.random.uniform()
        if r < p_probs_all[k][tok] / q_probs[k]:
            accepted.append(tok)
        else:
            residual = np.maximum(p_probs_all[k] - q_probs[k], 0)
            residual /= residual.sum()
            accepted.append(np.random.choice(len(residual), p=residual))
            return accepted
    # 4. All K accepted → sample bonus token from target
    accepted.append(np.random.choice(len(p_probs_all[-1]), p=p_probs_all[-1]))
    return accepted
Check: Build It0/8
1. In `main.py`, `speculative_step` is called with draft equal to target and K = 4. How many tokens does it return?Apply
An excerpt of speculative_step's accept check: ratio equals target over draft at the drafted token, and a uniform draw under the minimum of 1 and that ratio accepts the token. A question asks how many tokens the call returns when draft equals target and K is 4.
Code excerpted from the lesson's main.py; draft equal to target and K=4 are given in the stem.
2. In `main.py`, target = [0.5, 0.3, 0.2] and draft = [0.2, 0.3, 0.5]. Drafted token 2 is rejected. Which token is emitted as the replacement?Apply
Three pairs of p and q bars for token 0, token 1 and token 2, with token 2's pair outlined by a dashed box marking it as the rejected one. A question asks which token is the replacement.
The p and q values are the stem's own three-value target and draft arrays; which token was rejected is given, the replacement is the question.
3. With K = 4, the first drafted token fails the accept test inside `speculative_step`. How many tokens does the call return?Apply
An excerpt of speculative_step's accept/reject branch: on accept it appends the token, on reject it appends a residual sample and returns immediately. A question asks how many tokens the call returns when the first drafted token fails.
Code excerpted from the lesson's main.py; K=4 and a first-token failure are given in the stem.
4. `build_tree((3, 2, 2))` makes a tree with a root and three levels below it. How many entries are 1 in the mask row of a depth-3 leaf?Apply
Four level boxes describing build_tree((3, 2, 2)): a root at depth 0, a depth-1 level with 3 children per node, a depth-2 level with 2 children per node, and a depth-3 leaf level with 2 children per node. A question asks how many mask entries are 1 in one depth-3 leaf's row.
The branching factor (3, 2, 2) is the stem's own call to build_tree; the per-leaf ancestor count is the question.
5. In `main.py`, a drafted token has target probability 0.2 and draft probability 0.5. What is the chance it is accepted?Apply
A pair of bars, p at 0.2 and q at 0.5, for one drafted token x_t. A question asks what the chance is that this token is accepted.
p=0.2 and q=0.5 are the stem's own figures for this one token.
6. In the toy harness you replace the residual draw in `speculative_step` with a sample from `target`, and the distribution check no longer passes. What does that show?Analyze
A code panel showing the real rejection line from main.py, sampling from the normalized residual. A question asks what it shows if that line is replaced by a sample from target and the distribution check then fails.
The real rejection line is from the lesson's main.py; the hypothetical edit is the stem's own proposal.
7. `main.py` runs with `--alpha 0.75` and prints a measured α well above 0.75. What explains this?Analyze
A terminal panel running python main.py with alpha 0.75, printing an alpha measurement header with the measured value left as a question mark.
The --alpha 0.75 flag is given directly in the stem; the measured value is the question.
8. A teammate runs `main.py`, sees measured tokens per verify match the closed form and the tree mask check pass, and promises 3x on their chat product. What is wrong with that conclusion?Analyze
Two boxes, both outlined the same way: tokens per verify matching the closed form, and the tree mask check passing. A question asks what's wrong with promising 3x on a chat product from these two passes.
Both checks passing on the toy harness is given directly in the stem.

Use It

  • vLLM and SGLang ship first-class speculative decoding. Flags: --speculative_model, --num_speculative_tokens. EAGLE-2/3 support comes via the --spec_decoding_algorithm eagle flag.
  • NVIDIA TensorRT-LLM supports Medusa and EAGLE trees natively.
  • Reference draft models: Qwen/Qwen3-0.6B-spec (drafts for Qwen3-32B) and meta-llama/Llama-3.2-1B-Instruct-spec (drafts for 70B).
  • Medusa heads (Cai et al. 2024, "Medusa: Simple LLM Inference Acceleration Framework with Multiple Decoding Heads"): instead of a draft model, add K parallel prediction heads to the target itself. Simpler to deploy, with slightly lower acceptance than EAGLE.
Check: Use It0/3
1. What are Medusa heads?Define
A term card reading Medusa heads, from the Use It section, with a context note: Context: one alternative avoids hosting a separate draft model at all. A question asks: What are Medusa heads?
The term as the lesson names it; its mechanism is the question.
2. You want to serve Qwen3-32B with a draft model in vLLM. Which reference draft does the lesson list for it?Apply
Two boxes: a target, Qwen3-32B, and a draft left as a question mark. A question asks which reference draft the lesson lists for this target.
Qwen3-32B as the target is given in the stem; the reference draft is the question.
3. You must add speculative decoding where hosting a second model is a burden, and slightly lower acceptance is fine. Which approach fits?Design
Two boxes: a constraint that hosting a separate draft model is costly, and a constraint that slightly lower acceptance is fine. A question asks which approach fits both constraints.
Both constraints are given directly in the stem.

Ship It

This lesson produces outputs/skill-speculative-tuning.md, a skill that profiles a target model's workload and chooses the draft model, K (draft length), tree width, and temperature, and decides when to fall back to plain decode.

Check: Ship It0/1
1. A serving skill must decide when to fall back to plain decode. Which rule is best justified?Design
A single wide box: the goal of deciding when speculative decoding stops paying for itself. A question asks which fallback rule is best justified by the lesson.
The fallback decision itself is given directly in the stem, matching the lesson's Ship It section.
Author's Note

I'd run main.py before reading the EAGLE material. It finishes quickly and prints the pieces in order: a distribution check, a measured α, measured against predicted tokens per verify, a sweep over α at K=4, and the tree mask. Watching measured tokens per verify land close to the closed form is what makes the formula feel like arithmetic and not folklore.

Keep in mind what the toy leaves out. Every position draws from the same fixed target distribution, because there is no context and no network. That makes it a test of the accept/reject algebra and nothing else. It says nothing about how well a real draft tracks a real target, which is where α comes from in practice. The alpha flag is a hint to the blending code, and the measured value can come out well above it.

My bet is that the residual distribution (p - q)+ is the part worth sitting with. It looks like a patch for the rejection case, but it is what makes the output follow p, and the distribution check only passes because the replacement token is drawn from it. If you want to see it matter, replace the residual draw with a sample from target in speculative_step and rerun the check.

The tree section is topology only. The depth-3, branch (3, 2, 2) tree has 22 nodes, and the mask check confirms each row attends to exactly its ancestors. Nothing in main.py drafts into that tree or verifies a path through it, so the acceptance gains the EAGLE papers report are not something this code reproduces.

Exercises

  1. Implement the exact rejection rule and check it empirically. Run 10K samples via speculative_step and via plain target sampling; compute TV distance between the two output distributions. The distance should be below 0.01.

  2. Compute the speedup formula. Given fixed α and K, plot expected tokens per target-forward. Find the optimal K for α ∈ {0.5, 0.7, 0.9}.

  3. Train a tiny draft. Take a 124M GPT-2 target and distill a 30M GPT-2 draft on 100M tokens with KL loss. Measure α on held-out text. Expect 0.6-0.7.

  4. Implement EAGLE-style tree drafting. Instead of a chain, have the draft output top-3 branches at each depth. Build the tree attention mask. Verify the target accepts the longest correct branch.

  5. Measure failure modes. Run speculative decode at temperature=1.5 (high stochasticity). Show α collapses and the algorithm is slower than plain decode due to draft overhead.

Key Terms

TermWhat people sayWhat it actually means
Target model"The big model"The slow, high-quality model you want samples from (p distribution)
Draft model"The speculator"The small, fast predictor (q distribution); roughly 10-70x smaller
K / draft length"Look-ahead"Number of speculated tokens per verify pass
α / acceptance rate"Hit rate"Per-token probability that the draft's proposal is accepted
Exact rejection rule"The accept test"r < p/q compare that preserves target's distribution
Residual distribution"Corrected p-q"(p - q)+ /
Tree drafting"Branching speculation"Draft outputs a tree of candidates, verified in one pass with tree-structured attention mask
Tree attention mask"Topological mask"Causal mask encoding the tree topology so each node attends only to its ancestors
Medusa heads"Parallel heads"K extra prediction heads on the target itself; no separate draft model
EAGLE feature reuse"Hidden-state draft"Draft input is target's last hidden state, not raw tokens, shrinking the draft
Test-time simulation loss"EAGLE-3 training"Train draft on outputs matching target's test-time distribution, not teacher forcing

Further Reading

Code

Ships With