Naša kontrola stavu reštartovala zdravý server s modelom osemkrát za jeden deň
Prevádzka
22. júla watchdog reštartoval náš lokálny server s modelom osemkrát. Ani jeden z týchto reštartov nebol spôsobený pádom. Kontrola, ktorá mala udržať model v chode, bola tým, čo ho zhadzovalo.
Čo sa stalo
Server s modelom bežal na vLLM na jednom počítači NVIDIA GB10 a pre jednu požiadavku generoval približne 8 tokenov za sekundu. Každých päť minút mu watchdog poslal skutočnú chatovú požiadavku a čakal na odpoveď až 45 sekúnd. Päť neúspešných kontrol po sebe znamenalo zaseknutý server a watchdog ho reštartoval. Reštart odstránil model na niekoľko minút, kým sa znova načítalo približne 19 GB váh.
V ten deň dávková úloha zamestnávala na serveri dve až štyri požiadavky na minúty naraz. Požiadavka watchdogu čakala vo fronte za nimi, vypršal jej čas a započítala sa ako neúspech. Po piatich takýchto kontrolách bol zdravý server reštartovaný. Mali sme súbor s príznakom „busy“, ktorý watchdog rešpektoval, ale dávková úloha ho nikdy nenastavila.
Ako jeden falošný reštart viedol k ďalšiemu
Každý reštart ukončil prebiehajúce požiadavky s chybou 500 („cannot schedule new futures after shutdown“). Druhý watchdog počítal chyby 500 a reštartoval server, keď ich bolo príliš veľa, a čím viac chýb videl, tým skôr zasiahli. Každý falošný reštart teda spôsobil, že ďalší prišiel skôr. Celkovo štyri samostatné watchdogy mohli reštartovať tento server na časovačoch 5, 10, 15 a 30 minút.
Pravidlo, ktoré sme si z toho odniesli
Kontrola stavu nesmie používať to, čo chráni. Vzácnym zdrojom servera s modelom sú jeho sloty pre prebiehajúce požiadavky. Kontrola, ktorá jeden z týchto slotov zaberá alebo naň čaká, je súčasťou záťaže, ktorú má posudzovať. Kontrolujte lacno a reštartujte len vtedy, keď dokážete, že je server zaseknutý.
Kontrola, ktorá ju nahradila
vLLM zverejňuje vlastné počítadlá na /metrics. Nová kontrola ich najprv číta:
- Prebiehajúce požiadavky a motor robí pokroky: zdravý a zaneprázdnený. Neposiela sa žiadna testovacia požiadavka.
- Prebiehajúce požiadavky a žiadny pokrok medzi dvoma čítaniami: zaseknuté. Toto je prípad, ktorý stále reštartuje.
- Nič nebeží: nečinný. Až potom kontrola vyžiada krátku odpoveď, ktorú nečinný motor poskytne okamžite.
Prvá verzia počítala vygenerované tokeny ako pokrok. Prešla ôsmimi testmi a pri prvom ostrom behu našla server zaneprázdnený a zdravý: 2 prebiehajúce požiadavky, 107 nových tokenov medzi dvoma čítaniami.
Čo sme odvtedy zmenili
- Kroky motora, nie výstupové tokeny. Kým vLLM číta dlhý prompt, chvíľu negeneruje žiadne výstupové tokeny, ale stále vykonáva kroky. Počítanie krokov (počet vllm:iteration_tokens_total) zabraňuje tomu, aby dlhý prompt vyzeral ako zaseknutý server.
- Dva čakacie cykly pred „zaseknutím“, aby krátka pauza nebola považovaná za chybu.
- Reštart medzi dvoma čítaniami je zachytený pomocou času spustenia procesu v rovnakých metrikách; kontrola potom vyžaduje odpoveď namiesto porovnávania počítadiel z dvoch rôznych procesov.
- Proxy sa kontroluje iba cez /models. Za proxy s minimálnym počtom pripojení môže každé čítanie /metrics prísť z iného backendu, ako sme zistili, keď sme spustili kópiu modelu na dvoch strojoch. Backendy sa kontrolujú priamo.
Rozdiel je ľahko viditeľný. Keď sme písali túto poznámku, oba naše servery s modelmi spracovávali po 12 požiadaviek, čo bol ich limit. Testovacia požiadavka by čakala vo fronte. Nová kontrola hlásila oba servery ako zaneprázdnené a zdravé, pri 126 a 101 tokenoch za sekundu, bez toho, aby jednu poslala.
Factory Floor 1.0.2 prináša túto kontrolu ako models/llm-health.py, s testami pre nečinné, zaneprázdnené, zaseknuté a reštartované servery, server bez metrík, proxy a nefunkčný backend.