Наша проверка работоспособности восемь раз за день перезапускала исправный сервер моделей
Операции
22 июля watchdog восемь раз перезапустил наш локальный сервер моделей. Ни один из этих перезапусков не был вызван сбоем. Проверка, которая должна была держать модель в рабочем состоянии, стала причиной её остановки.
Что произошло
Сервер моделей запускал vLLM на одной машине NVIDIA GB10 и выдавал около 8 токенов в секунду для одного запроса. Каждые пять минут watchdog отправлял ему реальный чат-запрос и ждал ответа до 45 секунд. Пять неудачных проверок подряд означали зависший сервер, и watchdog перезапускал его. Перезапуск лишал вас модели на несколько минут, пока снова загружались веса объемом около 19 ГБ.
В тот день пакетная задача удерживала на сервере от двух до четырех запросов в течение нескольких минут. Запрос watchdog ждал в очереди за ними, время ожидания истекало, и проверка засчитывалась как неудачная. После пяти таких проверок исправный сервер был перезагружен. У нас был файл-флаг «занято», который watchdog учитывал, но пакетная задача его никогда не устанавливала.
Как один ложный перезапуск привел к следующему
Каждый перезапуск завершал текущие запросы ошибкой 500 («cannot schedule new futures after shutdown»). Второй watchdog подсчитывал ошибки 500 и перезапускал сервер, когда их становилось слишком много, и чем больше ошибок он видел, тем быстрее реагировал. Таким образом, каждый ложный перезапуск ускорял наступление следующего. Всего четыре независимых watchdog могли перезапустить этот сервер по таймерам на 5, 10, 15 и 30 минут.
Правило, которое мы вывели из этого
Проверка работоспособности не должна использовать то, что она контролирует. Дефицитным ресурсом сервера моделей являются слоты для текущих запросов. Проверка, занимающая один из этих слотов или ожидающая его, становится частью нагрузки, которую она должна оценивать. Проверяйте дешево и перезапускайте только тогда, когда можете доказать, что сервер завис.
Проверка, заменившая прежнюю
vLLM публикует собственные счетчики по адресу /metrics. Новая проверка сначала считывает их:
- Запросы в работе и движок продвигается: исправен и занят. Тестовый запрос не отправляется.
- Запросы в работе, но прогресса нет между двумя считываниями: завис. Это случай, который по-прежнему вызывает перезапуск.
- Ничего не выполняется: простой. Только тогда проверка запрашивает короткий ответ, который простаивающий движок дает мгновенно.
Первая версия считала прогрессом количество сгенерированных токенов. Она прошла восемь тестов, а при первом боевом запуске обнаружила сервер занятым и исправным: 2 запроса в работе, 107 новых токенов между двумя считываниями.
Что мы изменили с тех пор
- Шаги движка, а не токены вывода. Пока vLLM читает длинный запрос, он некоторое время не выдает токены вывода, но продолжает делать шаги. Подсчет шагов (значение vllm:iteration_tokens_total) не дает длинному запросу выглядеть как зависший сервер.
- Две паузы перед статусом «завис», чтобы короткая задержка не считалась сбоем.
- Перезапуск между двумя чтениями обнаруживается по времени запуска процесса в тех же метриках; тогда проверка запрашивает ответ, вместо того чтобы сравнивать счетчики из двух разных процессов.
- Прокси проверяется только через /models. За прокси с балансировкой по наименьшему числу соединений каждое чтение /metrics может приходить с разных бэкендов, как мы обнаружили, когда запустили копию модели на каждой из двух машин. Бэкенды проверяются напрямую.
Разница очевидна. Когда мы писали это примечание, оба наших сервера моделей обрабатывали по 12 запросов — их предел. Тестовый запрос ждал бы в очереди. Новая проверка сообщила, что оба заняты и здоровы, со скоростью 126 и 101 токен в секунду, не отправив ни одного.
Factory Floor 1.0.2 включает эту проверку в models/llm-health.py, с тестами для простаивающих, занятых, зависших и перезапущенных серверов, сервера без метрик, прокси и недоступного бэкенда.