通用资源 (GRES) 调度

目录

概述

Slurm 支持定义和调度任意通用资源 (GRES) 的能力。针对特定 GRES 类型,启用了额外的内置功能,包括图形处理单元 (GPU)、CUDA 多进程服务 (MPS) 设备和通过可扩展插件机制的分片。

配置

默认情况下,集群的配置中未启用任何 GRES。您必须在 slurm.conf 配置文件中明确指定要管理的 GRES。相关的配置参数是 GresTypesGres

有关更多详细信息,请参见 GresTypesGresslurm.conf 手册页中。

请注意,每个节点的 GRES 规范的工作方式与管理的其他资源相同。发现资源少于配置的节点将被置于 DRAIN 状态。

以下是示例 slurm.conf 文件的片段:

# 配置四个 GPU(带 MPS),加带宽
GresTypes=gpu,mps,bandwidth
NodeName=tux[0-7] Gres=gpu:tesla:2,gpu:kepler:2,mps:400,bandwidth:lustre:no_consume:4G

每个具有通用资源的计算节点通常包含一个 gres.conf 文件,描述节点上可用的资源、数量、相关的设备文件和应与这些资源一起使用的核心。

在某些情况下,您可能希望在节点上定义一个通用资源,而不指定该 GRES 的数量。例如,节点的文件系统类型在该节点上运行作业时不会减少其值。您可以使用 no_consume 标志,允许用户请求一个 GRES,而不必定义一个在请求时使用的数量。

要查看可用的 gres.conf 配置参数,请参见 gres.conf 手册页

运行作业

除非在作业提交时使用以下选项明确请求,否则作业将不会分配任何通用资源:

--gres
每个节点所需的通用资源
--gpus
每个作业所需的 GPU
--gpus-per-node
每个节点所需的 GPU。等同于 GPU 的 --gres 选项。
--gpus-per-socket
每个插槽所需的 GPU。要求作业指定任务插槽。
--gpus-per-task
每个任务所需的 GPU。要求作业指定任务数量。

所有这些选项都受到 sallocsbatchsrun 命令的支持。请注意,所有 --gpu* 选项仅由 Slurm 的 select/cons_tres 插件支持。当 select/cons_tres 插件 配置时,请求这些选项的作业将被拒绝。--gres 选项需要一个参数,指定所需的通用资源及其数量,格式为 name[:type:count],而所有 --gpu* 选项需要一个参数,格式为 [type]:countname 是由 GresTypesGres 配置参数指定的相同名称。type 标识该通用资源的特定类型(例如,特定型号的 GPU)。count 指定所需的资源数量,默认值为 1。例如:
sbatch --gres=gpu:kepler:2 ...

对类型与非类型通用资源的请求必须在作业内保持一致。例如,如果您使用 sbatch 请求 --gres=gpu:2,则不能使用 srun 请求 --gres=gpu:tesla:2 来创建作业步骤。反之亦然,如果您请求一个类型的 GPU 来创建作业分配,则应请求相同类型的 GPU 来创建作业步骤。

还有几个额外的资源需求规范专门用于 GPU,关于这些选项的详细描述可以在作业提交命令的手册页中找到。至于 --gpu* 选项,这些选项仅由 Slurm 的 select/cons_tres 插件支持。

--cpus-per-gpu
每个 GPU 分配的 CPU 数量。
--gpu-bind
定义任务如何绑定到 GPU。
--gpu-freq
指定 GPU 频率和/或 GPU 内存频率。
--mem-per-gpu
每个 GPU 分配的内存。

作业将根据需要分配特定的通用资源以满足请求。如果作业被挂起,这些资源不会变为其他作业可用。

作业步骤可以使用 --gres 选项从分配给作业的通用资源中分配通用资源,如上所述。默认情况下,作业步骤将分配作业请求的所有通用资源,除了在作业是独占时隐式请求的那些资源。如果需要,作业步骤可以明确指定与作业不同的通用资源数量。这个设计选择基于一个场景,即每个作业执行多个作业步骤。如果作业步骤默认获得所有通用资源的访问权限,则某些作业步骤需要明确指定零个通用资源数量,这被认为更令人困惑。作业步骤可以分配特定的通用资源,这些资源将不对其他作业步骤可用。以下是一个简单的示例。

