LabHub
学习 学习路径 课程

HPC 与 Slurm

用 GRES 定义 GPU

在 LabHub 中继续学习

一句话总结

在 Slurm 中,GPU 被视为一种名为 GRES(Generic RESource) 的通用设备资源。两个文件必须相互匹配——slurm.confgres.conf

概念图: GRES(Generic RESource) · 由管理员声明资源的机制 · 存在哪些 GRES 类型,以及每个节点各有多少资源 · 这些 GRES 实际对应哪些设备文件

为什么需要 GRES

Slurm 可以自行统计 CPU 和内存,但 GPU 呢?FPGA 呢?NVMe 呢?Slurm 无法直接识别这些设备,因此建立了一套由管理员声明资源的机制,这就是 GRES。

它是如何工作的

两个文件各自的职责

文件 填写什么 部署范围
slurm.conf 存在哪些 GRES 类型,以及每个节点各有多少资源 所有节点保持一致
gres.conf 这些 GRES 实际对应哪些设备文件 每个节点可以不同

slurm.conf 这一侧:

GresTypes=gpu
NodeName=gpu-node01 ... Gres=gpu:a100:4 State=UNKNOWN

gres.conf 这一侧:

NodeName=gpu-node01 Name=gpu Type=a100 File=/dev/nvidia[0-3] Cores=0-15

两边的数量必须完全一致。 如果 slurm.conf 中写的是 gpu:a100:8,而 gres.conf 中的 File=/dev/nvidia[0-3] 只代表 4 块设备,slurmd 就会在日志中留下 gres/gpu count reported lower than configured,并将节点置于 DRAIN 状态。这是最常见的 GRES 配置错误。

Cores 与 NUMA 亲和性

NodeName=gpu-node01 Name=gpu Type=a100 File=/dev/nvidia0 Cores=0-15
NodeName=gpu-node01 Name=gpu Type=a100 File=/dev/nvidia1 Cores=0-15
NodeName=gpu-node01 Name=gpu Type=a100 File=/dev/nvidia2 Cores=16-31
NodeName=gpu-node01 Name=gpu Type=a100 File=/dev/nvidia3 Cores=16-31

Cores= 用于指出与该 GPU 在物理上相邻、也就是连接到同一 NUMA 节点的 CPU 核心。Slurm 会利用这些信息把 GPU 与 CPU 安排在同一个插槽,从而减少 PCIe 往返传输。大规模训练中,这会带来几个百分点的性能差异。

可以使用 nvidia-smi topo -m 查看实际拓扑。

AutoDetect

AutoDetect=nvml

它通过 NVML 库自动探测 GPU,并自动填入设备文件与 NUMA 亲和性,使用起来很方便;但前提是系统已经安装 NVML,而且 Slurm 构建时启用了它。 此外,如果自动探测结果与 slurm.conf 中的声明不同,节点仍然会退出——自动探测并不能代替验证。

手工定义比较麻烦,但它明确且可复现。在隔离网络或异构集群中,手工配置往往更加安全。

MIG

在 A100/H100 上使用 MIG 时,一块物理 GPU 会被切分为多个实例。此时,每个 MIG 实例都会成为独立的 GRES 项,Type= 中填写配置文件名称。

NodeName=gpu-node01 Name=gpu Type=1g.10gb File=/dev/nvidia-caps/...

MIG 配置改变时,gres.conf 也必须同步改变。 如果不自动化这个过程,每次重新配置 MIG 都会使节点退出。

申请 GPU

sbatch --gres=gpu:2 train.sh                 # 타입 무관 2장
sbatch --gres=gpu:a100:2 train.sh            # a100 2장
sbatch --gpus=2 train.sh                     # 최신 문법
sbatch --gpus-per-node=2 --nodes=2 train.sh  # 노드당 2장씩 총 4장

作业内会自动设置 CUDA_VISIBLE_DEVICES其中的值不是物理设备编号,而是从 0 开始的逻辑编号。因此,不能在代码中硬编码物理编号。

实际工作中会遇到的情况

GPU 数量不一致。 节点上的一块 GPU 因硬件故障消失,配置却保持不变。slurmd 会报告数量不一致,并将节点置于 DRAIN 状态。这个告警反而是一件好事——它总比让作业继续使用故障 GPU 并产生异常结果要好。

没有填写 Cores=,导致性能不佳。 如果 GPU 和 CPU 被安排到不同插槽,数据就必须跨 PCIe 传输。这种影响在多 GPU 训练中尤为明显。

下一个实验要做什么

slurm.conf 中声明 GRES 类型和每个节点的 GPU,编写 gres.conf,并进一步验证两个文件中的数量是否一致