在服务器上使用Slurm管理工作负载时,主要通过编写包含资源请求的Bash脚本,并使用sbatch命令提交作业。以下是关键操作指南。
文章目录
- [1 安装](#1 安装)
-
- [1.1 安装 Munge](#1.1 安装 Munge)
-
- [1.1.1 单机环境](#1.1.1 单机环境)
- [1.1.2 集群节点间](#1.1.2 集群节点间)
- [1.2 安装 slurm](#1.2 安装 slurm)
- [2 资源设置](#2 资源设置)
-
- [2.1 单机配置](#2.1 单机配置)
- [2.2 节点其他设备配置](#2.2 节点其他设备配置)
- [2.3 启动](#2.3 启动)
- [3 使用](#3 使用)
-
-
- [🔧 编写Slurm作业脚本](#🔧 编写Slurm作业脚本)
- [⚙️ 提交与管理作业](#⚙️ 提交与管理作业)
- [🚀 高级用法与技巧](#🚀 高级用法与技巧)
- [💡 实用注意事项](#💡 实用注意事项)
-
1 安装
1.1 安装 Munge
sudo apt update
sudo apt install munge libmunge-dev
1.1.1 单机环境
安装后,需要生成一个密钥文件。这个密钥在单机环境下就足够了
sudo /usr/sbin/create-munge-key
sudo chown munge:munge /etc/munge/munge.key
sudo chmod 400 /etc/munge/munge.key
启动 Munge 服务
设置好密钥后,启动 Munge 服务并设置为开机自启
sudo systemctl enable munge
sudo systemctl start munge
或者
sudo service munge start
验证 Munge
使用以下命令测试 Munge 是否工作正常。如果配置正确,它会返回 STATUS: SUCCESS
munge -n | unmunge
1.1.2 集群节点间
# 在管理节点上生成密钥
sudo /usr/sbin/create-munge-key -r
# 或者使用:sudo dd if=/dev/urandom bs=1 count=1024 of=/etc/munge/munge.key
sudo chown munge: /etc/munge/munge.key
sudo chmod 400 /etc/munge/munge.key
# 将密钥复制到计算节点(例如,计算节点主机名为node1)
sudo scp /etc/munge/munge.key root@node1:/etc/munge/
启动Munge服务:在所有节点上启动并启用Munge服务。确保密钥文件权限正确。
sudo chown -R munge: /etc/munge/ /var/log/munge/ /var/lib/munge/ /run/munge
sudo systemctl enable munge
sudo systemctl start munge
测试认证:在任一节点上使用munge -n | ssh node1 unmunge命令测试到其他节点的认证是否成功
1.2 安装 slurm
apt install slurm-wlm slurmctld slurmd slurm-client
配置 Slurm
在 Slurm 的配置文件(通常是 /etc/slurm-llnl/slurm.conf或 /etc/slurm/slurm.conf)中,需要指定使用 Munge 进行认证
AuthType=auth/munge
2 资源设置
2.1 单机配置
创建slurm.conf文件:配置文件通常位于/etc/slurm/或/etc/slurm-llnl/目录下。你可以使用Slurm官方提供的在线配置工具(Slurm Configurator[https://slurm.schedmd.com/configurator.html\])生成一个基础模板,然后根据你的集群情况进行修改。
确保/etc/slurm/slurm.conf文件权限为644,slurm用户可读
单机服务器配置(8张A800 GPU、128个CPU逻辑核心、1TB内存),以下是一个针对高性能计算场景优化的Slurm配置文件。
sh
# slurm.conf - 单机A800服务器配置
ClusterName=a800_cluster
ControlMachine=localhost
SlurmctldPort=6817
SlurmdPort=6818
SlurmUser=slurm
AuthType=auth/munge
# 日志配置
SlurmctldLogFile=/var/log/slurm/slurmctld.log
SlurmdLogFile=/var/log/slurm/slurmd.log
SlurmctldPidFile=/var/run/slurmctld.pid
SlurmdPidFile=/var/run/slurmd.pid
StateSaveLocation=/var/spool/slurmctld
SlurmdSpoolDir=/var/spool/slurmd
# 调度参数
SchedulerType=sched/backfill
SelectType=select/cons_tres
SelectTypeParameters=CR_Core
MpiDefault=none
ProctrackType=proctrack/cgroup
TaskPlugin=task/affinity,task/cgroup
# 超时设置
SlurmctldTimeout=300
SlurmdTimeout=300
InactiveLimit=0
MinJobAge=300
KillWait=30
Waittime=0
# 定义计算节点
NodeName=localhost NodeAddr=127.0.0.1 CPUs=128 Sockets=2 CoresPerSocket=32 ThreadsPerCore=2 Gres=gpu:a800:8 State=UNKNOWN
# 定义分区(队列)
PartitionName=gpu Nodes=localhost Default=YES MaxTime=INFINITE State=UP OverSubscribe=NO
PartitionName=gpu-debug Nodes=localhost Default=NO MaxTime=02:00:00 State=UP OverSubscribe=NO DefMemPerGPU=24576
PartitionName=cpu Nodes=localhost Default=NO MaxTime=24:00:00 State=UP OverSubscribe=YES
# 内存管理
#DefMemPerCPU=8192
#MaxMemPerCPU=16384
#DefMemPerNode=1048576
# 通过进程组ID(PGID)来跟踪作业,对系统依赖更少。
ProctrackType=proctrack/pgid
关键参数说明:
ControlMachine:指定管理节点的主机名。
NodeName:定义计算节点,格式为NodeName=主机名 CPUs=核心数 RealMemory=内存大小(MB) State=UNKNOWN。
PartitionName:定义作业分区,类似于队列。
分发配置文件:将编辑好的slurm.conf文件复制到所有计算节点的完全相同的路径下。
创建必要的目录:手动创建配置文件中指定的目录(如StateSaveLocation),并确保slurm用户对其有写权限。
sudo mkdir -p /var/spool/slurmctld /var/spool/slurmd
sudo chown slurm: /var/spool/slurmctld /var/spool/slurmd
2.2 节点其他设备配置
# 定义计算节点
NodeName=localhost2 NodeAddr=172.16.73.64 CPUs=128 Sockets=2 CoresPerSocket=32 ThreadsPerCore=2 Gres=gpu:a800:8 State=UNKNOWN
NodeName=localhost3 NodeAddr=172.16.73.65 CPUs=128 Sockets=2 CoresPerSocket=32 ThreadsPerCore=2 Gres=gpu:a800:8 State=UNKNOWN
# 定义分区(队列)
PartitionName=gpu2 Nodes=localhost2 Default=YES MaxTime=INFINITE State=UP OverSubscribe=NO
PartitionName=gpu3 Nodes=localhost3 Default=YES MaxTime=INFINITE State=UP OverSubscribe=NO
2.3 启动
在管理节点上:启动slurmctld(控制守护进程)。
sudo systemctl enable slurmctld
sudo systemctl start slurmctld
service slurmctld start
在计算节点上:启动slurmd(计算节点守护进程)。
sudo systemctl enable slurmd
sudo systemctl start slurmd
service slurmd start
命令sinfo将显示分区和节点的状态,正常情况应为idle(空闲)。
sinfo -N -l
sinfo -o "%all"
查看详细节点信息:使用scontrol命令可以查看节点的详细信息。
scontrol show nodes
提交测试作业:运行一个简单的命令(如hostname)来测试作业调度。
srun -p gpu nvidia-smi
3 使用
🔧 编写Slurm作业脚本
Slurm作业脚本是标准的Bash脚本,其中包含以#SBATCH开头的特殊指令,用于向调度器申请资源。一个基础的脚本结构如下:
bash
#!/bin/bash
#SBATCH --job-name=my_training_job # 作业名称,便于识别
#SBATCH --partition=gpu # 指定提交的分区(队列)
#SBATCH --nodes=1 # 申请的计算节点数量
#SBATCH --ntasks-per-node=1 # 每个节点上运行的任务数(进程数)
#SBATCH --cpus-per-task=8 # 每个任务需要的CPU核心数
#SBATCH --gres=gpu:1 # 申请GPU数量,例如1块
#SBATCH --mem=32G # 每个节点需要的内存总量
#SBATCH --time=02:00:00 # 预计最大运行时间(时:分:秒)
#SBATCH --output=%j.log # 标准输出日志文件,%j会被替换为作业ID
#SBATCH --error=%j.err # 标准错误输出文件
#SBATCH --mail-type=BEGIN,END,FAIL # 邮件通知类型
#SBATCH --mail-user=your_email@domain.com # 接收通知的邮箱
# 加载必要的软件环境(例如,Conda、Python模块)
module load anaconda3/2021.05
source activate your_torch_env
# 进入作业提交时所在的目录
cd $SLURM_SUBMIT_DIR
# 执行你的训练命令
python train.py --config config.json
关键参数说明:
--partition:指定作业队列,如gpu、cpu或debug(测试队列,通常时间限制较短)。--gres:申请通用资源,如GPU(gpu:1)或特定型号GPU(gpu:v100:1)。--time:务必准确估计运行时间,超时作业会被系统强制终止。- 输出路径:确保
--output和--error中指定的目录存在,否则作业可能提交失败。
⚙️ 提交与管理作业
编写好脚本(例如job.sh)后,使用以下命令进行作业管理:
-
提交作业
使用
sbatch命令提交脚本。提交成功后,终端会返回一个作业ID(JobID)。bashsbatch job.sh -
查看作业状态
使用
squeue命令查看当前用户所有作业的状态。bashsqueue -u your_username # 查看指定用户的作业常见的作业状态(
ST列)包括:PD(Pending):作业正在队列中等待资源。R(Running):作业正在运行。CG(Completing):作业正在完成。
-
查看作业详细信息
使用
scontrol命令查看作业的详细配置信息。bashscontrol show job <JobID> -
取消作业
如果需要终止一个正在排队或运行的作业,使用
scancel命令。bashscancel <JobID> # 取消指定作业 scancel -u your_username # 取消用户的所有作业 -
查看历史作业记录
作业完成后,可以使用
sacct命令查看其运行效率等历史信息。bashsacct -j <JobID> --format=JobID,JobName,Partition,Elapsed,MaxRSS,State
🚀 高级用法与技巧
-
并行执行任务
如果需要在同一个作业内同时运行多个程序(例如,同时训练多个模型),可以在Bash脚本中使用
&将其放入后台执行,并用wait命令等待所有任务完成。bash# 在作业脚本中 python train_model_a.py > log_a.out 2>&1 & python train_model_b.py > log_b.out 2>&1 & wait # 等待所有后台任务结束 -
使用任务数组(Job Arrays)处理参数扫描
对于需要多次运行同一程序、仅参数不同的情况(如超参数搜索),使用任务数组可以高效管理。
bash# 在脚本开头添加 #SBATCH --array=1-5%2 # 定义任务数组索引从1到5,%2表示最多同时运行2个任务 python train.py --seed $SLURM_ARRAY_TASK_ID # 使用数组索引作为参数 -
任务依赖关系
如果任务B必须在任务A成功完成后才能开始,可以使用
--dependency参数建立依赖关系。bash# 提交任务A后,获取其JobID(例如为123) sbatch jobA.sh # 提交任务B,并指定其在任务A成功完成后开始 sbatch --dependency=afterok:123 jobB.sh
💡 实用注意事项
-
资源申请原则:只申请任务实际需要的资源量。过度申请(如申请过多CPU核或过长的运行时间)会导致作业排队时间变长,并降低整体资源利用率。
-
环境配置 :作业脚本中的环境变量(如
PATH)可能与登录shell不同。务必在脚本中显式地加载所需环境模块(module load)和激活Conda环境。 -
交互式调试 :对于短时间的测试或调试,可以考虑使用
srun命令进行交互式运行。bashsrun --partition=debug --gres=gpu:1 --time=00:30:00 --pty /bin/bash # 获得一个交互式shell,然后直接运行命令测试