Настройка автоскейлинга GPU-инфраструктуры для AI-нагрузок

GPU-инстанции для AI — дорогой ресурс: час A100 обходится существенно, а idle-простой «съедает» бюджет. Холодный старт нового пода занимает 3–10 минут (загрузка модели, инициализация CUDA), а стандартный CPU-автоскейлинг не учитывает специфику GPU. Без правильного автомасштабирования вы платите за п

Направления AI-разработки

Часто задаваемые вопросы

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1414
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1284
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    980
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1240
  • image_logo-advance_0.webp
    Разработка логотипа компании B2B Advance
    696
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    982

GPU-инстанции для AI — дорогой ресурс: час A100 обходится существенно, а idle-простой «съедает» бюджет. Холодный старт нового пода занимает 3–10 минут (загрузка модели, инициализация CUDA), а стандартный CPU-автоскейлинг не учитывает специфику GPU. Без правильного автомасштабирования вы платите за простои или теряете запросы во время пиков. Мы решаем эту задачу: настраиваем масштабирование, которое реально держит SLA и снижает затраты на 30–40%.

Проблемы, которые мы решаем

Холодный старт: время запуска GPU-пода 3–10 минут. За это время очередь запросов переполняется. Решения: keepalive-поды (минимум 1), pre-warming (запуск при 70% загрузки очереди) и буферизация через request queue. Использование spot-инстанций усугубляет проблему — они могут быть прерваны в любой момент, поэтому сочетаем spot с on-demand для критичных сервисов.

GPU utilization vs queue depth: загрузка GPU во время обработки длинного запроса — 100%, но новые запросы ждут. Полагаться на utilization — ошибка. Правильная метрика — vllm_num_requests_waiting или queue_depth. Мы используем комбинацию: scale-up по глубине очереди, scale-down по utilization.

Thrashing pods: частые взлёты и падения из-за резких пиков. Настройка стабилизационных окон предотвращает это: scale-down через 10 минут, scale-up за 30 секунд.

Почему queue depth — главная метрика для LLM?

GPU utilization не отражает задержки очереди. Когда модель обрабатывает длинный запрос, GPU загружен на 100%, но новые запросы стоят. Queue depth показывает реальную потребность в ресурсах. Именно она должна быть основным триггером для scale-up.

Как мы настраиваем автоскейлинг GPU

Kubernetes HPA с кастомными метриками

Пример конфигурации HPA
# Prometheus Adapter для кастомных метрик apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: vllm-autoscaler namespace: ai-serving spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: vllm-llama3 minReplicas: 1 maxReplicas: 8 metrics: # Основная метрика: очередь ожидающих запросов - type: Pods pods: metric: name: vllm_pending_requests target: type: AverageValue averageValue: "5" # скейл при > 5 запросов в очереди на pod # Дополнительная: GPU utilization (для scale-down) - type: Pods pods: metric: name: nvidia_gpu_duty_cycle target: type: AverageValue averageValue: "70" # scale-down при < 70% утилизации behavior: scaleUp: stabilizationWindowSeconds: 30 # быстрый scale-up policies: - type: Pods value: 2 periodSeconds: 60 # +2 пода каждую минуту scaleDown: stabilizationWindowSeconds: 600 # медленный scale-down (10 минут) policies: - type: Pods value: 1 periodSeconds: 300 # -1 pod каждые 5 минут 

KEDA для event-driven autoscaling

KEDA гибче HPA: скейлинг по Prometheus, Kafka, RabbitMQ, SQS. Ниже пример конфигурации.

apiVersion: keda.sh/v1alpha1 kind: ScaledObject metadata: name: vllm-keda-scaler namespace: ai-serving spec: scaleTargetRef: name: vllm-llama3 minReplicaCount: 1 maxReplicaCount: 10 cooldownPeriod: 300 triggers: - type: prometheus metadata: serverAddress: http://prometheus.monitoring.svc.cluster.local:9090 metricName: vllm_queue_size query: sum(vllm_num_requests_waiting{namespace="ai-serving"}) threshold: "10" # 1 replica на каждые 10 ожидающих запросов - type: prometheus metadata: serverAddress: http://prometheus.monitoring.svc.cluster.local:9090 metricName: request_rate query: rate(http_requests_total{job="vllm"}[2m]) threshold: "20" # дополнительный триггер по RPS 

Cloud-native autoscaling

Для облачных GPU-инстанций используем Auto Scaling Groups с кастомными метриками:

