集群调度系统 slurm 介绍【一般向】
一般来说,集群是由很多台不同种类的服务器组成的,这些服务器有着相同或类似的操作系统,共享一块容量较大的共享存储。给不同用户分配不同服务器计算资源的软件被称为调度系统。同时,集群普遍处于内网环境中,一般都需要通过VPN再进入集群
目前国内外大部分的集群,都使用slurm调度系统进行集群的统一管理,本文将以普通用户的角度,对slurm的使用方式进行介绍
一 使用概述
1.1 集群组成
- 登录服务器。专门给用户远程登录使用的服务器。用户凭管理员提供的集群账号及密码登入服务器,然后在服务器上可进行文件上传下载、文件编辑、程序编译、软件安装、计算任务提交等操作,但不能直接运行计算任务,否则会导致机器卡顿,影响其他用户登录及使用;
- 计算服务器。专门用来运行计算任务的服务器,数量多、性能强。
- 存储系统。并行存储系统,使用上可看成网盘,在登录服务器和计算服务器都有挂载,挂载的目录名为一般为online或data。数据务必要放在共享目录下才能保证良好的读写性能,以及登录服务器和计算服务器都可以访问操作;
- 调度系统。所有计算服务器由调度系统分配管理。用户首先向调度系统申请计算资源,然后再由调度系统将计算任务投放到分配的计算服务器上运行。
1.2 使用步骤
- 用户在外部互联网,通过
VPN
接入集群中心内部局域网,然后使用集群账号进行集群登录 - 将程序和数据上传到管理员指定的共享存储目录,一般文件夹名称为 online, data 等
- 编写计算任务提交脚本(向调度申请计算资源以及程序运行命令)
- 执行任务提交脚本,将计算任务投放到计算服务器上运行
- 查看程序运行状态
切记所有文件数据都要放在
共享存储
目录下,才能体验超大存储空间和高速读写性能!
1.3 集群登录
如果要远程登录集群,Windows 用户可以使用 Xshell 等终端软件进行连接,此外,还需要安装 Xftp 软件进行文件传输
MAC 和 Linux 用户可以使用操作系统内置的终端和 scp
命令进行连接和文件传输
在连接集群之前,请务必保证自己已经登录了 VPN
二 slurm 使用介绍
2.1 查看集群资源
集群会将不同种类的服务器分成不同的队列,根据配置的不同,一般可以分为:
-
测试队列:提供调试的服务器,一般会对所提交的任务运行最大时间进行限制
-
普通CPU队列:提供CPU算力的服务器,一般一个节点有两颗CPU,核心数与总内存的比值一般为1: 4或1: 2
-
胖节点队列:提供CPU算力的服务器,一般有四颗CPU,核心数与总内存的比值一般为1: 4
-
GPU队列:提供GPU算力的服务器,一般也有两颗CPU,核心数和总内存的比值为1: 8或1: 4
执行sinfo
命令可以查看当前集群的可用资源
[username@login01 data]$ sinfo
PARTITION AVAIL TIMELIMIT NODES STATE NODELIST
cpu* up infinite 10 fail node[047,080]
cpu* up infinite 10 mix node[007,030,035,045,048]
cpu* up infinite 20 alloc node[002-003,010]
cpu* up infinite 10 idle node[001,004-008]
gpu up infinite 10 idle gpu[001-002]
cpu_expr up 2:00:00 10 alloc node012
cpu_expr up 2:00:00 10 idle node[017-019]
-
PARTITION 为队列的分区,一个完整的队列会因为使用情况(被占用或空闲)的不同而自动分区
-
AVAIL 为可用情况,up 表示该队列可用
-
TIMELIMIT 为作业运行时长上限,infinite 表示该队列不限制作业运行时间
-
NODES 为该分区的节点数目
-
STATE 为该分区的状态,分为:
fail
(节点故障),alloc
(节点繁忙),idle
(节点可用),down
(节点下线),mix
(节点部分占用,但仍有剩余资源) -
NODELIST 为该分区的节点主机号范围,node[001,004-008]表示为:node001, node004, node005, node006, node007, node008
2.2 提交计算任务
执行以下命令,可以直接在命令行前台运行程序
srun -p gpu --gres=gpu:1 nvidia-smi
这表示向gpu队列申请了一张GPU以用于执行nvidia-smi
命令。在实际使用中,只需将nvidia-smi更换为自己的程序运行命令即可,但这种方式被称为前台提交,如果终端中断或者网络故障,会导致程序自动停止,所以在调试程序时可以用前台提交的方式,但更建议使用以下后台提交的方式。
新建文件run.sh
,输入以下内容:
#!/bin/bash
#SBATCH -p gpu
#SBATCH --gres=gpu:1
#SBATCH -o job.out
nvidia-smi
#!/bin/bash
,固定内容,不用修改#SBATCH -p gpu
,向调度系统申请gpu
队列的计算资源#SBATCH --gres=gpu:1
,申请1张GPU#SBATCH -o job.out
,程序的运行输出保存在job.out
文件,该文件名可以随意修改nvidia-smi
程序的运行命令,如果要运行 python 脚本,则为python xxx.py
执行sbatch run.sh
提交计算任务
[username@login01 data]$ sbatch run.sh
Submitted batch job 3656
以上为简单的示例程序,具体来说,还有以下额外的配置,用户按需要添加即可
#!/bin/bash
#SBATCH --job-name=JOBNAME #指定作业名称【可选】
#SBATCH -p q_amd_share #指定分区
#SBATCH -N 2 #指定节点数量【可选】
#SBATCH -n 32 #指定总进程数【可选】
#SBATCH --gres=gpu:8 #指定程序在每个节点申请的GPU数目【可选】
#SBATCH --gpus-per-task=1 #指定每个任务所使用的GPU数【可选】
#SBATCH -o job.out #指定输出文件输出
#SBATCH -e job.error.out #指定错误文件输出【可选】
#SBATCH --ntasks-per-node=16 #指定每个节点进程数【可选】
#SBATCH --cpus-per-task=1 #指定每个进程使用 CPU 核心数,不指定默认为 1 【可选】
#SBATCH --nodelist=node[3,4] #指定优先使用节点【可选】
#SBATCH --exclude=node[1,5-6] #指定避免使用节点【可选】
#SBATCH --exclusive #独占该节点【可选】
#SBATCH -t 20 #限制该作业最多运行时间为20s【可选】
module load 模块名 #加载软件或其他环境变量
python xxx.py #作业运行命令
注意:使用 --exclusive 独占选项后,其他人将无法再申请此节点的资源,计费也将基于所有资源计费,而不是实际使用的资源进行计费
2.3 查看任务状态
执行`squeue查看计算任务运行状态
[username@login01 data]$ squeue
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
3656 gpu run.sh admin R 0:23 10 node[054-063]
- JOBID,任务编号
- ST,任务状态,作业状态包括
R
(正在运行),PD
(正在排队),CG
(即将完成),CD
(已完成) - TIME,运行时间
- NODES,占用节点数目
- NODELIST,占用节点的编号
另外,可以规范化squeue的输出内容:
[username@login01 data]$ squeue -o "%.8i %.8P %.8j %.6u %.4T %.4M %.4D %.4C %.14b %V %.50Z"
JOBID PARTITIO NAME USER STAT TIME NODE CPUS TRES_PER_NODE SUBMIT_TIME WORK_DIR
121630 gpu run.sh user RUNN 1:01 1 1 gres:gpu:1 2024-11-19T10:53:30 /benchmark
用户可以根据自身需要,调整squeue的输出,其中TRES_PER_NODE 表示任务占用的GPU数目
2.4 查看程序输出
计算任务运行起来后,执行 tail -f job.out
可 以查看程序的实时输出,执行 Ctrl+C
退出查看
[username@login01 data]$ cat job.out
Tue Nov 19 10:05:11 2024
+---------------------------------------------------------------------------------------+
| NVIDIA-SMI 530.30.02 Driver Version: 530.30.02 CUDA Version: 12.1 |
|-----------------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|=========================================+======================+======================|
| 0 NVIDIA RTX A6000 Off| 00000000:4B:00.0 Off | Off |
| 30% 44C P8 9W / 300W| 8MiB / 49140MiB | 0% Default |
| | | N/A |
+-----------------------------------------+----------------------+----------------------+
+---------------------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=======================================================================================|
| 0 N/A N/A 12239 G /usr/libexec/Xorg 4MiB |
+---------------------------------------------------------------------------------------+
2.5 计算任务停止
执行 scancel 任务编号
停止计算任务,“任务编号” 通过 squeue
的 JOBID
字段可以查到。
scancel 3656
如果要停止自己的所有任务,则执行:
scancel -u username
2.6 计算任务详细信息查看
执行 scontrol show job 任务编号 -dd
可以查到计算任务的工作目录、输出文件等详细信息,如果该作业已经完成,则将无法查看
[username@login01 data]$ scontrol show job 121624 -dd
JobId=121624 JobName=run.sh
UserId=zhangwei1(6712) GroupId=nsccwx_zhangwei1(4594) MCS_label=N/A
Priority=1 Nice=0 Account=nsccwx_zhangwei1 QOS=qos_gpu_1n
JobState=RUNNING Reason=None Dependency=(null)
Requeue=1 Restarts=0 BatchFlag=1 Reboot=0 ExitCode=0:0
DerivedExitCode=0:0
RunTime=00:00:11 TimeLimit=UNLIMITED TimeMin=N/A
SubmitTime=2024-11-19T10:33:14 EligibleTime=2024-11-19T10:33:14
AccrueTime=2024-11-19T10:33:14
StartTime=2024-11-19T10:33:14 EndTime=Unknown Deadline=N/A
SuspendTime=None SecsPreSuspend=0 LastSchedEval=2024-11-19T10:33:14 Scheduler=Main
Partition=gpu AllocNode:Sid=login01:250020
ReqNodeList=(null) ExcNodeList=(null)
NodeList=gpu001
BatchHost=gpu001
NumNodes=1 NumCPUs=1 NumTasks=1 CPUs/Task=1 ReqB:S:C:T=0:0:*:*
ReqTRES=cpu=1,mem=16000M,node=1,billing=1,gres/gpu:rtx4090=1
AllocTRES=cpu=1,mem=16000M,node=1,billing=1,gres/gpu:rtx4090=1
Socks/Node=* NtasksPerN:B:S:C=0:0:*:* CoreSpec=*
JOB_GRES=gpu:rtx4090:1
Nodes=gpu001 CPU_IDs=32 Mem=16000 GRES=gpu:rtx4090:1(IDX:4)
MinCPUsNode=1 MinMemoryCPU=16000M MinTmpDiskNode=0
Features=(null) DelayBoot=00:00:00
OverSubscribe=OK Contiguous=0 Licenses=(null) Network=(null)
Command=/gpfs1p/nsccwx_zhangwei1/zhangwei1/benchmark/run.sh
WorkDir=/gpfs1p/nsccwx_zhangwei1/zhangwei1/benchmark
StdErr=/gpfs1p/nsccwx_zhangwei1/zhangwei1/benchmark/job.out
StdIn=/dev/null
StdOut=/gpfs1p/nsccwx_zhangwei1/zhangwei1/benchmark/job.out
Power=
TresPerNode=gres:gpu:1
在上面的输出中,重点关注以下内容:
ReqTRES=cpu=1,mem=16000M,node=1,billing=1,gres/gpu:rtx4090=1
AllocTRES=cpu=1,mem=16000M,node=1,billing=1,gres/gpu:rtx4090=1
Nodes=gpu001 CPU_IDs=32 Mem=16000 GRES=gpu:rtx4090:1(IDX:4)
ReqTRES表示用户申请的计算资源,上面的输出表示申请的是1个CPU核心,16GB内存,一张4090
AllocTRES表示集群给用户分配的计算资源,上面的输出表示分配的也是1个CPU核心,16GB内存,一张4090
GRES=gpu:rtx4090:1(IDX:4) 表示该任务具体运行在哪张卡上,在故障排查时会用到
2.7 查看节点状态
当某个队列为mix时,需要判断该节点上具体的可用资源有哪些,可以执行 scontrol show node gpu001
命令详细查看
[username@login01 data]$ scontrol show node gpu001
NodeName=gpu001 Arch=x86_64 CoresPerSocket=32
CPUAlloc=1 CPUEfctv=64 CPUTot=64 CPULoad=0.07
AvailableFeatures=(null)
ActiveFeatures=(null)
Gres=gpu:rtx4090:8(S:0-1)
NodeAddr=gpu001 NodeHostName=gpu001 Version=23.02.3
OS=Linux 5.14.0-162.6.1.el9_1.x86_64 #1 SMP PREEMPT_DYNAMIC Fri Nov 18 02:06:38 UTC 2022
RealMemory=1031000 AllocMem=16000 FreeMem=954732 Sockets=2 Boards=1
State=MIXED ThreadsPerCore=1 TmpDisk=0 Weight=1 Owner=N/A MCS_label=N/A
Partitions=gpu
BootTime=2024-10-31T08:03:28 SlurmdStartTime=2024-10-31T09:40:49
LastBusyTime=2024-11-18T11:01:54 ResumeAfterTime=None
CfgTRES=cpu=64,mem=1031000M,billing=64,gres/gpu:rtx4090=8
AllocTRES=cpu=8,mem=16000M,gres/gpu:rtx4090=1
CapWatts=n/a
CurrentWatts=0 AveWatts=0
ExtSensorsJoules=n/s ExtSensorsWatts=0 ExtSensorsTemp=n/s
以上信息中,只需要重点关注下面两行:
CfgTRES=cpu=64,mem=1031000M,billing=64,gres/gpu:rtx4090=8
AllocTRES=cpu=8,mem=16000M,gres/gpu:rtx4090=1
CfgTRES表示这个节点所有的计算资源,上面的输出显示,该节点一共有64个核心,1TB内存,八张4090
AllocTRES表示这个节点已被占用的计算资源,上面的输出显示该节点已经被申请了16GB内存,一张4090
一般来说,集群管理员会将集群的核心数和内存进行捆绑,比如申请一张卡时,会固定分配16GB内存和8个核心,如果程序出现内存不足的情况,则需要申请更多的卡数或向集群管理员协商解决方案
2.8 查找历史作业
使用 sacct
命令可以查看历史作业情况。示例:
sacct -S 2022-10-1500:00:00 -o "jobid,jobname,partition,user,alloccpus,state,nodelist,start,end,workdir%100" -X
该命令将查询从 2022 年 10 月 15 日 0 点以后的所有作业的作业号、作业名,所提交队列、账户名、申请的 CPU 核心数、作业状态、所使用的节点主机号、作业开始时间、作业结束时间、作业的提交目录(最长显示 100 个字符)。
如需进行二次模糊查找,可以使用管道符和 grep 进行筛选过滤。
2.9 集群软件
集群一般都会使用 module 进行软件环境的管理,方便用户加载/卸载软件环境或更换同一个软件的不同版本
使用 module avail
命令可以查看一个集群上已经安装好的全部软件,如下:
[username@login01 data]$ module ava
---------------------------- /data/modulefile ------------------------------
compiler/gcc/9.4.0 soft/amber/24/intel2023u1_impi2023u1_cuda11.8
compiler/intel/2017u5 soft/amber/24/intel2023u1_impi2023u1_cuda12.0.1
compiler/intel/2018u3 soft/amber/24/intel2023u1_impi2023u1_cuda12.4.1
compiler/intel/2019u5 soft/boost/1.82.0/gcc7.3
compiler/intel/2020u4 soft/boost/1.82.0/gcc9.4
compiler/intel/2022u1 soft/boost/1.82.0/gcc11.3.1
compiler/intel/2022u2 soft/cmake/3.19.1
compiler/intel/2023u1 soft/cuda/cuda11.8
mpich/4.0 soft/cuda/cuda12.1
mpich/4.1.2 soft/cuda/cuda12.2
openmpi/1.10.7 soft/cuda/cuda12.3
openmpi/3.1.6 soft/fvcom/4.1/intel2022u2
soft/amber/22/gcc9.4_intel2023u1_cuda11.8 soft/fvcom/4.4.7/intel2022u2
soft/amber/22/intel2023u1_impi2023u1_cuda11.8 soft/gcc-runtime/11.3.1-gcc-11.3.1-g5uvsxn
Key:
modulepath
使用 module load 模块名
加载您需要的软件环境。例如,加载 gcc9.4.0 编译器的命令为 module load compiler/gcc/9.4.0
,如:
[username@login01 data]$ module load compiler/gcc/9.4.0
[username@login01 data]$ gcc -v
使用内建 specs。
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/data/software/gcc/9.4.0/libexec/gcc/x86_64-pc-linux-gnu/9.4.0/lto-wrapper
目标:x86_64-pc-linux-gnu
配置为:../configure --prefix=/data/software/gcc/9.4.0 -enable-languages=c,c++,fortran -disable-multilib
线程模型:posix
gcc 版本 9.4.0 (GCC)
[zhangwei1@login01 benchmark]$
使用module load 模块1 模块2 模块3
同时加载多个模块
注意:使用 module 加载的环境仅临时存在于会话中,下次登录后仍需要重新加载,如需使环境永久生效,建议将 module 命令写入到 $HOME 目录下的
.bashrc
文件中。
使用 module list
命令查看当前会话中加载的全部模块,如:
[username@login01 data]$ module list
Currently Loaded Modulefiles:
1) compiler/gcc/9.4.0 2) openmpi/3.1.6 3) soft/cuda/cuda11.8
使用 module unload 模块名
卸载相应的环境。例如,您需要卸载 gcc9.4.0 并行编译器,则命令为:module unload compiler/gcc/9.4.0
如果您需要将会话中的环境全部卸载,可以使用命令:module purge
评论