中文翻译暂不可用,显示俄语原文。

Как вы делаете load shedding при перегрузке LLM сервера?

Краткий тезис

Load shedding — это стратегия защиты LLM-сервера от перегрузки путём выборочного отклонения части запросов. Основные приёмы: приоритизация запросов (premium → regular → batch), отказ от наименее важных (least critical first), возврат Service Unavailable|HTTP 503]] с заголовком Service Unavailable|Service Unavailable|Retry-After. В контексте Agentic RAG нагрузка может резко возрастать из-за цепочек вызовов агентов, поэтому load shedding критичен для стабильности системы.


1. Термин: Load shedding (отбрасывание нагрузки)

Что это: Механизм, при котором сервер намеренно отклоняет часть входящих запросов, чтобы сохранить доступность и качество обслуживания для оставшихся. Отличается от rate limiting (ограничение частоты запросов от одного клиента) и breaker|circuit breaker (размыкание цепи при высокой доле ошибок).

Почему важно для LLM-сервера:

  • LLM-инференс требует много GPU-памяти и времени (секунды на запрос).
  • При пиковой нагрузке (например, от множества агентов) очередь растёт, latency увеличивается, сервер может упасть.
  • Load shedding позволяет контролировать SLA (Agreement) для критичных запросов.

Термин «SLA» — соглашение об уровне обслуживания, например, «95% запросов должны обрабатываться за < 5 секунд».


2. Причины перегрузки LLM-сервера

ПричинаОписаниеПример в Agentic RAG
Flash crowd (внезапный наплыв)Резкий рост числа пользователейВирусный пост с ссылкой на агента
Цепочки агентовОдин запрос пользователя порождает 10–50 вызовов LLMАгент ищет документы, генерирует план, вызывает инструменты
Batch-обработкаФоновые задачи (индексация, суммаризация) конкурируют с онлайн-запросамиНочной пересчёт эмбеддингов
Сбои upstreamЗамедление векторной БД или внешнего APIRetry-логика агента умножает нагрузку

3. Стратегии load shedding

3.1 Приоритизация запросов (Priority queuing)

Запросы делятся на классы с разными приоритетами. При перегрузке низкоприоритетные отклоняются первыми.

КлассПримерыДействие при перегрузке
PremiumПлатные пользователи, критические бизнес-операцииВсегда обслуживаются
RegularБесплатные пользователи, обычные запросыОбслуживаются, если есть ресурсы
BatchФоновые задачи, аналитикаОтклоняются первыми

Реализация Очередь с приоритетами (например, heapq в Python или PriorityBlockingQueue в Java). При поступлении запроса сервер проверяет загрузку (например, длину очереди, utilisation GPU) и решает, принять или отклонить.

3.2 Отказ от наименее важных (Least critical first)

Основан на business value запроса. Например:

  • Запрос «покажи погоду» — низкая ценность.
  • Запрос «оплати заказ» — высокая ценность.

Метрика criticality может вычисляться на основе:

  • Типа запроса (read vs write).
  • Истории пользователя (LTV — Lifetime Value).
  • Времени суток (ночные batch-задачи менее критичны).

3.3 Graceful degradation (плавная деградация)

Вместо полного отказа сервер возвращает упрощённый ответ. Примеры:

  • Использовать меньшую модель (7B вместо 70B).
  • Уменьшить max_tokens или temperature.
  • Отключить retrieval (вернуть ответ без контекста).

3.4 Возврат 503 с Retry-After

Стандартный HTTP-способ сообщить клиенту: «перегружен, попробуй позже». Заголовок Retry-After указывает время ожидания в секундах.

HTTP/1.1 503 Service Unavailable
Retry-After: 30
Content-Type: application/json

{"error": "server overloaded, please retry after 30 seconds"}

Клиент (например, агент) должен реализовать exponential backoff и jitter, чтобы не создавать повторный всплеск.


4. Метрики для принятия решения о load shedding

МетрикаОписаниеПорог срабатывания
Queue depthДлина очереди ожидающих запросов> 100
P99 latency99-й перцентиль времени ответа> 10 секунд
GPU utilisationЗагрузка GPU (память, compute)> 90%
Error rateДоля ошибок 5xx> 5%
Concurrent requestsКоличество одновременно обрабатываемых запросов> max_workers

Формула для динамического порога
threshold = base * (1 - load_factor), где load_factor = current_load / max_capacity.


5. Реализация load shedding на Python (пример)

import asyncio
import time
from enum import Enum

