Two-node communication primer

6000D 双机通信与 NCCL 术语入门

节点:174.1.51.5 + 174.1.51.7 规模:16 GPU / TP16 版本:2026-07-30 17:54 CST

1. 先建立一张总图

SGLang 不会自己搬运 16 张 GPU 之间的 Tensor。模型代码发起 TP/MoE 通信, NCCL 决定用什么算法、经过哪条链路把数据送到其他 rank。

SGLang执行模型层、TP16 和 EP2
CollectiveAllReduce、AllGather、ReduceScatter、AllToAll
NCCL构造 rank、ring/tree 和 channel
Transport机内 P2P/IPC;跨机 NET/IB 或 NET/Socket
硬件GPU、PCIe、HCA、网卡、光模块、交换机
最重要的区分: NCCL bootstrap 是“启动时要完成的一件事”; NCCL_SOCKET_IFNAME 是“选择 IP 网卡的一个参数”; NET/IBNET/Socket 才是 NCCL 实际搬运数据的传输后端。

两类跨机路径

理想路径:RDMA

GPU → HCA → RoCE 网络 → HCA → GPU

日志应出现 NET/IB,支持时还会出现 GDRDMA

回退路径:TCP Socket

GPU/CPU → Linux Socket → ethX → TCP/IP → ethX

日志会出现 Using network Socket。这不是报错,但性能通常低得多。

2. eth0 和 mlx5_0 不是同一个设备

400G 是物理 Ethernet 端口的标称链路速率。 eth0 是该端口的 Linux netdev/IP 入口; mlx5_0 是映射到该端口的 RDMA Verbs/HCA 入口。 二者相关联,但不相等,也不代表 TCP 或 RDMA 应用一定能跑到 400G。
名字属于哪一层负责什么本机实例
eth0 Linux IP 网卡接口 配置 IP、TCP/UDP、路由;由 NCCL_SOCKET_IFNAME 选择 400 Gbit/s 计算网
eth3 Linux IP 网卡接口 第二条计算网 Rail 400 Gbit/s 计算网
mlx5_0 RDMA HCA / Verbs 设备 NET/IB 使用;由 NCCL_IB_HCA 选择 对应 eth0,挂 switch 1
mlx5_3 RDMA HCA / Verbs 设备 第二条 RDMA Rail 对应 eth3,挂 switch 2
/dev/infiniband/uverbs0 Linux 字符设备 容器进程访问 RDMA Verbs 的入口 对应 mlx5_0
mlx5_0 port 1 ==> eth0 (Up)
mlx5_3 port 1 ==> eth3 (Up)

同一条物理端口可以同时暴露 Linux IP 接口和 RDMA HCA。 eth0 是 IP/Socket 世界的入口,mlx5_0 是 RDMA Verbs 世界的入口。ibdev2netdev 输出的是映射关系,不是等号。 本项目部署时只把 eth0/eth3 作为节点间计算网。

同一条 400G 物理 Ethernet 端口
├── eth0   -> Linux netdev -> IP / TCP Socket
└── mlx5_0 -> RDMA HCA     -> RoCE / Verbs / GDRDMA

400 Gbit/s = 50 GB/s 只是单方向理论线速。协议开销、PCIe、 CPU、Socket 线程、消息大小和 collective 算法都会让实际 algbw/busbw 低于或采用不同统计口径。

3. 核心术语字典

术语通俗解释在本项目中的意义
NCCL NVIDIA 的多 GPU 通信库,负责高效实现 collective 和点对点通信。 SGLang TP16 每层跨 GPU 通信最终大量落到 NCCL。
rank 一个通信参与者的编号。TP16 communicator 有 rank 0–15。 两台机器各 8 个 GPU rank,共 16 个。
collective 一组 rank 共同参与的通信操作。 TP 常见 AllReduce、AllGather、ReduceScatter;MoE 还可能有 AllToAll。
RDMA 远端直接内存访问。网卡可直接读写远端内存,减少 CPU 和内核数据拷贝。 双机 TP16 希望使用的高速数据路径。
IB InfiniBand。既是一套高速网络体系,也常被 NCCL 用作 Verbs/RDMA 后端的统称。 NCCL 日志里的 NET/IB 也可承载 RoCE,不代表交换机一定是原生 IB。
RoCE RDMA over Converged Ethernet,在以太网上承载 RDMA。 本项目的 400G 计算网类型。
HCA Host Channel Adapter,提供 RDMA 能力的适配器。 mlx5_0mlx5_3
GDRDMA GPUDirect RDMA,让 HCA 直接访问 GPU 显存,减少经 CPU 内存中转。 跨机 GPU 通信的理想路径,日志可见 via NET/IB/.../GDRDMA
Socket / TCP 普通 IP 网络编程路径。NCCL 找不到 RDMA 时会使用。 本次脚本实际发生的回退路径。
Rail 一条相对独立的网络通道,通常由一张 HCA 和一套交换路径组成。 mlx5_0/switch 1mlx5_3/switch 2 是双 Rail。
ring / tree NCCL 对 collective 的通信拓扑组织方式。 NCCL_CROSS_NIC 决定同一 ring/tree 能否跨不同 NIC。
PFC / ECN RoCE 网络控制拥塞和丢包的机制。 RDMA 出现 retry、pause 或吞吐抖动时由运维检查。

4. NCCL bootstrap 到底是什么

NCCL 本身不是进程启动器。SGLang 先启动各个 worker,NCCL communicator 初始化时, rank 之间需要交换地址、唯一 ID、拓扑和连接信息,这段“先认识彼此”的过程就是 bootstrap。

  1. 每个 rank 启动并获得自己的 rank ID。
  2. 通过 IP Socket 交换 NCCL unique ID 和连接信息。
  3. NCCL 探测 GPU、PCIe、HCA 和节点拓扑。
  4. 构造 ring/tree/channel。
  5. 选择真正的数据传输后端:P2P、SHM、NET/IB 或 NET/Socket。