#!/bin/bash
#
# gres_test.bash
# 提交如下:
# sbatch --gres=gpu:4 -n4 -N1-1 gres_test.bash
#
srun --gres=gpu:2 -n2 --exclusive show_device.sh &
srun --gres=gpu:1 -n1 --exclusive show_device.sh &
srun --gres=gpu:1 -n1 --exclusive show_device.sh &
wait

自动检测

如果在 gres.conf 中设置 AutoDetect=nvmlAutoDetect=nvidiaAutoDetect=rsmiAutoDetect=nrtAutoDetect=oneapi,则会自动填充任何系统检测到的 GPU 的配置细节。这消除了在 gres.conf 中明确配置 GPU 的需要,但仍然需要在 slurm.conf 中的 Gres= 行,以告知 slurmctld 预期的 GRES 数量。

请注意,AutoDetect=nvmlAutoDetect=rsmiAutoDetect=oneapi 需要在节点上安装相应的 GPU 管理库,并在 Slurm 配置期间找到以便正常工作。AutoDetect=nvmlAutoDetect=nvidia 检测 NVIDIA GPU。AutoDetect=nvidia(在 Slurm 24.11 中添加)不需要安装 nvml 库,但不检测 MIG 或 NVlinks。

当自动检测需要加载上述 GPU 管理库时,它通常会在 slurmd 启动后立即卸载此库,以便其他进程可以随后访问该库。当在 slurm.conf 中设置 AcctGatherEnergyType=acct_gather_energy/gpu 时,情况则不同。在这种配置中,slurmd 将保持由自动检测选项指定的 GPU 库加载,以跟踪 GPU 能耗。

AutoDetect=nvmlAutoDetect=rsmi 还会导致 slurmstepd 加载并保持打开库,以在相关步骤请求 GPU 时执行 GPU 使用情况的计费。如果您不希望发生这种情况,请在 slurm.conf 中设置 JobAcctGatherParams=DisableGPUAcct

AutoDetect=nvmlAutoDetect=rsmiAutoDetect=oneapi 将导致 slurmstepd 加载并保持打开库,以在作业请求 --gpu-freq 时配置 GPU 频率。

在上述情况下,当进程保持打开 GPU 管理库时,任何其他进程都无法配置 GPU。如果您需要在 Prolog 或其他地方进行更改,则希望在 slurm.conf 中不设置 AcctGatherEnergyType=acct_gather_energy/gpu。如果作业在节点上共享 GPU,您可能还需要在 slurm.conf 中设置 JobAcctGatherParams=DisableGPUAcct

默认情况下,所有系统检测到的设备都将添加到节点中。然而,如果在 gres.conf 中的 TypeFile 与系统上的 GPU 匹配,则可以对任何其他明确指定的属性(例如 CoresLinks)进行双重检查。如果系统检测到的 GPU 与其匹配的 GPU 配置不同,则该 GPU 将被省略,并出现错误。这允许 gres.conf 作为可选的合理性检查,并通知管理员 GPU 属性的任何意外更改。

如果 slurm.conf 配置中未指定所有系统检测到的设备,则相关的 slurmd 将被排水。然而,如果在 gres.conf 中手动指定(禁用自动检测),仍然可以使用系统上找到的设备的子集。

示例 gres.conf 文件:

# 配置四个 GPU(带 MPS),加带宽
AutoDetect=nvml
Name=gpu Type=gp100  File=/dev/nvidia0 Cores=0,1
Name=gpu Type=gp100  File=/dev/nvidia1 Cores=0,1
Name=gpu Type=p6000  File=/dev/nvidia2 Cores=2,3
Name=gpu Type=p6000  File=/dev/nvidia3 Cores=2,3
Name=mps Count=200  File=/dev/nvidia0
Name=mps Count=200  File=/dev/nvidia1
Name=mps Count=100  File=/dev/nvidia2
Name=mps Count=100  File=/dev/nvidia3
Name=bandwidth Type=lustre Count=4G Flags=CountOnly

在此示例中,由于指定了 AutoDetect=nvml,因此每个 GPU 的 Cores 将与系统上找到的对应 GPU 进行检查,以匹配指定的 TypeFile。由于未指定 Links,因此将根据系统上找到的内容自动填写。如果未找到匹配的系统 GPU,则不会进行验证,并假定 GPU 如配置所示。

