English translation is not available yet. Showing Russian content.

Что такое autoscaling inference и как его настроить?

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

Autoscaling inference — это автоматическое увеличение или уменьшение количества инстансов (реплик) LLM на основе реальной нагрузки (GPU utilization, длина очереди запросов, p95 latency). Цель — балансировать cost (не оплачивать простаивающие ресурсы) и SLA-метрики (latency, throughput). На Kubernetes настройка выполняется через Pod Autoscaler|Horizontal Pod Autoscaler]] (HPA) с кастомными метриками, выставляемыми инструментами вроде Prometheus + custom-metrics-apiserver. Для LLM-сервинга критично учитывать cooldown и стабилизацию, чтобы избежать «трепетания» (thrashing) из-за резких скачков нагрузки.


1. Зачем нужен autoscaling для LLM inference?

LLM-модели — это тяжёлые вычислительные ресурсы, занимающие десятки гигабайт GPU-памяти. При фиксированном количестве реплик возникает дилемма:

РежимПроблема
Overprovisioning (избыток реплик)Дорого: GPU простаивают, платим за простаивающие ресурсы.
Underprovisioning (недостаток реплик)Долгое ожидание в очереди, превышение SLA по latency, плохой пользовательский опыт.

Autoscaling решает эту дилемму, добавляя реплики при росте нагрузки и удаляя при спаде. В Agentic RAG нагрузка особенно непредсказуема: агенты могут делать десятки последовательных вызовов LLM за один запрос пользователя, а количество одновременных сессий сильно варьируется.


2. Основные метрики для скейлинга

Выбор метрик — ключевой шаг. Чаще всего используют комбинацию:

МетрикаОписаниеТипичный порог для увеличенияПроблемы при игнорировании
GPU utilization% занятости вычислительных ядер GPU>70%Низкая пропускная способность (throughput)
Queue lengthКоличество запросов, ожидающих обработки>50–100Рост latency, таймауты
p95 latencyЗадержка обработки, которую испытывают 95% пользователей>2 секундыНарушение SLA, потеря пользователей
Requests per second (RPS)Интенсивность входящих запросовзависит от capacityПри резком скачке — queue забивается
Memory utilization% занятой GPU памяти>80%OOM (out-of-memory) — падение реплики

Для LLM-инференса GPU utilization — не всегда надёжная метрика: при маленьком batch-размере GPU может быть недогружена, но latency остаётся высокой. Поэтому часто используют queue length как более прямой показатель давления на сервер.


3. Типы autoscaling: reactive vs predictive

3.1 Reactive scaling (реактивный)

Срабатывает после того, как метрика превысила порог. Минус: есть задержка (обычно 1–2 минуты на сбор метрики + принятие решения + запуск подов). При резком всплеске трафика может потребоваться буферизация запросов.

Плюсы:

  • Простота настройки
  • Не требует исторических данных

Минусы:

  • Опоздание (lag)
  • Возможен «эффект качелей» (overshoot → undershoot)

3.2 Predictive scaling (предсказательный)

Использует исторические паттерны нагрузки (например, больше запросов днём, меньше ночью; пики после выхода новой версии). Выполняется schedule-based scaling (например, с 9:00 до 18:00 — 5 реплик, с 18:00 до 9:00 — 1 реплика) или ML-based prediction.

Плюсы:

  • Реагирует до начала роста нагрузки
  • Плавное изменение числа реплик

Минусы:

  • Требует сбора статистики и модели
  • Не срабатывает на аномальные всплески

В продакшене оба подхода комбинируют: predictive задаёт базовое количество реплик, reactive добивает при отклонениях.


4. Настройка autoscaling на Kubernetes с HPA

Horizontal Pod Autoscaler (HPA) — встроенный объект K8s, который изменяет количество реплик Deployment/StatefulSet на основе метрик.

4.1 Пример на основе встроенной метрики CPU

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: llm-server-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: llm-server
  minReplicas: 1
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 60

Но CPU для LLM‑инференса плохо отражает реальную нагрузку (GPU — узкое место). Нужны custom metrics.

4.2 Пример с кастомной метрикой GPU utilization (Prometheus + custom-metrics-apiserver)

Предположим, что каждый под экспортирует метрику gpu_utilization (например, через DCGM-экспортер). После настройки Prometheus и custom-metrics-apiserver можно использовать:

metrics:
  - type: Pods
    pods:
      metric:
        name: gpu_utilization
      target:
        type: AverageValue
        averageValue: 70

Аналогично для queue length:

metrics:
  - type: Object
    object:
      metric:
        name: requests_queue_length
      describedObject:
        apiVersion: v1
        kind: Service
        name: llm-server-service
      target:
        type: Value
        value: 100

4.3 Multiple metrics

HPA позволяет задать несколько метрик. Target для каждой считается независимо, а итоговое количество реплик берётся как максимальное среди расчётов. Например:

metrics:
  - type: Pods
    pods:
      metric: gpu_utilization
      target: AverageValue: 70
  - type: Object
    object:
      metric: queue_length
      target: Value: 100

5. Cooldown (стабилизация) и масштабирование

При autoscaling важно избежать thrashing — частых колебаний числа реплик, когда нагрузка скачет вокруг порога.

