Dva stroje třídy DGX Spark, jeden model: kopie na každém místo dělení
Provoz
Sedm týdnů běžel náš lokální jazykový model rozdělený mezi dva stroje NVIDIA GB10 s tenzorovou paralelizací. Dne 22. října jsme to nahradili úplnou kopií modelu na každém stroji a proxy s nejnižším počtem spojení před nimi. Propustnost vzrostla z přibližně 180 na 210 tokenů za sekundu a kterýkoli ze strojů lze nyní restartovat bez toho, aby byl model nedostupný.
Proč jsme model rozdělovali
Každý stroj má 128 GB paměti sdílené mezi CPU a GPU. V září se model vešel na jeden stroj, ale jeho cache sotva: použitá sestavení vLLM nedokázala udržet KV cache tohoto modelu ve formátu FP8, takže cache byla v BF16 a na jednom stroji bylo místo pro 499 110 tokenů. To je méně než dvě požadavky při plném kontextu modelu 262 144 tokenů. Při rozdělení mezi oba stroje s tenzorovou paralelizací přes jejich přímé síťové propojení cache narostla na více než tři miliony tokenů. Model jsme rozdělovali kvůli prostoru, ne kvůli rychlosti.
Co se změnilo
Novější 4bitové sestavení stejného modelu (NVFP4, vytvořené pomocí distilace s ohledem na kvantizaci) zabírá přibližně 71 GiB paměti a komunitní sestavení vLLM pro GB10 (eugr/spark-vllm-b12x) spouští jeho cache ve formátu FP8. Nyní jeden stroj pojme celý model a cache o velikosti 0,76 až 1,08 milionu tokenů, což je místo pro 2,9 až 4,1 požadavku při plném kontextu, v závislosti na tom, kolik paměti stroj modelu přidělí. Obě kopie využívají vlastní spekulativní dekódování modelu (MTP, čtyři náhledové tokeny). Před přepnutím jsme na novém sestavení spustili náš test volání nástrojů: dosáhl skóre 86, zatímco nahrazené sestavení mělo 75.
Co jsme změřili
| Rozděleno mezi dva stroje | Kopie na každém stroji | |
|---|---|---|
| KV cache | více než 3 miliony tokenů | 0,76 a 1,08 milionu tokenů |
| Požadavky při plném kontextu | přibližně 12 | 2,9 a 4,1 |
| Propustnost pod naší zátěží | přibližně 180 tokenů/s | 210 tokenů/s (111 + 99) |
| Spuštění | přibližně 20 minut | 5 až 13 minut na kopii |
| Restart jednoho stroje | model je nedostupný | slouží druhá kopie |
Jedna kopie sama o sobě podle počtu současně obsluhovaných požadavků: u krátkých promptů 1 požadavek poskytoval 36 tokenů za sekundu, 4 poskytovaly 82, 8 poskytovaly 109 a 16 poskytovalo 150. U delších promptů našeho e-mailového agenta 4 poskytovaly 81, 8 poskytovaly 113 a 16 pouze 87: nad osm takových požadavků další kopie zpomalovaly.
Během jednoho odpoledne jedna kopie obsluhovala nanejvýš 12 současných požadavků a druhá 8. První produkovala 91 až 93 tokenů za sekundu a dokončila 26 až 27 požadavků za minutu; druhá 81 až 83 tokenů za sekundu a 22 požadavků za minutu. Obě nyní berou 12.
Co jsme obětovali
Prostor. Rozdělený model měl jednu cache s více než třemi miliony tokenů; kopie mají dvě menší a požadavek může využít pouze cache kopie, která jej obsluhuje. Naši agenti odesílají mnoho krátkých a středně dlouhých požadavků a pro ně byla důležitější propustnost. Pokud obsluhujete několik velmi dlouhých kontextů současně, rozdělení může být stále lepší volbou. Rozdělené nastavení jsme ponechali a návrat zpět je jeden skript.
Co se pokazilo při přepínání
- Eleven minut bez modelu, pak 30 sekund chyb 502. Rozdělený model musel být zastaven dříve, než se na stejných strojích mohla načíst kopie, takže naši agenti čekali asi jedenáct minut. Když se první kopie spustila, proxy ještě asi 30 sekund odpovídalo "502 no live upstreams": označilo backendy za selhané, zatímco byly offline (max_fails=3, fail_timeout=30s), a nezkusilo je znovu, dokud tato doba nevypršela.
- Klient, který vynechal proxy. Jedna z našich dávkových úloh měla v konfiguraci adresu prvního stroje, takže veškerá její zátěž šla na jednu kopii, zatímco druhá měla volnou kapacitu. Každý klient nyní prochází přes proxy; vlastní adresy strojů slouží pouze ke kontrolám stavu.
- Metriky, které poskakovaly. Náš monitor propustnosti četl /metrics z vLLM přes proxy. Se dvěma backendy přicházely po sobě jdoucí čtení z různých kopií, čítače poskakovaly tam a zpět a monitor hlásil model jako vyčerpaný. Nyní čte každou kopii přímo a hodnoty sčítá.
- Starý hlídač, který by zastavil novou kopii. Rozdělené nastavení mělo hlídače, který restartoval službu, když model přestal odpovídat. Nová služba deklaruje Conflicts= se starou, takže by tento restart zastavil novou kopii. Musel být vypnutý pomocí
systemctl disable --now, ne jen zastavený, protože naše vrstva pro provoz restartuje jednotky, které jsou povolené, ale neběží. - Paměť na stroji, který dělá i jinou práci. Jeden stroj také běží naše databáze a sestavování webu. Při nastavení gpu-memory-utilization pro vLLM na 0,78 zbývalo pro všechno ostatní pouze 5 GiB, takže jsme to snížili na 0,74 a restartovali pouze tuto kopii, zatímco druhá nesla zátěž. Na těchto strojích jde podíl, který dáte vLLM, ze stejné paměti jako všechno ostatní.
Pokud máte dva takové stroje
- Pokud se model a cache, kterou potřebujete, vejdou na jeden stroj, spusťte kopii na každém za proxy s nejnižším počtem spojení. Rozdělte model pouze tehdy, když jeden stroj neudrží cache, kterou potřebujete.
- Nasměrujte každého klienta na proxy, včetně dávkových úloh a starých konfigurací.
- Čtěte metriky z každé kopie přímo.
- Dejte každému stroji vlastní podíl paměti podle toho, co na něm ještě běží.
- Nastavte, kolik požadavků kopie obslouží najednou, podle vašeho provozu: pro naši směs bylo 12 lepší než 8.
- Počítejte s tím, že přepnutí odebere model po dobu, kterou kopie potřebuje ke spuštění, a naplánujte to.
Factory Floor obsahuje proxy a konfigurační soubory pro spuštění na jednom nebo dvou strojích, kontrolu stavu a test použití nástrojů, který spouštíme před přepnutím modelů, spolu s hlídači a ochrannými mechanismy paměti pro zbytek stroje.