要使 Type 与系统检测到的设备匹配,它必须完全匹配或是 slurmd 通过自动检测机制报告的 GPU 名称的子字符串。此 GPU 名称将用下划线替换所有空格。要查看检测到的 GPU 及其名称,请运行: slurmd -C

$ slurmd -C
NodeName=node0 ... Gres=gpu:geforce_rtx_2060:1 ...
找到 gpu:geforce_rtx_2060:1,使用 AutoDetect=nvml(可以使用 GPU 名称的子字符串)
UpTime=...

在此示例中,GPU 的名称报告为 geforce_rtx_2060。因此,在您的 slurm.conf 和 gres.conf 中,GPU Type 可以设置为 geforcertx 2060geforce_rtx_2060,或任何其他 子字符串,slurmd 应该能够将其匹配到系统检测到的设备 geforce_rtx_2060。 要检查您的配置,您可以运行: slurmd -G 这将根据当前配置测试并打印 gres 设置,包括任何被忽略的自动检测的 gres。

计费

GPU 内存和 GPU 利用率可以作为使用 GPU 资源的任务的 TRES 进行跟踪。如果配置了 AccountingStorageTRES=gres/gpu,则 gres/gpumem 和 gres/gpuutil 将自动配置并从 GPU 作业中收集。gres/gpumem 和 gres/gpuutil 也可以在未设置 gres/gpu 时单独设置。

gres/gpumem 和 gres/gpuutil 仅在使用 AutoDetect=nvml 时可用于 NVIDIA GPU,在使用 AutoDetect=rsmi 时可用于 AMD GPU。

NVML 不支持 MIG 的利用率指标,因此 Slurm 不提供 MIG 设备的 gpumem 或 gpuutil 计费。请参见 NVIDIA 的 MIG 用户指南

以下是一个具有两个 NVIDIA A100 GPU 的示例节点:

$ nvidia-smi -L
GPU 0: NVIDIA A100-PCIE-40GB (UUID: GPU-...)
GPU 1: NVIDIA A100-PCIE-40GB (UUID: GPU-...)

以下是示例 slurm.conf 和 gres.conf 的摘录,这将自动启用对 gres/gpumem 和 gres/gpuutil 的跟踪。

slurm.conf:

AccountingStorageTres=gres/gpu
NodeName=n1 Gres=gpu:a100:2

gres.conf:

AutoDetect=nvml

这是一个使用每个任务一个 GPU、总共两个 GPU 的作业示例。

$ srun --tres-per-task=gres/gpu:1 -n2 --gpus=2 --mem=2G gpu_burn
GPU 0: NVIDIA A100-PCIE-40GB (UUID: GPU-...)
GPU 0: NVIDIA A100-PCIE-40GB (UUID: GPU-...)

作业完成后,我们可以使用 sacct 查看这些 TRES 的利用率详细信息。请注意,这里有多个任务,我们可以使用 TRESUsageIn[Min,Max,Ave,Tot] 来检查所有步骤中 gpumem 和 gpuutil 的“高水位线”,这与其他 TRESUsage* 值相同:

$ sacct -j 1277.0 --format=tresusageinave -p
TRESUsageInAve|
cpu=00:00:11,energy=0,fs/disk=87613,gres/gpumem=36266M,gres/gpuutil=100,mem=628748K,pages=0,vmem=0|
$ sacct -j 1277.0 --format=tresusageintot -p
TRESUsageInTot|
cpu=00:00:22,energy=0,fs/disk=175227,gres/gpumem=72532M,gres/gpuutil=200,mem=1257496K,pages=0,vmem=0|

GPU 管理

在 Slurm 的 GRES 插件用于 GPU 的情况下,环境变量 CUDA_VISIBLE_DEVICES 会为每个作业步骤设置,以确定每个节点上可用的 GPU。这一环境变量仅在特定计算节点上启动任务时设置(对于 salloc 命令未设置全局环境变量,而 sbatch 命令设置的环境变量仅反映该节点上分配给该作业的 GPU,即分配的节点零)。CUDA 版本 3.1(或更高版本)使用此环境变量在具有 GPU 的节点上运行多个作业或作业步骤,并确保分配给每个作业的资源是唯一的。在上述示例中,分配的节点可能具有四个或更多图形设备。在这种情况下,CUDA_VISIBLE_DEVICES 将引用每个文件的唯一设备,输出可能类似于:

