适用读者:要调 RDMA/通信库参数、要解释"通信提速 83% 但训练只快 21%"、要排查队列丢包与死锁的人。
前置:S23-J20(割集与分层归约)。
覆盖旧文:A-4340 §7.4–§7.6(数据交接/状态管理 + 拥塞与可靠性 + 关键路径,452 点)→ 452 点。
扩展点:E-S23-071(槽位释放速率:1.64 GB/s vs 网卡 50 GB/s)、E-S23-072(反馈时延上限T_f ≤ Q_free/(λ−B),20 μs 迟到丢 738 KB)、E-S23-073(通信快 83%,整步只快 21%)、E-S23-074(并发不足:128 × 256 B / 2 μs = 16.4 GB/s)。
上一篇:S23-J20 · 跨节点网络与远程访问路径
下一篇:S23-J22 · 请求执行、批处理与 KV 分配。
1. 一句话结论
通信优化的收益被 Amdahl 定律吃掉:通信从 7.6 ms 降到 1.3 ms(−83%),整步只从 29.6 ms 降到 23.3 ms(−21%)。 而且算法再好,并发不够也发挥不出来——128 个在途事务只有 16.4 GB/s。
出处:AI Infra 教材 §7.4–§7.6(
id 4340),16 rank、192 MiB 梯度、计算 20 ms、更新 2 ms。
T_step = T_compute + T_comm + T_update (串行)
T_step = max(T_compute, T_ready + T_comm) + T_update (重叠)
S = (T_c + T_n) / (T_c + T_n/s)
2. 数据交接:谁生成、谁使用、何时可复用(§7.4)
| 环节 | 关键约束 | 出错后果 |
|---|---|---|
| 分片生成 | 发送方按 rank 切好 | 切错 → 归约结果错位 |
| 缓冲区复用 | 接收方用完才能覆盖 | 覆盖 → 读到别的新数据 |
| 事务层/传输层分离(Jetty) | 传输与完成状态解耦 | 状态膨胀或丢完成 |
| 依赖与故障隔离 | 一个端点故障不拖垮全组 | 单点故障 → 整组挂 |
| 请求槽位释放 | 完成通知处理完才释放 | 吞吐被释放速率卡住 |
2.1 槽位不是收益,释放速率才是(E-S23-071)
场景:16 次操作、每次 8 KiB,每 1 μs 可提交一次,5 μs 完成;软件每 20 μs 处理 4 条完成通知。
| 槽位数 | 传输何时结束 | 槽位何时全部释放 |
|---|---|---|
| 16 | 20 μs | 80 μs |
| 8 | 48 μs | 80 μs |
处理能力 = 4 项 / 20 μs = 200,000 项/s × 8 KiB ≈ 1.64 GB/s
要达到 50 GB/s,需 ≈ 6.1M 项/s ≈ 每 0.164 μs 一项
判据:加倍槽位只让"传输提前",不改变"释放时刻"。 持续吞吐由完成通知处理速率或单次载荷大小决定——这就是背压的物理来源。
3. 拥塞:反馈迟到的代价(E-S23-072)
dQ/dt = λ(t) − B (队列非空未满)
场景:到达 100 GB/s、出口 50 GB/s → 每 μs 多积 50 KB;缓冲 512 KiB,已用 256 KiB。
| 项 | 数值 |
|---|---|
| 剩余空间可支撑 | 256 KiB / 50 KB/μs ≈ 5.2 μs |
| 实际反馈时延 | 20 μs |
| 超额数据 | (100−50) GB/s × 20 μs = 1 MB |
| 被丢弃 | 约 738 KB |
避免溢出:T_f ≤ Q_free/(λ − B)
反馈 50 μs 才降速 → 积压 2.5 MB
排空:降到 40 GB/s 时余量 10 GB/s → 512 KiB 需 52 μs;从起点约 72 μs 回到零
判据:拥塞控制要干两件事——阻止队列继续涨(降速到 λ=B)并且留出排空余量(降到 λ<B)。
3.1 两类机制与两类故障
| 机制 | 作用范围 | 速度 |
|---|---|---|
| 链路流控(PFC 类) | 相邻一跳 | 快,防局部溢出 |
| 端到端拥塞控制 | 整条路径 | 慢,调源头速率 |
| 故障 | 现象 | 处理 |
|---|---|---|
| 多路径乱序 | 重排/重传放大 | 选路或按序重组 |
| 重传风暴 | 有效带宽骤降 | 抑制重传、调超时 |
| 死锁 | 完全不动 | 打破循环依赖(路由/缓冲/顺序) |
4. 关键路径:优化该打在哪(E-S23-073)
4.1 串行链
| 方案 | 计算 | 通信 | 更新 | 整步 |
|---|---|---|---|---|
| 连续环 | 20 ms | 7.6 ms | 2 ms | 29.6 ms |
| 分层归约 | 20 ms | 1.3 ms | 2 ms | 23.3 ms |
通信 −83%,整步 −21%(S = 29.6/23.3 = 1.27)
判据:通信不是主要项时,把它优化到零也只省它自己那份。 先算 T_n/(T_c+T_n) 再决定投人。
4.2 并发不足会吃掉算法收益(E-S23-074)
每张网卡 128 个 256 B 事务在途、槽位周转 2 μs
吞吐 = 128 × 256 B / 2 μs = 16.4 GB/s(上限 50 GB/s)
跨机每卡 24 MiB → 约 1.5 ms;总通信约 2.3 ms → 整步 24.3 ms
需要 ≈ 391 个活跃事务并保证发起速率,才能回到 23.3 ms
判据:算法给出"字节数",并发决定"能不能跑满"。 两者都要配到位。
4.3 重叠:什么时候通信是免费的
T_step = max(T_compute, T_ready + T_comm) + T_update
本例:T_ready = 17 ms、T_comm = 1.3 ms → max(20, 18.3) + 2 = 22 ms
判据:重叠的充要条件是"通信完成时刻早于计算结束":T_ready + T_comm ≤ T_compute。否则通信直接延长关键路径。
5. 训练 vs 推理:瓶颈不同(§7.6.3)
| 负载 | 通信内容 | 频率 | 关键约束 |
|---|---|---|---|
| 训练 | 梯度 AllReduce(192 MiB 级) | 每步一次 | 3 ms 预算、并发、重叠 |
| decode | TP 归约(10 KiB/层) | 每层 2 次 | 启动开销主导(J19) |
| prefill | 激活交接(m×h,MB 级) |
每边界 | 带宽主导 |
判据:同一个集群,训练怕"大消息 + 预算紧",decode 怕"小消息 × 高频"。 优化手段完全不同。
6. 固定 1024 卡时,超节点变大怎么选(§7.6.4)
| 超节点规模 | 变化 | 选择倾向 |
|---|---|---|
| 小(8 卡) | TP 必须跨机 | 分层归约 + 高并发 |
| 中(32–64 卡) | TP 可留在机内 | TP 机内、DP 跨机 |
| 大(384 卡级) | EP/CP 可跨原边界 | 重新评估割集与收敛比 |
判据:超节点变大,改变的是"哪些通信落在割集上",不是"总带宽"。 每次扩容都要重算一遍 §7.2 的三种走法。
7. 可复算(实测)
$ cd /root/博客运营官/blog-v2 && python3 tools/s23_book_calc.py | tail -8
背压: 200,000 项/s × 8 KiB ≈ 1.64 GB/s(网卡 50 GB/s 需 6.1M 项/s)
16 槽位: 传输 20 μs 结束、槽位 80 μs 释放;8 槽位: 传输 48 μs、释放 80 μs
拥塞: 剩余 256 KiB / 50000 KB/μs = 5.2 μs
反馈 20 μs → 超额 1.00 MB → 丢 738 KB
排空: 余量 10 GB/s → 512 KiB 52 μs;从起点 72 μs 归零
关键路径: 串行 20+7.6+2 = 29.6 ms vs 20+1.3+2 = 23.3 ms(通信 -83%,整步 -21%)
并发: 128×256 B/2 μs = 16.4 GB/s → 24 MiB 需 1.5 ms;需 391 项才回到 23.3 ms
重叠: max(20, 17+1.3) + 2 = 22.0 ms
8. 前提与边界
| 结论 | 成立条件 | 不成立时 |
|---|---|---|
| 释放速率决定吞吐 | 完成通知批量处理 | 中断驱动/每完成即处理 → 更快 |
T_f ≤ Q_free/(λ−B) |
单一瓶颈、速率稳定 | 多瓶颈/突发 → 分段算 |
| 整步 −21% | 计算 20 ms 固定 | 计算更短 → 通信占比更高 |
| 重叠有效 | 通信与计算不争资源 | 争用同一接口 → 互相拖慢 |
9. 常见误区
| 误区 | 纠正 |
|---|---|
| "加槽位就能提高吞吐" | 只提前传输,不提前释放 |
| "通信优化 83%,训练就快 83%" | 整步只快 21%(Amdahl) |
| "换成更好的算法就够了" | 并发不足 16.4 GB/s,算法白给 |
| "降速到 λ=B 就行" | 队列不降,还要 λ<B 才排空 |
| "训练和推理的通信问题一样" | 大消息预算紧 vs 小消息高频 |
10. 自测
- 软件每 20 μs 处理 4 条完成通知、每条 8 KiB,持续吞吐多少?要到 50 GB/s 需要多快?
- 到达 100 GB/s、出口 50 GB/s、剩余缓冲 256 KiB,可容忍的反馈时延多少?
- 计算 20 ms、通信 7.6 ms、更新 2 ms,通信降到 1.3 ms 后整步加速比多少?
- 128 个 256 B 事务在途、周转 2 μs,网卡吞吐上限多少?
答案
1.64 GB/s;需约6.1M 项/s(每 0.164 μs 一项)。256 KiB / 50 KB/μs ≈ 5.2 μs。29.6/23.3 ≈ 1.27×(+27%,即整步 −21%)。128 × 256 B / 2 μs = 16.4 GB/s(上限 50 GB/s 的 33%)。
11. 下一篇
S23-J22 · 请求执行、批处理与 KV 分配 —— 进入第 8 章:一个请求从进队到出 token 的完整路径,continuous batching 与 PagedAttention 的工程细节。