服务器上用Slurm 管理训练bash 脚本任务

在服务器上使用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 Configuratorhttps://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:指定作业队列,如gpucpudebug(测试队列,通常时间限制较短)。
  • --gres:申请通用资源,如GPU(gpu:1)或特定型号GPU(gpu:v100:1)。
  • --time:务必准确估计运行时间,超时作业会被系统强制终止。
  • 输出路径:确保--output--error中指定的目录存在,否则作业可能提交失败。

⚙️ 提交与管理作业

编写好脚本(例如job.sh)后,使用以下命令进行作业管理:

  1. 提交作业

    使用 sbatch 命令提交脚本。提交成功后,终端会返回一个作业ID(JobID)。

    bash 复制代码
    sbatch job.sh
  2. 查看作业状态

    使用 squeue 命令查看当前用户所有作业的状态。

    bash 复制代码
    squeue -u your_username  # 查看指定用户的作业

    常见的作业状态(ST列)包括:

    • PD (Pending):作业正在队列中等待资源。
    • R (Running):作业正在运行。
    • CG (Completing):作业正在完成。
  3. 查看作业详细信息

    使用 scontrol 命令查看作业的详细配置信息。

    bash 复制代码
    scontrol show job <JobID>
  4. 取消作业

    如果需要终止一个正在排队或运行的作业,使用 scancel 命令。

    bash 复制代码
    scancel <JobID>          # 取消指定作业
    scancel -u your_username # 取消用户的所有作业
  5. 查看历史作业记录

    作业完成后,可以使用 sacct 命令查看其运行效率等历史信息。

    bash 复制代码
    sacct -j <JobID> --format=JobID,JobName,Partition,Elapsed,MaxRSS,State

🚀 高级用法与技巧

  1. 并行执行任务

    如果需要在同一个作业内同时运行多个程序(例如,同时训练多个模型),可以在Bash脚本中使用 & 将其放入后台执行,并用 wait 命令等待所有任务完成。

    bash 复制代码
    # 在作业脚本中
    python train_model_a.py > log_a.out 2>&1 &
    python train_model_b.py > log_b.out 2>&1 &
    wait  # 等待所有后台任务结束
  2. 使用任务数组(Job Arrays)处理参数扫描

    对于需要多次运行同一程序、仅参数不同的情况(如超参数搜索),使用任务数组可以高效管理。

    bash 复制代码
    # 在脚本开头添加
    #SBATCH --array=1-5%2  # 定义任务数组索引从1到5,%2表示最多同时运行2个任务
    python train.py --seed $SLURM_ARRAY_TASK_ID  # 使用数组索引作为参数
  3. 任务依赖关系

    如果任务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 命令进行交互式运行。

    bash 复制代码
    srun --partition=debug --gres=gpu:1 --time=00:30:00 --pty /bin/bash
    # 获得一个交互式shell,然后直接运行命令测试
相关推荐
用户03284722207015 小时前
如何搭建本地yum源(上)
运维
大树884 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠4 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质4 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
小宇宙Zz4 天前
Maven依赖冲突
java·服务器·maven
Inhand陈工4 天前
基于台达PLC与映翰通IG502的智慧水产养殖精准投喂与远程运维解决方案
运维·人工智能·物联网·阿里云·信息与通信
酣大智4 天前
ARP代理--工作原理
运维·网络·arp·arp代理
shushangyun_4 天前
2026年快消品B2B系统推荐:支持终端门店订货、促销政策自动化的工具?
java·运维·网络·数据库·人工智能·spring·自动化
古城小栈4 天前
Unix 与 Linux 异同小叙
linux·服务器·unix
施努卡机器视觉4 天前
SNK施努卡侧滑门锁上滑轮总成自动化装配线,从零件到组件,全流程精密制造方案
运维·自动化·制造