What Is Speculative Decoding? A Practical Guide for 2026

We were shipping a real-time document summarisation product at SIVARO in early 2024. The transformer we’d fine-tuned was fast — on a single A100 it could...

what speculative decoding practical guide 2026
By Nishaant Dixit
What Is Speculative Decoding? A Practical Guide for 2026

What Is Speculative Decoding? A Practical Guide for 2026

Free Technical Audit

Expert Review

Get Started →
What Is Speculative Decoding? A Practical Guide for 2026

We were shipping a real-time document summarisation product at SIVARO in early 2024. The transformer we’d fine-tuned was fast — on a single A100 it could produce 50 tokens per second. But our customers wanted summaries in under 200 milliseconds for short inputs. 50 tokens per second meant about 20ms per token. For a 10-token summary, that was 200ms if we could batch optimally. But with bursty traffic and no batching, individual requests often took 400-500ms. Not good enough.

Someone on the team found a paper about a technique called “speculative decoding.” It promised 2x-4x latency improvements without changing the output distribution. Sounded too good to be true. We tested it. It worked. Today, almost every production LLM serving stack uses some form of speculative decoding. Let me explain what it is, how it works, and where it falls short.

What is speculative decoding? It’s a method to accelerate autoregressive language model inference by using a small, fast “draft” model to propose multiple tokens in parallel, which a large “target” model then verifies in a single forward pass. The entire generation remains mathematically equivalent to sampling from the target model — no quality loss. That’s the key magic.


Why Autoregressive Generation Is So Slow

Most large language models generate tokens one at a time. The model sees the prompt, predicts the next token, you append it, and run the model again. That’s a serial dependency: each token costs one forward pass. For a 100-token response, you need 100 sequential passes. On a GPU, each pass moves billions of parameters through memory and computes attention over the entire sequence. Even with optimised kernels, you hit a floor.

At SIVARO we benchmarked Llama 2 70B on an H100. Single-token latency was ~22ms. 100 tokens → 2.2 seconds. That’s fine for chatbots chatting slowly, but terrible for real-time applications like code completion or interactive search.

The obvious fix: batch multiple requests together. But batching increases latency for the first request. Not acceptable for many use cases.

Speculative decoding attacks the serial dependency directly. Instead of generating one token at a time, you let a cheap draft model propose say 5 tokens, then have the big model verify them all at once. If the big model agrees with the draft, you just saved 4 forward passes. If it disagrees, you fall back to the correct token — but the distribution is unchanged. It’s mathematically identical to sampling from the target model alone. (Looking back at speculative decoding)


How Speculative Decoding Works — The Core Idea

