test_gpu_scripts/docs/multinode_nccl_concepts.md

11 KiB
Raw Blame History

多机多卡 NCCL 测试概念说明

本文先讲概念,不涉及脚本改造。目标是理解两台 8 卡 H100 服务器做多机多卡通信测试时,应该从哪些层次逐步验证,以及每一层到底在证明什么。

当前示例机器:

别名 主机名 内网 IP GPU
nccl-gpu-1 aikubeworker0012 172.72.8.12 8 x H100
nccl-gpu-2 aikubeworker0016 172.72.8.16 8 x H100

两台机器合起来就是 16 张 GPU。多机 NCCL 测试的核心问题是:这 16 张 GPU 是否能通过正确的 GPU、NVLink、PCIe、IB/RDMA 网络路径,高效且正确地完成集体通信。

1. 总体思路

多机多卡通信测试是一个自底向上的过程。越底层越接近硬件和链路,越上层越接近真实训练业务。

flowchart TD
    L0["0. 物理与基础连通<br/>电源 / GPU / 网卡 / 线缆 / 交换机 / SSH"] --> L1["1. 系统识别层<br/>nvidia-smi / lspci / ibstat / ibdev2netdev"]
    L1 --> L2["2. 单机 GPU 健康层<br/>温度 / 功耗 / ECC / PCIe / Throttling / NVLink Topo"]
    L2 --> L3["3. 单机 GPU 性能层<br/>HBM 带宽 / H2D-D2H / FP32-TF32-FP16-BF16-FP8 算力"]
    L3 --> L4["4. 单机多卡通信层<br/>单节点 8 卡 NCCL over NVLink/NVSwitch"]
    L4 --> L5["5. 跨机网络与 RDMA 层<br/>IP 连通 / IB Active / RDMA 带宽 / RDMA 延迟"]
    L5 --> L6["6. 跨机 NCCL 层<br/>两机 16 卡 AllReduce / AllGather / ReduceScatter / Broadcast / AllToAll"]
    L6 --> L7["7. 训练负载层<br/>torchrun / Megatron / DeepSpeed / 业务训练压测"]

最重要的原则:

上层失败,不一定是上层问题。

比如两机 all_reduce_perf 失败,原因可能在 NCCL也可能在 SSH、MPI、IB、GID、网卡选择、驱动版本、CUDA 版本、NCCL 版本或 GPU Direct RDMA。

所以排查顺序应该是:

基础连通 -> 单机健康 -> 单机性能 -> 单机 NCCL -> 跨机 RDMA -> 跨机 NCCL -> 训练业务

2. 两机 16 卡通信路径

单机内部主要走 NVLink/NVSwitch跨机器时数据必须经过 GPU、PCIe/NVLink、网卡、交换机和对端网卡。

flowchart LR
    subgraph A["aikubeworker0012 / 172.72.8.12"]
        A0["GPU0"] --- ASW["NVSwitch / NVLink"]
        A1["GPU1"] --- ASW
        A2["..."] --- ASW
        A7["GPU7"] --- ASW
        ASW --> ANIC["IB/RDMA NIC(s)"]
    end

    subgraph NET["InfiniBand / RoCE Fabric"]
        SW["IB Switch"]
    end

    subgraph B["aikubeworker0016 / 172.72.8.16"]
        BNIC["IB/RDMA NIC(s)"] --> BSW["NVSwitch / NVLink"]
        B0["GPU0"] --- BSW
        B1["GPU1"] --- BSW
        B2["..."] --- BSW
        B7["GPU7"] --- BSW
    end

    ANIC <--> SW
    SW <--> BNIC

这里有两个不同的通信域:

通信域 典型路径 主要测试
单机内 8 卡 GPU -> NVLink/NVSwitch -> GPU 单机 NCCL、NVLink topo、D2D
跨机器 16 卡 GPU -> NIC -> IB/RDMA 网络 -> NIC -> GPU RDMA、跨机 NCCL

这两个域的性能阈值不能混用。单机 NVSwitch 很快,跨机 RDMA 一般慢一些,跨机 NCCL 的瓶颈通常在 IB/RDMA 网络。

3. 每一层要测什么

3.1 基础连通层

这一层只证明机器能访问、身份和地址正确。

要确认:

检查项 目的
SSH 互通 MPI/NCCL 多机启动依赖远端拉起进程
hostname 正确 避免登录错机器
IP 正确 确认使用的是训练网络或 IB/RDMA 对应网络
时间同步 长时间训练日志和超时排查更可靠

这一层不证明 GPU 或 RDMA 性能,只证明“机器能互相找到”。

