Guide: Multi-Token Prediction (MTP)

The free speed boost hiding inside some model files: how built-in MTP heads draft tokens that the main model verifies in one pass, what the one flag that unlocks it is, and the community-mapped rules for getting the most out of it on your card.

one flag, no new files +33% to +145% reported llama.cpp draft-mtp

What MTP is

Standard generation reads the model weights once per token — bandwidth-bound, per the inference basics. Multi-token prediction works around that: the model ships with auxiliary prediction heads that are trained (by the MTP objective) to predict upcoming tokens. At inference:

  1. Draft — the MTP head proposes the next 1–N candidate tokens from the backbone's hidden state.
  2. Verify — the main backbone runs one forward pass that produces logits for all draft positions in parallel.
  3. Accept or reject — drafts that match the main model's distribution are committed for free; the first mismatch falls back to normal sampling from the verified logits.

Because verification is exact (rejection sampling preserves the model's output distribution), there is no quality trade-off — MTP is pure throughput. One weight read yields multiple committed tokens instead of exactly one. That trades idle compute — which bandwidth-bound generation leaves sitting around — against fewer full forward passes.

Which models have MTP

MTP only works when the checkpoint carries the MTP heads. As of writing:

Classic models (Llama, Mistral, older Qwens) have no MTP heads — the flag does nothing for them. When a card page on this site shows an "MTP est." column, it's describing MTP-capable models; your Llama-3.1-8B won't see any of those numbers.

The flag

Unlock MTP in llama.cpp llama-server -m qwen3.8-27b-q4_k_m.gguf -ngl 99 -c 131072 -fa 1 \
--cache-type-k q4_0 --cache-type-v q4_0 \
--spec-type draft-mtp --spec-draft-n-max 2 --parallel 1

llama.cpp's MTP support is young and improving fast — a current build alone was worth +10–15% in some community A/B tests before any flag was touched. Rebuild before you tune.

What to expect: reported numbers

The community A/B record behind these numbers (Qwen3.8-27B, probe.py streaming client, median of 3×3 runs, both arms at --parallel 1) spans 50+ configs from 2016 Pascal to desktop Blackwell, plus AMD, Apple Silicon and APUs. The shape of the data:

HardwareBaselineWith MTPGainn-max
RTX 3090 24 GB31.0 t/s41.3 t/s+33%2
RTX 3090 24 GB (newer build)41.3 t/s63.5 t/s+54%2
RTX 3090 Ti 24 GB42.0 t/s60.9 t/s+45%2
RTX 4090 24 GB47.7 t/s76.3 t/s+60%2
2× RTX 3090 + 3090 Ti (tensor)49.1 t/s81.1 t/s+65%2
3× RTX 3060 12 GB (layer split)17.3 t/s24.5 t/s+42%8
2× RTX 5060 Ti 16 GB (tensor)37.1 t/s65.9 t/s+78%2
RTX 5090 32 GB61.4 t/s135.0 t/s+119%4
RTX 5090 32 GB (UD-Q4_K_XL, 262K ctx)74.3 t/s179.7 t/s+142%4
2× Tesla P40 24 GB (2016)11.7 t/s22.6 t/s+93%4
Apple M4 base (24 GB)~5.8 t/s~5.8 t/s±0%2

The pattern matches the site's core thesis: bandwidth-starved cards get large % gains at n-max 2 (the drafter turns idle cycles into tokens), while the highest-bandwidth cards need deeper drafts (n-max 4–7) to squeeze the biggest absolute jumps out of their compute headroom. And on genuinely bandwidth-limited metal (base M4, low-clock iGPUs) the gain can vanish — the verify pass has no free lunch to take. Deltas are the durable part; absolute numbers move with builds, drivers and thermals.

The seven community rules

Mapped by 40 contributors in the first week after Qwen3.8 shipped. In order of how often they bite:

  1. n-max is card- and topology-dependent. 24 GB-class cards peak at 2; bigger or faster cards at 3–4 (some 5090s at 6–7). Changing anything — split mode, quant, context — moves the optimum, so re-sweep after any config change.
  2. The confidence gate helps starved cards and hurts fast ones. --spec-draft-p-min 0.60 made deep drafting nearly free on bandwidth-poor rigs; on desktop Blackwell it lowered throughput while raising acceptance. Acceptance is a vanity metric — sweep the gate, keep whichever is faster.
  3. The gain scales with generation length. Short answers can cost more than they earn; on already-bandwidth-bound rigs the full gain shows by ~400 tokens and length adds little beyond that.
  4. On multi-GPU boxes, fix the split mode before touching spec flags. Default --split-mode layer serializes decode; tensor was +68% on its own on one 5060 Ti pair, and the two levers stack (3.14× combined).
  5. Speculation is single-stream. The advantage is gone by --parallel 4. And a --parallel 2 baseline reads ~20% low, inflating your gain claim — always A/B at --parallel 1.
  6. Rebuild llama.cpp, and re-derive flags per card class. Upstream optimizes this path weekly (one contributor's fresh-build baseline equaled the day-one with-flag number). A config that pays on a bandwidth-starved APU inverted below baseline on a 960 GB/s card.
  7. A shared desktop halves everything, silently. A live compositor + browser spilled 3.5 GB of weights to host RAM over PCIe while /health stayed green and decode simply halved. Bench headless, or verify the weights are resident before trusting a number.

Costs and caveats

Measure it yourself

The whole method is two server runs:

A/B in ten minutes 1. Serve your model, --parallel 1, thinking off, nothing else special.
2. Stream a generation (any chat client or the repo's probe.py) — record t/s.
3. Restart with --spec-type draft-mtp --spec-draft-n-max 2 added, nothing else changed. Record t/s again.
4. Sweep n-max 2–4 (5–6 on big cards) and keep the fastest. Watch draft acceptance in the server log as a sanity check, not a goal.

The card pages on this site list an "MTP est." column in their performance tables. Treat those as priors to confirm with your own A/B — model, quant, context, llama.cpp build and card all move the number.

← VRAM & quantization next: n-gram embedding →