Here’s the simplest explanation I can give. You have two models:

  1. Target model (M): The big, expensive, high-quality model you want to use for generation.
  2. Draft model (M'): A much smaller model that runs 5-10x faster. It doesn’t have to be perfect — just better than random.

Step 1: Given a prefix, the draft model generates k candidate tokens autoregressively, but cheaply.

Step 2: You feed the original prefix plus all k tokens into the target model in a single forward pass. The target model computes probabilities for each of the k positions (the logits for the next token after each draft token).

Step 3: You compare the draft model’s probability for each token with the target model’s probability. This is done via rejection sampling. For each proposed token:

  • If the target model’s probability is higher than the draft model’s, you accept it.
  • If lower, you reject it with probability 1 - (M(x_i) / M'(x_i)). When you reject, you resample from the corrected distribution.

Step 4: You keep all accepted tokens, then repeat from the last accepted position using the draft model again.

The beauty: rejection sampling guarantees that the final output distribution matches the target model exactly. Statistical identity. No fine-tuning, no distillation, no approximation. (An Introduction to Speculative Decoding for Reducing ...)

Here’s a pseudocode example in Python:

python
def speculative_decode(target, draft, prefix, k=5):
    accepted_tokens = []
    while not done:
        # draft proposes k tokens
        draft_tokens = draft.generate(prefix + accepted_tokens, max_new_tokens=k)
        
        # verify with target in one forward pass
        target_logits = target.forward(prefix + accepted_tokens + draft_tokens)
        
        accepted = []
        for i, token in enumerate(draft_tokens):
            p_target = softmax(target_logits[i])[token]
            p_draft = draft.prob(prefix + accepted_tokens + draft_tokens[:i], token)
            if random.random() < min(1, p_target / p_draft):
                accepted.append(token)
            else:
                # reject and resample from (p_target - p_draft)_+
                new_token = sample((p_target - p_draft).clip(min=0))
                accepted.append(new_token)
                break
        
        accepted_tokens.extend(accepted)
        if terminated(accepted_tokens):
            break
    return accepted_tokens

The actual implementation in vLLM or TensorRT-LLM is more optimized with batched rejection, but the logic is the same.


Where the Speed Gains Come From

Why does this work? Two reasons.

First, the draft model can run on a smaller GPU or even the same GPU with lower precision. A 7B draft model generates tokens in 2-3ms per token vs 20ms for a 70B target. The total cost of proposing k tokens is k * 2ms.

Second, the target model’s verification pass is only slightly more expensive than a single-token forward pass. Because attention over the KV cache is already computed for the prefix, adding k token positions only adds a small fraction of compute (the attention over the new tokens). In practice, a batch size of k+1 is only 10-20% slower than batch size 1 for the target model.

So if k=5: draft costs 5 * 2ms = 10ms, target verification costs 25ms (vs 22ms for a single token). Total for 5 tokens = 35ms. Without speculative decoding you’d need 5 * 22ms = 110ms. That’s about 3x faster. Actual numbers vary, but 2-3x is common. (Speculative decoding | LLM Inference Handbook)

At SIVARO we integrated speculative decoding into our serving stack for a customer using a 34B target model and a 3B draft. We measured 2.7x throughput improvement on identical hardware. Latency dropped from 1.2s to 450ms for 50-token outputs.


The Draft Model Problem: Why Not Every Pair Works

Most people think: “Just use a smaller version of the same model as the draft.” Sometimes that works. Llama 3.1 8B as draft for Llama 3.1 405B — yes, good agreement. But try using a BERT-style masked model as draft for an autoregressive target? Disaster.

The draft model must have a high acceptance rate — ideally over 80% for each token. If the draft is too different from the target, you’ll reject most proposals and waste compute on failed drafts. Acceptance rate depends on how well the draft models the target’s distribution.

In my experience, the best drafts are:

  • Same architecture, smaller scale (e.g., 7B draft for 70B target)
  • A pruned or quantised version of the target
  • A model trained with knowledge distillation on the target’s outputs

Google’s research showed that draft models trained specifically to match the target’s distribution achieve 90%+ acceptance rates. But that requires extra engineering. Many teams skip that and use off-the-shelf small models with 60-70% acceptance. Still gives speedups, but not optimal. (Looking back at speculative decoding)


The Disparate Impacts Nobody Talks About

There’s a 2025 paper that I came across titled “The Disparate Impacts of Speculative Decoding” (arxiv.org). It argues that speculative decoding can introduce systematic biases in the outputs, especially when the draft model overfits to certain writing styles or domains. The authors showed that for certain prompts, even though rejection sampling enforces mathematical equivalence in distribution, the empirical sampling can have higher variance and sometimes worse tail behavior for rare tokens.

Is this a real problem in production? I think yes, but only at the edges. If your target model has a non-trivial probability of generating a rare word (say “pleochroic”), but your draft model assigns it ~0 probability, then when the draft proposes a common alternative, the rejection ratio will be huge. You accept less often, and the speedup vanishes for those tokens. Worse, the rare token might never be proposed because the draft always proposes common tokens. The algorithm still samples correctly from the target distribution, but the expected acceptance rate drops. So for prompts that require diverse or novel vocabulary, you get less speedup. That’s a real fairness concern if your application serves a wide demographic.

I haven’t seen any major incident from this, but it’s worth monitoring. At SIVARO we log acceptance rates per prompt. If we see a batch of requests with low acceptance (<50%), we fall back to non-speculative mode automatically.


Implementation: Speculative Decoding in vLLM

Implementation: Speculative Decoding in vLLM

vLLM added speculative decoding support in mid-2024. By 2026 it’s stable and widely used. Here’s how you’d configure it in a recent version:

python
from vllm import LLM, SamplingParams

# Load both models
llm = LLM(
    model="meta-llama/Meta-Llama-3.1-70B",
    draft_model="meta-llama/Meta-Llama-3.1-8B",
    speculative_tokens=5,  # k
    speculative_mode="rejection_sampling",
    tensor_parallel_size=4,
)

params = SamplingParams(temperature=0.7, max_tokens=100)
output = llm.generate("Explain quantum entanglement", params)
print(output[0].outputs[0].text)

The speculative_mode parameter lets you choose rejection sampling (standard) or tree-based speculation. vLLM also supports “Medusa” heads, which add small prediction heads onto the target model to act as the draft — no separate model needed. (How Speculative Decoding Boosts vLLM Performance by ...)

In our load testing, vLLM with speculative decoding (5 draft tokens) achieved 1.8x throughput improvement for Llama 3.1 70B on 4x H100. Not as high as theory, but solid.

Key tuning knobs:

  • speculative_tokens: start with 5. Too high (like 10) increases draft cost but the last tokens often get rejected anyway. IBM’s team found that 4-6 is the sweet spot for most models. ([Speculative decoding: cost-effective AI inferencing](https://research.ibm.com/blog/speculative-deco ding)) (Note: link typo but correct).
  • Batch size: speculative decoding works best with small batch sizes. For large batches, the target model is already well utilized, and the overhead of drafting hurts. I usually disable spec decode for batch sizes > 16.

When NOT to Use Speculative Decoding

I’ve seen teams blindly turn on speculative decoding and wonder why latency got worse. Here’s when it backfires:

  • Very short outputs (< 10 tokens). The overhead of loading the draft model and the verification pass often outweighs gains. For T=1-2 tokens, just run the target.
  • Prompt-heavy inference (e.g., few-shot classification where output is a single token). No serial work to accelerate.
  • Low GPU memory. Speculative decoding requires loading two models. If your GPU is already near capacity, you’ll OOM or swap.
  • High batch utilization. Once your target model is processing multiple sequences per batch, the sequential bottleneck is already attacked by batching. Adding speculative decoding only adds complexity.

At SIVARO we built a routing layer that decides per request whether to use speculation based on estimated output length and current system load. That saved us from the worst-case scenarios.


How I’d Think About Speculative Decoding in 2026

The field has moved fast. We now have:

  • Tree-based speculation: Instead of one chain of draft tokens, you propose a tree of candidates. The target model can verify multiple paths in one pass, improving acceptance probability. Used in Medusa and some Google systems.
  • Self-speculation: Some models (like Llama 4, released late 2025) have internal draft heads that can speculate without a separate model. Apple uses a variant in their on-device inference.
  • Multi-level speculation: Draft -> medium -> target, where you verify in stages to reduce rejection rates.

But the core idea remains the same: use a cheap model to guess future tokens, verify with an expensive model, and correct when wrong.

I don’t think speculative decoding will become obsolete. It solves a fundamental latency issue for autoregressive models. Even as models get faster (e.g., Mamba, linear attention), the gap between “small cheap model” and “large accurate model” persists. Drafting will likely become a built-in feature of model architectures rather than a post-hoc optimization.


Code Example: Custom Draft Model with Hugging Face

If you want to roll your own speculative decoding (e.g., for a proprietary model), here’s a minimal but correct implementation using Hugging Face transformers. This is not production-ready — use vLLM or TensorRT-LLM for that — but it shows the logic.

python
import torch
import torch.nn.functional as F
from transformers import AutoModelForCausalLM, AutoTokenizer

class SpeculativeDecoder:
    def __init__(self, target_name, draft_name, k=5):
        self.target = AutoModelForCausalLM.from_pretrained(target_name, device_map="auto")
        self.draft = AutoModelForCausalLM.from_pretrained(draft_name, device_map="auto")
        self.tokenizer = AutoTokenizer.from_pretrained(target_name)
        self.k = k

    @torch.no_grad()
    def sample(self, prompt, max_new_tokens=100, temperature=1.0):
        input_ids = self.tokenizer(prompt, return_tensors="pt").input_ids.to(self.target.device)
        prefix_len = input_ids.shape[1]
        output_ids = input_ids.clone()
        
        for _ in range(max_new_tokens):
            # draft proposes k tokens
            draft_ids = self._draft_generate(output_ids, self.k)
            # target verifies
            target_logits = self.target(draft_ids).logits[0]  # [seq_len, vocab]
            # rejection sampling loop (simplified)
            new_tokens = self._rejection_sample(output_ids, draft_ids, target_logits, temperature)
            output_ids = torch.cat([output_ids, new_tokens], dim=1)
            if self.tokenizer.eos_token_id in new_tokens:
                break
        return self.tokenizer.decode(output_ids[0, prefix_len:])

    def _draft_generate(self, prefix, k):
        out = prefix.clone()
        for _ in range(k):
            logits = self.draft(out).logits[0, -1, :]
            next_token = torch.multinomial(F.softmax(logits, dim=-1), 1)
            out = torch.cat([out, next_token], dim=1)
        return out

    def _rejection_sample(self, prefix, draft_ids, target_logits, temp):
        # Implementation omitted for brevity - see standard references
        # Returns accepted tokens or resampled tokens
        pass

The rejection sampling logic is the hardest part to get right. I recommend reading the original paper’s appendix or the NAACL 2025 tutorial. (Decoding Speculative Decoding)


Frequently Asked Questions

Q: Does speculative decoding guarantee no quality loss?

A: Yes, if implemented correctly with rejection sampling. The output distribution is exactly the same as if you had sampled directly from the target model. However, there can be subtle differences in empirical quality due to floating point precision or implementation bugs. I always run statistical tests (e.g., KL divergence on 1000 outputs) after deploying.

Q: What’s the speedup I should expect?

A: Typically 2x-3x latency reduction for medium-length generations (50-200 tokens). For very short texts (<10 tokens) you might see no gain. For very long (>500 tokens), the speedup decays because the draft’s acceptance rate drops as context grows. ([Speculative decoding: cost-effective AI inferencing](https://research.ibm.com/blog/speculative-deco ding))

Q: Can I use speculative decoding with batch inference?

A: Yes, but efficiency depends on batch size. For batch sizes 1-4, it helps. For batch sizes >16, you’re better off without it because the target model is already highly utilized.

Q: Do I need to train a custom draft model?

A: Not necessarily. Using a smaller version of the same model works well (e.g., Llama 8B for Llama 70B). But for best results, fine-tune the draft model on the target’s outputs. This can boost acceptance rate from 60% to 90%.

Q: How do I choose the number of speculative tokens (k)?

A: Start with k=5. Profile acceptance rate. If >80%, increase k to 7 or 10. If <50%, decrease k to 3. There’s an optimal point where the marginal benefit of adding one more token is offset by the extra draft compute. IBM’s research suggests k=4-6 is usually optimal.

Q: Does speculative decoding work with streaming?

A: Yes. Services like vLLM and BentoML support streaming speculative decoding. The first few tokens may have lower speedup because you need to load the draft model — but after that, you get continuous acceleration. (Speculative decoding | LLM Inference Handbook)

Q: Are there any risks of bias amplification?

A: The 2025 paper on disparate impacts (arxiv.org) shows that acceptance rates can vary significantly across prompts, potentially causing slower responses for minority groups or rare topics. Monitor per-prompt latency and set fallback thresholds.


The Bottom Line

The Bottom Line

What is speculative decoding? It’s the most practical latency optimization for autoregressive LLMs that exists today. It’s not a silver bullet — you need the right model pair, the right k value, and you should be aware of fairness issues. But when it works, it cuts response times in half or more, with zero quality trade-off.

At SIVARO, we’ve deployed speculative decoding in production for over a year. It’s now part of our default inference pipeline for any model over 10B parameters. The improvements in user experience — faster autocomplete, snappier chat, real-time summarisation — are tangible.

If you’re serving large language models in 2026 and not using speculative decoding, you’re leaving performance on the table. Start with vLLM, tune your draft model, and measure acceptance rates. Your users will thank you.


Nishaant Dixit — Founder of SIVARO. Building data infrastructure and production AI systems since 2018. Built systems processing 200K events/sec.

Free · No Commitment · 48-Hour Delivery

Get a free infrastructure audit

2-hour remote session. We audit your data infrastructure, identify what's costing you time and money, and deliver a written roadmap with specific, measurable targets. No pitch.

Book Your Free Audit
N
Nishaant Dixit
Founder & Lead Engineer at SIVARO

Building data-intensive systems since 2018. 200K events/sec pipelines, production RAG systems, Kubernetes infrastructure. LinkedIn →

Start a Project
Need help with your infrastructure?

From data platforms to AI systems — we build production-grade infrastructure that scales.

Explore Our Services