sskj/docs/dsv4pro_pro6000d_2node_sglang/6000D双机通信与NCCL术语入门.html

797 lines
30 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>6000D 双机通信、NCCL 与 Profiling 术语入门</title>
<style>
:root {
color-scheme: light;
--ink: #17202a;
--muted: #5f6b76;
--line: #d9dee3;
--panel: #f5f7f8;
--cyan: #087b83;
--cyan-soft: #e5f4f3;
--orange: #a64b17;
--orange-soft: #fff0e5;
--green: #287a45;
--green-soft: #eaf6ee;
--red: #a73535;
--red-soft: #fdecec;
--code: #f0f2f4;
--max: 1160px;
}
* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
margin: 0;
color: var(--ink);
background: #fff;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC",
"Hiragino Sans GB", "Microsoft YaHei", sans-serif;
font-size: 16px;
line-height: 1.72;
}
header {
color: #fff;
background: #172f35;
border-bottom: 5px solid #e57932;
}
.header-inner {
max-width: var(--max);
margin: 0 auto;
padding: 46px 28px 40px;
}
.eyebrow {
margin: 0 0 8px;
color: #9ed8d5;
font-size: 13px;
font-weight: 700;
text-transform: uppercase;
}
h1, h2, h3 { letter-spacing: 0; }
header h1 {
max-width: 850px;
margin: 0;
font-size: clamp(32px, 5vw, 54px);
line-height: 1.12;
}
.header-meta {
display: flex;
flex-wrap: wrap;
gap: 10px 22px;
margin-top: 22px;
color: #d4e4e5;
font-size: 14px;
}
.layout {
display: grid;
grid-template-columns: 240px minmax(0, 1fr);
gap: 38px;
max-width: var(--max);
margin: 0 auto;
padding: 34px 28px 70px;
}
nav {
position: sticky;
top: 20px;
align-self: start;
padding-right: 20px;
border-right: 1px solid var(--line);
}
nav strong {
display: block;
margin-bottom: 10px;
font-size: 13px;
color: var(--muted);
}
nav a {
display: block;
padding: 6px 0;
color: #40515a;
font-size: 14px;
text-decoration: none;
}
nav a:hover { color: var(--cyan); }
main { min-width: 0; }
h2 {
margin: 48px 0 16px;
padding-top: 8px;
font-size: 28px;
line-height: 1.25;
border-top: 2px solid var(--ink);
}
h2:first-child { margin-top: 0; }
h3 {
margin: 30px 0 10px;
font-size: 20px;
line-height: 1.35;
}
p { margin: 10px 0; }
a { color: var(--cyan); }
code {
padding: 2px 5px;
border-radius: 3px;
background: var(--code);
font-family: "SFMono-Regular", Consolas, monospace;
font-size: .92em;
}
pre {
overflow-x: auto;
margin: 14px 0;
padding: 16px 18px;
color: #e8f1f1;
background: #1c292d;
border-left: 4px solid #4cb3ae;
border-radius: 4px;
line-height: 1.55;
}
pre code {
padding: 0;
color: inherit;
background: transparent;
}
table {
width: 100%;
margin: 16px 0 24px;
border-collapse: collapse;
font-size: 14px;
}
th, td {
padding: 11px 12px;
text-align: left;
vertical-align: top;
border: 1px solid var(--line);
}
th {
color: #26363e;
background: #eef1f3;
}
ul, ol { padding-left: 24px; }
.note, .warning, .finding, .good {
margin: 18px 0;
padding: 15px 18px;
border-left: 4px solid;
border-radius: 4px;
}
.note { background: var(--cyan-soft); border-color: var(--cyan); }
.warning { background: var(--orange-soft); border-color: var(--orange); }
.finding { background: var(--red-soft); border-color: var(--red); }
.good { background: var(--green-soft); border-color: var(--green); }
.path {
display: grid;
grid-template-columns: repeat(5, minmax(0, 1fr));
gap: 8px;
margin: 18px 0 24px;
}
.path div {
min-height: 108px;
padding: 12px;
border: 1px solid var(--line);
border-top: 4px solid var(--cyan);
background: var(--panel);
}
.path b { display: block; margin-bottom: 5px; }
.split {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 18px;
margin: 18px 0;
}
.split section {
padding: 16px 18px;
border: 1px solid var(--line);
border-radius: 4px;
}
.split h3 { margin-top: 0; }
.metric {
font-variant-numeric: tabular-nums;
white-space: nowrap;
}
footer {
padding: 26px 28px 40px;
color: var(--muted);
text-align: center;
border-top: 1px solid var(--line);
}
@media (max-width: 900px) {
.layout { grid-template-columns: 1fr; }
nav {
position: static;
padding: 0 0 18px;
border-right: 0;
border-bottom: 1px solid var(--line);
}
nav a { display: inline-block; margin-right: 14px; }
.path { grid-template-columns: 1fr; }
.split { grid-template-columns: 1fr; }
}
@media print {
nav { display: none; }
.layout { display: block; max-width: none; }
header { color: #000; background: #fff; border-bottom-color: #000; }
.header-meta, .eyebrow { color: #333; }
pre { color: #000; background: #f4f4f4; }
}
</style>
</head>
<body>
<header>
<div class="header-inner">
<p class="eyebrow">Two-node communication primer</p>
<h1>6000D 双机通信、NCCL 与 Profiling 术语入门</h1>
<div class="header-meta">
<span>节点174.1.51.5 + 174.1.51.7</span>
<span>规模16 GPU / TP16</span>
<span>版本2026-07-31 15:25 CST</span>
</div>
</div>
</header>
<div class="layout">
<nav aria-label="目录">
<strong>阅读顺序</strong>
<a href="#mental-model">1. 一张总图</a>
<a href="#names">2. 设备名字</a>
<a href="#glossary">3. 核心术语</a>
<a href="#bootstrap">4. Bootstrap</a>
<a href="#parameters">5. NCCL 参数</a>
<a href="#logs">6. 日志怎么读</a>
<a href="#incident">7. 本次事故</a>
<a href="#checklist">8. 排查清单</a>
<a href="#sources">9. 官方资料</a>
</nav>
<main>
<h2 id="mental-model">1. 先建立一张总图</h2>
<p>
SGLang 不会自己搬运 16 张 GPU 之间的 Tensor。模型代码发起 TP/MoE 通信,
NCCL 决定用什么算法、经过哪条链路把数据送到其他 rank。
</p>
<div class="path" aria-label="通信路径">
<div><b>SGLang</b>执行模型层、TP16 和 EP2</div>
<div><b>Collective</b>AllReduce、AllGather、ReduceScatter、AllToAll</div>
<div><b>NCCL</b>构造 rank、ring/tree 和 channel</div>
<div><b>Transport</b>机内 P2P/IPC跨机 NET/IB 或 NET/Socket</div>
<div><b>硬件</b>GPU、PCIe、HCA、网卡、光模块、交换机</div>
</div>
<div class="note">
<strong>最重要的区分:</strong>
<code>NCCL bootstrap</code> 是“启动时要完成的一件事”;
<code>NCCL_SOCKET_IFNAME</code> 是“选择 IP 网卡的一个参数”;
<code>NET/IB</code><code>NET/Socket</code> 才是 NCCL 实际搬运数据的传输后端。
</div>
<h3>两类跨机路径</h3>
<div class="split">
<section>
<h3>理想路径RDMA</h3>
<p><code>GPU → HCA → RoCE 网络 → HCA → GPU</code></p>
<p>日志应出现 <code>NET/IB</code>,支持时还会出现 <code>GDRDMA</code></p>
</section>
<section>
<h3>回退路径TCP Socket</h3>
<p><code>GPU/CPU → Linux Socket → ethX → TCP/IP → ethX</code></p>
<p>日志会出现 <code>Using network Socket</code>。这不是报错,但性能通常低得多。</p>
</section>
</div>
<h2 id="names">2. eth0 和 mlx5_0 不是同一个设备</h2>
<div class="note">
<strong>400G 是物理 Ethernet 端口的标称链路速率。</strong>
<code>eth0</code> 是该端口的 Linux netdev/IP 入口;
<code>mlx5_0</code> 是映射到该端口的 RDMA Verbs/HCA 入口。
二者相关联,但不相等,也不代表 TCP 或 RDMA 应用一定能跑到 400G。
</div>
<table>
<thead>
<tr><th>名字</th><th>属于哪一层</th><th>负责什么</th><th>本机实例</th></tr>
</thead>
<tbody>
<tr>
<td><code>eth0</code></td>
<td>Linux IP 网卡接口</td>
<td>配置 IP、TCP/UDP、路由<code>NCCL_SOCKET_IFNAME</code> 选择</td>
<td>400 Gbit/s 计算网</td>
</tr>
<tr>
<td><code>eth3</code></td>
<td>Linux IP 网卡接口</td>
<td>第二条计算网 Rail</td>
<td>400 Gbit/s 计算网</td>
</tr>
<tr>
<td><code>mlx5_0</code></td>
<td>RDMA HCA / Verbs 设备</td>
<td><code>NET/IB</code> 使用;由 <code>NCCL_IB_HCA</code> 选择</td>
<td>对应 <code>eth0</code>,挂 switch 1</td>
</tr>
<tr>
<td><code>mlx5_3</code></td>
<td>RDMA HCA / Verbs 设备</td>
<td>第二条 RDMA Rail</td>
<td>对应 <code>eth3</code>,挂 switch 2</td>
</tr>
<tr>
<td><code>/dev/infiniband/uverbs0</code></td>
<td>Linux 字符设备</td>
<td>容器进程访问 RDMA Verbs 的入口</td>
<td>对应 <code>mlx5_0</code></td>
</tr>
</tbody>
</table>
<pre><code>mlx5_0 port 1 ==> eth0 (Up)
mlx5_3 port 1 ==> eth3 (Up)</code></pre>
<p>
同一条物理端口可以同时暴露 Linux IP 接口和 RDMA HCA。
<code>eth0</code> 是 IP/Socket 世界的入口,<code>mlx5_0</code> 是 RDMA
Verbs 世界的入口。<code>ibdev2netdev</code> 输出的是映射关系,不是等号。
本项目部署时只把 <code>eth0/eth3</code> 作为节点间计算网。
</p>
<pre><code>同一条 400G 物理 Ethernet 端口
├── eth0 -> Linux netdev -> IP / TCP Socket
└── mlx5_0 -> RDMA HCA -> RoCE / Verbs / GDRDMA</code></pre>
<p>
<code>400 Gbit/s = 50 GB/s</code> 只是单方向理论线速。协议开销、PCIe、
CPU、Socket 线程、消息大小和 collective 算法都会让实际
<code>algbw/busbw</code> 低于或采用不同统计口径。
</p>
<h2 id="glossary">3. 核心术语字典</h2>
<table>
<thead>
<tr><th>术语</th><th>通俗解释</th><th>在本项目中的意义</th></tr>
</thead>
<tbody>
<tr>
<td><strong>NCCL</strong></td>
<td>NVIDIA 的多 GPU 通信库,负责高效实现 collective 和点对点通信。</td>
<td>SGLang TP16 每层跨 GPU 通信最终大量落到 NCCL。</td>
</tr>
<tr>
<td><strong>rank</strong></td>
<td>一个通信参与者的编号。TP16 communicator 有 rank 015。</td>
<td>两台机器各 8 个 GPU rank共 16 个。</td>
</tr>
<tr>
<td><strong>collective</strong></td>
<td>一组 rank 共同参与的通信操作。</td>
<td>TP 常见 AllReduce、AllGather、ReduceScatterMoE 还可能有 AllToAll。</td>
</tr>
<tr>
<td><strong>RDMA</strong></td>
<td>远端直接内存访问。网卡可直接读写远端内存,减少 CPU 和内核数据拷贝。</td>
<td>双机 TP16 希望使用的高速数据路径。</td>
</tr>
<tr>
<td><strong>IB</strong></td>
<td>InfiniBand。既是一套高速网络体系也常被 NCCL 用作 Verbs/RDMA 后端的统称。</td>
<td>NCCL 日志里的 <code>NET/IB</code> 也可承载 RoCE不代表交换机一定是原生 IB。</td>
</tr>
<tr>
<td><strong>RoCE</strong></td>
<td>RDMA over Converged Ethernet在以太网上承载 RDMA。</td>
<td>本项目的 400G 计算网类型。</td>
</tr>
<tr>
<td><strong>HCA</strong></td>
<td>Host Channel Adapter提供 RDMA 能力的适配器。</td>
<td><code>mlx5_0</code><code>mlx5_3</code></td>
</tr>
<tr>
<td><strong>GDRDMA</strong></td>
<td>GPUDirect RDMA让 HCA 直接访问 GPU 显存,减少经 CPU 内存中转。</td>
<td>跨机 GPU 通信的理想路径,日志可见 <code>via NET/IB/.../GDRDMA</code></td>
</tr>
<tr>
<td><strong>Socket / TCP</strong></td>
<td>普通 IP 网络编程路径。NCCL 找不到 RDMA 时会使用。</td>
<td>本次脚本实际发生的回退路径。</td>
</tr>
<tr>
<td><strong>Rail</strong></td>
<td>一条相对独立的网络通道,通常由一张 HCA 和一套交换路径组成。</td>
<td><code>mlx5_0/switch 1</code><code>mlx5_3/switch 2</code> 是双 Rail。</td>
</tr>
<tr>
<td><strong>ring / tree</strong></td>
<td>NCCL 对 collective 的通信拓扑组织方式。</td>
<td><code>NCCL_CROSS_NIC</code> 决定同一 ring/tree 能否跨不同 NIC。</td>
</tr>
<tr>
<td><strong>PFC / ECN</strong></td>
<td>RoCE 网络控制拥塞和丢包的机制。</td>
<td>RDMA 出现 retry、pause 或吞吐抖动时由运维检查。</td>
</tr>
<tr>
<td><strong>NIC</strong></td>
<td>Network Interface Card网卡的统称。它可以暴露普通 IP 接口,也可以提供 RDMA 能力。</td>
<td><code>eth0/eth3</code> 是 Linux netdev 名;对应的 RDMA HCA 名是 <code>mlx5_0/mlx5_3</code></td>
</tr>
<tr>
<td><strong>NUMA</strong></td>
<td>Non-Uniform Memory Access。双路 CPU 机器中,每个 CPU 访问本地内存更快,访问另一侧内存更慢。</td>
<td>服务线程、GPU 和 NIC 若跨 NUMA 节点配合,可能增加 Host 侧延迟和 PCIe 路径长度。</td>
</tr>
<tr>
<td><strong>CUDA P2P / IPC</strong></td>
<td>P2P 让同机 GPU 直接互访显存IPC 让不同进程共享可访问的 GPU 内存句柄。</td>
<td>6000D 无 NVLink单机 8 卡的 NCCL P2P/IPC 实际经过 PCIe。</td>
</tr>
<tr>
<td><strong>PIX / SYS</strong></td>
<td>NVIDIA 拓扑标签。PIX 表示 GPU 间只跨一个 PCIe SwitchSYS 表示还要跨 CPU/NUMA 互联。</td>
<td>GPU03、GPU47 各自多为 PIX两组之间为 SYSP2P 微基准会分别汇总这两类路径。</td>
</tr>
<tr>
<td><strong>AllReduce</strong></td>
<td>所有 rank 先归约数据,再让每个 rank 都拿到相同结果的 collective。</td>
<td>TP16 高频使用Phase 2 分别测单机 8 rank 和双机 16 rank。</td>
</tr>
<tr>
<td><strong>algbw / busbw</strong></td>
<td><code>algbw</code> 是有效数据量除以操作时间;<code>busbw</code> 再按 collective 的理论链路流量换算,便于比较硬件通信效率。</td>
<td>AllReduce 使用 <code>busbw = algbw × 2 × (N-1) / N</code>。两者单位通常为 GB/s不能与 400 Gbit/s 直接混用。</td>
</tr>
<tr>
<td><strong>DCGM</strong></td>
<td>NVIDIA Data Center GPU Manager一套 GPU 健康、遥测和诊断框架。它比 <code>nvidia-smi</code> 提供更细的 GPU 活跃度计数器。</td>
<td>Phase 2 用它采集 SM、Tensor、设备显存接口和 PCIe 活跃度;它不是 Nsight Timeline。</td>
</tr>
<tr>
<td><strong>DCGM Host Engine</strong></td>
<td>DCGM 的后台服务,负责连接驱动、维护 GPU 清单并提供指标。systemd 服务通常叫 <code>nvidia-dcgm</code>,底层进程是 <code>nv-hostengine</code></td>
<td>两节点都必须运行;否则 <code>dcgmi dmon</code> 客户端存在也无法采集。</td>
</tr>
<tr>
<td><strong>dcgmi / Field ID</strong></td>
<td><code>dcgmi</code> 是 DCGM 命令行客户端Field ID 是某个遥测指标的数字编号。</td>
<td>Phase 2 使用 10011005、1009、1010并把缺失样本保留为 <code>-</code>,不会当成 0。</td>
</tr>
<tr>
<td><strong>SM</strong></td>
<td>Streaming MultiprocessorGPU 执行 CUDA Warp、Tensor Core 指令和大部分计算的基本处理单元。</td>
<td><code>sm_active</code> 高说明 SM 经常在工作,但不等于每个 SM 都满负载。</td>
</tr>
<tr>
<td><strong>Warp</strong></td>
<td>NVIDIA GPU 同步执行的一组线程,通常包含 32 个 CUDA 线程。</td>
<td><code>sm_occupancy</code> 反映活跃 Warp 相对硬件可容纳 Warp 的比例。</td>
</tr>
<tr>
<td><strong>SM Active / Occupancy</strong></td>
<td>前者回答“SM 有多少时间在工作”,后者回答“工作时驻留了多少 Warp”。</td>
<td>Active 高、Occupancy 低可能来自小 Kernel、资源约束或同步必须结合后续 Timeline 判断。</td>
</tr>
<tr>
<td><strong>Tensor Active</strong></td>
<td>Tensor Core 管线处于活跃状态的时间比例。</td>
<td>用于判断矩阵计算单元是否被充分使用;它不是模型总 FLOPS 利用率。</td>
</tr>
<tr>
<td><strong>DRAM Active</strong></td>
<td>DCGM 的历史字段名,表示 GPU 设备显存接口活跃比例,不限定显存必须是主机 DRAM 或 HBM。</td>
<td>Pro6000D 使用 GDDR7该指标仍用于观察设备显存带宽压力。</td>
</tr>
<tr>
<td><strong>测量窗口 / Epoch</strong></td>
<td>Epoch 是统一的 Unix 时间基准;测量窗口是正式 benchmark 开始到结束的精确时间段。</td>
<td>Phase 2 用 <code>Starting main benchmark run</code> 加 benchmark duration 切片,排除数据准备和 Warm-up。</td>
</tr>
<tr>
<td><strong>mpstat</strong></td>
<td>查看整机和每个逻辑 CPU 的利用率、I/O Wait 等。</td>
<td>回答是否整机 CPU 饱和,或只有少数核心成为热点。</td>
</tr>
<tr>
<td><strong>pidstat</strong></td>
<td>按进程统计 CPU、内存、I/O、缺页和上下文切换。</td>
<td>Phase 2 使用进程级 5 秒采样,避免旧版线程级 1 秒采样产生数百 MB 日志。</td>
</tr>
<tr>
<td><strong>sar</strong></td>
<td>sysstat 套件中的系统活动记录工具,可采集网卡吞吐和错误。</td>
<td>Phase 2 只看计算网 <code>eth0/eth3</code>,与 HCA RDMA Counter 分层比较。</td>
</tr>
<tr>
<td><strong>perf stat</strong></td>
<td>Linux 性能计数器工具,统计 CPU cycles、instructions、cache miss、迁移和缺页。</td>
<td>用于判断 Host 进程是否受 CPU 执行、Cache 或调度开销限制,不提供 GPU Kernel 时间线。</td>
</tr>
<tr>
<td><strong>numastat</strong></td>
<td>查看系统或进程在各 NUMA 节点上的内存分布。</td>
<td>Phase 2 每 5 秒保存结构化 Node0/Node1 MiB寻找跨 NUMA 内存放置。</td>
</tr>
</tbody>
</table>
<h2 id="bootstrap">4. NCCL bootstrap 到底是什么</h2>
<p>
NCCL 本身不是进程启动器。SGLang 先启动各个 workerNCCL communicator 初始化时,
rank 之间需要交换地址、唯一 ID、拓扑和连接信息这段“先认识彼此”的过程就是 bootstrap。
</p>
<ol>
<li>每个 rank 启动并获得自己的 rank ID。</li>
<li>通过 IP Socket 交换 NCCL unique ID 和连接信息。</li>
<li>NCCL 探测 GPU、PCIe、HCA 和节点拓扑。</li>
<li>构造 ring/tree/channel。</li>
<li>选择真正的数据传输后端P2P、SHM、NET/IB 或 NET/Socket。</li>
</ol>
<div class="warning">
<strong>容易误解的地方:</strong>
<code>NCCL_SOCKET_IFNAME</code> 不保证“只用于 bootstrap”。
RDMA 正常时它主要承担 bootstrapRDMA 失败并回退 Socket 后,它也会决定大块 Tensor
数据走哪张 IP 网卡。
</div>
<h2 id="parameters">5. 常见 NCCL 参数</h2>
<h3>NCCL_SOCKET_IFNAME</h3>
<p>筛选 NCCL 可使用的 Linux IP 接口。精确指定接口时可写:</p>
<pre><code>NCCL_SOCKET_IFNAME="=eth0"</code></pre>
<ul>
<li>RDMA 正常:主要影响 bootstrap/OOB IP 连接。</li>
<li>RDMA 不可用:决定 <code>NET/Socket</code> 的数据网卡。</li>
<li>部署时只允许使用计算网 <code>eth0/eth3</code>Socket 回退时不能落到其他接口。</li>
</ul>
<h3>NCCL_IB_HCA</h3>
<p>筛选 NCCL 的 RDMA HCA。推荐使用精确匹配</p>
<pre><code>NCCL_IB_HCA="=mlx5_0:1,mlx5_3:1"</code></pre>
<p>
这个变量只是“允许选择谁”,不会自动把宿主机 RDMA 设备送进容器。
容器还必须看到 <code>/dev/infiniband/rdma_cm</code>
<code>uverbs0</code><code>uverbs3</code>
</p>
<h3>NCCL_CROSS_NIC</h3>
<table>
<thead>
<tr><th></th><th>行为</th><th>适用直觉</th></tr>
</thead>
<tbody>
<tr>
<td><code>0</code></td>
<td>尽量让同一 ring/tree 在不同节点使用对应的同一条 Rail。</td>
<td>每张 NIC 接不同交换机、跨 Rail 代价高的 rail-optimized 网络。</td>
</tr>
<tr>
<td><code>1</code></td>
<td>允许同一 ring/tree 在不同节点使用不同 NIC。</td>
<td>所有 NIC 进入同一网络 Fabric跨 NIC 不构成额外问题。</td>
</tr>
<tr>
<td><code>2</code></td>
<td>优先对应同一 NIC但必要时允许跨 NIC。</td>
<td>NCCL 默认的折中策略。</td>
</tr>
</tbody>
</table>
<div class="note">
本项目的 <code>mlx5_0</code><code>mlx5_3</code> 分挂 switch 1/2
拓扑直觉上更偏向 <code>0</code> 或默认 <code>2</code>。最终值必须在
<strong>真正启用 NET/IB 后</strong>用 all_reduce 和 SGLang 端到端 A/B 决定。
当 NCCL 使用 NET/Socket 时,这个参数不参与路径选择。
</div>
<h3>NCCL_DEBUG 与 NCCL_DEBUG_SUBSYS</h3>
<pre><code>NCCL_DEBUG=INFO
NCCL_DEBUG_SUBSYS=INIT,NET,GRAPH,TUNING</code></pre>
<p>用于确认实际路径,诊断完成后应关闭,正式性能数据不要长期带 INFO 日志。</p>
<h2 id="logs">6. NCCL 日志速查</h2>
<table>
<thead>
<tr><th>日志</th><th>含义</th><th>判断</th></tr>
</thead>
<tbody>
<tr>
<td><code>Bootstrap: Using eth0:...</code></td>
<td>初始化控制连接选择 eth0。</td>
<td>只说明 bootstrap尚不能证明数据走 RDMA。</td>
</tr>
<tr>
<td><code>NET/IB : Using ... mlx5_0 ...</code></td>
<td>NCCL 已识别 RDMA HCA。</td>
<td>RDMA 数据后端可用。</td>
</tr>
<tr>
<td><code>via NET/IB/.../GDRDMA</code></td>
<td>跨机边通过 GPUDirect RDMA。</td>
<td>理想证据。</td>
</tr>
<tr>
<td><code>NET/IB : No device found</code></td>
<td>容器没有可用 RDMA 设备或驱动/权限不完整。</td>
<td>继续看是否回退 Socket。</td>
</tr>
<tr>
<td><code>NET/Socket : Using 非计算网...</code></td>
<td>跨机数据由普通 TCP Socket 传输。</td>
<td>若误入低速非计算网,性能会严重受限。</td>
</tr>
<tr>
<td><code>via P2P/IPC</code></td>
<td>同机 GPU 通过 CUDA P2P/IPC。</td>
<td>机内路径,不代表跨机路径。</td>
</tr>
</tbody>
</table>
<h2 id="incident">7. 2026-07-30 Prefill 变慢事故复盘</h2>
<h3>已观测事实</h3>
<ul>
<li>宿主机存在 <code>/dev/infiniband</code>,两条 400G Rail 均 Up。</li>
<li>原脚本容器内不存在 <code>/dev/infiniband</code></li>
<li>NCCL INFO 明确打印 <code>NET/IB : No device found</code><code>Using network Socket</code></li>
<li>原脚本选择 400G 计算网 <code>eth0</code>quick-map 曾误选低速非计算网。</li>
<li>部署规定只有 <code>eth0/eth3</code> 用于节点间通信,两者均为 400G。</li>
</ul>
<table>
<thead>
<tr><th>冷缓存 Shape</th><th>原脚本网络eth0 Socket</th><th>quick-map错误的非计算网</th><th>差异</th></tr>
</thead>
<tbody>
<tr>
<td>1K → 1, C=1</td>
<td class="metric">TTFT 1.458s / 693.1 input tok/s</td>
<td class="metric">TTFT 15.8816.04s / 约 64 tok/s</td>
<td>约 10.9×</td>
</tr>
<tr>
<td>32K → 1, C=1</td>
<td class="metric">TTFT 38.062s / 860.5 input tok/s</td>
<td class="metric">TTFT 504.44s / 64.96 tok/s</td>
<td>约 13.25×</td>
</tr>
</tbody>
</table>
<div class="finding">
<strong>根因判断:</strong>
quick-map 没有把 RDMA 设备透传进容器,却把 <code>NCCL_SOCKET_IFNAME</code>
设成低速非计算网。NCCL 回退 NET/Socket 后TP16 跨机数据没有进入规定的
<code>eth0/eth3</code> 计算网。<code>NCCL_CROSS_NIC=1</code> 在没有 NET/IB
的情况下不是致因。
</div>
<h3>为什么旧日志还会比 38 秒更短</h3>
<p>
旧矩阵脚本还有第二个独立因素:<code>warmup_requests=16</code>、固定
<code>seed=42</code>、ISL/OSL/C 升序运行,而且从不 flush Prefix Cache。
因此旧日志混入缓存命中,不能直接与冷 Prefill 比较。
</p>
<div class="good">
quick-map 现在只允许 <code>eth0/eth3</code>
<code>mlx5_0/mlx5_3</code>,并会透传精确 RDMA 设备、强制检查两端
<code>NET/IB</code> 日志。代码与 dry-run 已通过;下一步是真机启动验证,
在拿到运行时证据前不进入 Kernel 归因。
</div>
<h2 id="checklist">8. 从宿主机到 NCCL 的排查清单</h2>
<ol>
<li>
<strong>宿主机链路:</strong>
<code>ethtool eth0</code><code>ethtool eth3</code>
</li>
<li>
<strong>HCA 映射:</strong>
<code>ibdev2netdev</code>,确认 <code>mlx5_0→eth0</code>
<code>mlx5_3→eth3</code>
</li>
<li>
<strong>宿主机设备:</strong>
<code>ls -l /dev/infiniband</code>
</li>
<li>
<strong>容器设备:</strong>
<code>docker exec CONTAINER ls -l /dev/infiniband</code>
宿主机有、容器没有NCCL 仍然用不了 RDMA。
</li>
<li>
<strong>运行时证据:</strong>
用一次 <code>NCCL_DEBUG=INFO</code> 启动,搜索
<code>NET/IB</code><code>NET/Socket</code><code>GDRDMA</code>
</li>
<li>
<strong>硬件计数器:</strong>
同时观察 eth0/eth3 流量和 RDMA 端口计数;不能只看环境变量。
</li>
<li>
<strong>端到端 A/B</strong>
冷缓存、同一 prompt、同一模型参数仅改变一个网络变量。
</li>
</ol>
<h3>最小 RDMA 设备透传验证</h3>
<pre><code>docker run --rm \
--device=/dev/infiniband/rdma_cm \
--device=/dev/infiniband/uverbs0 \
--device=/dev/infiniband/uverbs3 \
IMAGE \
ls -l /dev/infiniband</code></pre>
<p>
能看到设备只是第一关。最终仍必须从 NCCL INFO 中看到 <code>NET/IB</code>
并通过通信基准与 SGLang 结果确认。
</p>
<h2 id="sources">9. 官方资料</h2>
<ul>
<li>
<a href="https://docs.nvidia.com/deeplearning/nccl/user-guide/docs/setup.html">
NVIDIA NCCL Setupbootstrap 与通信安全边界
</a>
</li>
<li>
<a href="https://docs.nvidia.com/deeplearning/nccl/user-guide/docs/env.html">
NVIDIA NCCL Environment VariablesSOCKET_IFNAME、IB_HCA、CROSS_NIC
</a>
</li>
<li>
<a href="https://docs.nvidia.com/deeplearning/nccl/user-guide/docs/troubleshooting/networking_troubleshooting.html">
NVIDIA NCCL Networking Troubleshooting
</a>
</li>
</ul>
<p>
<a href="./推理优化计划.html">返回推理优化主计划</a>
</p>
</main>
</div>
<footer>
本页以两台 6000D 的真实设备映射和 2026-07-30 实测日志为例。
</footer>
</body>
</html>