跳到主要内容

故障排除

确保您熟悉以下已知问题和有用的调试策略。

错误

MCCL 调用可能会返回各种返回码。确保返回码始终等于 mcclSuccess。如果任何调用失败并返回与 mcclSuccess 不同的值,将 MCCL_DEBUG 设置为 "WARN" 将使 MCCL 在返回错误之前打印一个明确的警告消息。

错误被分为不同的类别。

在任何情况下,请参阅 MCCL 警告消息以了解如何解决问题。

错误码

详细的错误码说明请参见 错误码

最佳实践

场景化最佳实践和优化策略请参见 最佳实践

GPU Direct

MCCL 严重依赖 GPU Direct 进行 GPU 间通信。这指的是 GPU 能够直接与另一个设备(如另一个 GPU 或网卡)使用直接点对点 PCI 消息进行通信的能力。

直接点对点 PCI 消息可能因各种原因失败或表现不佳,例如缺少组件、虚拟机或容器的配置错误,或某些 BIOS 设置。

GPU 到 GPU 通信

为确保 GPU 到 GPU 通信正常工作,请查找 MUSA 示例中的 p2pBandwidthLatencyTesthttps://github.com/mthreads/musa-samples

cd musa-samples/Samples/5_Domain_Specific/p2pBandwidthLatencyTest
make
./p2pBandwidthLatencyTest

测试应该能够顺利完成,并报告 GPU 之间的良好性能。

另一个检查 GPU 到 GPU 性能的工具叫做 nvbandwidth。这可以从以下代码和说明中下载并构建: https://github.com/mthreads/mtbandwidth

GPU 到 NIC 通信

GPU 也可以使用 GPU Direct RDMA (GDRDMA) 直接与网卡通信。这需要有兼容的网卡和驱动程序,以及加载一个额外的内核模块称为 mthreads-peermemmthreads-peermem 模块现在随 MUSA 驱动程序提供,但必须在每个节点启动时加载:

sudo modprobe mthreads-peermem

GDRDMA 也可以通过使用最新 Linux 内核的 DMA-BUF 特性结合开源 mthreads GPU 驱动程序来启用。在这种情况下,MCCL 将自动检测并启用 DMA-BUF,因此不需要 mthreads-peermem 模块。

PCI 访问控制服务 (ACS)

裸机系统

IO 虚拟化(也称为 VT-d 或 IOMMU)可能通过将所有 PCI 点对点流量重定向到 CPU 根复合体来干扰 GPU Direct,导致性能显著降低甚至挂起。您可以通过运行以下命令来检查 PCI 桥是否启用了 ACS:

sudo lspci -vvv | grep ACSCtl

如果行显示 "SrcValid+",则可能启用了 ACS。查看 lspci 的完整输出,可以检查 PCI 桥是否启用了 ACS。

sudo lspci -vvv

如果 PCI 开关启用了 ACS,则需要禁用它。在某些系统上,这可以通过 BIOS 禁用 IO 虚拟化或 VT-d 来完成。对于 Broadcom PLX 设备,可以从 OS 完成,但需要在每次重启后再次完成。

使用以下命令找到 PLX PCI 开关的 PCI 总线 ID:

sudo lspci | grep PLX

接下来,使用 setpci 禁用 ACS,命令如下,将 03:00.0 替换为每个 PCI 开关的 PCI 总线 ID。

sudo setpci -s 03:00.0 ECAP_ACS+0x6.w=0000

或者您可以使用类似的脚本:

for BDF in `lspci -d "*:*:*" | awk '{print $1}'`; do
# 如果不支持 ACS,则跳过
sudo setpci -v -s ${BDF} ECAP_ACS+0x6.w > /dev/null 2>&1
if [ $? -ne 0 ]; then
continue
fi
sudo setpci -v -s ${BDF} ECAP_ACS+0x6.w=0000
done

虚拟机

虚拟机需要 ACS 才能工作,因此禁用 ACS 不是一个选项。要在虚拟机内以最大性能运行,需要在网络适配器中启用 ATS。

拓扑检测

MCCL 依赖于 /sys 来发现 GPU 和网卡的 PCI 拓扑。在虚拟机或容器内运行时,请确保 /sys 正确挂载。如果 /sys 暴露虚拟 PCI 拓扑,可能导致性能不佳。

共享内存

为了在进程之间甚至在进程的线程之间进行通信,MCCL 在 /dev/shm 中创建共享内存段。操作系统对这些资源的限制可能需要相应增加。请参阅您的系统文档以获取详细信息。

如果共享内存不足,MCCL 将无法初始化。使用 MCCL_DEBUG=WARN 运行将显示类似以下的消息:

