Amazon Web Services zveřejnilo na svém blogu o umělé inteligenci návod, jak provozovat velký jazykový model (LLM) rozložený na více výpočetních uzlech. Příspěvek ukazuje nasazení jednoho takového modelu na dvou GPU uzlech ve službě Amazon EKS, tedy v řízeném prostředí Kubernetes od AWS. K tomu slouží multi-node kontejner Ray LLM Deep Learning Containers. Pro čtenáře je text užitečný hlavně jako praktická ukázka toho, jak se model běžící přes více strojů dá postavit na platformě, kterou AWS sama nabízí. Nejde o obecné srovnání přístupů, ale o konkrétní postup s konkrétními nástroji.
Zajímavý je i způsob, jakým je řešení uspořádané. Podle popisu v příspěvku běží fáze prefill a decode na oddělených uzlech. Navenek je však obě zastřešuje jeden koncový bod kompatibilní s OpenAI. Aplikace, která s modelem komunikuje, tak vidí jedno rozhraní, zatímco uvnitř se práce dělí mezi různé uzly. Rozdělení tedy není vidět na straně klienta a nevyžaduje, aby se volající staral o to, kde která fáze zrovna probíhá. Text přitom popisuje konkrétní ukázkové nasazení od AWS. Z dostupných podkladů nelze vyvozovat, jak by se podobná architektura chovala v jiných konfiguracích nebo jak by si vedla v porovnání s alternativami.
Proč oddělit prefill a decode
Proč se fáze prefill a decode oddělují? Podle blogu AWS to umožňuje vybrat pro každou fázi vhodný hardware i vlastnosti provozu a každou ji také škálovat nezávisle. Autoři to popisují jako cestu ke zlepšení celkového výkonu ve větším měřítku. Při takzvané PD disaggregation, tedy oddělení prefillu a decode, běží obě fáze na samostatných uzlech, takže se při práci navzájem nerušijí. Každou z nich tak lze dimenzovat podle jejích vlastních nároků, místo aby se obě tísnily na stejných zdrojích. AWS dále uvádí jeden praktický přínos: oddělení zabraňuje tomu, aby výpočetně náročné dlouhé prompty brzdily generování tokenů u požadavků, které už jsou rozpracované. Jde o tvrzení z dokumentace samotného poskytovatele, nikoli o nezávisle ověřené měření.
Oddělení má ale i svou cenu. Autoři ji označují za kompromis: KV cache, kterou model vytvoří během prefillu, se musí předat decode uzlu. AWS upozorňuje, že tento přenos má být dostatečně rychlý, aby nezrušil přínos oddělení fází. Pokud by data putovala pomalu, mohla by se výhoda ze specializovaných uzlů ztratit na cestě mezi nimi. Právě proto podle blogu záleží na propojení mezi uzly. Pro čtenáře z toho plyne jednoduchý závěr: samotné rozdělení práce na dva typy uzlů nestačí. Záleží i na tom, jak rychle si spolu mohou předat data, která jedna fáze připravila pro druhou. Podklady však neuvádějí konkrétní hodnoty přenosu ani srovnání s jinými konfiguracemi, takže míru přínosu z nich odhadnout nelze.
Nasazení jedním blokem YAML
Podle blogu AWS je celá serving aplikace pouze blok YAML. Knihovna Ray Serve LLM totiž obsahuje vestavěný nástroj pro sestavení aplikace, a tak odpadá práce, která se u nasazování modelů často čeká. Autoři výslovně uvádějí, že není potřeba handler třída, model archiver ani vlastní image, který by bylo nutné nejprve vytvořit. Konfigurace je tedy deklarativní: popisuje, co se má spustit, a samotné sestavení aplikace obstará knihovna. Jde o popis z dokumentace dodavatele, nikoli o nezávisle ověřené srovnání pracnosti s jinými postupy, a proto je lepší brát ho jako deklarovaný záměr řešení.
Praktický základ celé konfigurace tvoří jediná pomocná funkce build_pd_openai_app. Přijme konfiguraci pro prefill a konfiguraci pro decode a mezi oběma částmi zajistí přenos KV cache. Navenek se přitom podle AWS celé řešení tváří jako jeden endpoint kompatibilní s OpenAI. Klient tedy nemusí řešit, že odpověď vzniká na dvou oddělených skupinách uzlů. Zjednodušeně řečeno: dvě samostatné konfigurace se spojí jednou funkcí a výsledkem je jedno rozhraní. Podklady však nepopisují, jak náročné je v praxi ladění jednotlivých parametrů, ani jak se tento postup chová při větším zatížení. Z uvedených pasáží proto plyne hlavně to, že samotné nasazení je navrženo stručně a bez dalších vlastních komponent.
Přenos KV cache přes NIXL a EFA
Přenos dat mezi oběma fázemi zajišťuje podle blogu AWS komunikační vrstva NIXL. Při generování odpovědi se mezivýsledky, takzvaná KV cache, vytvoří na prefill workeru a odtud putují na decode worker. Přenos probíhá přes síťové rozhraní EFA, které NIXL využívá prostřednictvím backendu libfabric. Z popisu zároveň vyplývá praktické omezení: skupina GPU uzlů je připnutá k jediné Availability Zone, protože EFA podle dokumentace nedokáže překročit hranice zón. Kdo by chtěl takové řešení rozprostřít do více zón, musí s tím při plánování počítat. Jde o přímý důsledek toho, že rychlá cesta pro KV cache je vázaná na konkrétní síťové rozhraní.
Druhý detail se snadno přehlédne, přitom podle autorů rozhoduje o tom, zda přenos poběží po rychlé cestě. Klíčové je v konfiguraci vložit do kv_connector_extra_config volbu backends s hodnotou LIBFABRIC. Pokud tento řádek chybí, NIXL automaticky sáhne po knihovně UCX. Ta pak podle zdroje běží rychlostí TCP, i když je k dispozici EFA. Jde tedy o případ, kdy by nasazení mohlo na první pohled fungovat, ale nevyužilo by specializovanou síť, kvůli které se celá architektura staví. Jediný chybějící řádek konfigurace může přenos KV cache výrazně zpomalit. Podklady ovšem neuvádějí, o kolik by se přenos zpomalil, takže konkrétní dopad na výkon z nich vyčíst nelze.
Úskalí a ověření backendu
Nasazení může na první pohled vypadat v pořádku a přitom nevyužívat zamýšlenou síť. Podle autorů návodu se totiž NIXL vrací k transportu s rychlostí TCP, pokud nemůže použít libfabric, a to bez chybového hlášení. Žádná výjimka ani varování tedy zákazníka neupozorní, že přenos neprobíhá tak, jak čekal. Zdroj proto doporučuje ověřit, který backend NIXL skutečně zvolil. Jde o krok navíc, který se snadno přehlédne, protože služba běží a odpovídá na požadavky. Funkční odpověď modelu tedy sama o sobě nedokládá, že KV cache putuje po rychlé cestě.
Kontrola je podle návodu přímočará. Nejprve lze přes port-forward zpřístupnit službu a odeslat standardní požadavek chat-completion, protože kontejner nabízí rozhraní kompatibilní s OpenAI a nepotřebuje vlastní schéma. Ukázkový požadavek v příspěvku míří na model qwen3.5-9b, žádá nejvýše 200 tokenů a používá teplotu 0,7. Samotné ověření backendu pak spočívá v prohledání logů workerů. Příkaz projde pody s označením worker a hledá hlášení, že byl instanciován backend LIBFABRIC nebo UCX. Výsledky se seřadí a spočítají, takže je vidět, který z nich se použil. Autoři dále zmiňují, že skript deploy_node_group.sh při vytváření skupiny uzlů vypisuje počet zařízení vpc.amazonaws.com/efa na každém uzlu. Obě kontroly se tak doplňují: jedna ukazuje, že uzly EFA mají, druhá, že ho přenos skutečně využil.
Co si z ukázky odnést
Návod AWS dohromady popisuje poměrně ucelený obraz. Model se rozdělí na prefill a decode uzly, které stojí za jedním endpointem kompatibilním s OpenAI. Aplikaci popisuje blok YAML a pomocná funkce build_pd_openai_app mezi oběma částmi zajistí přenos KV cache. Zásadní roli má ale síť: přenos jde přes NIXL a EFA s backendem libfabric, uzly musí ležet v jedné Availability Zone a konfigurace musí výslovně vyžádat LIBFABRIC, jinak NIXL tiše sáhne po pomalejší cestě. Protože to systém nehlásí chybou, stojí za to po nasazení projít logy workerů. Všechny tyto údaje pocházejí z dokumentace samotného poskytovatele a podklady neobsahují nezávislá měření výkonu, takže je třeba je brát jako popis zamýšleného postupu, nikoli jako doložený benchmark.
Zdroje
- Run multi-node inference workloads using Ray LLM Deep Learning Containers | Artificial Intelligence — AWS Machine Learning Blog
Článek vznikl s pomocí AI; podklady a odkazy jsou uvedeny výše.