JobStep=1234.0 CUDA_VISIBLE_DEVICES=0,1
JobStep=1234.1 CUDA_VISIBLE_DEVICES=2
JobStep=1234.2 CUDA_VISIBLE_DEVICES=3

注意:请确保在 gres.conf 文件中指定 File 参数,并确保它们按递增的数字顺序排列。

环境变量 CUDA_VISIBLE_DEVICES 还将在作业的 Prolog 和 Epilog 程序中设置。请注意,作业设置的环境变量可能与 Prolog 和 Epilog 设置的环境变量不同,如果 Slurm 被配置为使用 Linux cgroup 限制作业可见的设备文件。这是因为 Prolog 和 Epilog 程序在任何 Linux cgroup 外部 运行,而作业在 cgroup 内部 运行,因此可能具有不同的可见设备集。例如,如果作业分配了设备 “/dev/nvidia1”,则 CUDA_VISIBLE_DEVICES 在 Prolog 和 Epilog 中将设置为值 “1”,而作业的 CUDA_VISIBLE_DEVICES 的值将设置为 “0”(即作业可见的第一个 GPU 设备)。有关更多信息,请参见 Prolog 和 Epilog 指南

在可能的情况下,Slurm 会使用 NVML 自动确定系统上的 GPU。NVML(为 nvidia-smi 工具提供支持)按其 PCI 总线 ID 对 GPU 进行编号。为了使此编号与 CUDA 报告的编号匹配,必须将环境变量 CUDA_DEVICE_ORDER 设置为 CUDA_DEVICE_ORDER=PCI_BUS_ID

GPU 设备文件(例如 /dev/nvidia1)基于 Linux 次要编号分配,而 NVML 的设备编号是通过 PCI 总线 ID 从低到高分配的。这两者之间的映射是非确定性的,依赖于系统,并且在硬件或操作系统更改后可能会在启动之间变化。在大多数情况下,这种分配似乎相当稳定。然而,启动后检查是必需的,以确保 GPU 设备分配给特定的设备文件。

请查阅 NVIDIA CUDA 文档,以获取有关 CUDA_VISIBLE_DEVICESCUDA_DEVICE_ORDER 环境变量的更多信息。

MPS 管理

CUDA 多进程服务 (MPS) 提供了一种机制,允许多个作业共享 GPU,每个作业分配 GPU 资源的某个百分比。节点上可用的 MPS 资源总数应在 slurm.conf 文件中配置(例如,“NodeName=tux[1-16] Gres=gpu:2,mps:200”)。在 gres.conf 文件中配置 MPS 有几种选项,如下所示,后面有示例:

  1. 无 MPS 配置:在 slurm.conf 中定义的 gres/mps 元素的数量将在节点上配置的所有 GPU 之间均匀分配。例如,“NodeName=tux[1-16] Gres=gpu:2,mps:200”将在每个 GPU 上配置 100 个 gres/mps 资源。
  2. MPS 配置仅包括 NameCount 参数:gres/mps 元素的数量将在节点上配置的所有 GPU 之间均匀分配。这与情况 1 类似,但在 gres.conf 文件中放置重复配置。
  3. MPS 配置包括 NameFileCount 参数:每个 File 参数应标识 GPU 的设备文件路径,而 Count 应标识该特定 GPU 设备可用的 gres/mps 资源数量。这在异构环境中可能很有用。例如,节点上的某些 GPU 可能比其他 GPU 更强大,因此与更高的 gres/mps 数量相关联。另一个用例是防止某些 GPU 用于 MPS(即它们的 MPS 数量为零)。

请注意,gres/mps 的 TypeCores 参数被忽略。该信息是从 gres/gpu 配置中复制的。

请注意,Count 参数被转换为百分比,因此该值通常是 100 的倍数。

请注意,如果安装了 NVIDIA 的 NVML 库,则 GPU 配置(即 TypeFileCoresLinks 数据)将自动从库中收集,无需记录在 gres.conf 文件中。

