Released this week
2026.05.06 · 9 min read
Gemma 4 · On Edge · MTP Explained

Gemma 4 on edge: Multi-Token Prediction unlocks 2× decode speedup — in one specific runtime.

Google released MTP drafters for Gemma 4 on May 5. The technique was already a known win on datacenter GPUs and Android phones; the open question for Gemma 4 on edge was whether it would land at batch=1 on Apple Silicon — the workload shape that defines every on-device LLM that runs on a laptop. A controlled benchmark across all three runtimes that can run Gemma 4 on a Mac shows it does, with caveats most posts will miss.

TL;DR
2.03×
Speedup
Gemma 4 E4B, real prompt
100tok/s
E4B throughput
2.6× the next-best stack
144tok/s
E2B throughput
single-batch, real prompts

01What Multi-Token Prediction is

Standard language-model decoding is strictly sequential. The target generates one token, feeds it back through the network, generates the next. Each token costs one full forward pass through a multi-billion-parameter model. The dependency chain cannot be parallelized — token n+1 needs token n to exist first.

The sequential bottleneck

Visualized as a timeline of GPU work, every output token is the same big block of compute. Five tokens cost five full passes:

Standard decoding · 5 tokens, 5 forward passes
Standardtarget only
tgt tgt tgt tgt tgt
t=05 t-units
Each block is one full target forward pass. Time scales linearly with output length.

MTP: parallelize verification, not generation

MTP pairs the target with a small drafter (78M parameters in Gemma 4's case — about 1% of the target's compute). The drafter proposes k candidate tokens cheaply, in sequence. The target then verifies all k in a single parallel forward pass. Every accepted token is a full token gained at the cost of one drafter step instead of one target step.

The same five tokens, with MTP at k=4, look like this on the timeline:

+ MTP, k=4 · 4 drafts + 1 parallel verify yields up to 5 tokens
+ MTPdrafter + verify
· · · · verify (parallel)
t=0~1.4 t-units
Speedup
5 tokens / 1.4 t = ~3.6× theoretical ceiling
Drafter steps (gold) are tiny because the model is ~100× smaller. Target verifies all 4 drafts plus emits a bonus 5th token in one parallel pass.

The verification cycle, animated

Inside one MTP step: drafter emits 4 token proposals (gold), they flow into the target, target verifies in one shot, accepted tokens (sage) flow into the output stream, the first rejected token (rose) stops the chain. The next cycle starts from there.

One MTP cycle, k = 4
Drafter~78M params
t₁
t₂
t₃
t₄
Targetverify in 1 pass
stream
accepted t₁ t₂ t₃ t₅*
draft proposal accepted rejected from here

How acceptance rate translates to real speedup

The drafter doesn't always agree with the target. Real-world acceptance rates depend on prompt predictability — code and JSON predict cleanly, freeform prose less so. Each cycle yields between 1 token (worst case: drafter wrong on first token, target falls back to its own next-token output) and k+1 tokens (best case: full agreement plus the bonus token). The cost is always ~1 target pass plus k tiny drafter passes:

Best caseall 4 accepted + bonus
+
4.8×5 tok / 1.04 cost
Typical (code, JSON)3 of 4 accepted
+
3.8×4 tok / 1.04
Mixed prose2 of 4 accepted
· +
2.9×3 tok / 1.04
Hard freeform1 of 4 accepted
· · +
1.9×2 tok / 1.04
Worst casedrafter wrong immediately
· · · +
0.96×1 tok / 1.04

The throughput math is exactly:

Tokens per cycleaccepted + 1 bonus
Cost per cycle1 target pass + k × drafter passes
Drafter cost ratio~1% of target (≈ 0.01)
k = 4, drafter ≈ 0.01tcost = 1 + 4(0.01) = 1.04
Real-world acceptance~2–3 of 4 on hard prompts
Realistic speedup~2× — measured below

Why MTP is lossless

At temperature=0, MTP is provably identical-output to running the target alone. The trick is the verification step: the target is shown the prompt plus all k draft tokens at once and produces its own next-token logits at every position. A draft is only accepted if the target's top-1 token at that position matches the drafted token. The first mismatch is replaced by the target's own choice and the chain halts. So the output is exactly what the target would have produced step by step — just produced in fewer wall-clock units.

This is what "up to 3× decode for free" actually means: free in tokens-per-second, free in quality, paid for only in the small extra drafter compute and slightly larger KV-cache footprint.

02Why MTP matters for Gemma 4 on edge

Running Gemma 4 locally on a phone, laptop, or Pi instead of through an API has four advantages that compound: privacy (prompts stay on the device), cost (free after the model download), latency (no network round-trip), and availability (works offline). The block was always speed — Gemma 4 on edge has been 5–10× slower per token than hosted equivalents.

MTP closes that gap most cleanly at exactly the regime edge deployments care about: single user, batch size 1, no API quota. Which is exactly the regime Google flagged as hardest in their announcement. That made batch=1 Apple Silicon the most interesting cell in the table to actually measure.

