序列与上下文并行
上下文长度从 4k 涨到 128k 甚至 1M,注意力就成了新的墙:激活与 KV cache 都随序列长度平方级/线性增长,单卡很快装不下。序列并行(SP)与上下文并行(CP)把序列维度切开:不同卡处理序列的不同段。本章讲清楚它们与 TP 的关系、注意力怎么跨卡算、以及长上下文的显存账。
长上下文的显存墙
Section titled “长上下文的显存墙”先算清楚墙在哪。12k 序列、单卡 batch 1、7B 模型的显存:
| 组成 | 12k 序列 | 128k 序列 | 增长 |
|---|---|---|---|
| 权重(BF16) | 14 GB | 14 GB | 不变 |
| 激活(无重计算) | ~20 GB | ~200 GB | 线性涨 |
| 注意力矩阵(无 FlashAttention) | ~6 GB | ~640 GB | 平方涨 |
| KV cache(每 token) | ~3 GB | ~30 GB | 线性涨 |
三个观察:
- 注意力矩阵是平方项,128k 序列裸算根本不可行——FlashAttention 先解决"算得动"(见内核卷),CP 解决"算得快"
- 激活与 KV cache 线性涨,TP 的 hidden 切分能摊薄一部分,但 TP 度有上限(NVLink 域),不够用
- 序列维度是还没被切过的维度——SP/CP 就是来切它的
TP-SP:与张量并行成对的序列并行
Section titled “TP-SP:与张量并行成对的序列并行”Megatron-SP 是 TP 的补充:TP 按 hidden 切权重与大部分激活,但 LayerNorm/Dropout 的激活不分片(每卡全量)。SP 把这部分按序列维度切开:
TP 区域(按 hidden 切) ←all-gather/reduce-scatter→ SP 区域(按 seqlen 切)关键技巧:TP 的 all-reduce 本来就拆成 all-gather + reduce-scatter,恰好完成两种切法的转换——通信量不增,纯赚显存。这就是"TP+SP 成对出现"的原因:SP 不是独立的并行维度,是 TP 的显存补丁。
上下文并行:注意力本身切分
Section titled “上下文并行:注意力本身切分”CP 是更彻底的切法:序列维度全面切分,注意力计算也按序列块跨卡进行。每个卡持有自己那段的 Q/K/V,然后环形传递 K/V 块、分块计算注意力(FlashAttention 的 online softmax 天然支持分块):
卡0: Q₀×(K₀,V₀) → Q₀×(K₁,V₁) → Q₀×(K₂,V₂) → ... 环形收 K/V,边收边算卡1: Q₁×(K₁,V₁) → Q₁×(K₂,V₂) → ...(每卡算"自己的 Q 对所有 K/V"的部分结果,online softmax 增量合并)三个要点:
- 通信 = 每步传一份 K/V 块(ring 状流转),量 = 单卡的 KV 大小,比 all-gather 全量 K/V 便宜一倍起
- 因果注意力的负载不均:段 只需要对前 段算注意力——用负载均衡的环序(先算远段)或 Z 字形分配解决
- CP 与 TP 正交:TP 切 hidden(头维度),CP 切序列,可叠加。128k 长度的标准配置是 TP=8(或 TP+SP)+ CP=2/4
长上下文的显存账:切分前后
Section titled “长上下文的显存账:切分前后”128k 序列、7B 模型、batch 1 的显存(FlashAttention 已开):
| 组成 | 不切(单卡) | TP=8 | TP=8 + CP=4 |
|---|---|---|---|
| 权重 | 14 GB | 1.75 GB | 1.75 GB |
| 激活 | ~200 GB | ~25 GB | ~6 GB |
| KV cache | ~30 GB | 3.75 GB | ~1 GB |
| 合计 | ✗ 装不下 | ~30 GB | ~9 GB |
CP 每加一倍,激活与 KV 除以 2——线性切分,对比注意力矩阵的平方增长是唯一现实的解法。代价是环形通信与 softmax 合并开销(实测端到端开销 ~10–20%,远小于不切就装不下的损失)。
- SP 与 CP 的选择:4k–32k 用 TP+SP 通常就够;32k–128k 加 CP;百万级 token 是 CP=8+ + 分层 KV 管理的领域
- 因果负载均衡:确认实现用了 Z 字形或先远后近的环序,否则一半卡空转(症状:CP 度越大 MFU 越低)
- 长序列的数据管道:CP 下每个微批的全局 seqlen = 单卡段长 × CP 度,数据加载与打包要配合
- RoPE 与位置编码:CP 切分后位置编码按全局位置计算(每卡要知道自己段的全局偏移),框架已内置,但自定义算子容易踩
- 调试:CP 的数值验证用"单卡跑 1/CP 长度 + 全局对齐"对比 loss;位置编码错位是头号 bug
- 长上下文的三堵墙:注意力矩阵(平方,FlashAttention 解)、激活/KV(线性,TP 摊不动,要 CP)。
- TP-SP 是 TP 的显存补丁:按 seqlen 切 LayerNorm/Dropout 激活,借 all-reduce 的两半转换,通信量不增。
- CP 按序列块分片注意力:环形传 K/V、online softmax 增量合并;每加一倍 CP,激活与 KV 减半。
- 因果注意力的负载不均要靠环序/分配解决,否则 CP 越大 MFU 越低。
- 实用阶梯:4k–32k 用 TP+SP;32k+ 加 CP=2/4;TP 与 CP 正交可叠加。
- 张量并行 — 上一章:hidden 维度的切分与 SP 的由来
- MoE 与专家并行 — 下一章:第五个维度
- FlashAttention 与算子融合 — CP 依赖的分块注意力
- 混合并行与配置方法论 — CP 嵌入整体配置