MCCL WARN Error: failed to extend /dev/shm/mccl-03v824 to 4194660 bytes

Docker

特别是,Docker 容器默认限制共享和固定内存资源。在容器内使用 MCCL 时,请确保调整容器内的共享内存大小,例如,通过向 docker 启动命令行添加以下参数:

--shm-size=1g --ulimit memlock=-1

Systemd

当使用 mpirun 或 SLURM 运行作业时,systemd 可能会在检测到相应用户未登录时删除共享内存中的文件,试图清理旧的临时文件。这可能导致 MCCL 在初始化期间崩溃,并出现类似以下的错误:

MCCL WARN unlink shared memory /dev/shm/mccl-d5rTd0 failed, error: No such file or directory

鉴于 mpirun 和 SLURM 作业可以在节点上运行而用户不被 systemd 视为已登录,系统管理员需要禁用该清理机制,这可以通过 SLURM 尾声脚本来完成。为此,需要在 /etc/systemd/logind.conf 中设置以下行:

RemoveIPC=no

更新后,应使用以下命令重启守护进程:

sudo systemctl restart systemd-logind

muMem 主机内存分配机制

MCCL 支持采用 muMem 主机内存分配(muMem host allocations)作为替代的共享内存机制。该功能将默认启用,并优先替代传统的 /dev/shm 机制。

然而,muMem 主机内存分配依赖于正确配置且可用的 NUMA(非统一内存访问)支持,而某些虚拟机(VM)和容器化环境可能无法提供这一支持。例如,Docker 默认禁用 NUMA 支持(可通过 --cap-add SYS_NICE 参数启用)。

若检测到 muMem 主机内存分配不可用,MCCL 会自动回退至 /dev/shm 方案。对于更早的版本,需手动设置环境变量 MCCL_muMem_HOST_ENABLE=0 以实现相同效果。

我们仍建议配置底层系统以确保 muMem 主机内存分配可用,因为该机制在通信器(communicator)异常终止时能提供更高的可靠性。

网络问题

IP 网络接口

MCCL 自动检测用于节点间通信的网络接口。如果某些接口处于 UP 状态但无法在节点间通信,MCCL 仍可能尝试使用它们,因此在 init 函数期间或甚至挂起时失败。

有关如何指定要使用的接口的信息,请参见环境变量部分,特别是 MCCL_SOCKET_IFNAME 环境变量。

IP 端口

MCCL 打开 TCP 端口以连接进程并交换连接信息。要限制 MCCL 使用的端口范围,可以设置 Linux 内核的 net.ipv4.ip_local_port_range 属性。

此示例显示如何将 MCCL 端口限制为 50000-51000:

echo 50000 51000 > /proc/sys/net/ipv4/ip_local_port_range

或者要使此设置永久生效,将一行添加到 /etc/sysctl.conf:

echo "net.ipv4.ip_local_port_range = 50000 51000" >> /etc/sysctl.conf

限制端口范围可能有助于在防火墙中打开相应的范围,例如在 Google Cloud 上:

gcloud compute --project=myproject firewall-rules create mcclnet0-ingress --direction=INGRESS --priority=1 --network=mcclnet --action=ALLOW --rules=tcp:50000-51000,22,1024-1039 --destination-ranges=0.0.0.0/0 --target-tags=mcclnet

InfiniBand

在 InfiniBand 上运行 MCCL 之前,运行低级别的 InfiniBand 测试(特别是 ib_write_bw 测试)可以帮助验证节点是否能够正常通信。

InfiniBand 的常见问题是库无法注册足够的固定内存。在这种情况下,您可能会看到类似以下的错误:

MCCL WARN Call to ibv_create_qp failed

MCCL WARN Call to ibv_reg_mr failed

解决方案是取消对注册固定内存的用户限制。这可以通过向 /etc/security/limits.conf 配置文件或您的 Linux 发行版中的等效文件添加以下行来完成:

* soft memlock unlimited
* hard memlock unlimited

通过聚合以太网 (RoCE) 的 RDMA

在 RoCE 上运行 MCCL 之前,运行低级别的 RDMA 测试(特别是 ib_write_bw 测试)可以帮助验证节点是否能够正常通信。

RoCE 的常见问题是为 RoCE v2 NIC 选择了错误的 GID 索引。这可能导致以下错误:

MCCL WARN Call to ibv_modify_qp failed with error Invalid argument

GID 索引是动态选择的。

使用基于 RoCE 的网络时,用户可能还需要设置 MCCL_IB_TC。有关应设置的值,请参阅供应商的文档。