服务器上用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 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:指定作业队列,如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,然后直接运行命令测试
相关推荐
孙同学要努力3 小时前
《Linux篇》进程控制——进程创建(写时拷贝)、进程终止(退出码,exit,_exit)
linux·运维·服务器
咕噜企业签名分发-淼淼3 小时前
app分发平台哪个好点?手机app应用内测分发平台支持负载均衡的重要性
运维·智能手机·负载均衡
一个儒雅随和的男子3 小时前
Nginx‌如何配置负载均衡,并使用对不同同负载均衡算法进行配置
运维·nginx·负载均衡
奋斗的蛋黄3 小时前
SRE 进阶:AI 驱动的集群全自动化排查指南(零人工干预版)
运维·人工智能·kubernetes·自动化
激动的兔子3 小时前
Geoserver修行记-安装CSS插件避坑
运维·geoserver·插件安装
来让爷抱一个3 小时前
技术文档搭建实战:基于PandaWiki的五步自动化方案
运维·人工智能·自动化
AC是你的谎言3 小时前
c++仿muduo库实现高并发服务器--connection类
linux·服务器·c++·学习
007tg3 小时前
Facebook多账号管理实战指南:安全合规与效率提升策略
运维·安全·facebook
sanzk4 小时前
S7-PLCSIM Advanced V3.0下载PLC显示红色IP
服务器·网络·tcp/ip