3.2 系统识别层

这一层证明系统能看见 GPU 和网卡。

常见信息:

工具 看什么
nvidia-smi GPU 数量、型号、驱动、CUDA、温度、功耗
nvidia-smi topo -m GPU、NIC、CPU NUMA、NVLink/NVSwitch 拓扑
ibstat IB 设备、端口状态、链路速率
ibdev2netdev mlx5 设备和网络接口的映射
/sys/class/infiniband 端口状态、link layer、rate、GID

这一层很关键,因为 NCCL 经常因为选错网卡而跑到 TCP 或错误的接口上。

3.3 单机 GPU 健康层

这一层证明每台机器自己是健康的。

flowchart LR
    H["单机健康检查"] --> T["温度"]
    H --> P["功耗"]
    H --> E["ECC 错误"]
    H --> PCIE["PCIe Gen/Width"]
    H --> C["SM/Mem Clock"]
    H --> TH["Throttling"]
    H --> PM["Persistence Mode"]

如果某张卡温度过高、ECC double-bit、PCIe 降级或 throttling后面的 NCCL 测试即使能跑,结果也不可信。

3.4 单机 GPU 性能层

这一层证明每台机器的 GPU 本身性能正常。

测试 证明什么
HBM/D2D 带宽 GPU 显存和设备间拷贝能力
H2D/D2H 带宽 CPU/Host 到 GPU 的 PCIe 路径
FP32/TF32 基础矩阵计算能力
FP16/BF16/FP8 训练常用 Tensor Core 能力

这一步是单机验收。它不能证明两台机器之间通信正常,但可以排除“某台机器本身 GPU 算力或带宽异常”。

3.5 单机多卡 NCCL 层

这一层验证单台机器 8 卡之间的集体通信。

flowchart TD
    S["单机 8 卡 NCCL"] --> AR["AllReduce"]
    S --> AG["AllGather"]
    S --> RS["ReduceScatter"]
    S --> BC["Broadcast"]
    S --> AT["AllToAll"]

单机 NCCL 主要看 NVLink/NVSwitch 通信路径是否正常。常见指标:

指标 含义
algbw 算法视角的有效带宽
busbw 总线视角的带宽,更适合比较通信链路利用率
#wrong 结果错误数量,必须是 0

单机测试通过后,只能说明单台服务器内部 8 卡通信正常。

3.6 跨机 RDMA 层

这一层验证两台机器之间的网络和 RDMA 能力,不涉及 NCCL。

sequenceDiagram
    participant N1 as aikubeworker0012
    participant FAB as IB/RDMA Fabric
    participant N2 as aikubeworker0016

    N1->>N2: ping / ssh
    N1->>FAB: ib_write_bw client
    FAB->>N2: ib_write_bw server
    N1->>FAB: ib_read_bw client
    FAB->>N2: ib_read_bw server
    N1->>N2: ib_write_lat / ib_read_lat

这一层要回答:

问题 说明
IB 端口是否 Active 没 Active 就不用跑 NCCL
RDMA 带宽是否达标 证明网络数据面能跑起来
RDMA 延迟是否正常 高延迟会影响小消息和训练同步
是否是 InfiniBand/RoCE 两者环境变量和排障点不同

如果 RDMA 层失败,跨机 NCCL 大概率也会失败或退化到 TCP。

3.7 跨机 NCCL 层

这一层才是真正的多机多卡 NCCL 测试。

两台 8 卡机器通常是:

2 nodes x 8 GPUs = 16 ranks
每个 rank 绑定 1 张 GPU

概念上是:

flowchart LR
    subgraph N1["Node 1: 172.72.8.12"]
        R0["rank 0 / GPU0"]
        R1["rank 1 / GPU1"]
        R2["..."]
        R7["rank 7 / GPU7"]
    end

    subgraph N2["Node 2: 172.72.8.16"]
        R8["rank 8 / GPU0"]
        R9["rank 9 / GPU1"]
        R10["..."]
        R15["rank 15 / GPU7"]
    end

    R0 <--> R8
    R1 <--> R9
    R7 <--> R15
    N1 <--> N2

典型测试项:

NCCL 测试 训练里对应什么
AllReduce 数据并行梯度同步
ReduceScatter ZeRO/FSDP 梯度切分
AllGather ZeRO/FSDP 参数聚合
Broadcast 参数广播、初始化
AllToAll MoE、专家并行、部分并行策略
SendRecv 点对点通信、pipeline parallel

跨机 NCCL 要看:

指标 判定
是否成功启动 16 rank MPI/SSH/路径/环境是否正常
#wrong == 0 正确性必须过
busbw 跨节点通信链路利用率
是否走 IB/RDMA 需要从 NCCL_DEBUG=INFO 确认
是否退化 TCP 如果退化,性能会明显偏低

4. NCCL 为什么要分单机和跨机

单机 8 卡通信和跨机 16 卡通信的瓶颈不同。

flowchart TD
    A["NCCL 性能结果"] --> B{"测试范围"}
    B --> C["单机 8 卡"]
    B --> D["跨机 16 卡"]

    C --> C1["主要瓶颈NVLink / NVSwitch"]
    C --> C2["阈值可参考 GPU NVLink 能力"]

    D --> D1["主要瓶颈IB/RDMA 网络"]
    D --> D2["阈值应参考网卡数量、速率、拓扑和 rail 数"]

所以不能用单机 NVLink 的阈值直接判断跨机 NCCL。跨机要根据真实网络能力设阈值例如

网络配置 理论上限理解
单张 400G 网卡 约 50 GB/s 单向原始带宽
8 张 400G 网卡 约 400 GB/s 原始聚合带宽
实测 NCCL busbw 会受拓扑、GDR、rail、NUMA、交换机、NCCL 算法影响

实际验收时,应该先知道每台机器有几张 IB/RDMA 网卡、每张速率多少、GPU 到 NIC 的拓扑关系,再定跨机 NCCL 阈值。

5. 常见失败位置

flowchart TD
    F["跨机 NCCL 失败"] --> A["启动失败"]
    F --> B["能启动但很慢"]
    F --> C["运行中 timeout"]
    F --> D["结果 #wrong 非 0"]

    A --> A1["SSH 不通"]
    A --> A2["远端路径不存在"]
    A --> A3["MPI 环境不一致"]
    A --> A4["root 运行未允许"]

    B --> B1["NCCL_SOCKET_IFNAME 选错"]
    B --> B2["没走 IB/RDMA退化 TCP"]
    B --> B3["NCCL_IB_HCA 没选对"]
    B --> B4["GPU Direct RDMA 没生效"]

    C --> C1["IB 端口不稳定"]
    C --> C2["交换机/PFC/ECN 问题"]
    C --> C3["NCCL timeout 配置"]
    C --> C4["驱动/CUDA/NCCL 版本不兼容"]

    D --> D1["通信正确性失败"]
    D --> D2["必须 FAIL不能只看带宽"]

6. 推荐验收顺序

下面是面向两台 8 卡机器的推荐顺序:

flowchart TD
    A["Step 1: 两台机器基础信息"] --> B["Step 2: 两台机器单机 GPU 健康"]
    B --> C["Step 3: 两台机器单机 benchmark"]
    C --> D["Step 4: 两台机器分别跑单机 8 卡 NCCL"]
    D --> E["Step 5: 两台机器互测 RDMA bandwidth/latency"]
    E --> F["Step 6: 两机 16 卡 NCCL correctness"]
    F --> G["Step 7: 两机 16 卡 NCCL performance"]
    G --> H["Step 8: 两机训练 demo 或业务压测"]

每一步的意义:

步骤 目的
Step 1 确认没有登录错机器,基础网络和环境存在
Step 2 排除 GPU 健康问题
Step 3 排除 GPU 单卡/单机性能问题
Step 4 排除单机 NVLink/NVSwitch/NCCL 问题
Step 5 排除跨机 RDMA 问题
Step 6 先证明 NCCL 正确性
Step 7 再证明 NCCL 性能
Step 8 最后用真实训练形态验证稳定性

7. 对当前脚本的映射

当前脚本已有模块和上面层次的关系:

当前模块 覆盖层次 备注
gpu_info 系统识别层 单机
health 单机 GPU 健康层 单机
benchmark 单机 GPU 性能层 单机
nccl 单机多卡通信层 当前主要是单机
rdma RDMA 检查 当前偏本机检查,不是两机互测
stress 稳定性 单机
training 训练负载层 当前偏单机
建议新增 multi_node_nccl 跨机 NCCL 层 专门处理 hostfile、mpirun、多节点环境、结果解析

如果未来要扩展脚本,比较自然的方向是新增一个多机模块,而不是把所有逻辑塞进现有 nccl 模块。

8. 最小概念模型

记住这句话即可:

单机 NCCL 验证 GPU 之间的 NVLink/NVSwitch。
跨机 RDMA 验证机器之间的网络。
跨机 NCCL 验证 NCCL 是否能把 GPU 和网络组合起来,为真实训练提供高效通信。

因此,多机多卡测试不是一个命令,而是一条验证链路。