class Priority(Enum):
    PREMIUM = 0
    REGULAR = 1
    BATCH = 2

class Request:
    def __init__(self, priority: Priority, payload: dict):
        self.priority = priority
        self.payload = payload
        self.timestamp = time.time()

class LoadShedder:
    def __init__(self, max_queue: int = 100, max_concurrent: int = 10):
        self.queue = asyncio.PriorityQueue()
        self.max_queue = max_queue
        self.max_concurrent = max_concurrent
        self.current_concurrent = 0

    async def accept(self, request: Request) -> bool:
        # Проверка перегрузки
        if self.queue.qsize() >= self.max_queue:
            if request.priority == Priority.BATCH:
                return False  # отклоняем batch
            elif request.priority == Priority.REGULAR:
                # Можно отклонить, если очередь слишком большая
                if self.queue.qsize() >= self.max_queue * 0.8:
                    return False
        # Premium всегда принимается
        await self.queue.put((request.priority.value, request))
        return True

    async def process(self):
        while True:
            _, request = await self.queue.get()
            if self.current_concurrent >= self.max_concurrent:
                # Возвращаем 503
                print(f"503: {request.payload}")
                continue
            self.current_concurrent += 1
            asyncio.create_task(self._handle(request))

    async def _handle(self, request: Request):
        try:
            # Симуляция обработки LLM
            await asyncio.sleep(1)
            print(f"Processed: {request.payload}")
        finally:
            self.current_concurrent -= 1

6. Load shedding в архитектуре Agentic RAG

Агенты могут генерировать каскадные вызовы:

  • Пользовательский запрос → агент вызывает LLM для планирования → затем несколько вызовов retrieval + LLM для каждого шага.
  • Если каждый шаг — отдельный HTTP-запрос к LLM-серверу, нагрузка умножается.

Рекомендации

  • Агент должен поддерживать retry с backoff и обрабатывать 503.
  • На уровне оркестратора агентов (например, LangGraph) можно ввести rate limiter на количество параллельных вызовов LLM.
  • Использовать circuit breaker: если доля 503 превышает порог, временно блокировать все запросы от данного агента.

7. Сравнение со смежными техниками

ТехникаЦельМеханизмПример
Rate limitingОграничить частоту от одного клиентаToken bucket, sliding window100 req/min per user
Load sheddingЗащитить сервер при общей перегрузкеПриоритеты, отклонениеОтклонить batch при queue > 100
Circuit breakerПредотвратить каскадные сбоиОтслеживание ошибок, размыканиеПосле 50% 503 за 10 сек — break
AutoscalingУвеличить мощностьДобавление инстансовKubernetes HPA

8. Мониторинг и алертинг

Для эффективного load shedding нужно отслеживать:

  • Request rate (RPS) по классам.
  • Drop rate — доля отклонённых запросов.
  • SLA compliance — процент запросов, уложившихся в лимит времени.

Пример алерта в Prometheus

ALERT HighDropRate
  IF rate(llm_requests_dropped_total[5m]) > 0.1
  FOR 2m
  LABELS { severity = "critical" }
  ANNOTATIONS { summary = "Load shedding dropping >10% requests" }

Пет-проект для закрепления

Задача Реализовать симулятор LLM-сервера с load shedding, который обрабатывает запросы от трёх классов (premium, regular, batch) и динамически отклоняет низкоприоритетные при перегрузке.

Инструменты Python, asyncio, aiohttp (для HTTP-сервера), Prometheus client (для метрик).

Шаги:

  1. Создать HTTP-сервер с эндпоинтом /generate.
  2. Внедрить приоритетную очередь (asyncio.PriorityQueue).
  3. Реализовать логику load shedding: при queue > 80% от max — отклонять batch, при > 95% — regular.
  4. Добавить метрики: количество принятых/отклонённых запросов по классам, текущая длина очереди.
  5. Написать нагрузочный тест (например, с помощью locust), который генерирует смешанный трафик.
  6. Визуализировать метрики в Grafana.

Ожидаемый результат Сервер стабильно держит P99 latency < 5 секунд, даже при 3-кратном превышении номинальной нагрузки, за счёт отбрасывания batch и части regular запросов.


Связь с другими вопросами

ВопросТема
248Как вы проектируете систему для обработки burst-нагрузки?
250Как вы реализуете rate limiting для LLM API?
247Как вы обеспечите fault tolerance в Agentic RAG?
245Как вы мониторите производительность LLM-сервера?
251Как вы используете circuit breaker в агентных системах?
246Как вы масштабируете LLM-инференс горизонтально?

Навигация