Сервис развивается: тестируем формат, собираем идеи, улучшаем сервис. Есть идеи?

Написать
Войти
Дайджесты новостей
Иллюстрация к статье о миграции ML-нагрузок из Slurm в Kubernetes через SkyPilot

Миграция ML-нагрузок из Slurm в Kubernetes: запуск распределённого обучения через SkyPilot

Практическое руководство по переносу AI-пайплайнов из планировщика Slurm в кластер Kubernetes: фреймворк SkyPilot сохраняет привычный синтаксис пакетных задач, транслирует переменные окружения и решает проблему общего хранилища через специализированные тома без необходимости переписывать код обучения.

Миграция ML-нагрузок из Slurm в Kubernetes: запуск распределённого обучения через SkyPilot

Перенос рабочих нагрузок машинного обучения с традиционных суперкомпьютерных кластеров на платформу Kubernetes стал ключевым направлением развития инфраструктуры искусственного интеллекта. Исторически HPC-среда опиралась на планировщик пакетных задач Slurm (Simple Linux Utility for Resource Management). Он предоставлял инженерам простой интерфейс: shell-скрипт с директивами #SBATCH, запуск распределённого обучения через srun и прозрачный доступ к общей сетевой файловой системе (NFS) без контейнерной изоляции.

Однако при масштабировании инфраструктуры платформенные команды стремятся консолидировать мощности в единой среде Kubernetes. Оркестратор обеспечивает централизованный контроль оборудования, разграничение прав (RBAC), декларативное управление конфигурациями, изоляцию в контейнерах и развитый мониторинг. Но для ML-исследователей переход на «чистый» Kubernetes создает высокий порог входа: вместо лаконичного скрипта приходится писать многостраничные YAML-манифесты Pod и Job, вручную настраивать тома PersistentVolumeClaims (PVC) и сетевое взаимодействие узлов.

Открытый фреймворк SkyPilot устраняет этот разрыв. Выступая декларативным диспетчером задач, он транслирует сценарии запуска в примитивы Kubernetes и сохраняет привычный исследовательский цикл без необходимости переписывать обучающие пайплайны.

Отличие парадигм: почему прямой перенос вызывает сложности

Различие между Slurm и Kubernetes кроется в их фундаментальных моделях:

  1. Модель планирования: Slurm ориентирован на научные расчеты и реализует семантику gang scheduling («всё или ничего»). Если задаче требуются два узла по восемь GPU, планировщик не запустит процесс до тех пор, пока все шестнадцать ускорителей не будут одновременно выделены. Стандартный планировщик Kubernetes размещает контейнеры по мере освобождения ресурсов: он может выделить один Pod, а второй оставить в ожидании (Pending). В распределенном обучении PyTorch это приводит к блокировке части GPU и сбою инициализации по таймауту. Для решения проблемы в кластер внедряют специализированные очереди вроде Volcano или Kueue.
  2. Модель окружения: В Slurm окружение активируется системными модулями (module load cuda) и виртуальными средами Python прямо на хосте. В Kubernetes среда строго изолирована внутри Docker-образа.
  3. Файловая система: Slurm предоставляет общую точку монтирования NFS/Lustre с поддержкой POSIX на всех узлах. В Kubernetes сетевой том необходимо явно объявлять через PersistentVolume.

Анатомия манифеста: от Slurm-скрипта к task.yaml

SkyPilot предлагает декларативный формат описания задачи task.yaml. Вместо сложных структур Kubernetes Job разработчик описывает необходимые ресурсы, подготовку окружения (setup) и команду запуска (run).

Сравним классический batch-скрипт Slurm и манифест SkyPilot для распределенного обучения Llama:

Скрипт Slurm (train.sh):

#!/bin/bash
#SBATCH --job-name=llama-pretrain
#SBATCH --nodes=2
#SBATCH --gpus-per-node=8

module load cuda/12.4
source /shared/envs/torch/bin/activate

srun torchrun \
    --nnodes=$SLURM_NNODES \
    --nproc_per_node=$SLURM_GPUS_PER_NODE \
    --rdzv_id=$SLURM_JOB_ID \
    --rdzv_backend=c10d \
    --rdzv_endpoint=$(scontrol show hostnames $SLURM_JOB_NODELIST | head -n 1):29500 \
    train.py --batch-size 32

Манифест SkyPilot (task.yaml):

name: llama-pretrain

num_nodes: 2

resources:
  accelerators: H100:8
  infra: kubernetes

setup: |
  pip install --upgrade pip
  pip install torch torchvision --index-url https://download.pytorch.org/whl/cu124
  pip install -r requirements.txt

