Inference clustery: vLLM tensor parallel, pipeline parallel a co Vás každý z nich reálně stojí

Model třídy 70B se nevejde na jedno GPU při žádné kvantizaci, která by ponechala použitelnou KV cache. Model 405B se nevejde do jednoho uzlu. Jakmile to platí, otázka už nezní „které GPU“, ale „jak model rozkrájet mezi GPU, která mám, a co mě každý řez bude stát“.

Tento článek popisuje čtyři způsoby, jimiž vLLM umožňuje model rozkrájet — tenzorový paralelismus, pipeline paralelismus, expertní paralelismus a datový paralelismus — co každý z nich udělá s Vaším účtem za propustnost a jak mezi nimi vybrat v nabídce Kentino (5090, RTX Pro 6000 Blackwell, L40 a L4 připojené přes PCIe — žádné díly SXM s NVLink fabricem). Čtenář už přečetl I01, ví, co je vLLM, a teď potřebuje rozhodnout o konfiguraci.

Čtyři roviny, v nichž lze model rozkrájet

Každý framework pro distribuovanou inferenci — vLLM, SGLang, TensorRT-LLM i Triton — nabízí nějakou kombinaci týchž čtyř os. Nejsou to alternativy; skládají se dohromady.

Osa Co dělí Komunikace na token Citlivá na propustnost? Dopad na latenci
Tenzorový paralelismus Každou vrstvu (střípky matmulu) All-reduce na vrstvu (×2) Ano — výrazně Snižuje latenci
Pipeline paralelismus Vrstvy mezi fáze Aktivace na každém rozhraní fází Ne — málo Zvyšuje latenci i propustnost
Expertní paralelismus MoE experty mezi GPU All-to-all na každou MoE vrstvu Ano — nárazově Závisí na modelu
Datový paralelismus Celé nezávislé repliky Během inference žádná Ne Stejná latence, N× propustnost

Třetí sloupec je celá hra. TP na sběrnici křičí v každé vrstvě. PP si mezi dvěma fázemi jen šeptá. Tenhle jediný fakt rozhoduje o tom, jestli necháte TP uvnitř jedné skříně, pošlete PP mezi uzly a kudy ta hranice vede.

Tenzorový paralelismus — jak to doopravdy funguje

V TP se každá matice vah v transformeru (attention QKV, výstup attention, FFN nahoru, FFN dolů) rozkrájí mezi tensor_parallel_size GPU. Každé GPU drží jeden střípek každé vrstvy a počítá jeden střípek každé aktivace. Protože attention i FFN obsahují matmuly, které potřebují před další operací (softmax, SwiGLU) poskládat celou aktivaci, je nutné dílčí výsledky spojit. vLLM to dělá pomocí operace all-reduce na konci attention a další na konci FFN — tedy dvakrát na každý blok transformeru.

Llama 3.3 70B má 80 vrstev a skrytý rozměr 8192. Při dekódování s dávkou 32 přesune každý all-reduce ~512 KB, ×160 na každý vygenerovaný token → ~80 MB na token přes sběrnici. Prefill je dramaticky horší: prefill 4 K s dávkou 32 protlačí jedním dopředným průchodem all-reduce kruhem řádově 300 GB.

Právě proto má TP tak rád NVLink. NVLink u SXM H100/B200 nabízí 900 GB/s. PCIe Gen 5 x16 dává 64 GB/s jednosměrně a v nejlepším případě 128 GB/s obousměrně — což na desce se 4 GPU platí málokdy (linky bývají sdílené, viz W02). Rozdíl 14×–28× se projeví v benchmarcích: efektivita škálování se u NVLinku pohybuje kolem 0.92× na kartu, u PCIe kolem 0.70–0.78× na kartu u modelů třídy 70B.

Praktický důsledek: TP škáluje dobře do 4 GPU v jednom uzlu s PCIe Gen 5. Nad tuto hranici stojí all-reduce víc, než kolik paralelismus ušetří, a měli byste raději sáhnout po pipeline paralelismu.