"the 26B mixture-of-experts model presents unique routing challenges at a batch size of 1 on Apple Silicon... batch sizes of 4 to 8 unlock up to a ~2.2× speedup locally."

That phrasing implies muted on-edge gains at batch=1. The data below shows the ceiling holds at batch=1 too — for the smaller Gemma 4 sizes most edge devices will run, in the runtime Google shipped specifically for it.

03The benchmark setup

One representative on-edge Mac. Three runtimes that can run Gemma 4 locally on it. Real prompts at temperature=0. Paired baseline / +MTP runs with the program cache primed. Output tokens counted via the matching Hugging Face tokenizer to compute true tok/s.

Model MacBook Pro · Mac16,8
Chip Apple M4 Pro (8P + 4E cores)
Memory 24 GB unified
OS macOS 26.3.1
Workload single user, batch = 1
Models Gemma 4 E2B / E4B (instruct)

Two scripts (both in the repo) produce every number that follows: bench_mtp.py for the transformers + MPS path, bench_litertlm.py for the LiteRT-LM path. Each reports paired baseline / +MTP rates and a hash check on output equality at greedy.

04The result, on one machine

Same hardware. Same prompts. Real-prompt decode tok/s, end-to-end:

RuntimeModelBaseline+ MTPSpeedup
LiteRT-LM Metal GPUE4B44.682.81.86×
2.03× best
LiteRT-LM Metal GPUE2B84.2144.31.71×
transformers + MPSE4B12.115.11.24×
transformers + MPSE2B21.922.91.04×
llama.cpp Q8_0E4B39.0no MTP

LiteRT-LM Metal GPU + MTP is 2.6× faster than transformers+MPS+MTP and 2.1× faster than llama.cpp Q8_0 on E4B. Three runtimes, identical technique, identical hardware — and one delivers the headline while the others land between a fifth and a quarter of it.

05The benchmark trap

The single most common reason MTP looks broken on Apple Silicon: the default measurement tool is the wrong tool for the job.

Synthetic benchmarks lie

The bundled litert-lm benchmark command decodes random tokens. Drafter acceptance rate on random sequences is ≈ 0%, which makes MTP pure verification overhead — and reads as a regression. A correctly engaged MTP path scored 0.93× through this tool versus 1.79–2.03× through real prompts. Use litert-lm run with externally-timed real prompts. bench_litertlm.py in the repo does this in 110 lines.

The fix is in the script repo: bench_litertlm.py spawns litert-lm run per prompt, times wall-clock externally, and counts output tokens with the matching Hugging Face tokenizer to compute true tok/s. That's the measurement that produces the 2.03× result above.

06Reproduce in 5 minutes

# Clone the bench scripts and install the LiteRT-LM CLI
git clone https://github.com/iprajax/gemma4-mtp
cd gemma4-mtp
uv tool install litert-lm

# Run the headline benchmark on E2B (smaller, ~1 min)
python bench_litertlm.py --model e2b

# Verify the engine flag flips (proves MTP is engaged)
litert-lm run \
  --from-huggingface-repo=litert-community/gemma-4-E2B-it-litert-lm \
  --backend=gpu \
  --enable-speculative-decoding=true \
  --temperature=0 --verbose \
  --prompt="Hello" 2>&1 | grep "Speculative decoding"
# Expected: Speculative decoding : true

07What to do, what to skip

Do
  • Use LiteRT-LM v0.11.0 Metal GPU + MTP for fastest Gemma 4 on edge
  • Re-download bundles dated before 2026-05-05
  • Pick E4B over E2B if the RAM allows — bigger speedup
  • Run real prompts to measure speed; --verbose to confirm
Don't
  • Trust litert-lm benchmark for any MTP measurement
  • Expect the headline 2× through transformers+MPS — it's 1.04–1.24×
  • Wait for llama.cpp + MTP — gemma4_assistant isn't merged yet
  • Use MTP on E2B in transformers — on a small target it can be a net loss

08Why one runtime wins

The technique is identical across runtimes — same drafter weights, same verification step. The runtime carries the rest. Three structural differences explain the gap:

The single most useful takeaway from the experiment: for Gemma 4 on edge, runtime choice is at least as important as model choice. Two runtimes, identical hardware, identical model, identical technique — one delivers the headline, the other delivers a fifth of it.

Source & benchmarks github.com/iprajax/gemma4-mtp →
Bottom line for Gemma 4 on edge

On-device Gemma 4 inference just crossed a real threshold this week. ~100 tok/s on E4B at batch=1 on a 24 GB MacBook is hosted-API-grade speed with zero network. The conditions are specific — one runtime, one model size, real-prompt measurement — but they're documented, reproducible, and they hold today. The narrative most posts will run with next week is "MTP doesn't work on Mac." The data says it works better on Mac than any other path.