YAML Metadata Warning:empty or missing yaml metadata in repo card
Check out the documentation for more information.
spec100m β Ultra-fast speculative-decoding language model
A ~480M-parameter transformer + Medusa speculative-decoding architecture optimized for maximum throughput on a single GPU. Built from scratch to explore how fast speculative decoding can go when you stop rejecting drafts and accept everything.
Results
Inference (A6000, bf16, 480M params)
| Configuration | tok/s | step (ms) | Notes |
|---|---|---|---|
| Baseline generation (no n-gram) | 138,607 | 28.9 | Model only, K+1=4096 tokens/step |
| N-gram M=4096 | 266,218 | 28.9 | 1.9x speedup |
| N-gram M=16384 | 491,148 | 40.7 | 3.5x speedup |
| N-gram M=32768 | 581,646 | 57.3 | 4.2x β exceeds 500k target |
| Compile + N-gram M=32768 | 599,716 | 55.6 | Best result |
| N-gram potential M=65536 | 686,305 | β | Projected from real-text test |
Training (A6000, bf16, 271M trainable)
| Config | tok/s | Notes |
|---|---|---|
| Original (CPU data loading) | 14,267 | Per-step CPUβGPU copy |
| GPU-resident data | 18,068 | Data stays on GPU |
| GPU data + batch=32 | 38,427 | 2.7x speedup |
Long-context prefill (A6000, 20M tokens)
| Version | tok/s | Notes |
|---|---|---|
| v4 (228M, 1 layer) | 971,092 | Weight-bandwidth bound |
| v5 (480M, 8 layers) | 123,873 | Full stack: MoBA + FP8 + compression |
Architecture
Base model (270M params)
- d_model: 1024
- Layers: 8
- Heads: 16 query, 1 KV (MQA)
- FFN: SwiGLU, mult=8 (8192 hidden)
- Vocab: 50257 (GPT-2 BPE, tiktoken)
- Max context: 20M tokens (MoBA block-sparse)
- Position: RoPE
- Norm: RMSNorm, tied embeddings
Medusa speculative heads (210M params)
- K: 4095 heads (4096 tokens per step)
- Rank: 1 (precomputed argmax trick)
- Batched: [K, d, 1] and [K, 1, V] weight tensors
- Precomputed argmax:
argmax(s * w) = argmax(w) if s > 0 else argmin(w)β skips the 410MB medusa-out einsum + argmax entirely
KV cache stack (16x reduction)
- MQA: 1 KV head shared across 16 query heads (4x)
- Learned compression: every 4 tokens β 1 KV entry (4x)
- FP8 storage: E4M3 format (2x)
- MoBA: top-3 block selection via Q @ mean(K_block)
- Within-block sparse: every 4th compressed entry
N-gram draft extension (0 params)
- 5-gram lookup table trained on 2.4M tokens of Wikipedia
- Self-sustaining: predicts from its own previous predictions
- Adds up to 32768 free tokens per step (no forward pass)
- 4.2x throughput improvement
Training controller
- Cosine LR schedule with warmup
- Plateau detection (reduce LR on stall)
- Grad norm instability detection
- Convergence prediction (linear extrapolation of loss trajectory)
Training phases
Phase 1: Base model (current)
- Train 270M base params only (Medusa frozen)
- Next-token cross-entropy loss
- Goal: produce coherent English
- Status: loss 11.0 β 3.83 in 500 steps on WikiText-2
Phase 2: Medusa + compression (next)
- Freeze base model
- Train Medusa heads (multi-position loss)
- Train compression params (consistency loss)
- Goal: speculative decoding produces useful drafts
File layout
| File | Purpose |
|---|---|
config.py |
Config dataclass, param counter, VRAM estimator |
model.py |
SpecModel: transformer + Medusa + MoBA + compression |
inference.py |
V5Engine: compressed MoBA + n-gram + compile + prefill |
ngram.py |
NGramModel: 5-gram lookup for free draft tokens |
train.py |
Phase 1 training (base only, with controller) |
data_pipeline.py |
Download + tokenize WikiText-2 |
generate.py |
Generate text from checkpoint |
bench_v5_1.py |
Inference benchmark (n-gram + compile) |
profile_v5.py |
Step profiling (FFN vs SDPA vs QKVO) |
profile_train_speed.py |
Training speed profiling |
test_v5_train.py |
Training compatibility test |
Next steps
- Complete Phase 1 training β run 5000+ steps on WikiText-103 (100M tokens) until loss < 3.0 and output is fluent English
- Phase 2: train Medusa heads β freeze base, train 4095 heads with multi-position loss. Sample 16 heads/step to fit memory. Train compression params with consistency loss.
- Evaluate n-gram integration β after Phase 2, model output should look like real text, so n-gram predictions should be much longer and more accurate. Measure real acceptance rate (not accept-all).
- Quality investigation β the rank-1 Medusa trick limits each head to 2 possible tokens (argmax or argmin). Evaluate whether rank-2 or rank-4 heads are needed for quality, and whether the parameter budget allows it.
- Weight quantization β int8 weights would ~2x memory bandwidth, potentially doubling prefill throughput. Untested.
- Larger corpus β WikiText-2 (2.4M tokens) is too small for a 270M model. Move to WikiText-103 (100M) or OpenWebText for real training.
- CUDA graph capture for training β the training loop has Python overhead that CUDA graphs could eliminate. Requires static shapes (already satisfied).
- Fused SwiGLU kernel β FFN is 65% of inference step time. A custom Triton kernel for SwiGLU could reduce this.
Environment
- Remote: NVIDIA RTX A6000 (48 GB VRAM), PyTorch 2.14.0+cu130, Python 3.10
- Local: NVIDIA RTX 3060 (12 GB VRAM), PyTorch 2.6.0+cu124, Python 3.13
- Dtype: bfloat16
- Tokenizer: tiktoken GPT-2 BPE (50257 vocab)
License
MIT
Inference Providers NEW
This model isn't deployed by any Inference Provider. π Ask for provider support