Konfigurace vLLM: tensor_parallel_size

--tensor-parallel-size N říká enginu, aby každý tenzor vah rozdělil mezi N GPU v rámci lokálního uzlu. Omezení:

  • N musí beze zbytku dělit počet attention hlav modelu (Llama 70B jich má 64 → N ∈ {1, 2, 4, 8, 16, 32, 64}).
  • vLLM umisťuje TP ranky na stejný uzel a předpokládá rychlou sběrnici uvnitř uzlu.
  • KV cache je rozdělená podél rozměru hlav — každé GPU drží total_heads / N hlav. Vyšší TP dává víc místa pro KV na požadavek.

Na hardwaru Kentino: TP=4 na skříni se 4× RTX 5090 nebo 4× RTX Pro 6000 Blackwell je ideální poloha. TP=8 funguje, ale sběrnice PCIe sténá; ve skříni s 8 GPU obvykle pořídíte lépe s TP=4 × PP=2.

Pipeline paralelismus — volba „přes celou místnost“

PP dělí model podle hloubky. Při pipeline_parallel_size=2 drží GPU 0 vrstvy 0–39 modelu Llama 70B a GPU 1 vrstvy 40–79. Požadavek projde GPU 0, tenzor aktivací se odešle na GPU 1 a GPU 1 dopředný průchod dokončí.

Komunikaci tvoří jeden tenzor tvaru (batch, seq_len, hidden_size) na každé rozhraní fází. Pro dávku 32, délku 4096, skrytý rozměr 8192 a FP16 je to ~1 GB na prefill a ~0.5 MB na dekódovaný token při dávce 32 — o dva řády méně než all-reduce u TP. PP běží bez potíží i přes obyčejné 25 GbE, nebo dokonce 10 GbE.

Daní za to je latence. Při PP=2 každý token skáče mezi fázemi — naivně tedy 2× delší reálný čas na token. vLLM to tlumí mikrodávkováním: fáze 0 začíná další mikrodávku, zatímco fáze 1 dokončuje tu předchozí. Při dostatečné souběžnosti se bublina zavře; u jednoho požadavku bez dávkování je PP jen daň z latence bez jakéhokoli přínosu.

Konfigurace vLLM: pipeline_parallel_size

--pipeline-parallel-size M rozdělí model po vrstvách do M skupin. Celkový počet GPU = tensor_parallel_size × pipeline_parallel_size. Doporučení z dokumentace:

  • Jeden uzel, ≤ 8 GPU, model se vejde: čisté TP, pipeline_parallel_size=1.
  • Více uzlů: TP uvnitř uzlu, PP mezi uzly. Cluster ze dvou uzlů s 8 GPU běží na TP=4, PP=2.
  • Počet GPU nedělí beze zbytku počet hlav: nastavte TP=1, PP=počet GPU. PP se o počet hlav nestará. (Skříň s 5 GPU — jeden slot padl na síťovku — rozběhne Llamu jedině přes PP=5.)

Expertní paralelismus — jen pro MoE

Modely MoE (DeepSeek-V3, Mixtral, varianty Qwen-MoE) neaktivují na každém tokenu všechny parametry. Mají směrované FFN vrstvy, kde se na token spustí jen malá podmnožina „expertů“; husté attention vrstvy zůstávají husté.

Expertní paralelismus (EP) rozděluje experty mezi GPU, zatímco husté vrstvy drží pod TP nebo DP. S přepínačem --enable-expert-parallel se expertní vrstvy z replikovaných změní na rozdělené, s jedním nebo několika experty na GPU. Komunikační vzorec je all-to-all na každou MoE vrstvu: tokeny se směrují na GPU, které vlastní cílového experta, spočítají se a vrátí.

EP je na propustnost nárazový. Teprve díky němu jsou velké MoE modely na PCIe clusterech vůbec zvládnutelné — plné TP na modelu s 671B aktivními parametry je beznadějné. Pro nasazení Kentino je EP relevantní jen u modelů třídy DeepSeek-V3; husté Llamě 70B nepomůže. Výchozím vstupním bodem je vestavěný EP ve vLLM v aktuálním buildu.

