故障排除
这是 Dask-CUDA 在各种系统上遇到的常见问题列表。
错误的设备索引
在创建 worker 时,通常依赖于 nvidia-smi
显示的设备索引,这也是 Dask-CUDA 中的默认设置。在大多数情况下,nvidia-smi
提供与 CUDA_VISIBLE_DEVICES
的一对一映射,但在某些系统中排序可能不匹配。虽然 CUDA_VISIBLE_DEVICES
按 PCI Bus ID 对 GPU 进行索引,但 nvidia-smi
按最快的 GPU 排序。在包含 4 个 A100 GPU 外加一个显示 GPU 的 DGX Station A100 中常见此问题,其中显示 GPU 可能不是按 PCI Bus ID 排列的最后一个 GPU。为了纠正此问题并确保按照 PCI Bus ID 进行映射,在启动 Python 进程时需要设置 CUDA_DEVICE_ORDER=PCI_BUS_ID
环境变量
$ CUDA_DEVICE_ORDER=PCI_BUS_ID python
$ CUDA_DEVICE_ORDER=PCI_BUS_ID ipython
$ CUDA_DEVICE_ORDER=PCI_BUS_ID jupyter lab
$ CUDA_DEVICE_ORDER=PCI_BUS_ID dask-cuda-worker ...
对于 DGX Station A100,显示 GPU 通常是 PCI Bus ID 排序中的第四个,因此需要使用 GPU 0、1、2 和 4 来运行 Dask-CUDA
>>> from dask_cuda import LocalCUDACluster
>>> cluster = LocalCUDACluster(CUDA_VISIBLE_DEVICES=[0, 1, 2, 4])
设置 CPU 亲和性失败
为 Dask-CUDA worker 设置正确的 CPU 亲和性对于确保最佳性能非常重要,尤其是在需要与系统内存进行数据传输时。在 Dask-CUDA 中,这是一项自动功能,它会尝试根据 worker 所针对的 GPU 来确定每个 worker 的适当 CPU 亲和性。
在某些情况下,设置 CPU 亲和性可能会失败,更常见的情况涉及到大型计算集群使用的负载管理器和作业调度器,例如 Slurm。
在一个具有多个物理 CPU(即多个 CPU 插槽)和多个 GPU 的节点中,此类系统通常会将 GPU 直接连接到特定的物理 CPU 以平衡资源。例如,考虑一个具有 4 个 GPU 和 40 个 CPU 核心的节点,其中 CPU 核心分布在两个物理 CPU 上,在这种情况下,GPU 0 和 1 可能连接到 CPU 0-19,而 GPU 2 和 3 可能连接到 CPU 20-39。在这种设置中,如果整个节点都分配给了 Dask-CUDA 作业,则设置 CPU 亲和性很可能会成功,但是,作业仍有可能将错误的 CPU 20-39 分配给 GPU 0 和 1,或将 CPU 0-19 分配给 GPU 2 和 3,在这种情况下,设置 CPU 亲和性将不可能,因为作业没有可用的正确 CPU/GPU 资源。发生这种情况时,Dask-CUDA 所能做的最好事情就是发出警告,将您重定向到本节,并且不设置任何 CPU 亲和性,让操作系统根据情况处理所有传输,即使它们可能遵循次优路径。
如果在按照本节中的说明(包括查阅集群手册和管理员)后,问题仍然存在,请 [在 Dask-CUDA 仓库下提交问题](https://github.com/rapidsai/dask-cuda/issues),并包含以下所有命令的输出,这些命令必须在分配的集群作业中执行
conda list
,如果环境是使用 conda 安装的或使用了 RAPIDS 提供的 Docker 镜像;pip list
,如果环境是使用 pip 安装的;nvidia-smi
;nvidia-smi topo -m
;python print_affinity.py
,print_affinity.py
的代码紧随其后。
# print_affinity.py
import math
from multiprocessing import cpu_count
import pynvml
pynvml.nvmlInit()
for i in range(pynvml.nvmlDeviceGetCount()):
handle = pynvml.nvmlDeviceGetHandleByIndex(i)
cpu_affinity = pynvml.nvmlDeviceGetCpuAffinity(handle, math.ceil(cpu_count() / 64))
print(f"GPU {i}: list(cpu_affinity)")
Slurm
此问题更常见的报告案例发生在 Slurm 集群上。解决此问题的常见方法通常是使用以下参数之一为作业提供特定的 CPU 子集
–cpus-per-task=N:作业将分配的 CPU 数量,您可能需要申请所有 CPU 以确保 GPU 拥有与其相关的所有可用 CPU;
–exclusive:确保将 CPU 独占分配给作业。
遗憾的是,无法为所有现有的集群配置提供精确的解决方案,因此请务必查阅集群手册和管理员以获取详细信息和进一步的故障排除帮助。