适用读者:要做多卡部署/训练切分、要解释"为什么 8 卡没快 8 倍"的人。
前置:S23-J09、J10、J13(KV、专家、roofline)。
覆盖旧文:A-4339 §6.1–§6.3(从单卡到多卡 + 六种并行 + 组合并行,455 点)→ 455 点。
扩展点:E-S23-058(容量四件套:单卡 473.9 GB vs 八卡每卡 61.50 GB)、E-S23-059(单 token 的 MFU 上限 0.3% 与硬件无关)、E-S23-060(TP:省 176 μs 读取,付 10 KiB 归约)、E-S23-061(PP 气泡η = b/(q+b−1))、E-S23-062(KV 头是不可再分单位:TP 超过 KV 头数就复制)。
上一篇:S23-J17 · 融合、编译器与运行时
下一篇:S23-J19 · 集合通信、超节点组织与内存池。
1. 一句话结论
多卡的三种动机是容量、延迟、吞吐——它们对应不同的切法,不能互相替代。 Qwen3-235B-A22B 单卡要 473.9 GB(放不下),八卡每卡 61.50 GB(放得下);而单 token decode 的 MFU 最多 0.3%,这不是实现差,是硬件约束。
出处:AI Infra 教材 §6.1–§6.3(
id 4339),算例平台 HGX H100(8×80 GB、3.35 TB/s、989.4 TFLOP/s、NVLink 450 GB/s/方向、CX-7 50 GB/s)。
切 B → 数据并行(吞吐)
切 H → 张量并行(容量 + 延迟)
切 S → 序列/上下文并行(长上下文容量)
切 L → 流水线并行(容量)
切 E → 专家并行(MoE 容量)
2. 起手:容量四件套(E-S23-058)
W_i(权重) + K_i(KV) + A_i(激活) + U_i(工作区) ≤ C_i (6-1)
Qwen3-235B-A22B:94 层、d=4096、64 查询头 / 4 KV 头、头维 128、128 专家 top-8、f=1536;BF16 权重 470.2 GB;每 token KV:
2 × 94 × 4 × 128 × 2 = 188 KiB/token
| 放置 | 权重 | KV(8K) | 激活+工作区 | 合计 |
|---|---|---|---|---|
| 单卡 | 470.2 GB | 1.58 GB | 2.15 GB | 473.9 GB ❌(80 GB) |
| 八卡每卡 | 58.96 GB | 0.39 GB | 2.15 GB | 61.50 GB ✅ |
每卡权重略多于 1/8(59.1 vs 58.8):归一化参数与路由器每卡一份副本
剩余 18.5 GB / 0.39 GB ≈ 可再存 47 个 8K 会话
判据:"总容量"不是"每卡容量 × 卡数"——副本项(归一化、路由器)不随卡数缩小。
3. 单 token 的 MFU 上限是 0.3%(E-S23-059)
一层专家计算(A22B 的 8 个专家):
权重 = 8 × 3 × 4096 × 1536 × 2 B = 288 MiB → 读一次 90.1 μs(3.35 TB/s)
算力 = 约 3.02 亿 FLOPs → 0.31 μs(989.4 TFLOP/s)
| 项 | 时间 |
|---|---|
| 读取 | 90.1 μs |
| 矩阵 | 0.31 μs |
| MFU 上限 | 0.31/90.1 ≈ 0.3% |
整模型单 token:读约 43.1 GB 权重 + 1.58 GB KV → 单卡 13.3 ms;八卡均分(每卡 5.79 GB)→ 1.73 ms。
判据:这是 batch=1 时硬件允许的上限,与实现好坏无关。 所有并行方式都在这个约束下重新组织"权重读取与复用"。
3.1 换成 prefill,主导项会翻转
8192 token 的 prefill:128 个专家全被选中,一层专家权重读 4.5 GiB → 1.44 ms;矩阵 2.47 TFLOPs → 2.50 ms。
decode:读取 90.1 μs ≫ 计算 0.31 μs (带宽主导)
prefill:计算 2.50 ms > 读取 1.44 ms (算力主导)
判据:"decode 看带宽、prefill 看算力"不是口号,是同一公式 max(F/P, V/B) 在不同 M 下的自然结果。
4. 六种并行一览
| 并行 | 切什么 | 每卡存/算什么 | 必须交换什么 |
|---|---|---|---|
| DP 数据 | 样本 B | 完整模型,不同样本 | 推理不交换;训练汇合梯度 |
| TP 张量 | 特征 H(权重列/行、注意力头) | 同一层矩阵的一部分 | 输出分片收集;部分和相加 |
| SP 序列 | 逐 token 算子的位置 S | 同序列在这些算子上的一段 | 进矩阵乘前收集;部分和求和后重新分片 |
| CP 上下文 | 注意力的位置 S | 一段位置的 Q/K/V | 远端 K/V,或注意力统计量 |
| PP 流水 | 层 L | 一段连续的层 | 相邻阶段交接激活(训练再加梯度) |
| EP 专家 | 专家 E | 一部分专家 | 把 token 送到专家所在卡,再送回结果 |
记忆法(原文的"套娃"):DP 在最外层管"同时推进多少份工作" → PP 沿层切 → 层内 EP 分专家、TP 分特征、SP/CP 分位置。
4.1 TP 的账(E-S23-060)
Qwen3-32B:h=5120, f=25600,中间维均分到 4 卡。
| 项 | 单卡 | 4 卡每卡 |
|---|---|---|
| 三个投影矩阵 | 750 MiB | 187.5 MiB |
| 单 token 读取 | 234.8 μs | 58.7 μs |
| 省下 | — | 176.1 μs |
| 代价 | — | 各卡 10 KiB 部分和相加 |
SwiGLU: Y = [SiLU(XW_g) ⊙ (XW_u)] W_d
切 f:上投影切列(各卡得一半中间激活),下投影切行(各卡得部分和)
⇒ 每层:注意力输出 + FFN 输出 各一次归约,64 层共 128 次
判据:TP 用"10 KiB 的通信"换"176 μs 的读取"。 这就是为什么 TP 通常限制在机内(NVLink 域),跨机时通信会吃掉收益。
4.2 KV 头是不可再分单位(E-S23-062)
Qwen3-32B:8 个 KV 头
TP8 → 每卡 1 个 KV 头
TP16 → 同一 KV 头被两张卡各存一份(复制)
128K 上下文:每个 KV 头状态 4 GiB
8 卡 → 32 GiB;16 卡 → 64 GiB(多出来的是副本)
判据:TP 卡数一旦超过 KV 头数,继续增加只增加 KV 副本,不减少容量。 Qwen3-235B-A22B 只有 4 个 KV 头,八卡分法已经让每头存两份。
4.3 PP 的气泡(E-S23-061)
T_PP = (q + b − 1)·t q 阶段、b 个 micro-batch、每阶段 t
η_PP = b/(q + b − 1)
四阶段、每阶段 1 ms、4 个 micro-batch:第一个结果 4 ms 产生,最后一个 7 ms;η = 4/7 ≈ 57%。
| q | b | η |
|---|---|---|
| 4 | 4 | 57% |
| 4 | 32 | 91% |
| 8 | 32 | 82% |
判据:PP 的效率只跟 b/q 有关。 阶段越少、micro-batch 越多,气泡占比越低——但 micro-batch 受显存限制(J12 的激活生命周期)。
5. 组合与坐标(§6.3)
DP 复制一个完整的 TP×PP×EP 实例
SP 常在 TP 组内复用同一批卡
CP 随长上下文加入(状态容量 + 注意力计算)
Qwen3-235B-A22B 的八卡分法:TP=8(切特征与头)、PP=1、EP 隐含在专家分布里、DP=1;每卡 61.50 GB、47 个 8K 会话。
5.1 到万亿参数怎么变(原文 §6.3.3 结论方向)
| 规模 | 主要矛盾 | 组合倾向 |
|---|---|---|
| 数百亿(单机可容) | 吞吐 | DP 为主,TP 少量 |
| 数千亿(跨机) | 容量 + 延迟 | TP 机内 + PP 跨机 + EP |
| 万亿 | 容量压倒一切 | PP × EP × TP 三层组合,DP 收缩 |
判据:并行组合是"按瓶颈排序"的结果,不是"能切就切"。 每加一种切分都新增一类通信与同步。
6. 可复算(实测)
$ cd /root/博客运营官/blog-v2 && python3 tools/s23_book_calc.py | tail -8
容量: 单卡 473.9 GB(超 80 GB);八卡每卡 61.50 GB;剩 18.5 GB → 47 个 8K 会话
单 token 一层专家: 读 288 MiB = 90.1 μs vs 算 0.302 GFLOPs = 0.31 μs → MFU 上限 0.3%
整模型单 token: 43.1 GB + 1.58 GB KV → 单卡 13.3 ms;八卡 5.79 GB/卡 → 1.73 ms
prefill 8192: 专家权重 4.5 GiB = 1.44 ms vs 2.47 TFLOPs = 2.50 ms(转为算力主导)
TP 4 卡(Qwen3-32B f=25600): 750 → 187.5 MiB/卡;234.8 → 58.7 μs,省 176.1 μs
PP: q=4,b=4 → T=(4+4-1)t=7t,η=57%;q=4,b=32 → η=91%
7. 前提与边界
| 结论 | 成立条件 | 不成立时 |
|---|---|---|
| 每卡 61.50 GB | TP=8、PP=1、8K 上下文 | 上下文变长 → KV 线性涨 |
| MFU 0.3% | batch=1、纯 decode | 有 batch → 上限提高(J13 的 345 行) |
| TP 省读取 | 切分维度内可并行 | 切 K 维 → 需 AllReduce |
| PP η 公式 | 各阶段等时 | 阶段不均 → 由最慢阶段决定 |
8. 常见误区
| 误区 | 纠正 |
|---|---|
| "8 卡就该 8 倍" | 单 token decode 受 MFU 0.3% 限制,卡多只降读取 |
| 容量 = 单卡 × 卡数 | 归一化/路由器/复制的 KV 不缩小 |
| TP 越多越好 | 超过 KV 头数就复制;跨机通信吃掉收益 |
| PP 阶段越多越好 | 气泡 b/(q+b−1) 随 q 变差 |
| 把 SP 与 CP 混为一谈 | SP 切逐 token 算子,CP 切注意力(要交换 K/V) |
9. 自测
- Qwen3-235B-A22B 单卡需要多少内存?八卡每卡多少?差的 0.54 GB 从哪来?
- 一层专家 288 MiB、单 token,读与算各多久?MFU 上限多少?
- TP 4 卡把
f=25600切开,每卡权重多少?省多少读取?付多少通信? - 8 阶段、16 个 micro-batch,PP 效率多少?
答案
- 473.9 GB;61.50 GB;每卡的归一化参数与路由器副本(59.1 vs 58.8)。
- 90.1 μs 与 0.31 μs;
0.31/90.1 ≈ 0.3%。 - 750 → 187.5 MiB;省 176.1 μs;付 10 KiB 部分和归约(每层 2 次 × 64 层)。
η = 16/(8+16−1) = 16/23 ≈ 70%。
10. 下一篇
S23-J19 · 集合通信、超节点组织与内存池 —— AllReduce/ReduceScatter/AllGather 的轮次与字节数,环与树的差别,超节点拓扑,以及"内存池"如何改变放置。