Datový paralelismus — nudná, ale skvělá osa

DP je nejjednodušší osa škálování a zároveň ta, kterou většina instalací nevyužívá dost. Spustíte N identických kopií modelu, každou na vlastní sadě GPU (a ta může sama o sobě používat TP a/nebo PP). Load balancer rozstřikuje požadavky té replice, která má volnou kapacitu.

Co DP přináší:

  • Lineární škálování propustnosti (N× požadavků za sekundu).
  • Nulovou komunikaci mezi replikami během inference.
  • Nezávislé KV cache u každé repliky (prefix cache je vždy jen v rámci repliky).
  • Triviální izolaci poruch.

Co DP stojí:

  • N× víc paměti GPU — každá replika drží celý model.
  • Žádné snížení latence. Jeden požadavek trvá na jedné replice přesně tak dlouho, jak trvá.

Pokud máte skříň se 4× RTX Pro 6000 a Llama 70B se vejde do TP=4, druhá skříň se 4 GPU Vám dá DP=2 × TP=4 — dvojnásobnou propustnost při stejné latenci na požadavek. U chatovacích, agentních a RAG workloadů je to správný obchod. Přepínač --data-parallel-size ve vLLM (a novější režim data_parallel_deployment) repliky spouští a spravuje. DP je nejčistší způsob, jak škálovat za hranici jedné skříně.

Kombinace os — praktické pravidlo

Vejde se na jedno GPU
TP=1, škálujte přes DP repliky
↓
Vejde se do jednoho uzlu (≤4 PCIe GPU)
TP uvnitř uzlu, DP mezi uzly
↓
Do jednoho uzlu se nevejde
TP uvnitř každého uzlu, PP mezi uzly, DP nad tím

Výběr osy: začněte nejmenším paralelismem, který se vejde, a teprve pak přidejte DP — dřív než PP.

Příklad z praxe. Provoz Llama 3.3 70B (FP8 ≈ 75 GB vah plus KV) při vysoké souběžnosti:

  • Skříň se 4× RTX Pro 6000 Blackwell (4 × 96 GB = 384 GB) ho v pohodě utáhne v TP=4, přičemž zbyde ~250 GB na KV, prefix cache a CUDA grafy.
  • Přidejte druhou skříň se 4× Pro 6000. DP=2 × TP=4. Dvě repliky za routerem. Dvojnásobná propustnost, stejná latence.
  • A Llama 3.1 405B ve FP8 (~400 GB vah)? Do jedné skříně se 4× Pro 6000 se nevejde. Do dvou skříní přes PP=2 × TP=4 ano — a spoj mezi uzly přenáší aktivace, ne all-reduce. 25 GbE stačí, se 100 GbE máte pohodlí.

KV cache: část, kterou každý podceňuje

KV cache jsou kumulované klíčové a hodnotové tenzory attention pro každý token promptu, každý vygenerovaný token, každý souběžný požadavek a každou vrstvu. Roste lineárně s délkou kontextu i se souběžností. Llama 70B při kontextu 8 K potřebuje zhruba 2.5 GB KV cache na požadavek ve FP16. Při 32 souběžných požadavcích je to 80 GB — víc než celá VRAM jedné 5090.

Jak paralelismus ovlivňuje KV:

  • Pod TP je KV rozdělená po attention hlavách v rámci TP skupiny. KV na jedno GPU = total / tensor_parallel_size. Vyšší TP → víc prostoru pro souběžné požadavky.
  • Pod PP zůstává KV na tom GPU, které drží vrstvu, jež ji vytvořila. Každá fáze vlastní svou KV.
  • Pod DP je KV plně nezávislá u každé repliky.
  • Pod kontextovým paralelismem (novější režim vLLM) je KV rozdělená podél rozměru sekvence — což se hodí u velmi dlouhých kontextů jednoho požadavku.

