128+3 台 B300 推理集群 · 整体网络架构图
128 台在线推理节点 + 3 台热备机 | 8×B300/节点 | 800G Rail-Optimized Fabric | Prefill/Decode 分离推理。
集群整体网络总览(推理业务视角)

单台节点内部架构(每台服务器内部)


节点->Leaf->Spine布线细节(Rail-Optimized)


先把最根本的问题问清楚:为什么需要交换机分层?
一、起点:131 台机器怎么互相连
每台节点有 8 张网卡,全集群 131 × 8 = 1,048 个网口。这 1,048 个口要能互相通信。
最笨的办法是两两拉一根线,需要 1048 × 1047 ÷ 2 ≈ 54.8 万根线。物理上不可能。
所以引入交换机:一个盒子,上面有一排口,谁要发数据就交给它,它负责转到目标口。所有人只需要各拉一根线到这个盒子。1,048 根线,问题解决。
但交换机的口数有物理上限。 一台交换机的核心是一颗交换芯片,芯片的引脚数、封装面积、功耗、散热都有天花板。当前最强的 800G 级交换芯片大约支持 144 个 800G 端口(本方案选型的 Quantum-X800 Q3400 就是这个规格)。
于是矛盾出现了:需要接 1,048 个口,但一台交换机只有 144 个口。
二、Leaf 和 Spine 是什么
多台交换机必须组合使用。怎么组合?
错误做法:串联(菊花链)。 交换机 A 接 B,B 接 C。结果是 A 和 C 之间的所有流量都要挤过 B,B 成为瓶颈,而且距离越远跳数越多,延迟不均。
正确做法:分角色、分层。
| 角色 | 中文 | 干什么 | 接不接服务器 |
|---|---|---|---|
| Leaf | 叶交换机 / 接入层 | 服务器直接插在它上面 | 接 |
| Spine | 脊交换机 / 核心层 | 只连 Leaf,把所有 Leaf 串起来 | 绝不接 |
名字来自树的比喻:Spine 是脊柱/主干,Leaf 是末端的叶子。服务器挂在叶子上,叶子之间要通信就借道脊柱。
这个结构有三个名字,指的是同一个东西:
- Leaf-Spine 架构——工程界最常用的叫法
- 两层 Clos 网络——1953 年贝尔实验室的 Charles Clos 为电话交换设计的多级无阻塞结构,这是理论源头
- 胖树 Fat-Tree——1985 年 Charles Leiserson 提出。普通树越往上越细会堵车,"胖树"要求上层带宽和下层一样粗
Spine 为什么绝不能接服务器? 因为一旦接了,网络就不对称了:挂在 Spine 上的服务器到别人只要 1 跳,挂在 Leaf 上的要 3 跳。路由算法依赖"所有节点地位相同"这个前提,破坏对称性会让负载均衡和故障切换全部失效。这是硬规矩。
三、核心计算:为什么一台 Leaf 只接 72 台服务器
这是你问的"值怎么算出来的"的关键。
一台 Leaf 有 144 个口。这 144 个口必须分成两部分:
┌─────────── 144 个 800G 口 ───────────┐
│ │
│ 72 个"上联口" ──→ 连 Spine │
│ ────────────────────────────── │
│ 72 个"下联口" ──→ 接服务器 │
│ │
└───────────────────────────────────────┘
为什么正好一半一半?
考虑最坏情况:这台 Leaf 下面 72 台服务器同时要和外面(其他 Leaf 下的机器)满速通信。这些流量全都得从上联口出去。
- 下联总带宽 = 72 × 800G = 57.6 Tb/s
- 如果上联只有 36 个口 = 28.8 Tb/s,那就只能过一半,另一半排队 → 堵
所以要不堵,必须 上联带宽 ≥ 下联带宽,即 72 = 72。
这个比值有个专门的名字:收敛比(也叫超配比 oversubscription ratio)= 下联 : 上联。
| 收敛比 | 配置 | 含义 | 成本 |
|---|---|---|---|
| 1:1 | 72下 / 72上 | 无阻塞,任意时刻全速互通 | 基准(本方案采用) |
| 2:1 | 96下 / 48上 | 一半机器满速时另一半要排队 | 交换机少约 40% |
| 4:1 | 115下 / 29上 | 只在轻载时不堵 | 便宜,但训练场景不可接受 |
这就是 N-10 图纸末尾那个"能省 1,500 万"的可选优化项的技术含义。
四、本方案的完整推导
第一步:如果不做 Rail 优化(标准算法)
端点总数 = 131 × 8 = 1,048
Leaf 数 = ⌈1,048 ÷ 72⌉ = 15 台
上联总数 = 15 × 72 = 1,080 条
Spine 数 = ⌈1,080 ÷ 144⌉ = 8 台
交换机合计 = 23 台
第二步:加上 Rail 优化的约束
Rail 优化要求:所有节点的第 i 张 GPU,必须接到同一台(组)Leaf 上。这就把"1,048 个端点随便分"变成了"8 条 Rail,每条 Rail 独立分"。
每条 Rail 的端点数 = 131 台节点 × 每台 1 张卡 = 131 个
131 > 72(单台 Leaf 下联上限)
↓
每条 Rail 需要 2 台 Leaf,131 个端点分成 66 + 65
Leaf 总数 = 8 条 Rail × 2 台 = 16 台
第三步:单台 Leaf 的端口账本
下联 66 口 ──→ 66 台节点的同号 GPU
上联 66 口 ──→ 分散连到 8 台 Spine(1:1 无阻塞)
空闲 12 口 ──→ 扩容余量
────────────────────────────────
合计 144 口
第四步:Spine 数量
上联总数 = 16 台 Leaf × 66 条 = 1,056 条
每台 Spine 144 口
Spine 数 = ⌈1,056 ÷ 144⌉ = 8 台
每台 Spine 实际占用 = 1,056 ÷ 8 = 132 口(还空 12 口)
交换机合计 = 16 + 8 = 24 台。 图上标的所有数字都从这四步来。
五、图里那些交叉线是什么意思
你看到 Leaf 和 Spine 之间密密麻麻的线,规则只有一条:
每一台 Leaf,都必须和每一台 Spine 有直接链路,且条数尽量均等。
具体分配:一台 Leaf 的 66 条上联要分给 8 台 Spine,66 ÷ 8 = 8.25,所以是 2 台 Spine 各分 9 条 + 6 台 Spine 各分 8 条(18 + 48 = 66)。
为什么要这样均分,而不是把 66 条全插在 SP-1 上? 两个原因:
- 容错——如果全插 SP-1,SP-1 一挂这台 Leaf 就彻底断了。均分之后,挂一台 Spine 只损失 1/8 的跨 Rail 带宽(约 12.5%),业务不中断。
- 负载分担——流量哈希到 8 条不同路径,避免某一条被打满。
这也回答了"为什么 Spine 要 8 台而不是 1 台大的":Spine 的数量就是跨 Rail 通信的冗余度。
六、节点与节点到底怎么通信:四种情况
这是最核心的部分。假设节点 001 的某张卡要给节点 047 的某张卡发数据。
情况 A:同一台机器内(GPU0 → GPU3)
GPU0 ──NVLink──> NVSwitch ──NVLink──> GPU3
根本不经过任何以太/IB 交换机,不出机箱。延迟约 2–3 µs,带宽 1.8 TB/s。
情况 B:跨机器、同号卡(节点001-GPU3 → 节点047-GPU3)★最重要
两张卡都插在 LF-3a(Rail-3 的 a 组 Leaf)上:
节点001-GPU3 ──光纤──> LF-3a ──光纤──> 节点047-GPU3
↑
只经过 1 台交换机
这是 Rail 优化的全部意义。 延迟约 2–3 µs,完全不占用 Spine 带宽。
情况 C:跨机器、跨号卡(节点001-GPU0 → 节点047-GPU5)
GPU0 在 LF-0a 上,GPU5 在 LF-5a 上,两台不同的交换机,必须借道 Spine:
节点001-GPU0 ──> LF-0a ──> SP-3 ──> LF-5a ──> 节点047-GPU5
↑
经过 3 台交换机
延迟约 4–5 µs,且占用 Leaf-Spine 上联带宽。
关于"跳数"的说法,我在图纸里的用词需要澄清一下。 图上写的"1 跳 / 2 跳"是业界习惯口径,指的是穿越了几层网络(情况 B 只穿 Leaf 层,情况 C 穿了 Leaf→Spine→Leaf)。如果按"经过几台交换机"数,情况 B 是 1 台、情况 C 是 3 台。两种口径都常见,看文档时注意上下文。
情况 D:软件的巧妙规避(NCCL 实际在做的事)
情况 C 其实大多数时候可以避免。NCCL 会这样改写:
第一步(机内):节点001-GPU0 ──NVLink──> 节点001-GPU5 约 2 µs
第二步(跨机):节点001-GPU5 ──LF-5a──> 节点047-GPU5 约 3 µs
用一次几乎免费的 NVLink 搬运,把"跨 Rail 2 层"换成了"同 Rail 1 层"。
这才是 Rail 优化真正的威力:它不是让跨 Rail 通信变快,而是让绝大多数通信根本不需要跨 Rail。Spine 层在正常训练/推理中利用率很低,主要作为兜底和故障时的备用路径存在。
七、一个数据包的物理旅程(情况 B 的完整展开)
| # | 发生了什么 | 耗时 |
|---|---|---|
| 1 | NCCL 下发指令,网卡通过 GPUDirect RDMA 直接从 GPU 显存读数据(不经 CPU 内存) | ~0.5 µs |
| 2 | 网卡封装 IB 数据包,写入目标 LID(本地标识符,由子网管理器统一分配的地址) | ~0.3 µs |
| 3 | 电信号进 OSFP 光模块,调制成 8 路光信号(8 × 100G,这就是 "SR8" 里 8 的含义) | ~0.1 µs |
| 4 | 多模光纤传输 30 米(光在光纤里约 20 万 km/s) | 0.15 µs |
| 5 | 到达 LF-3a 的光模块,还原成电信号 | ~0.1 µs |
| 6 | 交换芯片查转发表(表由 UFM 子网管理器预先算好下发),确定从第 47 号口出去 | ~0.3 µs |
| 7 | 再经光纤 30 米到节点 047 的网卡 | 0.15 µs |
| 8 | 网卡 GPUDirect 直写目标 GPU 显存 | ~0.5 µs |
| 单向端到端合计 | ≈ 2–3 µs |
有意思的是:光纤传播和交换机转发加起来还不到总延迟的 20%,大头在两端的网卡与协议栈处理。这也是为什么把 Leaf 放机房中央(30 米 vs 60 米)主要省的是光模块的钱,而不是延迟。
补充一个容易混淆的点:文档里 N-06 图写的"跨节点 IB ≈ 25–40 µs"和这里的 2–3 µs 不矛盾。前者是集合通信(All-Reduce)的延迟——8 张卡要多轮交换、同步、归约,是几十次点对点通信的总和;后者是单次点对点延迟。看到延迟数字时一定要确认是哪一种。
八、两层架构的天花板在哪
既然两层这么好,什么时候需要三层?
每台 Spine 最多 144 口,每台 Leaf 至少要连它 1 条
↓ 所以 Leaf 数量上限 = 144 台
每台 Leaf 最多接 72 台服务器
↓
两层架构理论上限 = 144 × 72 = 10,368 个端点
本方案 1,048 个端点,只用了理论容量的 10%,两层绰绰有余。
顺带说明 R-01 里提到的方案 B(131 台 GB300 NVL72,9,432 个端点):它 9,432 已经逼近 10,368 这个上限,虽然理论上塞得下,但一点扩容和冗余余量都没有了,所以实践中会直接上三层。
九、一个我需要修正的地方
推导过程中发现方案里有处不一致,应当告诉你:
G-01 图纸写的是"交换机端口全部按 160 节点配"。但按上面的账本核对:
当前 16 台 Leaf,每台下联上限 72
↓
每条 Rail 上限 = 2 × 72 = 144 个端点
↓
本架构的扩容天花板是 144 台节点,不是 160
要扩到 160 台,每条 Rail 需要 3 台 Leaf,Leaf 总数从 16 增到 24 台,Spine 也要相应增加。
建议的修正:机电部分(机柜、母线、CDU、液冷管路)继续按 160 节点预留,这部分成立且必要;网络部分明确写"当前配置支持扩容至 144 台,超出需增补 8 台 Leaf"。招标时把这句话写进技术要求,避免二期扩容时才发现端口不够、被迫停机改造。
要不要我把这套基础原理整理成一张新图纸(X-02 网络基础原理)加进 HTML 方案里?包含端口预算示意图、四种通信路径的对比图,以及上面这条 144/160 的修正。这样评审时给不熟悉网络的人看会方便很多。
一次推理请求的完整通信路径(实际推理流程)

为者常成,行者常至
自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)