Нашиот health check рестартираше здрав модел-сервер осум пати во еден ден
Операции
На 22 јули watchdog рестартираше нашиот локален модел-сервер осум пати. Ниту еден од тие рестарти немаше пад (crash) зад себе. Проверката што требаше да го држи моделот активен беше тоа што го собори.
Што се случи
Модел-серверот работеше со vLLM на една NVIDIA GB10 машина и произведуваше околу 8 токени во секунда за едно барање. На секои 5 минути watchdog испраќаше вистинско chat барање и чекаше до 45 секунди за одговор. Пет неуспешни проверки по ред значеа сервер во заглавување, и watchdog го рестартираше. Рестартот го отстрануваше моделот за неколку минути додека не се вчитаа повторно околу 19 GB тежини.
Тој ден batch job држеше две до четири барања зафатени на серверот со минути наред. Барањето на watchdog чекаше во редот зад нив, истече времето и се броеше како неуспех. По пет такви проверки, здрав сервер беше рестартиран. Имавме „busy“ flag file што watchdog го почитуваше, но batch job никогаш не го постави.
Како еден лажно рестартирање доведе до следното
Секој рестарт ги неуспешно заврши барањата во тек со 500 грешка („cannot schedule new futures after shutdown“). Втор watchdog броеше 500 грешки и го рестартираше серверот кога имаше премногу, и колку повеќе грешки гледаше, толку побрзо дејствуваше. Значи, секое лажно рестартирање го направи следното побрзо. Вкупно, четири посебни watchdogs можеа да го рестартираат тој сервер, на тајмери од 5, 10, 15 и 30 минути.
Правилото што го извлековме од тоа
Health check не смее да го користи она што го чува. Scarce ресурсот на модел-серверот се неговите слотови за барања во тек. Проверка што зазема еден од тие слотови, или чека за еден, е дел од оптоварувањето што треба да го оцени. Проверувајте евтино и рестартирајте само кога можете да покажете дека серверот е заглавен.
Проверката што го замени
vLLM ги објавува своите бројачи на /metrics. Новата проверка прво ги чита нив:
- Барања во тек и напредок на engine: здраво и зафатено. Не се испраќа тест барање.
- Барања во тек и без напредок помеѓу две читања: заглавено. Ова е случајот што сè уште рестартира.
- Ништо не работи: idle. Само тогаш проверката бара краток одговор, што idle engine го дава веднаш.
Првата верзија ги бројаше генерираните токени како напредок. Помина осум тестови, и на своето прво live извршување го најде серверот зафатен и здрав: 2 барања во тек, 107 нови токени помеѓу двете читања.
Што сменивме од тогаш
- Чекори на моторот, не излезни токени. Додека vLLM чита долг промпт, тој не произведува излезни токени некое време, но сепак презема чекори. Бројењето на чекорите (бројот на vllm:iteration_tokens_total) спречува долгиот промпт да изгледа како сервер кој е заглавен.
- Две чекања пред „заглавување“, за кратко паузирање да не се смета за грешка.
- Рестартирање помеѓу двете читања се детектира преку времето на стартување на процесот во истите метрики; проверката потоа бара одговор наместо да споредува бројачи од два различни процеси.
- Прокси се проверува само преку /models. Зад прокси со најмалку врски, секое читање на /metrics може да доаѓа од различен backend, како што откривме кога пуштивме копија од моделот на секоја од двете машини. Backend-ите се проверуваат директно.
Разликата е лесно видлива. Додека ја пишувавме оваа белешка, двата наши сервери за модели извршуваа по 12 барања, што е нивниот лимит. Тест барање би чекало во редот. Новата проверка пријави дека се зафатени и здрави, со 126 и 101 токен во секунда, без да испрати ниту едно барање.
Factory Floor 1.0.2 ја вклучува оваа проверка како models/llm-health.py, со тестови за неактивни, зафатени, заглавени и рестартирани сервери, сервер без метрики, прокси и мртов backend.