English translation is not available yet. Showing Russian content.
Как вы делаете load shedding при перегрузке LLM сервера?
Краткий тезис
Load shedding — это контролируемый сброс части входящих запросов при превышении допустимой нагрузки на LLM-сервер. Основная цель — сохранить отказоустойчивость и предсказуемое качество ответов для наиболее критичных клиентов. Стратегия строится на приоритизации трафика, пошаговой деградации некритических функций и прозрачном информировании клиентов через HTTP-статусы. Ключевые метрики — процент отброшенных запросов и время восстановления сервиса.
1. Термин: Load Shedding
Load shedding (буквально «сброс нагрузки») — это техника, при которой сервер намеренно отклоняет часть запросов, когда ресурсы (GPU, CPU, память, пропускная способность) находятся на границе исчерпания. В отличие от rate limiting (ограничение частоты запросов от одного клиента), load shedding работает на уровне общего пула запросов и применяется ситуационно — только в моменты пиковой нагрузки.
| Характеристика | Load Shedding | Rate Limiting |
|---|---|---|
| Цель | Защита сервера от коллапса | Защита от злоупотребления одного клиента |
| Основание | Глобальная загрузка (CPU/GPU/очередь) | Ключ клиента (token bucket, leaky bucket) |
| Реакция | Сброс части запросов (с приоритетом) | Отклонение запросов, превысивших лимит |
| Длительность | Пока пик не спадет | Постоянно действующий лимит |
2. Причины перегрузки LLM-сервера
LLM-инференс ресурсоёмкий: генерация одного токена может занимать миллисекунды, но при batch-обработке и длинных контекстах нагрузка резко растёт. Основные сценарии перегрузки:
- Всплеск трафика (например, после публикации нового AI-продукта).
- Тяжёлые запросы с контекстом 32K+ токенов — они занимают GPU надолго и блокируют остальные.
- Отказ upstream-сервисов (например, базы данных) — запросы начинают зависать и накапливаться в очереди.
- Проблемы с автоскейлингом — новые инстансы не успевают подняться.
При перегрузке без load shedding сервер может уйти в thrashing (частые переключения контекста, OOM), что приведёт к падению всех запросов и длительному восстановлению.
3. Базовая стратегия: приоритизация запросов
Первый шаг — разделить весь трафик на классы. Типичная схема:
| Приоритет | Тип запросов | Пример |
|---|---|---|
| 1 (высший) | Premium / платные | Пользователи с подпиской, критичные API |
| 2 (средний) | Regular | Бесплатные пользователи, обычные web-запросы |
| 3 (низший) | Batch / async / фоновые | Пакетная обработка, аналитика, re-ranking |
При превышении порога нагрузки (например, 80% GPU utilization) начинается selective shedding: сначала сбрасываются запросы 3-го приоритета, потом 2-го. Запросы 1-го приоритета не сбрасываются до тех пор, пока не наступит критическая черта (95%+).
Важно: приоритеты должны быть настраиваемыми через конфигурацию или runtime API. В RAG|Agentic RAG также можно ранжировать запросы по «стоимости» (ожидаемое число токенов) и SLA клиента.
4. Отказ от наименее важных (least critical first)
Это частный случай приоритизации — сброс именно тех запросов, которые принесут наименьший бизнес-ущерб. Как определить «наименее важный»:
- По типу операции — например, re-ranking второстепенных кандидатов можно пропустить, а ответ пользователю — нет.
- По источнику — внутренние тестовые запросы сбрасываются раньше, чем внешние клиентские.
- По истории — для недавно зарегистрированных пользователей можно снизить приоритет (но рискованно с точки зрения UX).
В контексте Agentic RAG least critical часто означает «запросы без привязки к сессии пользователя» — например, фоновый мониторинг качества retrieval’а.
5. Возврат HTTP 503 с Retry-After: 5
Когда сервер решает отбросить запрос, он должен вернуть понятный клиенту ответ. HTTP 503 Service Unavailable — стандартный код для временной недоступности. Обязательно добавлять заголовок Retry-After, чтобы клиент знал, когда повторить попытку.
Пример ответа:
HTTP/1.1 503 Service Unavailable
Retry-After: 5
Content-Type: application/json
{
"error": "server_overloaded",
"message": "Сервер временно перегружен. Повторите запрос через 5 секунд."
}
Retry-After можно выставлять:
- Фиксированное значение (например, 5 или 10 секунд) — просто, но не адаптивно.
- Динамическое — на основе ожидаемого времени освобождения ресурсов (проверяется по длине очереди).
Важно: не все клиенты корректно обрабатывают 503 — для Agentic RAG с собственными AI-агентами нужно предусмотреть логику повторных попыток (exponential backoff).
6. Graceful Degradation (плавная деградация функций)
Вместо полного сброса запроса можно отключить некоторые «тяжёлые» или некритичные компоненты. Это называется graceful degradation. Примеры для LLM-сервера:
- Отключить semantic caching — кеш экономит время, но его запись/чтение добавляет latency. При перегрузке можно временно пропускать кеш.
- Отключить re-ranking — если используется двухступенчатый retrieval (sparse + dense + cross-encoder re-ranker), можно выполнять re-ranking только для premium-запросов.
- Снизить число candidates в retrieval — например, уменьшить top_k с 20 до 5.
- Уменьшить max_tokens генерации — ограничить длину ответа LLM.
- Переключиться на меньшую модель — если есть каскад моделей (например, GPT-4 → GPT-3.5), временно отправлять все запросы на более дешёвую и быструю.
Каждая деградация должна быть измерена по влиянию на качество (faithfulness, answer relevance). Для Agentic RAG можно временно отключать инструменты (tools), которые требуют внешних вызовов (например, поиск в интернете).
7. Мониторинг и алертинг (процент отброшенных запросов)
Load shedding — это не «разовое действие», а управляемый процесс. Необходимо отслеживать:
- Процент отброшенных запросов (% of shedded requests). Целевое значение – менее 1%, иначе страдает пользовательский опыт.
- Среднюю latency и latency p99 при включённом shedding.
- GPU utilization и длину очереди (queue depth).
- Количество деградированных функций (сколько раз отключали re-ranking и т.д.).
При превышении порога (например, > 5% shedded requests или latency p99 > 10s) должен срабатывать алерт. Инструменты: Prometheus + Grafana, Datadog, Sentry.
Полезно вести лог каждого decision — какой запрос сброшен, какой приоритет, какая причина. Это помогает анализировать после инцидента.
8. Архитектурные решения: очереди, circuit breaker, rate limiting
Load shedding не работает в вакууме — его нужно встраивать в общую архитектуру.
Очереди (message queue) — все запросы проходят через буфер (например, Redis Streams, RabbitMQ). Когда очередь переполняется (превышает max queue size), начинается сброс самых старых или низкоприоритетных запросов.
Circuit Breaker — паттерн, который предотвращает каскадные отказы. Если сервис ретривалов (векторная БД) начал отвечать с ошибками, circuit breaker может быстро завершать запросы без обращения к LLM, экономя ресурсы.
Rate Limiting — дополняет load shedding: ограничивает одного клиента, но не защищает от общего пика. Желательно использовать вместе.
Пример архитектуры (псевдокод на Python с asyncio):
import asyncio
from enum import Enum
class Priority(Enum):
PREMIUM = 1
REGULAR = 2
BATCH = 3
async def process_request(request, priority, server_state):
# Проверка состояния
if server_state.should_shed(priority):
raise HTTPException(503, {"Retry-After": 5})
# Graceful degradation: отключаем re-ranking если нагрузка > 90%
if server_state.gpu_util > 90 and priority != Priority.PREMIUM:
request.rerank = False
# Обработка
result = await llm_generate(request)
return result
9. Сравнение стратегий load shedding
| Стратегия | Плюсы | Минусы |
|---|---|---|
| Приоритизация | Сохраняет качество для важных клиентов | Нужна классификация, административные затраты |
| Least critical first | Эффективно при массовых запросах | Сложно определить «критичность» для каждого запроса |
| 503 + Retry-After | Простой, стандартный, обрабатывается клиентами | Клиент может уйти; нет гарантии, что повторит |
| Graceful degradation | Сохраняет сервис, жертвуя качеством | Сложная логика отключения, нужно следить за качеством |
| Очередь с автоматическим shedding | Гибкий, можно настраивать правила | Дополнительные компоненты, latency из-за очереди |
10. Пет-проект для закрепления
Задача: Реализовать middleware для FastAPI, который добавляет load shedding с приоритизацией и graceful degradation.
Инструменты: FastAPI, Redis, httpx (для ретраев), prometheus_client.
Шаги:
- Создать FastAPI endpoint
/v1/generate, который принимает запрос с полемpriority(premium/regular/batch). - Завести глобальный счётчик загрузки GPU (симулировать через random, или измерять реальный utilization через nvidia-smi).
- Реализовать проверки:
- Если GPU utilization > 85% → для
batchвозвращать 503 с Retry-After: 5. - Если GPU > 90% → отключать
rerankдля всех запросов (установить флагrerank=False). - Если GPU > 95% → сбрасывать
regular, кромеpremium.
- Если GPU utilization > 85% → для
- Добавить middleware, который логирует каждый факт shedding (причина, приоритет) в Redis-список.
- Экспортировать метрики через prometheus_client:
shedding_totalиdegradations_total. - Написать тест с синтетической нагрузкой (locust или aiohttp).
Ожидаемый результат:
- При низкой нагрузке все запросы обслуживаются.
- При повышении GPU utilization до 85% batch-запросы получают 503 и должны повторно приходить через 5 секунд.
- При 90%+ regular-запросы также начинают сбрасываться, но premium остаются.
- Метрики в Prometheus показывают корректное число сбросов.
11. Связь с другими вопросами
| Вопрос | Тема |
|---|---|
| 408 | Как вы измеряете latency и throughput RAG-системы? |
| 410 | Как вы реализуете rate limiting для AI-агентов? |
| 413 | Как вы проектируете отказоустойчивость Agentic RAG? |
| 415 | Как вы масштабируете LLM-сервер для Agentic RAG? |
| 417 | Как вы реализуете graceful degradation в Agentic RAG? |
| 420 | Как вы тестируете систему на устойчивость к пиковым нагрузкам? |
Навигация
- Предыдущий: 415
- Следующий: 417
- Индекс: 00. Индекс разборов