Az állapotellenőrzésünk nyolcszor indított újra egy egészséges modellszervert egy nap alatt
Üzemeltetés
Július 22-én egy őrszem nyolcszor indította újra a helyi modellszerverünket. Egyik újraindítás mögött sem volt összeomlás. Az az ellenőrzés, amelynek a modellt fent kellett volna tartania, az döntötte le.
Mi történt
A modellszerver vLLM-et futtatott egy NVIDIA GB10 gépen, és másodpercenként körülbelül 8 tokent generált egyetlen kéréshez. Öt percenként egy őrszem valódi chat kérést küldött neki, és legfeljebb 45 másodpercet várt a válaszra. Öt egymást követő sikertelen ellenőrzés akadt modellt jelentett, és az őrszem újraindította. Az újraindítás több percre elvette a modellt, miközben körülbelül 19 GB súlyt töltött be újra.
Aznap egy kötegelt feladat percenként két-négy kérést tartott elfoglaltan a szerveren. Az őrszem kérése a sorban ezek mögött várt, elfogyott az ideje, és sikertelennek számított. Öt ilyen ellenőrzés után egy egészséges szervert indítottunk újra. Volt egy „elfoglalt” jelzőfájlunk, amelyet az őrszem tiszteletben tartott, de a kötegelt feladat soha nem állította be.
Hogyan vezetett egy téves újraindítás a következőhöz
Minden újraindítás 500 hibával („cannot schedule new futures after shutdown”) bukta el a folyamatban lévő kéréseket. Egy második őrszem számolta az 500-as hibákat, és újraindította a szervert, ha túl sok volt belőlük, és minél több hibát látott, annál hamarabb lépett. Így minden téves újraindítás előbbre hozta a következőt. Összesen négy különálló őrszem indíthatta újra azt a szervert 5, 10, 15 és 30 perces időzítőkön.
A szabály, amelyet levontunk belőle
Egy állapotellenőrzés nem használhatja azt, amit őriz. A modellszerver ritka erőforrása a folyamatban lévő kérések helye. Egy ellenőrzés, amely elfoglal egy ilyen helyet, vagy vár egyre, részese annak a terhelésnek, amelyet ítélkeznie kellene. Ellenőrizzen olcsón, és csak akkor indítson újra, ha bizonyítható, hogy a szerver beragadt.
Az ellenőrzés, amely felváltotta
A vLLM saját számlálóit közli a /metrics címen. Az új ellenőrzés először ezeket olvassa el:
- Futó kérések és haladó motor: egészséges és elfoglalt. Nem küldenek teszt kérést.
- Futó kérések és haladás nélkül két leolvasás között: beragadt. Ez az az eset, amely még mindig újraindít.
- Nincs futó kérés: tétlen. Csak ekkor kéri az ellenőrzés egy rövid választ, amelyet a tétlen motor azonnal megad.
Az első verzió a generált tokeneket számolta haladásnak. Nyolc teszten ment át, és az első éles futtatáskor elfoglalt és egészséges szervert talált: 2 futó kérés, 107 új token a két leolvasás között.
Mit változtattunk azóta
- Motorlépések, nem kimeneti tokenek. Amíg a vLLM egy hosszú promptot olvas, egy ideig nem hoz létre kimeneti tokeneket, de továbbra is tesz lépéseket. A lépések számlálása (a vllm:iteration_tokens_total száma) megakadályozza, hogy egy hosszú prompt beragadt szervernek tűnjön.
- Két várakozás a „beragadt” állapot előtt, így egy rövid szünet nem számít hibának.
- A két leolvasás közötti újraindítást észleli a folyamatindítási idő ugyanazon metrikákban; az ellenőrzés ekkor választ kér, ahelyett, hogy két különböző folyamat számlálóit hasonlítaná össze.
- Egy proxyt csak a /models végponton keresztül ellenőriz. Egy legkevesebb kapcsolaton alapuló proxy mögött a /metrics minden egyes leolvasása más-más backendről érkezhet, ahogy azt tapasztaltuk, amikor a modell egy-egy példányát futtattuk két gépen. A backendszervereket közvetlenül ellenőrizzük.
A különbség könnyen látható. Amikor ezt a jegyzetet írtuk, mindkét modellszerverünk egyenként 12 kérést dolgozott fel, a limitjükön. Egy teszt kérésnek várnia kellett volna a sorban. Az új ellenőrzés mindkettőt elfoglalt és egészséges állapotban jelentette, másodpercenként 126 és 101 tokennel, anélkül, hogy küldött volna egyet.
A Factory Floor 1.0.2 ezt az ellenőrzést models/llm-health.py néven szállítja, tesztekkel üresjáratú, elfoglalt, beragadt és újraindított szerverekre, metrikák nélküli szerverre, proxyra és halott backendre.