Při dimenzování skříně nekontrolujte jen to, jestli se vejdou váhy. Spočítejte KV pro cílovou souběžnost a kontextové okno. Nejčastějším tichým selháním produkčního vLLM je engine, který pod tlakem KV odkládá požadavky.

Směrování požadavků — co stojí před clusterem

Jediná instance vLLM si řeší vlastní interní dávkování (kontinuální dávkování, prefix caching, plánování). Mezi repliky ale nesměruje. To je práce routeru.

Router Co zohledňuje Kdy ho použít
Obyčejný NGINX Nic (round-robin) Nasazení s jedním modelem, kde vyhrává jednoduchost
HAProxy Nic + health-check Více modelů, směrování podle hlaviček
vLLM Router (Rust) KV / prefix / frontu ≥4 repliky, kde záleží na směrování podle prefixu
llm-d (Kubernetes) Vše výše uvedené + EP Flotily na K8s, MoE, oddělení prefillu a dekódování

NGINX je správná výchozí volba pro instalaci se 2 replikami — round-robin, health-check na /health, hotovo. vLLM Router (v Rustu, vydaný koncem roku 2025) se vyplatí ve chvíli, kdy Vaši koncovou latenci určuje úspěšnost prefix cache: směruje podle konzistentního hashe prefixu promptu, takže repliky s teplou cache dostávají stále tytéž konverzace. U agentního workloadu s dlouhými sdílenými systémovými prompty to oproti round-robinu dokáže zdvojnásobit efektivní propustnost.

Matematika propustnosti

Odkazy: N02, N06.

Workload Potřebná propustnost Reálný spoj u Kentino
TP=4 uvnitř jedné skříně (PCIe Gen 5) 50–200 GB/s na dvojici PCIe uvnitř uzlu
PP mezi dvěma uzly, dávka 32, dekódování 0.05–0.2 GB/s 10 GbE — s rezervou
PP mezi dvěma uzly, dávka 32, prefill nárazově 1–4 GB/s 25 GbE pohodlně, 10 GbE hraničně
DP mezi dvěma uzly ~0 (jen router) stačí 1 GbE pro správu
EP mezi 8 GPU v jedné skříni (MoE) nárazově 20–80 GB/s Pouze uvnitř uzlu
Široké EP mezi 2 uzly (třída DeepSeek-V3) trvale 10–40 GB/s 100 GbE RoCE nebo InfiniBand

Upřímné shrnutí: TP a EP chtějí zůstat uvnitř skříně. PP a DP je to jedno. Se spojem 10–25 GbE mezi uzly jsou PP i DP v pohodě. Jakmile budete chtít TP napříč uzly, platíte za InfiniBand HDR nebo 200 GbE RoCE — a měli byste si nejdřív položit otázku, jestli stejného výsledku nedosáhnete za desetinu rozpočtu pomocí DP nad jednouzlovými TP skupinami. U většiny nasazení velikosti Kentino ano.

Dva konkrétní konfigurační recepty

Recept A — jeden uzel, 4× RTX 5090, Llama 70B Q4 / FP8

Hardware: Kentino AI 256 Turin Dual nebo libovolná skříň se 4× 5090. PCIe Gen 5, žádný NVLink, hostitel na AMD EPYC.

vllm serve meta-llama/Llama-3.3-70B-Instruct-FP8 \
  --tensor-parallel-size 4 \
  --pipeline-parallel-size 1 \
  --max-model-len 8192 \
  --gpu-memory-utilization 0.92 \
  --enable-prefix-caching \
  --max-num-seqs 64 \
  --dtype auto \
  --port 8000

Očekávejte zhruba 30–40 tok/s na požadavek při nízké souběžnosti a v součtu ~400–600 tok/s při 32 souběžných (liší se podle skladby promptů, úspěšnosti prefix cache a konkrétní kvantizace — berte to jako výchozí rozpětí). Úzkým hrdlem při dekódování je all-reduce přes PCIe Gen 5; prefill škáluje téměř lineárně.

Recept B — dva uzly, celkem 8× RTX Pro 6000 Blackwell, Llama 405B FP8

