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

Настроить capacity planning для GPU кластера

ТЕХНИЧЕСКОЕ ЗАДАНИЕ: Настроить capacity planning для GPU кластера

1. Цель задачи

Научиться проектировать и реализовывать систему capacity planning для GPU-кластера, которая предсказывает загрузку графических процессоров и автоматически масштабирует вычислительные ресурсы для поддержания целевой утилизации 70–80%. В ходе выполнения будут построены прогнозная модель на основе исторических метрик и механизм авто-масштабирования (horizontal pod autoscaler с custom metrics), что позволит балансировать между производительностью и стоимостью инфраструктуры.

Ключевой результат Рабочий пайплайн capacity planning, обеспечивающий стабильную утилизацию GPU в заданном диапазоне при переменной нагрузке.

2. Исходные данные

Что нужноОткуда взять
GPU-кластер (реальный или тестовый)Kubernetes (k8s) с узлами, оснащёнными NVIDIA GPU (минимум 2–4 GPU, например, T4 или A10G)
Метрики использования GPU (utilization, memory, temperature)NVIDIA DCGM Exporter + Prometheus + Grafana
Исторические данные нагрузки (не менее 7 дней)Prometheus metrics за период; при отсутствии — сгенерировать синтетическую нагрузку с помощью gpu-burn или инференса модели
Конфигурация кластера (количество GPU, типы, планировщик)k8s kubectl describe nodes или дашборд кластера
Инструмент для нагрузочного тестированияlocust или кастомный скрипт на Python, отправляющий batch-запросы к инференс-сервису

Если нет реального инструмента — симулируем:

  1. Развернуть тестовый k8s-кластер локально (minikube + nvidia-device-plugin) или в облаке (GKE/AKS с GPU-нодами).
  2. Запустить инференс-сервис на базе ONNX Runtime / Triton Inference Server с моделью ResNet-50.
  3. Создать скрипт генерации исторической нагрузки: изменять интенсивность запросов (RPS) по расписанию (утром – пик, ночью – спад) в течение 7 дней.
  4. Настроить сбор метрик: Prometheus с DCGM exporter’ом, визуализация в Grafana.

3. Технологический стек

КомпонентИнструментыНазначение
Мониторинг GPUNVIDIA DCGM Exporter, PrometheusСбор метрик utilization, memory, power
ВизуализацияGrafanaДашборд для анализа загрузки и алертов
Кластерный оркестраторKubernetes (k8s) + nvidia-device-pluginРазвёртывание инференс-сервисов, управление GPU-ресурсами
Авто-масштабированиеHorizontal Pod Autoscaler (HPA) v2 / KEDAМасштабирование подов на основе кастомных метрик
Прогнозирование временных рядовPython (Prophet, statsmodels ARIMA) + scikit-learnПостроение модели предсказания утилизации
Нагрузочное тестированиеLocust, shell-скриптыГенерация синтетической нагрузки
Инференс-серверTriton Inference Server / ONNX RuntimeТестовый сервис для утилизации GPU

4. Этапы выполнения

Этап 1: Настройка мониторинга GPU-кластера (2–3 часа)

Действия

  1. Развернуть стек мониторинга в namespace monitoring:

    apiVersion: monitoring.coreos.com/v1
    kind: ServiceMonitor
    metadata:
      name: dcgm-exporter
      namespace: monitoring
    spec:
      selector:
        matchLabels:
          app: dcgm-exporter
      endpoints:
      - port: metrics
        interval: 15s
    
  2. Создать дашборд Grafana для отображения:

    • Средняя утилизация GPU по всем узлам (Gauge)
    • Утилизация по каждому GPU (Time series)
    • Memory usage и температура
    • История за последние 7 дней (для построения baseline)
  3. Проверить сбор данных — выполнить curl к метрикам Prometheus и убедиться, что метрики GPU присутствуют.

Ожидаемый результат этапа Работающий дашборд Grafana с метриками GPU utilisation, Prometheus хранит историю с шагом 15 с.

Этап 2: Сбор и анализ исторической нагрузки (2–3 часа)

Действия

  1. Сгенерировать исторические данные (если нет записи за 7 дней):

    • Написать Python-скрипт, который через Triton Inference Server отправляет запросы с переменной интенсивностью (по расписанию: 8:00–20:00 — 100 RPS, 20:00–8:00 — 20 RPS).
    • Запустить скрипт на 7 дней (в реальности можно ускорить, воспроизведя типичный недельный паттерн за 2 часа с помощью ускоренного времени).
    import time, random
    while True:
        hour = time.localtime().tm_hour
        rps = 100 if 8 <= hour < 20 else 20
        for _ in range(rps):
            # отправляем запрос к Triton
            ...
            time.sleep(1 / rps)
        time.sleep(1)  # пауза на секунду
    
  2. Экспортировать данные из Prometheus через HTTP API за период (query: avg(rate(DCGM_FI_DEV_GPU_UTIL[5m]))). Сохранить в CSV-файл.

  3. Провести анализ:

    • Средняя, пиковая, ночная утилизация.
    • Определить weekly seasonality (разница рабочих/выходных дней).
    • Выбросы: моменты, когда utilization > 95% или < 5% (перегрузка/недогрузка).