默认情况下,作业请求 MPS 需要适合每个节点上的单个 GPU。这可以通过在 slurm.conf 配置文件中使用标志进行覆盖。请参见 OPT_MULTIPLE_SHARING_GRES_PJ

请注意,同一 GPU 可以分配为 GRES 的 GPU 类型或 MPS 类型的 GRES,但不能同时分配。换句话说,一旦 GPU 被分配为 gres/gpu 资源,它将不再作为 gres/mps 可用。同样,一旦 GPU 被分配为 gres/mps 资源,它将不再作为 gres/gpu 可用。然而,同一 GPU 可以作为 MPS 通用资源分配给多个属于多个用户的作业,只要分配给作业的 MPS 总数不超过配置的数量。此外,由于共享 GRES(MPS)不能与共享 GRES(GPU)同时分配,因此此选项仅分配所有共享 GRES,而不分配任何基础共享 GRES。以下是 Slurm 的 gres.conf 文件的一些示例配置。

# 示例 1 的 gres.conf
# 配置四个 GPU(带 MPS)
AutoDetect=nvml
Name=gpu Type=gp100 File=/dev/nvidia0 Cores=0,1
Name=gpu Type=gp100 File=/dev/nvidia1 Cores=0,1
Name=gpu Type=p6000 File=/dev/nvidia2 Cores=2,3
Name=gpu Type=p6000 File=/dev/nvidia3 Cores=2,3
# 将 gres/mps Count 值设置为 100,在每个可用的 4 个 GPU 上
Name=mps Count=400
# 示例 2 的 gres.conf
# 配置四种不同的 GPU 类型(带 MPS)
AutoDetect=nvml
Name=gpu Type=gtx1080 File=/dev/nvidia0 Cores=0,1
Name=gpu Type=gtx1070 File=/dev/nvidia1 Cores=0,1
Name=gpu Type=gtx1060 File=/dev/nvidia2 Cores=2,3
Name=gpu Type=gtx1050 File=/dev/nvidia3 Cores=2,3
Name=mps Count=1300   File=/dev/nvidia0
Name=mps Count=1200   File=/dev/nvidia1
Name=mps Count=1100   File=/dev/nvidia2
Name=mps Count=1000   File=/dev/nvidia3

注意gres/mps 需要使用 select/cons_tres 插件。

请求 MPS 的作业将与任何其他 GRES 一样处理,只是请求必须仅使用每个节点上的一个 GPU 满足,并且每个节点上只能配置一个 GPU 用于 MPS。例如,作业请求 “--gres=mps:50” 将不会通过使用一个 GPU 的 20% 和第二个 GPU 的 30% 在单个节点上满足。来自不同用户的多个作业可以同时在节点上使用 MPS。请注意,GPU 的 GRES 类型 MPS 不能在单个作业中请求。此外,请求 MPS 资源的作业不能指定 GPU 频率。

应使用 Prolog 程序根据需要启动和停止 MPS 服务器。一个示例 Prolog 脚本随 Slurm 分发包一起提供,位于 etc/prolog.example。其操作模式是,如果作业分配了 gres/mps 资源,则 Prolog 将设置 CUDA_VISIBLE_DEVICESCUDA_MPS_ACTIVE_THREAD_PERCENTAGESLURM_JOB_UID 环境变量。然后,Prolog 应确保为该 GPU 和用户(UID == 用户 ID)启动 MPS 服务器。它还会在本地文件中记录 GPU 设备 ID。如果作业分配了 gres/gpu 资源,则 Prolog 将设置 CUDA_VISIBLE_DEVICESSLURM_JOB_UID 环境变量(不包括 CUDA_MPS_ACTIVE_THREAD_PERCENTAGE)。Prolog 应终止与该 GPU 相关的任何 MPS 服务器。可能需要根据需要修改此脚本以适应本地环境。有关更多信息,请参见 Prolog 和 Epilog 指南

