Author: João Felipe De Souza
Real implementation of speculative decoding with prompt-dependent speedup analysis.
This project compares two draft→target configurations:
- GPT-2 → GPT-2-medium
- GPT-2 → GPT-2-large
and measures when speculative decoding actually beats baseline target-only decode.
For architecture and methodology, see DESIGN.md.
Speculative decoding is often described as a universal inference optimization:
- a small draft model proposes
Ktokens - a larger target model verifies them in parallel
- accepted tokens are committed
- generation continues
In practice, whether this is faster depends on:
- how expensive the target model is
- how often draft and target agree
- how large
Kis - runtime and cache-management overhead
- prompt structure
This project measures all of that directly.
| Role | Model |
|---|---|
| Draft | GPT-2 (117M) |
| Target A | GPT-2-medium (345M) |
| Target B | GPT-2-large (774M) |
| Spec | Value |
|---|---|
| GPU | NVIDIA RTX 2070 |
| VRAM | 8.6 GB |
| CUDA | 13.0 |
- 12 prompt types
K = 1, 2, 4, 8, 16- output length: 128 tokens
- baseline target-only decode for each prompt
| Config | Mean best speedup | Prompts with speedup > 1× | Best overall speedup |
|---|---|---|---|
| GPT-2 → GPT-2-medium | 1.013× | 6 / 12 | 1.495× |
| GPT-2 → GPT-2-large | 1.253× | 8 / 12 | 1.846× |
A more expensive target model gives speculative verification more room to amortize draft cost.
| Prompt | Best K | Acceptance | Speedup |
|---|---|---|---|
| dialogue | 16 | 0.896 | 1.846× |
| repetitive | 16 | 1.000 | 1.669× |
| wikipedia_style | 16 | 0.821 | 1.644× |
| list_items | 16 | 0.702 | 1.487× |
| repetitive_pattern | 8 | 0.855 | 1.449× |
| code | 8 | 0.724 | 1.217× |
| code_python | 8 | 0.507 | 1.068× |
| creative_fiction | 8 | 0.615 | 1.086× |
| natural | 4 | 0.714 | 0.950× |
| technical | 4 | 0.671 | 0.903× |
| code_json | 4 | 0.655 | 0.855× |
| technical_ml | 8 | 0.455 | 0.857× |
Structured, repetitive, and high-agreement prompts benefit most.
Prompts with strong speedup often have high acceptance:
- repetitive: 1.000
- dialogue: 0.896
- wikipedia_style: 0.821
But acceptance alone does not guarantee speedup:
- natural: 0.714 acceptance, still 0.950×
- technical: 0.671 acceptance, still 0.903×
This means the speedup condition is not just “high acceptance”, but:
high enough acceptance to overcome draft-model and runtime overhead
For successful prompts, large K usually wins:
K=16dominates for repetitive / dialogue / wikipedia / list_itemsK=8dominates for code / repetitive_pattern / code_python / creative_fiction
For weaker prompts, large K often hurts because acceptance decays too fast.
Even in the stronger small -> large setup, some prompts still fail to beat baseline:
- natural
- technical
- code_json
- technical_ml
This confirms that speculative decoding is a conditional systems optimization, not a guaranteed speedup.
Speculative decoding works best when:
- the target model is much more expensive than the draft model
- draft-target agreement remains high over long draft horizons
- prompt structure is predictable enough to maintain acceptance
On RTX 2070:
- GPT-2 → GPT-2-medium gives only marginal average benefit
- GPT-2 → GPT-2-large gives strong benefit on many prompts
- best-case speedup reaches 1.846×
This makes speculative decoding a prompt-sensitive and model-gap-sensitive inference optimization.
| File | Description |
|---|---|
| results/speculative_decoding_results.csv | Original 4-prompt sweep |
| results/extended_sweep_results.csv | Extended 8-prompt sweep |
| results/combined_results.csv | Combined dataset |
| results/optimized_sweep_results.csv | Final optimized 2-config sweep |
| results/best_k_by_prompt.csv | Original best K summary |
| results/best_k_summary.csv | Combined best K summary |
| results/metadata.json | Original metadata |
| results/extended_metadata.json | Extended metadata |
| File | Description |
|---|---|
| plots/speedup_vs_k.png | Original speedup vs K |
| plots/acceptance_vs_k.png | Original acceptance vs K |
| plots/throughput_vs_k_by_prompt.png | Original throughput curves |
| plots/acceptance_vs_speedup.png | Original acceptance/speedup scatter |
| plots/speedup_vs_k_all.png | Combined speedup vs K |
| plots/acceptance_vs_speedup_all.png | Combined acceptance vs speedup |
| plots/best_speedup_per_prompt.png | Best speedup per prompt |
| plots/throughput_by_category.png | Throughput by prompt category |
speculative-decoding-impl/
├── speculative_decoding.py
├── extended_sweep.py
├── optimized_sweep.py
├── plot_speculative.py
├── plot_final.py
├── README.md
├── DESIGN.md
├── LICENSE
├── requirements.txt
├── results/
└── plots/
python3 -m venv venv && source venv/bin/activate
pip install -r requirements.txt
python3 speculative_decoding.py
python3 extended_sweep.py
python3 optimized_sweep.py
python3 plot_speculative.py
python3 plot_final.py
- Single-request batch size only
- Python implementation, not fused kernels
- Consumer GPU only (RTX 2070)
- GPT-2 family only
- Prompt set is illustrative, not exhaustive
- Leviathan et al., Fast Inference from Transformers via Speculative Decoding (2023)
- Chen et al., Accelerating Large Language Model Decoding with Speculative Sampling (2023)