Ожидаемый результат этапа CSV-файл с историей utilization за 7 дней, графики в Jupyter Notebook, выводы о типичных пиках и спадах.

Этап 3: Построение модели предсказания нагрузки (3–4 часа)

Действия

  1. Подготовить временной ряд: агрегировать метрики до 5-минутных интервалов (среднее за окно).

  2. Построить baseline-модель — простое скользящее среднее (SMA) с окном 60 минут. Рассчитать MAE на последних 6 часах.

  3. Улучшить модель: использовать Prophet от Facebook (устойчив к пропускам, сезонность). Настроить weekly и daily seasonality.

    from prophet import Prophet
    import pandas as pd
    
    df = pd.read_csv('gpu_util.csv')
    df.columns = ['ds', 'y']  # ds – timestamp, y – utilization
    model = Prophet(yearly_seasonality=False, weekly_seasonality=True, daily_seasonality=True)
    model.fit(df)
    future = model.make_future_dataframe(periods=60, freq='5min')  # прогноз на 5 часов
    forecast = model.predict(future)
    
  4. Оценить качество: MAE, RMSE на тестовой выборке (последние 24 часа). Цель – MAE < 10 процентных пунктов.

  5. Сохранить модель в формат prophet_model.pkl и скрипт инференса predict_util.py, который выдаёт предсказание на следующий интервал (например, на +30 минут).

Ожидаемый результат этапа Сохранённая модель Prophet, скрипт предсказания, отчёт с метриками MAE/RMSE.

Этап 4: Настройка авто-масштабирования на основе предсказаний (3–4 часа)

Действия

  1. Создать Custom Metrics Adapter в k8s, который будет публиковать метрику predicted_gpu_util из Prometheus.

    • Установить Prometheus Adapter (helm install prometheus-adapter ...).
    • Настроить правило в values.yaml для преобразования:
    rules:
      - seriesQuery: 'DCGM_FI_DEV_GPU_UTIL{namespace="inference"}'
        resources:
          overrides:
            namespace: {resource: "namespace"}
            pod: {resource: "pod"}
        name:
          as: "predicted_gpu_util"
        metricsQuery: |
          avg(
            predict_linear(
              DCGM_FI_DEV_GPU_UTIL[5m],
              300,  # прогноз на 5 минут
            )
          ) by (<<.GroupBy>>)
    

    Примечание: predict_linear — встроенная функция Prometheus для линейной экстраполяции. Для Prophet-модели придётся использовать внешний адаптер (например, KEDA ScaledObject с HTTP-источником).

    Альтернатива (рекомендуемая): использовать KEDA с метрикой от внешнего HTTP-эндпоинта, который возвращает предсказание.

    • Развернуть микросервис capacity-predictor (FastAPI), который загружает Prophet-модель, принимает запросы и возвращает predicted_util.
    • Настроить KEDA ScaledObject:
    apiVersion: keda.sh/v1alpha1
    kind: ScaledObject
    metadata:
      name: inference-service-scaler
    spec:
      scaleTargetRef:
        name: inference-service
      triggers:
        - type: metrics-api
          metadata:
            targetValue: "75"          # желаемая утилизация %
            url: "http://capacity-predictor.default.svc.cluster.local/predict"
            valueLocation: "predicted_util"
    
  2. Настроить HPA (или KEDA) с параметрами:

    • minReplicas: 1 (один под для фоновой нагрузки)
    • maxReplicas: 10 (максимум)
    • targetMetric: 75 (целевое значение predicted_gpu_util)
  3. Протестировать триггер: вручную увеличить нагрузку, убедиться, что capacity-predictor возвращает растущие значения, и KEDA увеличивает количество реплик.

Ожидаемый результат этапа Автоматическое масштабирование подов сервиса инференса в зависимости от предсказанной загрузки GPU.

Этап 5: Тестирование и валидация (2–3 часа)