请求 MPS 资源的作业将设置 CUDA_VISIBLE_DEVICESCUDA_DEVICE_ORDER 环境变量。设备 ID 是相对于 MPS 服务器控制下的那些资源,并且在当前实现中始终具有值零(每个节点只能在 MPS 模式下使用一个 GPU)。作业还将设置 CUDA_MPS_ACTIVE_THREAD_PERCENTAGE 环境变量,以表示分配给该作业的 MPS 资源的百分比。该百分比将基于分配给作业步骤的 Gres 中配置的 Count 的部分进行计算。例如,请求 “--gres=mps:200” 的作业,并使用上述 配置示例 2,将被分配
15% 的 gtx1080(File=/dev/nvidia0,200 x 100 / 1300 = 15),或
16% 的 gtx1070(File=/dev/nvidia0,200 x 100 / 1200 = 16),或
18% 的 gtx1060(File=/dev/nvidia0,200 x 100 / 1100 = 18),或
20% 的 gtx1050(File=/dev/nvidia0,200 x 100 / 1000 = 20)。

另一种操作模式是允许作业分配整个 GPU,然后根据作业中的注释触发 MPS 服务器的启动。例如,如果作业分配了整个 GPU,则搜索作业中的 “mps-per-gpu” 或 “mps-per-node” 的注释(使用 “scontrol show job” 命令),并以此为基础启动每个 GPU 或所有 GPU 的一个 MPS 守护进程。

请查阅 NVIDIA 多进程服务文档,以获取有关 MPS 的更多信息。

请注意,NVIDIA 驱动程序的早期版本存在一个漏洞,可能会影响共享 GPU 的用户。有关更多信息,请参见 CVE-2018-6260安全公告:NVIDIA GPU 显示驱动程序 - 2019 年 2 月

NVIDIA MPS 对不同用户之间的 GPU 共享有内置限制。系统上只能有一个用户拥有活动的 MPS 服务器,MPS 控制守护进程将排队来自不同用户的 MPS 服务器激活请求,导致用户之间对 GPU 的串行独占访问(请参见 MPS 文档中的 第 2.3.1.1 节 - 限制)。因此,不同用户无法真正同时在 GPU 上运行 MPS;相反,GPU 将在用户之间进行时间切片(有关此过程的图示,请参见 MPS 文档中的 第 3.3 节 - 配置序列)。

MIG 管理

从版本 21.08 开始,Slurm 现在支持 NVIDIA 多实例 GPU(MIG)设备。此功能允许一些较新的 NVIDIA GPU(如 A100)将 GPU 切分为多达七个独立的、隔离的 GPU 实例。Slurm 可以将这些 MIG 实例视为单独的 GPU,配备 cgroup 隔离和任务绑定。

要在 Slurm 中配置 MIG,请在具有 MIG 的节点的 gres.conf 中指定 AutoDetect=nvml,并在 slurm.conf 中指定 Gres,就像 MIG 是常规 GPU 一样,例如:NodeName=tux[1-16] gres=gpu:2。可以指定一个可选的 GRES 类型,以区分不同大小的 MIG 以及集群中的其他 GPU。此类型必须是节点在其 slurmd 日志中以 debug2 日志级别报告的 “MIG Profile” 字符串的子字符串。以下是一个示例 slurm.conf,适用于具有 2 个 GPU 的系统,其中一个被划分为 2 个 MIG,且 “MIG Profile” 为 nvidia_a100_3g.20gb

AccountingStorageTRES=gres/gpu,gres/gpu:a100,gres/gpu:a100_3g.20gb
GresTypes=gpu
NodeName=tux[1-16] gres=gpu:a100:1,gpu:a100_3g.20gb:2

MultipleFiles 参数允许您为 GPU 卡指定多个设备文件。

不支持 MIG 的合理性检查自动检测模式。Slurm 期望 MIG 设备已经被划分,并且不支持动态 MIG 划分。

有关 NVIDIA MIG 的更多信息(包括如何划分它们),请参见 MIG 用户指南

分片

