slurm

Slurm GPU 集群作业提交、资源申请与调度排错。

补充说明

Slurm 是 HPC 和训练集群常用的作业调度器。GPU 训练的关键是正确声明 GRES、CPU、内存和时限,并理解 cgroup 约束与排队原因。

本文以单机多卡和单节点多作业为主,集群管理命令需要相应权限。

安装与启动

sinfo -o "%20P %5D %14F %8z %10m %25N %10G"
scontrol show node "$NODE" | grep -Ei 'state|gres|cpu|real_memory'
scontrol show config | grep -Ei 'SelectType|GresTypes'

节点没有注册 GPU 时,先检查 gres.conf 的 AutoDetect=nvml 和 slurm.conf 的 GresTypes=gpu。

常用示例

提交单机 8 卡训练作业:

cat > train.sbatch <<'SH'
#!/bin/bash
#SBATCH --job-name=qwen-sft
#SBATCH --partition=gpu
#SBATCH --nodes=1
#SBATCH --ntasks-per-node=1
#SBATCH --cpus-per-task=64
#SBATCH --gres=gpu:8
#SBATCH --mem=512G
#SBATCH --time=24:00:00
#SBATCH --output=%x-%j.out

set -euo pipefail
export OMP_NUM_THREADS=$SLURM_CPUS_PER_TASK
torchrun --nproc_per_node=8 train.py --config config.yaml
SH

sbatch train.sbatch
squeue -u "$USER" -o "%.18i %.9P %.30j %.8T %.10M %.6D %R"

交互式申请一张卡调试:

salloc --partition=gpu --nodes=1 --ntasks=1 --cpus-per-task=16 \
  --gres=gpu:1 --mem=64G --time=2:00:00
srun --pty bash
nvidia-smi
exit

作业结束后核对资源与退出状态:

sacct -j "$JOBID" --format=JobID,JobName,Partition,Elapsed,State,ExitCode,MaxRSS,AllocTRES%50

维护节点:

scontrol update NodeName="$NODE" State=DRAIN Reason="GPU ECC error"
scontrol update NodeName="$NODE" State=RESUME

易错点与排错

读完自测

合上页面,先回答,再展开对照。

  1. 为什么申请了 GPU 但程序看不到卡?
  2. 单机 8 卡为什么用 torchrun --nproc_per_node=8 而不是 8 个 srun 任务?
  3. --mem 和 --mem-per-cpu 怎么选?
答案
  1. 可能是没有用 srun 进入分配、cgroup 未约束,或集群没配置 GPU GRES。先在分配内运行 nvidia-smi -L 和 env | grep CUDA 确认。
  2. torchrun 自己负责启动 8 个进程并完成 rendezvous。外层再用 srun --ntasks=8 会变成 64 个进程,争抢同一批 GPU。
  3. 两者互斥,按集群计费习惯选一个。--mem 是作业总内存,--mem-per-cpu 会乘以申请的核心数;后者在核心多时容易申请过量。

相关条目