Деплой больших языковых моделей (LLM) — это всегда боль при пиковых нагрузках. В классических веб-сервисах при высоких RPS можно включить балансировщик или вернуть HTTP 429 Too Many Requests. Но в генеративном AI отбрасывать запросы слишком дорого: пользователь уже вложил время, написал промпт и ждёт ответ.
Масштабирование GPU-кластера занимает минуты, которых часто нет. Вместо отбрасывания запросов мы применили подход под названием «Динамическая лень» (Dynamic Degradation). Он позволяет сохранять доступность сервиса при 100% утилизации GPU, заставляя модель отвечать короче. Для этого мы создали open-source шлюз LazyGate.
Архитектура LazyGate
LazyGate — это легковесный ASGI-прокси на FastAPI и httpx, размещённый перед vLLM-сервером. Его основная задача — отслеживать нагрузку на GPU, опрашивая драйверы NVIDIA (или эмулятор в dev-режиме).
Мы выделили три состояния кластера:
- Normal Load (<75%): обычный режим. Модель генерирует полноценные ответы с max_tokens = 100%.
- Tired Load (75–90%): нагрузка растёт, растёт и очередь continuous batching. Шлюз добавляет в промпт инструкцию: «Отвечай кратко», а max_tokens снижается до 70%.
- Extremely Lazy (>90%): аварийный режим. Инжектируется жёсткий системный промпт: «Provide extremely short answers only. No explanations. Code only if asked.» и лимит токенов падает до 30%.
Zero-Blocking поллинг NVML
Чтение метрик GPU через pynvml на каждый HTTP-запрос блокировало бы event loop. Чтобы этого избежать, опрос драйверов вынесен в фоновую asyncio-задачу.
Теперь для каждого запроса получение нагрузки — это просто чтение из памяти: monitor.current_load.
Сохранение стриминга и TTFT
Одна из ключевых фич vLLM — стриминг токенов (stream=True). Если бы шлюз буферизовал ответ, это убило бы Time-to-First-Token (TTFT).
Поэтому мы используем StreamingResponse и передаём токены потоково, не нарушая задержки.
Автономные тесты: AI тестирует свою «лень»
Мы не хотели вручную обновлять Pytest-тесты при каждом изменении профилей нагрузки в config.yaml. Поэтому создали tester_agent.py — внутреннего агента на базе ИИ.
Он читает YAML-конфиг, анализирует тесты через AST и проверяет, покрыты ли все сценарии (Normal, Tired, Lazy). Если находит пробел — автоматически дописывает недостающий тест в test_main.py и перезапускает CI/CD.
Заключение
Динамическая модификация поведения модели через промпт — более гибкая альтернатива жёсткому rate limiting. Вместо отказа в обслуживании мы снижаем сложность генерации, сохраняя доступность.
В планах — заменить прямой опрос NVML на отслеживание Token Velocity, чтобы точнее оценивать пропускную способность очередей vLLM.
Проект открыт и доступен на GitHub под лицензией для академического и некоммерческого использования.