首页
/ 告别集群等待:SLURM环境下多节点训练极速部署指南

告别集群等待:SLURM环境下多节点训练极速部署指南

2026-02-05 04:56:17作者:虞亚竹Luna

你是否还在为SLURM集群中多节点训练配置而头疼?等待数小时却因参数错误功亏一篑?本文将带你一步搞定从环境准备到任务监控的全流程,让你在10分钟内启动分布式训练,轻松应对节点分配、资源调度与故障排查。

读完本文你将掌握:

  • 3分钟编写专业SLURM作业脚本
  • 多节点通信配置核心参数
  • 任务优先级与资源抢占技巧
  • 节点故障快速定位与排除方法
  • 分布式训练日志分离与分析

SLURM基础:从资源申请到任务提交

SLURM(Simple Linux Utility for Resource Management)是高性能计算集群中最常用的作业调度系统。在机器学习训练场景中,它负责协调GPU、CPU、内存等资源分配,确保多用户公平共享集群资源。

核心概念速览

  • 分区(Partition):集群中的资源池,通常按硬件配置或用途划分。例如dev分区用于开发测试,prod分区用于正式训练。
  • 作业(Job):用户提交的计算任务单元,包含资源需求和执行命令。
  • 节点(Node):集群中的物理服务器,每个节点可包含多个GPU和CPU核心。

查看集群节点状态的命令:

sinfo -p dev  # 查看dev分区节点状态
sinfo -p prod # 查看prod分区节点状态

极简作业脚本模板

最基础的SLURM作业脚本结构如下,完整示例可参考orchestration/slurm/example.slurm

#!/bin/bash
#SBATCH --job-name=llama-train      # 作业名称
#SBATCH --nodes=2                   # 节点数量
#SBATCH --ntasks-per-node=1         # 每个节点任务数(关键:分布式训练通常设为1)
#SBATCH --cpus-per-task=96          # 每个任务CPU核心数
#SBATCH --gres=gpu:8                # 每个节点GPU数量
#SBATCH --time=24:00:00             # 运行时间限制
#SBATCH --partition=prod            # 分区名称
#SBATCH --output=%x-%j.out          # 输出日志文件

# 激活环境和执行命令
conda activate ml-env
python train.py --config config.yaml

提交作业命令:sbatch train.slurm

多节点训练核心配置

分布式训练的关键在于节点间通信配置和启动器设置。以下是基于PyTorch的多节点训练完整配置流程。

环境变量与通信设置

在作业脚本中需要设置的核心环境变量:

GPUS_PER_NODE=8
NNODES=$SLURM_NNODES                  # 从SLURM自动获取节点数量
MASTER_ADDR=$(scontrol show hostnames $SLURM_JOB_NODELIST | head -n 1)  # 主节点地址
MASTER_PORT=6000                      # 通信端口

Torchrun启动器配置

使用PyTorch官方启动器torchrun的完整配置,详见orchestration/slurm/launchers/torchrun-launcher.slurm

LAUNCHER="python -u -m torch.distributed.run \
    --nproc_per_node $GPUS_PER_NODE \
    --nnodes $NNODES \
    --node_rank \$SLURM_PROCID \          # 节点序号(关键:必须延迟解析)
    --rdzv_endpoint $MASTER_ADDR:$MASTER_PORT \
    --rdzv_backend c10d \
    "

PROGRAM="train.py --epochs 10 --batch-size 32"  # 实际训练命令

srun --wait=60 --kill-on-bad-exit=1 bash -c "$LAUNCHER $PROGRAM"

关键注意事项\$SLURM_PROCID必须保留反斜杠,确保在每个节点上单独解析,否则所有节点都会被识别为主节点导致通信失败。

高级调度技巧

掌握以下技巧可显著提高资源利用率和训练效率。

作业依赖与优先级

通过作业依赖机制,可以实现训练任务的自动接续,避免长时间等待队列:

# 提交依赖于作业ID 12345的新作业
sbatch --dependency=12345 continue-train.slurm

查看作业预计启动时间:

squeue -u $(whoami) --start  # 显示当前用户作业的预计启动时间

节点资源预留

预分配节点资源用于交互式开发,避免频繁排队:

# 预留一个节点2小时
srun --pty --partition=dev --nodes=1 --gres=gpu:8 --time=2:00:00 bash

作业数组批量处理

使用作业数组可以批量提交相似任务,适合超参数搜索等场景:

# 提交10个任务的数组,每次并行运行1个
sbatch --array=1-10%1 hyperparam-search.slurm

在作业脚本中通过$SLURM_ARRAY_TASK_ID获取当前任务序号。

故障排查与监控

常见错误及解决方法

  1. 节点数量不匹配

    # 在脚本中添加节点数量检查
    if [ "$NNODES" != "$SLURM_NNODES" ]; then
        echo "错误:NNODES=$NNODES 与 SLURM_NNODES=$SLURM_NNODES 不匹配"
        exit 1
    fi
    
  2. GPU不可用 检查节点GPU状态的命令:

    srun --jobid $SLURM_JOB_ID --gres=gpu:0 nvidia-smi  # 在分配的节点上执行nvidia-smi
    
  3. 分布式通信失败 确保--node_rank \$SLURM_PROCID参数正确设置,且没有被提前解析。详细排查方法参见orchestration/slurm/users.md

日志管理策略

为避免多节点日志混乱,建议在脚本中设置按节点分离日志:

#SBATCH --output=%x-%j-%N.out  # %N会被替换为节点主机名

查看作业详细信息的命令:

sacct -j JOBID --long  # 查看作业详细运行信息
sacct -j JOBID -o submitline  # 查看作业提交命令

节点健康检查

快速检测节点GPU是否正常工作的命令:

srun python -c "import torch; print(f'{torch.cuda.is_available()=}')"

性能优化配置

CPU与GPU资源匹配

根据CPU核心数和GPU数量调整线程配置,避免资源浪费:

  • 启用超线程:默认配置,--cpus-per-task设为物理核心数的2倍
  • 禁用超线程:添加#SBATCH --hint=nomultithread--cpus-per-task设为物理核心数

网络性能优化

对于多节点训练,启用NCCL调试日志有助于排查通信瓶颈:

export NCCL_DEBUG=INFO
export NCCL_DEBUG_SUBSYS=COLL

作业脚本最佳实践

完整的高性能作业脚本应包含:

  • 环境一致性检查
  • 资源使用监控
  • 自动错误恢复
  • 详细日志记录

可参考orchestration/slurm/launchers/目录下的各类框架启动器脚本。

总结与进阶

通过本文介绍的方法,你已经能够在SLURM集群上高效部署多节点机器学习训练任务。关键要点:

  1. 正确设置资源需求参数,特别是--ntasks-per-node=1
  2. 确保分布式启动器配置正确,尤其是节点序号和主节点地址
  3. 使用作业依赖和数组提高资源利用率
  4. 实施完善的日志管理和错误检查机制

进阶学习资源:

希望本文能帮助你在SLURM集群中顺利开展大规模模型训练。如有问题或优化建议,欢迎贡献到项目orchestration/slurm/README.md

行动清单

  • [ ] 保存本文到收藏夹
  • [ ] 尝试使用作业数组提交超参数搜索任务
  • [ ] 优化现有训练脚本的日志和错误处理
登录后查看全文
热门项目推荐
相关项目推荐