run: |
  HEAD_IP=$(echo "$SKYPILOT_NODE_IPS" | head -n 1)
  
  torchrun \
    --nnodes=$SKYPILOT_NUM_NODES \
    --nproc_per_node=$SKYPILOT_NUM_GPUS_PER_NODE \
    --node_rank=$SKYPILOT_NODE_RANK \
    --master_addr=$HEAD_IP \
    --master_port=29500 \
    train.py --batch-size 32

Блок setup выполняется при инициализации среды на каждом узле. Для ускорения старта команды используют базовые Docker-образы с предустановленным PyTorch и CUDA через директиву image_id.

Трансляция переменных окружения и CLI-команд

Официальная документация Migrating from Slurm to SkyPilot определяет прямое соответствие между системными переменными:

ПараметрSlurmSkyPilot
Количество узлов$SLURM_NNODES$SKYPILOT_NUM_NODES
Ранг узла (Rank)$SLURM_NODEID / $SLURM_PROCID$SKYPILOT_NODE_RANK
GPU на узел$SLURM_GPUS_PER_NODE$SKYPILOT_NUM_GPUS_PER_NODE
Список IP узлов$SLURM_JOB_NODELIST$SKYPILOT_NODE_IPS
ID задачи$SLURM_JOB_ID$SKYPILOT_TASK_ID

В отличие от Slurm, где список узлов передается строкой вида node[01-02], переменная $SKYPILOT_NODE_IPS содержит простой построчный список IP-адресов. Нумерация рангов $SKYPILOT_NODE_RANK всегда начинается с нуля, где нулевой ранг выполняет роль координатора рандеву.

Сопоставление команд жизненного цикла задачи:

  • Интерактивная отладка: salloc --gpus=8sky launch -c dev-node --gpus H100:8.
  • Запуск команды на узле: srun python train.pysky exec dev-node python train.py.
  • Пакетная отправка: sbatch script.shsky jobs launch task.yaml.
  • Просмотр очереди: squeuesky status или sky jobs queue.
  • Отмена задачи: scancel <id>sky jobs cancel <id> или sky down dev-node.

Организация дисковой подсистемы: SkyPilot Volumes

В суперкомпьютере датасеты доступны по единому пути /shared/datasets. В Kubernetes локальная файловая система пода эфемерна. Для создания общего сетевого хранилища с поддержкой параллельной записи (ReadWriteMany) SkyPilot использует декларативные тома поверх PVC:

name: shared-checkpoints
type: k8s-pvc
infra: kubernetes
size: 500Gi
config:
  access_mode: ReadWriteMany

Применение тома выполняется вызовом sky volumes apply -f volume.yaml, после чего в task.yaml подключается директива:

volumes:
  /mnt/checkpoints: shared-checkpoints

Для существующего NFS-сервера параметры монтирования указываются через pod_config. Локальный код синхронизируется директивой workdir: ..

Пошаговый регламент миграции и проверка

Для безопасного переноса пайплайнов рекомендуется следовать регламенту:

  1. Инвентаризация скрипта: Зафиксировать версии CUDA, зависимости Python, сетевые порты и параметры torchrun.
  2. Формирование окружения: Подготовить образ или команды в блоке setup.
  3. Настройка томов: Создать манифесты SkyPilot Volumes для чекпоинтов и датасетов.
  4. Одиночный smoke-тест: Запустить тестовую сессию на одном узле:
    sky launch -c test-node --gpus 1 task-single.yaml
    
    Внутри проверить вывод nvidia-smi, доступность каталога /mnt/checkpoints и импорт библиотек в Python.
  5. Проверка распределенного запуска: Запустить двухнодовый тест на 2–3 шага обучения, проверив логи инициализации через sky logs <job_id>.
  6. Пакетный запуск: Отправить задачу через sky jobs launch task.yaml и контролировать ход обучения через sky jobs queue и SkyPilot Dashboard.

Эксплуатационные компромиссы и безопасность

  • Очереди и квоты: Для исключения монополизации GPU кластер Kubernetes необходимо оснастить механизмом Kueue, гарантирующим соблюдение Fair Share и очередей между командами.
  • Безопасность секретов: API-ключи и пароли к хранилищам данных запрещено указывать в task.yaml открытым текстом — их следует передавать через переменные окружения из k8s secrets.
  • Производительность I/O: Сетевые PVC могут уступать локальным дискам HPC. Оптимальная практика — кэшировать датасеты на локальных NVMe-накопителях узлов, сохраняя на сетевой том только контрольные точки.

Использование SkyPilot позволяет объединить гибкость Kubernetes с продуктивностью HPC-инструментов, сохраняя проверенные алгоритмы обучения.