分片提供了一种通用机制,允许多个作业共享 GPU。虽然它允许多个作业在给定的 GPU 上运行,但并不限制在 GPU 上运行的进程,它仅允许 GPU 被共享。因此,分片最适合于同质工作流。建议将节点上的分片数量限制为可以同时在节点上运行的最大作业数量(即核心)。节点上可用的分片总数应在 slurm.conf 文件中配置(例如,“NodeName=tux[1-16] Gres=gpu:2,shard:64”)。在 gres.conf 文件中配置分片有几种选项,如下所示,后面有示例:

  1. 无分片配置:在 slurm.conf 中定义的 gres/shard 元素的数量将在节点上配置的所有 GPU 之间均匀分配。例如,“NodeName=tux[1-16] Gres=gpu:2,shard:64”将在每个 GPU 上配置 32 个 gres/shard 资源。
  2. 分片配置仅包括 NameCount 参数:gres/shard 元素的数量将在节点上配置的所有 GPU 之间均匀分配。这与情况 1 类似,但在 gres.conf 文件中放置重复配置。
  3. 分片配置包括 NameFileCount 参数:每个 File 参数应标识 GPU 的设备文件路径,而 Count 应标识该特定 GPU 设备可用的 gres/shard 资源数量。这在异构环境中可能很有用。例如,节点上的某些 GPU 可能比其他 GPU 更强大,因此与更高的 gres/shard 数量相关联。另一个用例是防止某些 GPU 用于分片(即它们的分片数量为零)。

请注意,gres/shard 的 TypeCores 参数被忽略。该信息是从 gres/gpu 配置中复制的。

请注意,如果安装了 NVIDIA 的 NVML 库,则 GPU 配置(即 TypeFileCoresLinks 数据)将自动从库中收集,无需记录在 gres.conf 文件中。

请注意,同一 GPU 可以分配为 GRES 的 GPU 类型或分片类型的 GRES,但不能同时分配。换句话说,一旦 GPU 被分配为 gres/gpu 资源,它将不再作为 gres/shard 可用。同样,一旦 GPU 被分配为 gres/shard 资源,它将不再作为 gres/gpu 可用。然而,同一 GPU 可以作为分片通用资源分配给多个属于多个用户的作业,只要分配给作业的 SHARD 总数不超过配置的数量。

默认情况下,请求分片的作业需要适合每个节点上的单个 GPU。这可以通过在 slurm.conf 配置文件中使用标志进行覆盖。请参见 OPT_MULTIPLE_SHARING_GRES_PJ

为了正确配置,相关节点需要将 shard 关键字添加为相关节点的 GRES,并添加到 GresTypes 参数中。如果您希望在计费中跟踪分片,则 shard 也需要添加到 AccountingStorageTRES 中。请参见示例 slurm.conf 中的相关设置:

AccountingStorageTRES=gres/gpu,gres/shard
GresTypes=gpu,shard
NodeName=tux[1-16] Gres=gpu:2,shard:64

以下是 Slurm 的 gres.conf 文件的一些示例配置。

# 示例 1 的 gres.conf
# 配置四个 GPU(带分片)
AutoDetect=nvml
Name=gpu Type=gp100 File=/dev/nvidia0 Cores=0,1
Name=gpu Type=gp100 File=/dev/nvidia1 Cores=0,1
Name=gpu Type=p6000 File=/dev/nvidia2 Cores=2,3
Name=gpu Type=p6000 File=/dev/nvidia3 Cores=2,3
# 将 gres/shard Count 值设置为 8,在每个可用的 4 个 GPU 上
Name=shard Count=32
# 示例 2 的 gres.conf
# 配置四种不同的 GPU 类型(带分片)
AutoDetect=nvml
Name=gpu Type=gtx1080 File=/dev/nvidia0 Cores=0,1
Name=gpu Type=gtx1070 File=/dev/nvidia1 Cores=0,1
Name=gpu Type=gtx1060 File=/dev/nvidia2 Cores=2,3
Name=gpu Type=gtx1050 File=/dev/nvidia3 Cores=2,3
Name=shard Count=8    File=/dev/nvidia0
Name=shard Count=8    File=/dev/nvidia1
Name=shard Count=8    File=/dev/nvidia2
Name=shard Count=8    File=/dev/nvidia3

注意gres/shard 需要使用 select/cons_tres 插件。

请求分片的作业不能指定 GPU 频率。

请求分片资源的作业将设置 CUDA_VISIBLE_DEVICESROCR_VISIBLE_DEVICESGPU_DEVICE_ORDINAL 环境变量,这将与 GPU 相同。

具有分片的步骤将设置 SLURM_SHARDS_ON_NODE,指示分配的分片数量。

最后修改于 2025 年 4 月 10 日