Dve škatli razreda DGX Spark, en model: kopija na vsaki premaga delitev
Operacije
Sedem tednov je naš lokalni jezikovni model tekel razdeljen na dveh računalnikih NVIDIA GB10 s tenzorskim paralelizmom. 22. oktobra smo to nadomestili s polno kopijo modela na vsakem računalniku in proxyjem za najmanjše število povezav spredaj. Pretočnost je narasla s približno 180 na 210 žetonov na sekundo, vsak računalnik pa se lahko zdaj znova zažene, ne da bi odstranil model.
Zakaj smo ga razdelili
Vsak računalnik ima 128 GB pomnilnika, ki si ga delita CPU in GPU. Septembra se je model prilegal na en računalnik, a komajda njegov predpomnilnik: uporabljena različica vLLM ni mogla hraniti KV-predpomnilnika tega modela v FP8, zato je bil predpomnilnik v BF16, na enem računalniku pa je bilo prostora za 499.110 žetonov predpomnilnika. To je manj kot dve zahtevi pri polnem kontekstu modela, ki znaša 262.144 žetonov. Razdeljen na oba računalnika s tenzorskim paralelizmom prek njune neposredne omrežne povezave je predpomnilnik narasel na več kot tri milijone žetonov. Model smo razdelili zaradi prostora, ne zaradi hitrosti.
Kaj se je spremenilo
Novejša 4-bitna različica istega modela (NVFP4, narejena s kvantizacijsko ozaveščeno distilacijo) zavzame približno 71 GiB pomnilnika, skupnostna različica vLLM za GB10 (eugr/spark-vllm-b12x) pa svoj predpomnilnik poganja v FP8. Zdaj en računalnik drži celoten model in predpomnilnik od 0,76 do 1,08 milijona žetonov, kar je prostor za 2,9 do 4,1 zahteve pri polnem kontekstu, odvisno od tega, koliko pomnilnika mu računalnik nameni. Obe kopiji uporabljata modelovo lastno predikativno dekodiranje (MTP, štirje osnutki žetonov). Pred preklopom smo na novi različici izvedli naš test klicev orodij: dosegel je 86, različica, ki jo je nadomestil, pa 75.
Kaj smo izmerili
| Razdeljeno na dva računalnika | Kopija na vsakem računalniku | |
|---|---|---|
| KV-predpomnilnik | več kot 3 milijone žetonov | 0,76 in 1,08 milijona žetonov |
| Zahteve pri polnem kontekstu | približno 12 | 2,9 in 4,1 |
| Pretočnost pod našo obremenitvijo | približno 180 žetonov/s | 210 žetonov/s (111 + 99) |
| Zagon | približno 20 minut | 5 do 13 minut na kopijo |
| En računalnik se znova zažene | model je nedosegljiv | druga kopija streže |
Ena kopija sama po sebi, glede na število hkrati obravnavanih zahtev: s kratkimi pozivi je 1 zahteva dajala 36 žetonov na sekundo, 4 so dale 82, 8 so dale 109 in 16 so dale 150. Z daljšimi pozivi našega e-poštnega agenta so 4 zahteve dale 81, 8 so dale 113 in 16 le 87: nad osem takih zahtev jih je več pomenilo počasnejše delovanje.
Popoldne je ena kopija hkrati obravnavala največ 12 zahtev, druga pa 8. Prva je proizvajala 91 do 93 žetonov na sekundo in zaključila 26 do 27 zahtev na minuto; druga 81 do 83 žetonov na sekundo in 22 zahtev na minuto. Obe zdaj obravnavata 12 zahtev.
Kaj smo žrtvovali
Prostor. Razdeljeni model je imel en predpomnilnik z več kot tremi milijoni žetonov; kopiji imata dva manjša, zahteva pa lahko uporabi le predpomnilnik kopije, ki jo obravnava. Naši agenti pošiljajo veliko kratkih in srednje dolgih zahtev, zanje je bila pretočnost pomembnejša. Če hkrati obravnavate nekaj zelo dolgih kontekstov, je razdelitev morda še vedno boljša izbira. Nastavitev z razdelitvijo smo obdržali in preklop nazaj je en skript.
Kaj je šlo narobe med preklopom
- Enajst minut brez modela, nato 30 sekund napak 502. Razdeljeni model se je moral ustaviti, preden se je kopija naložila na istih strojih, zato so naši agenti čakali približno enajst minut. Ko se je prva kopija zagnala, je proxy še približno 30 sekund vračal "502 no live upstreams": označil je zaledne strežnike kot okvarjene, medtem ko so bili ugasnjeni (
max_fails=3,fail_timeout=30s), in jih ni poskusil znova, dokler ta čas ni potekel. - Odjemalec, ki je preskočil proxy. Ena od naših serijskih nalog je imela v konfiguraciji naslov prvega računalnika, zato je celotna obremenitev šla na eno kopijo, medtem ko je imela druga še dovolj zmogljivosti. Vsak odjemalec zdaj poteka prek proxyja; lastni naslovi računalnikov so namenjeni le preverjanju zdravja.
- Metrike, ki so poskočile. Naš nadzornik prepustnosti je bral vLLM-jeve
/metricsprek proxyja. Pri dveh zalednih strežnikih so zaporedni bralci prihajali z različnih kopij, števec je poskakoval gor in dol, nadzornik pa je poročal, da je model lačen. Zdaj bere vsako kopijo neposredno in jih sešteva. - Stari varuh, ki bi ustavil novo kopijo. Razdeljena postavitev je imela varuha, ki je znova zagnal svojo storitev, ko model ni več odgovarjal. Nova storitev navaja
Conflicts=s staro, zato bi ta ponovni zagon ustavil novo kopijo. Izklopiti jo je bilo treba zsystemctl disable --now, ne samo ustaviti, ker naša operativna plast znova zažene enote, ki so omogočene, a ne tečejo. - Pomnilnik na stroju, ki opravlja tudi drugo delo. En stroj poganja tudi naše baze podatkov in gradnje spletnih strani. Pri vLLM-jevem
gpu-memory-utilizationna 0,78 je za vse ostalo ostalo le še 5 GiB, zato smo ga znižali na 0,74 in znova zagnali samo to kopijo, medtem ko je druga prevzela obremenitev. Na teh strojih delež, ki ga dodelite vLLM, pride iz istega pomnilnika kot vse ostalo.
Če imate dva takšna stroja
- Če se model in predpomnilnik, ki ga potrebujete, prilegata na en stroj, zaženite kopijo na vsakem stroju za proxyjem z razporeditvijo po najmanj povezavah. Model razdelite šele, ko en stroj ne more vsebovati predpomnilnika, ki ga potrebujete.
- Usmerite vse odjemalce na proxy, vključno z serijskimi opravili in starimi konfiguracijami.
- Berite metrike neposredno z vsake kopije.
- Vsakemu stroju dodelite svoj delež pomnilnika glede na to, kaj drugega se na njem poganja.
- Nastavite, koliko zahtev hkrati postreže kopija, glede na svoj promet: pri našem mešanici je 12 premagalo 8.
- Predvidite, da bo preklop začasno odstranil model za čas, ki ga kopija potrebuje za zagon, in se na to pripravite.
Factory Floor vsebuje proxy in konfiguracije za zagon na enem ali dveh strojih, preverjanje zdravja in test uporabe orodij, ki ga izvedemo pred preklopom modelov, skupaj z varuhi in zaščitnimi mehanizmi za pomnilnik za preostanek stroja.