MTP vs prompt caching — Qwen3.8-27B-FP8 2× H100-on: mit érdemes használni?
A minap két H100-on is lefuttattam a Qwen3.8-27B-FP8-at, és az MTP-speculative decoding hozta a legnagyobb decode-gyorsulást (49 → 95 tok/s). De van egy bökkenő: a vLLM-ben az MTP és a prefix caching kölcsönösen kizárja egymást, szóval az volt a kérdés, hogy melyik konfigurációt érdemes élesben használni.
A választ úgy kaptam meg, hogy egymás ellen futtattam a két verziót: GPU0 no-MTP + prefix caching, GPU1 MTP (3 draft token). Mindkettő TP1-es, 262K maximum kontextus, FP8 KV cache, és egy LiteLLM proxy osztja el köztük a forgalmat. Az összes szám TTFT p50, hacsak nem írom másképp.
Decode: az MTP viszi a pontot#
Először is a jó hír: decode-ban az MTP a teljes konkurrenciasávban gyorsabb, 1K tokenes promptokkal és 512 kimeneti tokennel:

Egyetlen session-nél 1,9×-es az előny (94,9 vs 49,9 tok/s), ami 32 párhuzamos session-nél 1,28-szorosra szűkül. Szóval ha hideg promptokból generálsz sok tokent, az MTP a barátod.
Single-turn: közös prefix, egyedi suffixek#
Itt már fordul a kocka. Ha több session ugyanazt a prefixet használja (pl. közös rendszerpromptot), akkor a cache-sel futó konfiguráció a konkurrencia növekedésével gyakorlatilag lapos marad, míg az MTP-nek minden kérésnél újra prefill-elnie kell a teljes prefixet. 4K prefixnél konkurrencia nélkül még az MTP nyer (0,85 s vs 1,02 s), de 32 session-nél már 2,6-szeres hátrányban van (13,55 s vs 5,20 s). 16K prefixnél pedig 16 session-nél már 8-szoros a különbség (27,85 s vs 3,49 s).
A cache-hit sem elhanyagolható: második kérésnél, 16K prefix mellett a cache-hit 2,4-szer gyorsabb, mint az MTP re-prefillje (0,91 s vs 2,20 s) — igaz, 4K-nál a hash-elés többletköltsége felemészti az előny nagy részét.
Multi-turn: itt dől el a dolog#
Háromfordulós meneteket futtattam, minden forduló ~1K tokennel növelte a kontextust (4K-tól 64K-ig). A második forduló TTFT-je — vagyis az első követő kérdés ideje — lineáris skálán, kontextusonként külön panelen:

Lineáris skálán lehetetlen nem észrevenni a lényeget: a cache-t használó konfiguráció lapos marad (~1,4–5,5 s minden kontextusméretnél, 8 párhuzamos sessionig — csak az ~1K új suffixet prefill-eli, a közös prefix cache-hit, a futás alatt ~65%-os hit rate), míg az MTP minden követő fordulónál újra lefuttatja a teljes felhalmozott kontextust.
Nagyobb kontextusokra az MTP görbéit külön is megmutatom — logaritmikus skálán ez a „fal" szinte nem is látszik:

A cache oldalát pedig közelről, hogy a laposság tényleg látszódjon (a 132 s-os pont 64K/16-nál mindkét konfig közös KV-kapacitás-határa, nem cache-hiba):

Számokban: 8 session / 32K-nál az MTP már 28,6 s; 16 session / 64K-nál 80,9 s. Az arány egészen 16,8×-ig megy (64K, 4 concurrent). A 64K/16-os sarok viszont kivétel: ott mindkét konfig a KV cache kapacitáshatárába ütközik (16 × 64K élő KV ~1,05M token a 1,32M-es pool ellen, ráadásul a cache-elő példányon a pinned cache-blokkok miatt még rosszabbul is romlik a helyzet) — ez kapacitáshatár, nem konfigurációs hatás.
Verdikt#
| Munkaterhelés | Nyertes |
|---|---|
| Egy session, hosszú generálás, hideg prompt | MTP (1,3–2,2× decode) |
| Multi-turn, párhuzamos sessionök, növekvő kontextus | Prefix caching (akár 17× TTFT) |
| 64K+ kontextus, 16+ párhuzamos session | Egyik sem — KV kapacitáshatár |
A lényeg: konverzációs, multi-turn munkaterhelésnél a prefix caching az alapértelmezés, főleg ha több felhasználó osztozik a kontextuson vagy a rendszerprompton. Az MTP csak akkor fizetődik ki, ha decode-nehéz, hideg, egy-session munkád van. Mivel a vLLM-ben a kettő nem működhet együtt, ez a mérés eldöntötte nálam, hogy mit rakok élesbe.