ICML 2022 · Intra-op
张量并行与 AllReduce
一张卡装不下大模型时,把同一个矩阵乘切开、多卡一起算。关键是:切哪一维,要不要 AllReduce。
1. 为什么要并行(两种切法)
GPT-3 量级权重几百 GB,单卡只有几十 GB。办法:把图切开,多设备一起算,并付通信账。
| 视角 | 人话 | 常见名 | 通信 |
|---|---|---|---|
| Inter-op | 不同层放到不同卡,像流水线 | PP | 点对点;容易空等(bubble) |
| Intra-op | 同一层的矩阵切开,多卡各算一块 | TP | 集合通信(AllReduce 等);卡更忙 |
真实训练常是 DP × TP × PP(3D 并行)。本页把 TP / AllReduce 钉死即可。
2. 集合通信先认这四个
| 原语 | 直觉 |
|---|---|
| AllReduce | 各卡一份同 shape 张量 → 加总(常 sum)后,每张卡都有完整结果 |
| ReduceScatter | 先加总,再按块散开,每卡只留一块 |
| AllGather | 各卡一块 → 拼成完整,每卡都有全量 |
| AllToAll | 按分区对换(MoE 路由常用) |
AllReduce ≈ ReduceScatter + AllGather
DDP 训练里,梯度同步就是隐式 AllReduce。
3. 一个 Matmul 怎么切(飞书自测:切 m / n / k)
C[m,n] = A[m,k] @ B[k,n],设备数 p。
m、n是空间维:切开不必马上规约k是求和维:切开后每卡只有部分和,必须 AllReduce
脚本会打印具体 shape:
python code/03_tp_shapes_and_allreduce.py
4. Megatron MLP:列为行配对 + 一次 AllReduce
x ──► Linear W1(列并行)──► GeLU ──► Linear W2(行并行)──► AllReduce ──► +残差
- W1 按输出通道切开 → 每卡算一部分激活;GeLU 本地做
- W2 按输入通道切开(和上一层对齐)→ 每卡只有部分输出
- 前向末尾 AllReduce 把部分输出加总
- 反向在对称位置再来一次 AllReduce
Attention 的 QKV(列)和 Wo(行)也是这套配对,少做多余 AllGather。
通信量直觉:一层 MLP 前向 AllReduce 元素量约 B · T · H(激活)。卡很多时启动延迟变大,朴素 Ring AllReduce 不一定最优。
5. Pipeline 对照(浅记即可)
- 层划成 stage,微批流水(GPipe、1F1B)
- GPipe 空泡比例约
(D-1)/(D-1+N),D=卡数/stage,N=微批数 - 同步流水数学上像单卡;异步可消泡但破坏同步 SGD
6. 和编译器主线
| 话题 | 关系 |
|---|---|
| 选切轴、插 AllReduce | 图级并行策略 |
| 通信与计算重叠 | 调度 / 通算融合 |
| 单算子内 tiling | Triton(你的主战场) |
7. 自测
- 切 m / n / k:每卡存什么?要不要 AllReduce?
- 8 卡纯 TP,一层里 AllReduce 出现在哪些投影之后?
- 为什么列并行 Linear 后面常接行并行 Linear?
python code/03_tp_shapes_and_allreduce.py
# 可选:
torchrun --nproc_per_node=2 code/03_tp_shapes_and_allreduce.py --dist