import boto3 autoscaling = boto3.client('autoscaling', region_name='us-east-1') autoscaling.put_scaling_policy( AutoScalingGroupName='llm-gpu-asg', PolicyName='scale-on-queue-depth', PolicyType='TargetTrackingScaling', TargetTrackingConfiguration={ 'CustomizedMetricSpecification': { 'MetricName': 'LLMQueueDepth', 'Namespace': 'Custom/LLMMetrics', 'Statistic': 'Average', }, 'TargetValue': 5.0, 'ScaleInCooldown': 300, 'ScaleOutCooldown': 60, 'DisableScaleIn': False, } ) 

Публикация кастомных метрик из vLLM

Собираем метрики напрямую из инференс-сервера:

from prometheus_client import Gauge, start_http_server import requests import time QUEUE_SIZE = Gauge('llm_queue_depth', 'Number of pending requests') GPU_MEMORY = Gauge('llm_gpu_memory_used_gb', 'GPU memory usage in GB', ['gpu_id']) def collect_metrics(): response = requests.get("http://localhost:8000/metrics").text for line in response.split('\n'): if 'vllm:num_requests_waiting' in line and not line.startswith('#'): queue_size = float(line.split()[-1]) QUEUE_SIZE.set(queue_size) import subprocess result = subprocess.run( ['nvidia-smi', '--query-gpu=memory.used', '--format=csv,noheader,nounits'], capture_output=True, text=True ) for i, mem_mb in enumerate(result.stdout.strip().split('\n')): GPU_MEMORY.labels(gpu_id=str(i)).set(float(mem_mb) / 1024) start_http_server(9091) while True: collect_metrics() time.sleep(15) 

Как pre-warming предотвращает cold start?

Предотвращаем холодный старт прогнозированием загрузки. Если queue depth превышает 70% от максимальной, запускаем дополнительный под заранее. Код стратегии:

class PreWarmingStrategy: def __init__(self, warmup_threshold: float = 0.7, warmup_lead_time: int = 180): self.warmup_threshold = warmup_threshold self.warmup_lead_time = warmup_lead_time def should_scale_up(self, current_queue: int, max_queue: int, forecast: list) -> bool: if current_queue / max_queue >= self.warmup_threshold: return True future_queue = forecast[self.warmup_lead_time // 15] return future_queue / max_queue >= self.warmup_threshold 

Почему GPU-автоскейлинг сложнее CPU?

Основные отличия: GPU-инстанции нельзя «дробить» между сервисами, cold start значительно дольше (загрузка модели ~5 ГБ), а метрики загрузки вводят в заблуждение. На CPU вы опираетесь на CPU utilization, на GPU — только на глубину очереди и скорость поступления запросов. Кроме того, стоимость ошибки выше: лишний GPU-под — лишние расходы в месяц.

Как выбрать метрику для скейлинга?

Метрика Описание Для чего подходит
GPU utilization Доля времени работы ядер, проста в сборе Scale-down, мониторинг базовой загрузки
Queue depth (pending requests) Количество запросов в очереди, требует кастомного экспортера Scale-up, основная метрика
Request rate (RPS) Скорость поступления запросов, хороша для прогноза Pre-warming, дополнительный триггер
GPU memory usage Занятость видеопамяти, низкая вариативность Уведомления о перегрузке

Лучшее решение — комбинация queue depth для scale-up и GPU utilization для scale-down.

Что входит в нашу работу

Мы предлагаем внедрение под ключ:

  1. Аудит текущей инфраструктуры — анализ нагрузки, определение узких мест, подбор инстансов.
  2. Проектирование схемы скейлинга — выбор метрик, настройка HPA/KEDA, оптимизация поведения (stabilization windows, policies).
  3. Реализация — развёртывание Prometheus-стэка, интеграция с vLLM/TGI, настройка автоскейлинг-групп облака.
  4. Тестирование — нагрузочное тестирование с симуляцией пиков, калибровка порогов.
  5. Документация и обучение — runbook для дежурных, описание метрик и алертов.
  6. Пост-релизная поддержка — мониторинг в первые недели, корректировка политик по факту.

Сроки и экономия

Ориентировочные сроки:

  • Базовая настройка (метрики + HPA) — от 5 дней.
  • Расширенная конфигурация (KEDA + pre-warming) — от 10 дней.
  • Полный цикл с нагрузочным тестированием — от 3 недель.

Стоимость рассчитывается индивидуально, исходя из сложности стека и объёма работ. Наши клиенты экономят 30–40% ежемесячных затрат на GPU после внедрения.

Закажите внедрение автоскейлинга GPU и начните экономить уже через неделю. Мы занимаемся инфраструктурой для AI 5+ лет, выполнили 20+ проектов. Гарантируем стабильную работу — в договоре прописываем SLA на время реакции скейлинга. Kubernetes HPA и KEDA — проверенные инструменты. Свяжитесь с нами для консультации по вашему проекту — мы проанализируем нагрузку и предложим оптимальную схему.