容易误解的地方: NCCL_SOCKET_IFNAME 不保证“只用于 bootstrap”。 RDMA 正常时它主要承担 bootstrap;RDMA 失败并回退 Socket 后,它也会决定大块 Tensor 数据走哪张 IP 网卡。

5. 常见 NCCL 参数

NCCL_SOCKET_IFNAME

筛选 NCCL 可使用的 Linux IP 接口。精确指定接口时可写:

NCCL_SOCKET_IFNAME="=eth0"

NCCL_IB_HCA

筛选 NCCL 的 RDMA HCA。推荐使用精确匹配:

NCCL_IB_HCA="=mlx5_0:1,mlx5_3:1"

这个变量只是“允许选择谁”,不会自动把宿主机 RDMA 设备送进容器。 容器还必须看到 /dev/infiniband/rdma_cmuverbs0uverbs3

NCCL_CROSS_NIC

行为适用直觉
0 尽量让同一 ring/tree 在不同节点使用对应的同一条 Rail。 每张 NIC 接不同交换机、跨 Rail 代价高的 rail-optimized 网络。
1 允许同一 ring/tree 在不同节点使用不同 NIC。 所有 NIC 进入同一网络 Fabric,跨 NIC 不构成额外问题。
2 优先对应同一 NIC,但必要时允许跨 NIC。 NCCL 默认的折中策略。
本项目的 mlx5_0mlx5_3 分挂 switch 1/2, 拓扑直觉上更偏向 0 或默认 2。最终值必须在 真正启用 NET/IB 后用 all_reduce 和 SGLang 端到端 A/B 决定。 当 NCCL 使用 NET/Socket 时,这个参数不参与路径选择。

NCCL_DEBUG 与 NCCL_DEBUG_SUBSYS

NCCL_DEBUG=INFO
NCCL_DEBUG_SUBSYS=INIT,NET,GRAPH,TUNING

用于确认实际路径,诊断完成后应关闭,正式性能数据不要长期带 INFO 日志。

6. NCCL 日志速查

日志含义判断
Bootstrap: Using eth0:... 初始化控制连接选择 eth0。 只说明 bootstrap,尚不能证明数据走 RDMA。
NET/IB : Using ... mlx5_0 ... NCCL 已识别 RDMA HCA。 RDMA 数据后端可用。
via NET/IB/.../GDRDMA 跨机边通过 GPUDirect RDMA。 理想证据。
NET/IB : No device found 容器没有可用 RDMA 设备或驱动/权限不完整。 继续看是否回退 Socket。
NET/Socket : Using 非计算网... 跨机数据由普通 TCP Socket 传输。 若误入低速非计算网,性能会严重受限。
via P2P/IPC 同机 GPU 通过 CUDA P2P/IPC。 机内路径,不代表跨机路径。

7. 2026-07-30 Prefill 变慢事故复盘

已观测事实

冷缓存 Shape原脚本网络:eth0 Socketquick-map:错误的非计算网差异
1K → 1, C=1 TTFT 1.458s / 693.1 input tok/s TTFT 15.88–16.04s / 约 64 tok/s 约 10.9×
32K → 1, C=1 TTFT 38.062s / 860.5 input tok/s TTFT 504.44s / 64.96 tok/s 约 13.25×
根因判断: quick-map 没有把 RDMA 设备透传进容器,却把 NCCL_SOCKET_IFNAME 设成低速非计算网。NCCL 回退 NET/Socket 后,TP16 跨机数据没有进入规定的 eth0/eth3 计算网。NCCL_CROSS_NIC=1 在没有 NET/IB 的情况下不是致因。

为什么旧日志还会比 38 秒更短

旧矩阵脚本还有第二个独立因素:warmup_requests=16、固定 seed=42、ISL/OSL/C 升序运行,而且从不 flush Prefix Cache。 因此旧日志混入缓存命中,不能直接与冷 Prefill 比较。

quick-map 现在只允许 eth0/eth3mlx5_0/mlx5_3,并会透传精确 RDMA 设备、强制检查两端 NET/IB 日志。代码与 dry-run 已通过;下一步是真机启动验证, 在拿到运行时证据前不进入 Kernel 归因。

8. 从宿主机到 NCCL 的排查清单

  1. 宿主机链路: ethtool eth0ethtool eth3
  2. HCA 映射: ibdev2netdev,确认 mlx5_0→eth0mlx5_3→eth3
  3. 宿主机设备: ls -l /dev/infiniband
  4. 容器设备: docker exec CONTAINER ls -l /dev/infiniband。 宿主机有、容器没有,NCCL 仍然用不了 RDMA。
  5. 运行时证据: 用一次 NCCL_DEBUG=INFO 启动,搜索 NET/IBNET/SocketGDRDMA
  6. 硬件计数器: 同时观察 eth0/eth3 流量和 RDMA 端口计数;不能只看环境变量。
  7. 端到端 A/B: 冷缓存、同一 prompt、同一模型参数,仅改变一个网络变量。

最小 RDMA 设备透传验证

docker run --rm \
  --device=/dev/infiniband/rdma_cm \
  --device=/dev/infiniband/uverbs0 \
  --device=/dev/infiniband/uverbs3 \
  IMAGE \
  ls -l /dev/infiniband

能看到设备只是第一关。最终仍必须从 NCCL INFO 中看到 NET/IB, 并通过通信基准与 SGLang 结果确认。

9. 官方资料

返回推理优化主计划