1. 先建立一张总图
SGLang 不会自己搬运 16 张 GPU 之间的 Tensor。模型代码发起 TP/MoE 通信, NCCL 决定用什么算法、经过哪条链路把数据送到其他 rank。
NCCL bootstrap 是“启动时要完成的一件事”;
NCCL_SOCKET_IFNAME 是“选择 IP 网卡的一个参数”;
NET/IB 和 NET/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 不是同一个设备
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_0、mlx5_3。 |
| GDRDMA | GPUDirect RDMA,让 HCA 直接访问 GPU 显存,减少经 CPU 内存中转。 | 跨机 GPU 通信的理想路径,日志可见 via NET/IB/.../GDRDMA。 |
| Socket / TCP | 普通 IP 网络编程路径。NCCL 找不到 RDMA 时会使用。 | 本次脚本实际发生的回退路径。 |
| Rail | 一条相对独立的网络通道,通常由一张 HCA 和一套交换路径组成。 | mlx5_0/switch 1 与 mlx5_3/switch 2 是双 Rail。 |
| ring / tree | NCCL 对 collective 的通信拓扑组织方式。 | NCCL_CROSS_NIC 决定同一 ring/tree 能否跨不同 NIC。 |
| PFC / ECN | RoCE 网络控制拥塞和丢包的机制。 | RDMA 出现 retry、pause 或吞吐抖动时由运维检查。 |
| NIC | Network Interface Card,网卡的统称。它可以暴露普通 IP 接口,也可以提供 RDMA 能力。 | eth0/eth3 是 Linux netdev 名;对应的 RDMA HCA 名是 mlx5_0/mlx5_3。 |
| NUMA | Non-Uniform Memory Access。双路 CPU 机器中,每个 CPU 访问本地内存更快,访问另一侧内存更慢。 | 服务线程、GPU 和 NIC 若跨 NUMA 节点配合,可能增加 Host 侧延迟和 PCIe 路径长度。 |
| CUDA P2P / IPC | P2P 让同机 GPU 直接互访显存;IPC 让不同进程共享可访问的 GPU 内存句柄。 | 6000D 无 NVLink,单机 8 卡的 NCCL P2P/IPC 实际经过 PCIe。 |
| PIX / SYS | NVIDIA 拓扑标签。PIX 表示 GPU 间只跨一个 PCIe Switch;SYS 表示还要跨 CPU/NUMA 互联。 | GPU0–3、GPU4–7 各自多为 PIX,两组之间为 SYS;P2P 微基准会分别汇总这两类路径。 |
| AllReduce | 所有 rank 先归约数据,再让每个 rank 都拿到相同结果的 collective。 | TP16 高频使用;Phase 2 分别测单机 8 rank 和双机 16 rank。 |
| algbw / busbw | algbw 是有效数据量除以操作时间;busbw 再按 collective 的理论链路流量换算,便于比较硬件通信效率。 |
AllReduce 使用 busbw = algbw × 2 × (N-1) / N。两者单位通常为 GB/s,不能与 400 Gbit/s 直接混用。 |
| DCGM | NVIDIA Data Center GPU Manager,一套 GPU 健康、遥测和诊断框架。它比 nvidia-smi 提供更细的 GPU 活跃度计数器。 |
Phase 2 用它采集 SM、Tensor、设备显存接口和 PCIe 活跃度;它不是 Nsight Timeline。 |
| DCGM Host Engine | DCGM 的后台服务,负责连接驱动、维护 GPU 清单并提供指标。systemd 服务通常叫 nvidia-dcgm,底层进程是 nv-hostengine。 |
两节点都必须运行;否则 dcgmi dmon 客户端存在也无法采集。 |
| dcgmi / Field ID | dcgmi 是 DCGM 命令行客户端;Field ID 是某个遥测指标的数字编号。 |
Phase 2 使用 1001–1005、1009、1010,并把缺失样本保留为 -,不会当成 0。 |
| SM | Streaming Multiprocessor,GPU 执行 CUDA Warp、Tensor Core 指令和大部分计算的基本处理单元。 | sm_active 高说明 SM 经常在工作,但不等于每个 SM 都满负载。 |
| Warp | NVIDIA GPU 同步执行的一组线程,通常包含 32 个 CUDA 线程。 | sm_occupancy 反映活跃 Warp 相对硬件可容纳 Warp 的比例。 |
| SM Active / Occupancy | 前者回答“SM 有多少时间在工作”,后者回答“工作时驻留了多少 Warp”。 | Active 高、Occupancy 低可能来自小 Kernel、资源约束或同步,必须结合后续 Timeline 判断。 |
| Tensor Active | Tensor Core 管线处于活跃状态的时间比例。 | 用于判断矩阵计算单元是否被充分使用;它不是模型总 FLOPS 利用率。 |
| DRAM Active | DCGM 的历史字段名,表示 GPU 设备显存接口活跃比例,不限定显存必须是主机 DRAM 或 HBM。 | Pro6000D 使用 GDDR7;该指标仍用于观察设备显存带宽压力。 |
| 测量窗口 / Epoch | Epoch 是统一的 Unix 时间基准;测量窗口是正式 benchmark 开始到结束的精确时间段。 | Phase 2 用 Starting main benchmark run 加 benchmark duration 切片,排除数据准备和 Warm-up。 |
| mpstat | 查看整机和每个逻辑 CPU 的利用率、I/O Wait 等。 | 回答是否整机 CPU 饱和,或只有少数核心成为热点。 |
| pidstat | 按进程统计 CPU、内存、I/O、缺页和上下文切换。 | Phase 2 使用进程级 5 秒采样,避免旧版线程级 1 秒采样产生数百 MB 日志。 |
| sar | sysstat 套件中的系统活动记录工具,可采集网卡吞吐和错误。 | Phase 2 只看计算网 eth0/eth3,与 HCA RDMA Counter 分层比较。 |
| perf stat | Linux 性能计数器工具,统计 CPU cycles、instructions、cache miss、迁移和缺页。 | 用于判断 Host 进程是否受 CPU 执行、Cache 或调度开销限制,不提供 GPU Kernel 时间线。 |
| numastat | 查看系统或进程在各 NUMA 节点上的内存分布。 | Phase 2 每 5 秒保存结构化 Node0/Node1 MiB,寻找跨 NUMA 内存放置。 |
| HCA Counter | 网卡硬件维护的发送、接收、等待、丢弃和错误累计计数器。 | Phase 2.5 用 mlx5_0/mlx5_3 的 counter 差值计算正式 benchmark 窗口内的 RDMA Gbit/s。 |
| bytes/input-token/rail | 模型每处理一个输入 token,平均要在一条 Rail 上发送的字节数。 | 当前 DSV4-Pro TP16/EP2 Scout 拟合为约 3.332 MB/token/rail;换模型或并行策略必须重新标定。 |
| 带宽平台 / 拐点 | 继续增加并发后,吞吐与网络带宽都几乎不再增长的位置。 | Phase 2.5 以相邻点的 Input TPS 和 Rail Mean 增益同时低于 5% 判断,当前拐点为 C=16。 |
| 渐近线 / 饱和上限 | 饱和曲线在并发继续增大时逼近、但不会明显超过的预测上限。 | 当前 64K Prefill 的拟合上限约 80.32 Gbit/s/rail,表示模型产流量上限,不表示网卡硬件只能跑 80G。 |
4. NCCL bootstrap 到底是什么
NCCL 本身不是进程启动器。SGLang 先启动各个 worker,NCCL communicator 初始化时, rank 之间需要交换地址、唯一 ID、拓扑和连接信息,这段“先认识彼此”的过程就是 bootstrap。
- 每个 rank 启动并获得自己的 rank ID。
- 通过 IP Socket 交换 NCCL unique ID 和连接信息。
- NCCL 探测 GPU、PCIe、HCA 和节点拓扑。
- 构造 ring/tree/channel。
- 选择真正的数据传输后端: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"
- RDMA 正常:主要影响 bootstrap/OOB IP 连接。
- RDMA 不可用:决定
NET/Socket的数据网卡。 - 部署时只允许使用计算网
eth0/eth3;Socket 回退时不能落到其他接口。
NCCL_IB_HCA
筛选 NCCL 的 RDMA HCA。推荐使用精确匹配:
NCCL_IB_HCA="=mlx5_0:1,mlx5_3:1"
这个变量只是“允许选择谁”,不会自动把宿主机 RDMA 设备送进容器。
容器还必须看到 /dev/infiniband/rdma_cm、
uverbs0 和 uverbs3。
NCCL_CROSS_NIC
| 值 | 行为 | 适用直觉 |
|---|---|---|
0 |
尽量让同一 ring/tree 在不同节点使用对应的同一条 Rail。 | 每张 NIC 接不同交换机、跨 Rail 代价高的 rail-optimized 网络。 |
1 |
允许同一 ring/tree 在不同节点使用不同 NIC。 | 所有 NIC 进入同一网络 Fabric,跨 NIC 不构成额外问题。 |
2 |
优先对应同一 NIC,但必要时允许跨 NIC。 | NCCL 默认的折中策略。 |
mlx5_0 和 mlx5_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 变慢事故复盘
已观测事实
- 宿主机存在
/dev/infiniband,两条 400G Rail 均 Up。 - 原脚本容器内不存在
/dev/infiniband。 - NCCL INFO 明确打印
NET/IB : No device found和Using network Socket。 - 原脚本选择 400G 计算网
eth0;quick-map 曾误选低速非计算网。 - 部署规定只有
eth0/eth3用于节点间通信,两者均为 400G。
| 冷缓存 Shape | 原脚本网络:eth0 Socket | quick-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× |
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 比较。
eth0/eth3 和
mlx5_0/mlx5_3,并会透传精确 RDMA 设备、强制检查两端
NET/IB 日志。代码与 dry-run 已通过;下一步是真机启动验证,
在拿到运行时证据前不进入 Kernel 归因。
8. 从宿主机到 NCCL 的排查清单
-
宿主机链路:
ethtool eth0、ethtool eth3。 -
HCA 映射:
ibdev2netdev,确认mlx5_0→eth0、mlx5_3→eth3。 -
宿主机设备:
ls -l /dev/infiniband。 -
容器设备:
docker exec CONTAINER ls -l /dev/infiniband。 宿主机有、容器没有,NCCL 仍然用不了 RDMA。 -
运行时证据:
用一次
NCCL_DEBUG=INFO启动,搜索NET/IB、NET/Socket、GDRDMA。 - 硬件计数器: 同时观察 eth0/eth3 流量和 RDMA 端口计数;不能只看环境变量。
- 端到端 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 结果确认。