Navigation
⚡ Inference Systems· 10 min read

Practical Integration

vLLM and SGLang configuration, measuring acceptance rate, benchmarking speculative decoding, and tuning for your workload.

speculative-decodingvllmsglangbenchmarkconfigurationtuning

This chapter provides the practical steps: configure speculative decoding in vLLM/SGLang, measure acceptance rate, benchmark against baseline, and tune for your specific workload.


1. vLLM Configuration

Separate Draft Model

vllm serve meta-llama/Llama-3.1-70B-Instruct \
    --tensor-parallel-size 4 \
    --speculative-model meta-llama/Llama-3.1-8B-Instruct \
    --num-speculative-tokens 5 \
    --speculative-draft-tensor-parallel-size 1

N-gram Speculation

vllm serve meta-llama/Llama-3.1-70B-Instruct \
    --tensor-parallel-size 4 \
    --speculative-model [ngram] \
    --num-speculative-tokens 5 \
    --ngram-prompt-lookup-max 4 \
    --ngram-prompt-lookup-min 2

EAGLE

# Requires matching EAGLE checkpoint
vllm serve meta-llama/Llama-3.1-70B-Instruct \
    --tensor-parallel-size 4 \
    --speculative-model /path/to/eagle-llama-70b \
    --speculative-model-quantization fp8 \
    --num-speculative-tokens 5

Key Parameters

ParameterDefaultTuning guidance
--num-speculative-tokens5Start at 3-5; increase only if acceptance rate > 0.8
--speculative-draft-tensor-parallel-size1Keep at 1 unless draft model is large
--spec-decoding-acceptance-methodrejection_samplerUse typical_acceptance_sampler for slightly faster but approximate

2. Measuring Acceptance Rate

Per-Request Metrics

# vLLM returns acceptance rate in metrics
import requests

response = requests.post("http://localhost:8000/v1/completions", json={
    "model": "meta-llama/Llama-3.1-70B-Instruct",
    "prompt": "Write a Python function to sort a list",
    "max_tokens": 200,
    "temperature": 0.0,
})

# Check vLLM metrics endpoint
metrics = requests.get("http://localhost:8000/metrics").text
# Look for: vllm:spec_decode_draft_acceptance_rate

Prometheus Metrics

# Key speculative decoding metrics in vLLM:
vllm:spec_decode_draft_acceptance_rate          # average acceptance rate
vllm:spec_decode_num_accepted_tokens_total      # total accepted
vllm:spec_decode_num_draft_tokens_total         # total drafted
vllm:spec_decode_num_emitted_tokens_total       # total emitted (accepted + bonus)

Target: acceptance rate > 0.7 for speculation to be worthwhile.


3. Benchmarking: Baseline vs Speculative

Step 1: Establish Baseline

# Baseline (no speculation)
python -m vllm.entrypoints.openai.api_server \
    --model meta-llama/Llama-3.1-70B-Instruct \
    --tensor-parallel-size 4

# Benchmark
python benchmark_serving.py \
    --model meta-llama/Llama-3.1-70B-Instruct \
    --dataset-name sharegpt \
    --request-rate 1 \
    --num-prompts 200
# Record: TTFT, TPOT, throughput

Step 2: Run with Speculation

# Same model, add speculation
python -m vllm.entrypoints.openai.api_server \
    --model meta-llama/Llama-3.1-70B-Instruct \
    --tensor-parallel-size 4 \
    --speculative-model meta-llama/Llama-3.1-8B-Instruct \
    --num-speculative-tokens 5

# Same benchmark
python benchmark_serving.py \
    --model meta-llama/Llama-3.1-70B-Instruct \
    --dataset-name sharegpt \
    --request-rate 1 \
    --num-prompts 200
# Compare: TTFT, TPOT, throughput

Step 3: Compare at Different Load Levels

# Test at increasing request rates
for rate in 1 2 4 8 16 32; do
    python benchmark_serving.py \
        --request-rate $rate \
        --num-prompts 200
done
# Plot: throughput vs TPOT at each rate, baseline vs speculative

4. What to Look For

MetricBaselineWith speculationWhat it means
TPOT (low load)40 ms18 ms✅ 2.2× speedup — speculation working
TPOT (high load)15 ms17 ms❌ No benefit — batching already efficient
TTFT500 ms600 ms⚠️ Slightly worse — draft adds to first step
Throughput (low load)25 tok/s55 tok/s✅ 2.2× throughput gain
Throughput (high load)800 tok/s780 tok/s❌ Slight regression — overhead at saturation
Acceptance rate—0.78Good (> 0.7 threshold)

Decision

  • Low-load latency-sensitive: Speculation helps significantly (2-3× TPOT reduction)
  • High-load throughput-focused: Speculation doesn’t help (batching already efficient)
  • Mixed workload: Evaluate at your actual request rate distribution

5. Tuning Guide

If you see…Try…
Acceptance rate < 0.6Better draft model (closer to target)
Acceptance rate > 0.9Increase num-speculative-tokens
TTFT regressionReduce num-speculative-tokens or use n-gram (no extra TTFT)
Throughput worse at high loadDisable speculation at high concurrency (adaptive)
Memory pressure from draftUse EAGLE/Medusa (no separate model memory) or smaller draft
Code tasks: high acceptanceN-gram works great, no draft model needed
Creative tasks: low acceptanceConsider disabling speculation

Quality Verification

Speculative decoding with proper rejection sampling is mathematically lossless. But verify:

# Generate same prompts with and without speculation
# Compare: exact match for greedy (temperature=0)
# Compare: distribution similarity for sampling (temperature>0)

For the theoretical foundations, see Core Idea: Draft & Verify. For understanding the speedup formula, see Acceptance Rate & Speedup Bounds.


Self-Check

  • Configure vLLM with a separate draft model, n-gram, and EAGLE
  • Measure acceptance rate from vLLM metrics
  • Benchmark speculative decoding against baseline at multiple load levels
  • Interpret results: when does speculation help vs hurt
  • Apply the tuning guide for a given acceptance rate and workload
  • Verify quality: compare outputs with and without speculation

References