Helsekontrollen vår startet en sunn modellserver på nytt åtte ganger på én dag
Drift
Den 22. juli startet en overvåker den lokale modellserveren vår på nytt åtte ganger. Ingen av disse omstartene hadde en krasj bak seg. Kontrollen som skulle holde modellen oppe, var det som tok den ned.
Hva som skjedde
Modellserveren kjørte vLLM på én NVIDIA GB10-maskin og produserte omtrent 8 tokens i sekundet for én forespørsel. Hvert femte minutt sendte en overvåker en ekte chatforespørsel til den og ventet i opptil 45 sekunder på svaret. Fem feilede kontroller på rad betydde en hengende server, og overvåkeren startet den på nytt. En omstart tok modellen bort i flere minutter mens omtrent 19 GB med vekter lastet inn igjen.
Den dagen holdt en batchjobb to til fire forespørsler opptatt på serveren i minutter om gangen. Overvåkerens forespørsel ventet i køen bak dem, gikk tom for tid og ble telt som en feil. Etter fem slike kontroller ble en sunn server startet på nytt. Vi hadde en "busy"-flaggfil som overvåkeren respekterte, men batchjobben satte den aldri.
Hvordan én falsk omstart førte til den neste
Hver omstart feilet de pågående forespørslene med en 500-feil ("cannot schedule new futures after shutdown"). En andre overvåker telte 500-feil og startet serveren på nytt når det var for mange, og jo flere feil den så, desto raskere handlet den. Så hver falske omstart fikk den neste til å komme tidligere. Totalt kunne fire separate overvåkere starte den serveren på nytt, på 5, 10, 15 og 30 minutters timere.
Regelen vi tok med oss fra det
En helsekontroll må ikke bruke det den beskytter. Modellserverens knappe ressurs er dens plasser for pågående forespørsler. En kontroll som tar en av disse plassene, eller venter på en, er en del av lasten den skal vurdere. Sjekk billig, og start på nytt bare når du kan vise at serveren er hengende.
Kontrollen som erstattet den
vLLM publiserer sine egne tellere på /metrics. Den nye kontrollen leser dem først:
- Pågående forespørsler og motoren som gjør fremdrift: sunn og opptatt. Ingen testforespørsel sendes.
- Pågående forespørsler og ingen fremdrift mellom to lesinger: hengende. Dette er tilfellet som fortsatt starter på nytt.
- Ingenting pågår: inaktiv. Bare da ber kontrollen om et kort svar, som en inaktiv motor gir med en gang.
Den første versjonen telte genererte tokens som fremdrift. Den besto åtte tester, og på den første live-kjøringen fant den serveren opptatt og sunn: 2 pågående forespørsler, 107 nye tokens mellom de to lesingene.
Hva vi har endret siden
- Steg i motoren, ikke utdatatokens. Mens vLLM leser en lang prompt, produserer den ingen utdatatokens en stund, men tar likevel steg. Å telle steg (antallet av vllm:iteration_tokens_total) forhindrer at en lang prompt ser ut som en fastlåst server.
- To ventetider før «fastlåst», slik at en kort pause ikke teller som en feil.
- En omstart mellom de to avlesningene fanges av prosessens starttid i samme metrikker; sjekken ber da om et svar i stedet for å sammenligne tellere fra to ulike prosesser.
- En proxy sjekkes kun via /models. Bak en proxy med minst tilkoblinger kan hver avlesning av /metrics komme fra en forskjellig backend, som vi fant ut da vi kjørte en kopi av modellen på hver av to maskiner. Backendene sjekkes direkte.
Forskjellen er lett å se. Da vi skrev denne notisen, kjørte begge modellserverne våre 12 forespørsler hver, som er grensen. En testforespørsel ville ha ventet i køen. Den nye sjekken rapporterte begge som opptatte og friske, på henholdsvis 126 og 101 tokens i sekundet, uten å sende én.
Factory Floor 1.0.2 leverer denne sjekken som models/llm-health.py, med tester for inaktive, opptatte, fastlåste og omstartede servere, en server uten metrikker, en proxy og en død backend.