Dvě skříně Kentino AI, každá se 4× Pro 6000 (96 GB). Mezi nimi spoj 100 GbE RoCE, nebo 25 GbE, pokud je rozpočet napjatý (bude to fungovat, jen s pomalejším prefillem).

# Uzel 0 (hlavní):
vllm serve meta-llama/Llama-3.1-405B-Instruct-FP8 \
  --tensor-parallel-size 4 \
  --pipeline-parallel-size 2 \
  --distributed-executor-backend ray \
  --max-model-len 8192 \
  --gpu-memory-utilization 0.90 \
  --enable-prefix-caching \
  --max-num-seqs 32

# Uzel 1 (worker, připojený přes Ray):
ray start --address=<head-ip>:6379

TP=4 uvnitř každého uzlu využívá pro all-reduce PCIe Gen 5. PP=2 mezi uzly posílá aktivace přes 25/100 GbE. S Rayem jako distribuovaným backendem (výchozí volba vLLM pro více uzlů) koordinuje hlavní uzel plánování i stav KV.

Upřímné hodnocení výkonu: 405B ve FP8 na 8× Pro 6000 přes PCIe a Ethernet vychází kolem 6–12 tok/s na požadavek — výrazně pod šasi s 8× SXM B200, ovšem za zlomek investice a bez potíží s dostupností SXM. Pokud Vaše SLA zní „odpověz do 30 s na dokončení o 500 tokenech“, funguje to. Pokud zní „odpověz do 2 s“, nepoužívejte 405B — použijte 70B.

Co neprovozujeme

NVLink, NVSwitch, SXM B200 ani plné desky HGX v nabídce Kentino nejsou. Jsou správnou odpovědí, pokud na ně máte rozpočet i odpovídající workload. Nejsou správnou odpovědí pro většinu našich zákazníků, kteří dimenzují na 1–4 souběžné agentní workflow nebo na jednu robotickou platformu, ne na SaaS inferenci pro 1 000 uživatelů. Cesta přes PCIe je upřímná v tom, co zvládne a co ne. TP přes 16 GPU pod 10 ms na token je jiná debata — a jiný cluster, než o jakém je tento článek.

Co udělat dál

Pokud skládáte vLLM cluster, projděte si popořadě tyto kroky:

  1. Sepište si model a SLA. Počet parametrů, kvantizaci, cílový počet tok/s na požadavek, cílový počet souběžných požadavků a cílové kontextové okno. Bez těchto čísel je volba paralelismu jen dohad.
  2. Spočítejte váhy + KV při cílové souběžnosti. Pokud samotná KV přesáhne volnou VRAM jednoho GPU, potřebujete TP. Pokud váhy přesáhnou jeden uzel, potřebujete PP.
  3. Začněte nejmenším TP, které se vejde. TP=2 před TP=4 a to před TP=8. Každý další stupeň ubere na PCIe kus efektivity škálování.
  4. Kvůli propustnosti přidejte dřív DP než PP. Dva uzly přes DP téměř vždy porazí jeden uzel rozdělený přes PP, pokud jde o workload citlivý na latenci.
  5. PP si nechte na případ, kdy se model nevejde, nebo kdy potřebujete pokrýt počet uzlů, který TP beze zbytku nerozdělí.
  6. Postavte před cluster router, i když máte jen dvě repliky. Na začátek stačí round-robin NGINX; na vLLM Router přejděte, až začne záležet na úspěšnosti prefix cache.
  7. Sledujte využití KV, nejen využití GPU. Cluster na 95 % GPU a 100 % KV odkládá požadavky. Dashboard, který chcete, je vllm_kv_cache_usage_perc v čase.

Navazující články v této řadě: úložiště clusteru (K04), plánování (K05), řešení výpadků (K06) a strop PCIe jako propojení (K07). Matematiku sítí rozebírají N02 a N06.


Toto je součást Kentino Wiki, referenční série o AI výpočtech, robotice a systémech, které je propojují. Komentáře a opravy uvítáme na info@kentino.com.