Настроить 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-запросы к инференс-сервису |
Если нет реального инструмента — симулируем:
- Развернуть тестовый k8s-кластер локально (minikube + nvidia-device-plugin) или в облаке (GKE/AKS с GPU-нодами).
- Запустить инференс-сервис на базе ONNX Runtime / Triton Inference Server с моделью ResNet-50.
- Создать скрипт генерации исторической нагрузки: изменять интенсивность запросов (RPS) по расписанию (утром – пик, ночью – спад) в течение 7 дней.
- Настроить сбор метрик: Prometheus с DCGM exporter’ом, визуализация в Grafana.
3. Технологический стек
| Компонент | Инструменты | Назначение |
|---|---|---|
| Мониторинг GPU | NVIDIA 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 часа)
Действия
-
Развернуть стек мониторинга в namespace monitoring:
- Установить Prometheus Operator (helm) или развернуть Prometheus вручную.
- Установить NVIDIA DCGM Exporter (nvidia/dcgm-exporter) как DaemonSet.
- Настроить ServiceMonitor для сбора метрик с DCGM Exporter (например, DCGM_FI_DEV_GPU_UTIL,
DCGM_FI_DEV_MEM_COPY_UTIL).
apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: name: dcgm-exporter namespace: monitoring spec: selector: matchLabels: app: dcgm-exporter endpoints: - port: metrics interval: 15s -
Создать дашборд Grafana для отображения:
-
Проверить сбор данных — выполнить
curlк метрикам Prometheus и убедиться, что метрики GPU присутствуют.
Ожидаемый результат этапа Работающий дашборд Grafana с метриками GPU utilisation, Prometheus хранит историю с шагом 15 с.
Этап 2: Сбор и анализ исторической нагрузки (2–3 часа)
Действия
-
Сгенерировать исторические данные (если нет записи за 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) # пауза на секунду -
Экспортировать данные из Prometheus через HTTP API за период (query:
avg(rate(DCGM_FI_DEV_GPU_UTIL[5m]))). Сохранить в CSV-файл. -
Провести анализ:
- Средняя, пиковая, ночная утилизация.
- Определить weekly seasonality (разница рабочих/выходных дней).
- Выбросы: моменты, когда utilization > 95% или < 5% (перегрузка/недогрузка).
Ожидаемый результат этапа CSV-файл с историей utilization за 7 дней, графики в Jupyter Notebook, выводы о типичных пиках и спадах.
Этап 3: Построение модели предсказания нагрузки (3–4 часа)
Действия
-
Подготовить временной ряд: агрегировать метрики до 5-минутных интервалов (среднее за окно).
-
Построить baseline-модель — простое скользящее среднее (SMA) с окном 60 минут. Рассчитать MAE на последних 6 часах.
-
Улучшить модель: использовать 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) -
Оценить качество: MAE, RMSE на тестовой выборке (последние 24 часа). Цель – MAE < 10 процентных пунктов.
-
Сохранить модель в формат
prophet_model.pklи скрипт инференсаpredict_util.py, который выдаёт предсказание на следующий интервал (например, на +30 минут).
Ожидаемый результат этапа Сохранённая модель Prophet, скрипт предсказания, отчёт с метриками MAE/RMSE.
Этап 4: Настройка авто-масштабирования на основе предсказаний (3–4 часа)
Действия
-
Создать 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" - Установить Prometheus Adapter (
-
Настроить HPA (или KEDA) с параметрами:
minReplicas: 1(один под для фоновой нагрузки)maxReplicas: 10(максимум)targetMetric: 75(целевое значение predicted_gpu_util)
-
Протестировать триггер: вручную увеличить нагрузку, убедиться, что
capacity-predictorвозвращает растущие значения, и KEDA увеличивает количество реплик.
Ожидаемый результат этапа Автоматическое масштабирование подов сервиса инференса в зависимости от предсказанной загрузки GPU.
Этап 5: Тестирование и валидация (2–3 часа)
Действия
-
Запустить нагрузочный тест с сценарием «типичный день» (пик 8:00–20:00) с помощью Locust.
- Вариант: синтезировать реалистичный трафик, меняя RPS от 10 до 200.
-
Мониторить в реальном времени:
-
Проверить целевой диапазон:
- Среднее значение GPU utilization за период теста должно быть 70–80%.
- Не допускается превышение 90% в течение более 10 минут.
- При спаде нагрузки количество реплик должно уменьшаться, не допуская utilization менее 30% (чтобы не тратить ресурсы вхолостую).
-
Зафиксировать результаты:
-
Оптимизировать — при необходимости подкрутить окна прогнозирования, коэффициенты 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%.
- Я задокументировал все шаги, конфиги и результаты в репозитории.