Параметры в HPA:

  • stabilizationWindowSeconds (для каждого типа метрики) — временное окно, в течение которого HPA запоминает историю и усредняет значение.
  • behavior — тонкая настройка правил:
behavior:
  scaleDown:
    stabilizationWindowSeconds: 300   # не удалять поды раньше 5 минут после снижения
    policies:
    - type: Percent
      value: 10                       # удалять не более 10% реплик за один шаг
      periodSeconds: 60
  scaleUp:
    stabilizationWindowSeconds: 0     # добавлять реплики при первом же превышении
    policies:
    - type: Pods
      value: 4                        # добавлять до 4 реплик за 60 секунд
      periodSeconds: 60

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

  • Cooldown на scale down — 3–5 минут, чтобы нагрузка успела стабилизироваться.
  • Cooldown на scale up — минимальный (0–30 секунд), так как рост нагрузки требует быстрой реакции.
  • Для LLM серверов с continuous batching (например, vLLM, TensorRT-LLM) при увеличении реплик важно, чтобы новые поды загрузили модель (скачивание весов может занимать 1–2 минуты) — учитывать время readiness probe.

6. Особенности autoscaling для LLM Agentic RAG

Агентные системы создают пикообразную нагрузку: один запрос пользователя может вызвать цепочку из 5–20 вызовов LLM внутри агента. При этом:

  • Queue length может резко вырасти, но после обработки цепочки также резко упасть.
  • GPU utilization может оставаться высокой из-за больших batch-ов, если используется динамическое батчирование.
  • Predictive scaling особенно полезен, если известны типичные сценарии использования агентов.

На практике в Agentic RAG часто используют hybrid scaling:

  • Базовое количество реплик, вычисленное на основе средней нагрузки (predictive).
  • HPA с низким порогом по queue length и коротким cooldown для scale up (react). Для scale down — долгий cooldown (10–15 минут), чтобы не «схлопнуть» реплики между цепочками вызовов агента.

7. Инструменты для реализации autoscaling LLM inference

ИнструментРоль
Kubernetes HPAОсновной контроллер для масштабирования подов
PrometheusСбор метрик (GPU utilization, queue length)
custom-metrics-apiserver / Prometheus AdapterПроксирует метрики из Prometheus в K8s API для HPA
KEDA (Kubernetes Event-Driven Autoscaling)Расширенный autoscaler; поддерживает масштабирование по SQS, Kafka, custom triggers (например, queue length RabbitMQ). Для LLM может быть удобнее, чем HPA с кастомными метриками.
NVIDIA DCGM ExporterЭкспорт GPU-метрик в Prometheus
Seldon / MLServer / KServeПлатформы для serving ML-моделей, включают autoscaling из коробки

Пример с KEDA (scaled object):

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: llm-server-scaledobject
spec:
  scaleTargetRef:
    name: llm-server
  triggers:
  - type: prometheus
    metadata:
      serverAddress: http://prometheus:9090
      metricName: queue_length
      query: sum(rate(llm_queue_length[1m]))
      threshold: "100"

8. Best practices

  1. Начинайте с predictive (schedule-based): проще и безопаснее. Затем добавляйте reactive на основе queue length.
  2. Не используйте одну только GPU utilization: при small batch GPU может быть недогружена, но latency высока. Комбинируйте несколько метрик.
  3. Учитывайте холодный старт: новые поды должны успеть загрузить модель в GPU (download + load). Используйте pre-warmed pools или readiness probe с начальным периодом.
  4. Мониторьте thrashing: если число реплик меняется чаще чем раз в 2 минуты — увеличьте stabilizationWindowSeconds.
  5. Разделяйте модели на разные деплойменты: для агентов и для обычных RAG-запросов — разные HPA с разными политиками.
  6. Автоматически выключайте реплики в периоды zero traffic: используйте scale-to-zero (KEDA) для test/staging сред.

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

Задача: Развернуть маленькую LLM (например, microsoft/DialoGPT-small или distilgpt2) на локальном Kubernetes (minikube) и настроить autoscaling по queue length с помощью KEDA.

Инструменты:

Шаги:

  1. Создать Docker-образ с простым LLM сервером (загружает модель, принимает POST /predict).
  2. Развернуть Deployment и Service в minikube.
  3. Установить KEDA в кластер.
  4. Написать ScaledObject, который масштабирует поды до 5, когда queue length превышает 10 (замерять из приложения через prometheus client).
  5. Сгенерировать нагрузку с помощью locust или hey (10–50 параллельных запросов).
  6. Наблюдать, как число подов увеличивается, а после спада нагрузки — уменьшается через cooldown (настроить stabilizationWindow).

Ожидаемый результат:

  • При росте числа запросов количество реплик поднимется с 1 до 2–5.
  • После остановки нагрузки реплики постепенно вернутся к минимальному значению.
  • Ни одно сообщение не будет потеряно: очерёдность поддерживается через внутреннюю очередь (либо через сервис очереди, например Redis).

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

ВопросТема
820Что такое LLM inference и как он устроен?
823Что такое continuous batching и как он влияет на throughput?
824Что такое speculative decoding и когда его применять?
826Как настроить load balancing для LLM серверов?
827Как мониторить LLM inference в продакшене?
828Какие существуют фреймворки для LLM serving (TGI, vLLM, TensorRT-LLM)?

Навигация