Чего не может видеть LiteLLM: мониторинг работы GPU-сервера под шлюзом
LiteLLM отслеживает запросы и расходы. Для учета времени ожидания в очереди, режимов предварительного заполнения данных и декодирования, перезапусков контейнеров, а также нагрузки на хост требуются метрики Prometheus, vLLM, cAdvisor и трейсы.
Переход от ручно написанного шлюза FastAPI к централизованным журналам запросов LiteLLM, учету токенов и виртуальных ключей, а также сокращение объема кода пользовательского шлюза. Шлюз по-прежнему видит только трафик, проходящий через его границы. Работа в продакшене породила целый ряд вопросов, на которые LiteLLM сам по себе не может ответить — вопросы о очередях, способах предварительного заполнения данных и их декодирования, перезапуске контейнеров и насыщении хоста, что определяет, был ли одиннадцатисекундный запрос успешным или застрял.
Предыстория
LiteLLM находится на границе обработки запросов. Он фиксирует, что пришел запрос, какая модель его обработала, количество токенов, какой виртуальный ключ использовался, а также результат выполнения — успех или неудача. Для ежедневного отслеживания затрат это почти все, что нужно финансовому отделу и команде разработки продукта.
Ниже этой границы картина меняется. Запрос длительностью одиннадцать секунд может означать ожидание в очереди на перегруженном GPU или генерацию длинного ответа. С точки зрения шлюза они выглядят одинаково; однако решения для них разные. Рассматривание их как единого показателя ведет операторов службы поддержки по неверному пути.
На трех уровнях ниже шлюза каждый из них нуждается в собственных показателях:
- Время выполнения модели — здесь определяется задержка. Время до появления первого токена включает как ожидание в очереди, так и предварительную загрузку, причем последняя влияет сильнее, чем декодирование. Пропускная способность при предварительной загрузке и декодировании ограничивается по-разному. Эти данные поступают из собственного интерфейса
/metricsдвижка обслуживания (например, vLLM), а не из шлюза. - Контейнеры — через cAdvisor: какой процесс потребляет память, какой контейнер был перезапущен за ночь.
- Хосты — через node-exporter: общее количество CPU, памяти и дискового пространства на устройстве, где размещены GPU.
Четыре источника данных важны, потому что ни один коллекционер не может увидеть всю картину целиком. Логи Gateway без метрик времени выполнения дают лишь частичную информацию; метрики времени выполнения без контекста хоста и контейнера не учитывают факторы, вроде соседних процессов, которые перезагрузились в три часа ночи.
Полная стек-архитектура
На одном локальном сервере с GPU два проекта Docker Compose намеренно разделяют функции.
Компоненты Gateway: LiteLLM, PostgreSQL для хранения виртуальных ключей и данных о тратах, Redis для кэширования ограничений по частоте запросов.
Компоненты мониторинга: Prometheus, Grafana, node-exporter, cAdvisor. Процессы vLLM часто запускаются на хосте вне обоих стеков — по одному процессу на каждую обслуживаемую модель. Prometheus собирает данные с четырех источников, отвечающих за метрики, связанные с Gateway и самими моделями. Такое разделение не является эстетическим выбором — это способ сохранить опциональную инфраструктуру в режиме опциональности.
Ключевые решения
1. Два файла compose, а не один. LiteLLM уже обслуживал другие команды на момент добавления функции мониторинга. Если объединить Prometheus в тот же файл compose, любые изменения конфигурации сбора данных будут связаны с файлом гейтвея в продакшене. Разделение позволяет изолировать сбои: можно свободно пересоздавать механизмы мониторинга, и LiteLLM этого не заметит. Зависимости существуют в одном направлении. Сетевое взаимодействие между компонентами представляет собой единоразовые затраты по сравнению с постоянным риском распространения сбоев. Если мониторинг выйдет из строя, модели продолжат работать; если гейтвей выйдет из строя, мониторинг всё равно будет фиксировать состояние хоста для анализа после сбоя.
2. По умолчанию отсутствуют postgres-exporter и redis-exporter. Хост может без проблем запускать эти компоненты. Однако их использование отложено:
- Пока LiteLLM работает нормально, внутренним компонентам базы данных и кэша редко требуется панель управления; сбои обычно проявляются сначала на уровне гейтвея.
/metrics уже покрывают критически важные слои.Неиспользуемые панели управления влекут за собой затраты на техническое обслуживание без какой-либо отдачи. Пересмотрите ситуацию, когда ошибки подключения к PostgreSQL станут регулярными, аутентификация с использованием виртуальных ключей замедлится из-за конкуренции за запросы, или давление на память Redis станет реальной проблемой — тогда добавьте экспортеры в тот же неделю. Запишите критерии для отказа, чтобы принятие решения о пропуске оставалось осознанным, а не результатом забывчивости.
3. Сохранение Langfuse. LiteLLM обеспечивает возможность отслеживания запросов, однако одно действие в приложении часто подразумевает множество вызовов модели: получение данных, их краткое изложение, дальнейшая обработка. Общие идентификаторы сессий позволяют группировать такие вызовы в LiteLLM, но отслеживание пользовательского опыта и удержания различается. Логи шлюза предназначены не для долгосрочного хранения. Более старые записи используются в качестве наборов для оценки при замене моделей и помогают в отладке отчетов за предыдущие недели. Метрики представляют собой агрегатные данные; записи позволяют восстановить полную картину. Ни один из этих подходов не может полностью заменить другой — именно поэтому они сохраняются оба.
Практическое использование
1. Указание моделей только в файле config.yaml было неудобно. Модели, хранящиеся в файлах, отображают специальный значок конфигурации в интерфейсе, и их нельзя изменить или удалить без редактирования настроек подключения и перезагрузки активного прокси. Модели, зарегистрированные через API администратора, хранятся в PostgreSQL и сохраняются после перезагрузки системы:
curl -X POST <http://localhost:4000/model/new> \
-H "Authorization: Bearer$LITELLM_MASTER_KEY" \
-H "Content-Type: application/json" \
-d '{
"model_name": "CHAT_MODEL",
"litellm_params": {
"model": "openai/CHAT_MODEL",
"api_base": "<http://host.docker.internal:8001/v1>",
"api_key": "dummy"
}
}'
Рекомендуется использовать конфигурацию для настроек и базу данных для каталога моделей. Такое разделение позволяет операторам добавлять экспериментальные модели, не влияя на процесс шлюза, который используют другие команды.
2. Панель управления Node-Exporter практически не использовалась. После того как нагрузка стабилизировалась, а процессы развертывания замедлились, общие показатели хостов перестали давать ценную информацию. Сохраните скрейпинг, но не вкладывайте слишком много ресурсов в ненужные панели. Панели cAdvisor и vLLM привлекали больше ежедневного внимания, поскольку отражают видимую для пользователя задержку.
3. Полезные стартовые шаблоны Grafana
- Панели сообщества vLLM (например, публичная панель на grafana.com с номером 23991)
- cAdvisor (14282)
- Node Exporter Full (1860)
Импортируйте их в качестве базовых шаблонов, затем удаляйте панели, которые никогда не открываются.
Итог
Очевидным недостатком является отсутствие системы уведомлений: показатели существуют, но страница не отображается при превышении пороговых значений. Подключение API электронной почты приложения к хостам с GPU приводит к смешению функций; в следующий раз выберите более надежный способ уведомлений. Концептуально Prometheus и Grafana отвечают на уже известные вопросы; Langfuse восстанавливает последствия действий пользователя через серию вызовов. Агрегация и восстановление данных дополняют друг друга. Миграция гейтвея без плана мониторинга лишь перемещает «слепую зону» на нижний уровень.