Действия

  1. Запустить нагрузочный тест с сценарием «типичный день» (пик 8:00–20:00) с помощью Locust.

    • Вариант: синтезировать реалистичный трафик, меняя RPS от 10 до 200.
  2. Мониторить в реальном времени:

    • Фактическая утилизация GPU (дашборд Grafana)
    • Количество реплик сервиса
    • Задержки (latency) и ошибки (error rate)
  3. Проверить целевой диапазон:

    • Среднее значение GPU utilization за период теста должно быть 70–80%.
    • Не допускается превышение 90% в течение более 10 минут.
    • При спаде нагрузки количество реплик должно уменьшаться, не допуская utilization менее 30% (чтобы не тратить ресурсы вхолостую).
  4. Зафиксировать результаты:

    • Скриншоты дашборда
    • Логи масштабирования: kubectl get hpa --watch
    • Графики utilization до/после внедрения capacity planning.
  5. Оптимизировать — при необходимости подкрутить окна прогнозирования, коэффициенты HPA, min/max replicas.

Ожидаемый результат этапа Отчёт с графиками, подтверждающий, что utilisation удерживается в интервале 70–80% при реалистичной нагрузке.

5. Критерии приемки (Definition of Done)

  • Prometheus собирает метрики GPU utilization с интервалом ≤ 30 с.
  • Дашборд Grafana отображает текущую и историческую загрузку GPU за последние 7 дней.
  • Модель Prophet обучена на исторических данных, сохранена, MAE прогноза < 10 процентных пунктов.
  • Скрипт предсказания (или микросервис) развёрнут, возвращает метрику predicted_gpu_util для KEDA.
  • KEDA/HPA настроен с целевым значением 75% и корректно масштабирует поды инференс-сервиса.
  • При нагрузочном тесте (не менее 30 минут) средняя utilisation GPU держится в диапазоне 70–80%.
  • Отсутствие ошибок в подах (OOM, crash loop) в процессе масштабирования.
  • Создана документация: README с инструкцией по запуску, конфиги k8s в Git.

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

Основной артефакт Репозиторий с кодом и конфигурациями, содержащий:

  • Папку monitoring/ — манифесты для развёртывания Prometheus, DCGM Exporter, Grafana.
  • Папку predictor/ — скрипт train_model.py, файл модели prophet_model.pkl, микросервис capacity-predictor (FastAPI).
  • Папку scaler/ — манифесты KEDA ScaledObject или HPA, конфиг Prometheus Adapter.
  • Папку loadtest/ — скрипт на Locust для генерации нагрузки.
  • Папку docs/ — отчёт с анализом исторических данных, графиками, результатами тестов.

Дополнительные результаты

  • Дашборд Grafana, импортированный в формате JSON.
  • Видео/скринкаст демонстрации авто-масштабирования в действии.

7. Возможные сложности и их решение

СложностьРешение
Отсутствие длинной истории метрик (меньше 7 дней)Сгенерировать синтетические данные на основе известных паттернов (синусоида + шум) или использовать ускоренное время
Модель Prophet даёт плохие предсказания из-за нестабильного паттернаДобавить регрессоры (например, часы пик, день недели), попробовать более простой ARIMA или использовать скользящее среднее с коррекцией
Медленное масштабирование (поды стартуют >5 минут)Уменьшить интервал опроса HPA (с 15 с до 5 с), использовать burstable QoS или держать 1 hot-standby pod
PromQL-выражение predict_linear имеет ограниченную точностьИспользовать внешний адаптер (capacity-predictor) с Prophet или LSTM
При масштабировании подов возникает конкуренция за GPU (oversubscription)Настроить requests и limits для GPU в контейнере, включить Guaranteed QoS

8. Бюджет времени (оценка)

ЭтапВремя (часы)
Этап 1: Мониторинг GPU-кластера2–3
Этап 2: Сбор и анализ исторической нагрузки2–3
Этап 3: Построение модели предсказания3–4
Этап 4: Настройка авто-масштабирования3–4
Этап 5: Тестирование и валидация2–3
Итого12–17

Примечание: Для первого выполнения рекомендуется заложить верхнюю границу оценки, так как могут возникнуть неожиданные проблемы с конфигурацией k8s и Prometheus.

9. Связанные вопросы из базы знаний

ВопросТема
101Мониторинг GPU в Kubernetes
205Настройка HPA с custom metrics
312Прогнозирование временных рядов (ARIMA, Prophet)
418Сбор метрик с Prometheus и их экспорт
523Конфигурация KEDA ScaledObject
634Оптимизация cost-performance для GPU-инфраструктуры
745Обработка burstable нагрузки и hot-standby
856Тестирование авто-масштабирования с помощью Locust

10. Чек-лист самопроверки

  • Я развернул DCGM Exporter и Prometheus, метрики GPU отображаются в Grafana.
  • Я проанализировал недельную историю utilisation, построил baseline и прогнозную модель с MAE < 10%.
  • Я настроил KEDA/HPA с метрикой predicted_gpu_util и целевым значением 75%.
  • Я провёл нагрузочный тест, убедился, что средняя utilisation находится в диапазоне 70–80%.
  • Я задокументировал все шаги, конфиги и результаты в репозитории.