想象你经营一家大型进口货仓,一批紧急货物(一个巨大的矩阵)必须赶在中午前全部上架。最初你安排一条超长传送带,工人们站成一排,每人负责一段货物。问题是:每搬完一轮,所有人都要放下手头的活,跑到会议室开全员大会、核对各自进度——这就是一维张量并行里全员参与的 AllReduce。十六个人开会还能忍,一千个人开会时,光是对表就要半小时。于是你换了思路:把仓库划成四排四列的货位格子,每个工人只需要和自己的左邻右舍、楼上楼下对表。会议从千人大会缩小成了小组碰头会——这就是 2D/3D 张量并行的核心思想:不增加工人,只改变大家的站位和沟通方式。本文就用这个“仓库调度”的故事,带你读懂 2D/3D 张量并行如何把通信瓶颈一点点拆解掉。
掌握 2D/3D 张量并行,你就能理解千卡级大模型训练中通信瓶颈的破解之道,在分布式训练领域做出真正能落地的架构决策。
可视化演示
展示系统处理流水线、实时性能指标曲线及多方案对比分析,包含数据流转、吞吐延迟监控与方案评估。
本节配有交互动效(进入视口后自动加载,约 3KB)。
系统可视化 处理流程:输入→处理→模型→输出 性能监控:实时指标 P=L×T
一维并行瓶颈
回到那座港口仓库。最初,你只有一条超长的传送带,所有工人在传送带旁站成一排,每人负责一段货物。这种安排很直观,可货量一大,问题就暴露了:每搬完一批货,全体工人必须停下手里的活,到会议室开全员大会,由每个人汇报自己搬了哪一段,再由所有人汇总成完整进度。人越多,这个会开得越久——十六个人还能忍,一千人的大会,光点名就要半小时。
这个“全员大会”就是 1D 张量并行里的 AllReduce 通信。在 Megatron 式的一维张量并行中,一个巨大的权重矩阵只沿一个方向(行或列)切成 P 段,分给 P 台 GPU。前向计算时,每台 GPU 只算自己那一段,但每算完一层,就必须把各段的中间结果汇总给所有设备——也就是一次全员参与的 AllReduce。设备数 P 越大,通信开销越失控。
全员通信的代价是:通信组规模等于设备总数 P,总通信量随 P 线性增长:
于是,港口调度员开始思考:能不能不开千人大会,把大家拆成小组各自碰头?这正是 2D/3D 张量并行要解决的问题——不增加工人,只改变大家站队和说话的方式。
- P参与通信的设备数:$P$ 越大,开会的人越多,通信量线性上涨,这就是“人越多会越久”的数学表达。
- L单台设备待共享的数据量:$L$ 是激活或梯度等中间结果的大小,类似每个人要在会上汇报的进度内容量。
- 系数 2收发两个方向:$\times 2$ 表示 AllReduce 既要发出去也要收回来,一来一回都是开销。
二维切分原理
调度员把仓库从一条传送带改成一张货位图:货物按行、列切成小块,工人们也按同样的行列排成 p×q 的网格,每人只站在自己的格子里、负责一块货。每个人都有一块明确的“地盘”,不用再满仓库跑。
对应到技术上,就是把权重矩阵 W 同时沿两个维度切分:行方向切 p 份、列方向切 q 份。设备 (i,j) 只持有 W_{ij} 这一小块,配合输入矩阵的对应行块,实现经典的 SUMMA 式二维矩阵乘法:
SUMMA 的巧妙之处在于:它把一次大矩阵乘拆成一串小矩阵乘加。算法循环共享维度 K 的每一小段,用哪块 A、哪块 B 由网格坐标决定,每台设备在本地累加自己的输出块。切分维度从 1 变 2,单设备持有数据量从 M×N/P 降为 (M/p)×(N/q),更重要的是——后面的通信规模发生了质变。就像工人们发现:不用再满仓库跑,只要站在原地,等同一排、同一列的邻居把货递过来就行。
- 按行列切成 p×q 块$p$ 行 $q$ 列共 $pq=P$ 块,正好对应 $P$ 台设备的货位,每台设备分到唯一一块。
- 块 $W_{ij}$ 的形状$(M/p)\times(N/q)$,行方向切 $p$ 份、列方向切 $q$ 份,两个方向的切分共同决定每块的大小。
- 唯一归属第 $i$ 行第 $j$ 列的格子由设备 $(i,j)$ 独占,没有两份相同的权重块,存储无冗余。
二维通信机制
货位图带来两轮小组会。第一轮:同一排的同事碰头,核对这一行各段的进度;第二轮:同一列的同事碰头,汇总这一列的结果。两轮会议每轮都只有 √P 人参加,与此前上千人的全员大会形成鲜明对比。
技术上,这两轮就是 2D 张量并行中的两次 AllReduce:先沿行方向,让同行 √P 台设备交换各自的部分和;再沿列方向,让同列 √P 台设备交换结果。每一轮通信都只发生在一个小得多的通信组里,每台设备的“说话对象”从 P−1 人骤减到 2(√P−1) 人。
总通信量也随之从线性降到开方量级:
以 P=1024 为例:1D 是 2048L 的通信量,2D 降到 128L,整整低了一个数量级。两轮小会看似比一轮大会麻烦,实际每个人只需和几个邻居说话——会议总数多了,总嗓门却小了一个量级。这正是 2D 并行的精髓:把“全员广播”改成“邻居协作”。
- 行方向小组通信$2\sqrt{P}L$,同行 $\sqrt{P}$ 台设备做一次 AllReduce,相当于第一轮排会。
- 列方向小组通信$2\sqrt{P}L$,同列 $\sqrt{P}$ 台设备再做一次,相当于第二轮列会。
- 总通信量两轮相加得 $4\sqrt{P}L$,从 1D 的线性 $O(P)$ 降为开方量级 $O(\sqrt{P})$。
三维深度扩展
如果 2D 是给仓库画格子,3D 就是给仓库加盖楼层。调度员把 p×q 的平面网格升级成 c×c×c 的立体货架:每个工人不仅和同排、同列的邻居协作,还能和楼上楼下的同事垂直对表。楼层越多,每次碰头的人越少。
3D 张量并行把设备组织成 P = c³ 的立方体,沿 x、y、z 三个轴各做一轮小范围通信。通信组从 √P 进一步缩小到 P^{1/3}。以 P=512 为例:2D 的通信组约 23 台,3D 每轮只有 8 台。通信量再降一档:
代价也随之而来:立体仓库需要把部分货物多备几份——深度维度的副本带来内存冗余,冗余因子同样是 P^{1/3}。货物多备一份,找起来也麻烦一点:通信原语和编程逻辑都更复杂。楼层越高,每次碰头的人越少,但仓库的管理成本也越高——3D 不是免费的午餐,它用显存和工程复杂度换来了通信量的再次下降。
- 立方体分组$P^{1/3}$ 是立方体一条边上的设备数,也就是每个方向通信组的大小。
- 三个轴向各一轮$3\times$ 代表 x、y、z 三个方向各做一轮小组 AllReduce,对应“同排、同列、同楼层”三场碰头会。
- 每轮收发系数 2每轮通信依然包含发出与收回两个方向,所以总通信量为 $6P^{1/3}L$。
代价与权衡
立体仓库听起来很完美,但调度员心里清楚:楼层越多,需要的管理员越多,备货也越多。现实中,2D/3D 的收益并非无条件的,“维度越高越好”是个危险的错觉。
工程代价集中在三方面:一是编程复杂度——网格与立方体的坐标逻辑、通信原语替换,都远比 1D 的“一切了之”复杂;二是内存冗余——3D 深度方向的副本让显存占用放大;三是有时还存在计算冗余,部分中间结果被重复计算。显存冗余的定量表达是:
因此要用“收益递减”的眼光判断:集群只有 8 卡 16 卡时,2D/3D 的收益微乎其微,复杂度却立刻拉满;只有当 P 大到全员大会无法忍受(千卡以上),拆小组的收益才真正兑现。就像给十个人的小仓库盖三层楼纯属浪费,给十万件货的大仓库加装立体货架才是明智之选——选不选 2D/3D,关键看你的“仓库”够不够大。
- $M_{2D}$ 基准存储2D 方案中每台设备只存一块权重,没有冗余,是存储基线。
- $M_{3D}$ 副本存储3D 深度方向复制 $c$ 份副本,存储量同步放大。
- 比值$R = P^{1/3}$,楼层越高冗余越大,这是用显存换通信的核心代价。
工业实践
真正的大港口都是怎么调度的?答案是:立体货架和传送带混着用。千卡级大模型训练集群中,通信往往占据 30%–50% 的训练时间,是当之无愧的第一瓶颈。用 2D/3D 张量并行把全员大会拆成小组会,通信时间能压到两三成以下。
实际架构中,2D/3D 张量并行几乎总是与数据并行、流水线并行、专家并行(MoE)混合使用:外层做数据并行,中间层做流水并行,层内用 2D/3D 张量并行把单层矩阵乘的通信组缩小。Colossal-AI 等框架已原生支持 2D/3D 张量并行,Megatron 系社区也有大量落地方案。通信收益可以量化:
从一条传送带,到一张货位图,再到一栋立体仓库,调度员的每一步都踩在同一个原则上:让人更少说话,让货更顺畅地流动。理解了通信方式,就理解了分布式训练的一大半。
- 分子$2PL$ 是 1D 全员大会的总通信量,随设备数线性膨胀。
- 分母$6P^{1/3}L$ 是 3D 三轴小组会的总通信量,只随设备数的立方根增长。
- 代入千卡规模$P=1000$ 时 $S \approx 33.3$,3D 通信量约为 1D 的 3%。
AI 应用场景
千亿参数模型预训练
阶段:模型训练(分布式训练基础设施)
解决的问题:传统方案用数据并行 + 1D 张量并行训练千亿参数模型时,千卡集群中每层 AllReduce 都是上千台设备全员参与,通信占比超过 40%,计算卡大量空转等待。2D/3D 张量并行把通信组缩到 √P 或 P^{1/3} 规模,通信压力大幅缓解。
具体案例:某团队在 1024 卡集群训练 175B 参数模型,将 1D 张量并行替换为 4×8 网格的 2D 切分,单层 AllReduce 参与设备从 1024 降到 8–32 台,通信时间占比从 45% 降到约 20%,训练吞吐提升近 1.5 倍。这就像把千人大会拆成几十人的小组碰头会,把“等人对表”的时间省下来真正搬货。
长序列大模型训练
阶段:训练优化(长上下文模型)
解决的问题:处理 128K 超长序列时,激活值极大,1D 张量并行每层通信的数据量 L 巨大,即使设备不多也会通信饱和。2D/3D 切分能把单次通信的数据规模连同参与设备一起降下来。
具体案例:训练 128K 上下文的大模型时,采用 3D 张量并行(4×4×4 立方体),把注意力层的前向通信从全体 64 台降为 4 台小组,长序列场景下 GPU 利用率提升 20% 以上。对应仓库的比喻:货物本身太大搬不动时,把货拆成小块并让每层的人接力,反而更快。
Python 演示
# -*- coding: utf-8 -*-"""模拟 2D/3D 张量并行矩阵乘法并对比通信规模"""import numpy as np def matmul_summa_2d(A, B, p): """SUMMA 2D 并行: p x p 网格, 行列交替通信的矩阵乘法""" M, K = A.shape N = B.shape[1] bm, bk, bn = M // p, K // p, N // p C = np.zeros((M, N)) for k in range(p): for i in range(p): for j in range(p): a_blk = A[i*bm:(i+1)*bm, k*bk:(k+1)*bk] b_blk = B[k*bk:(k+1)*bk, j*bn:(j+1)*bn] C[i*bm:(i+1)*bm, j*bn:(j+1)*bn] += a_blk @ b_blk return C def matmul_3d(A, B, c): """3D 并行: c x c x c 立方体, 沿深度维度累加部分和""" M, K = A.shape N = B.shape[1] bm, bk, bn = M // c, K // c, N // c C = np.zeros((M, N)) for d in range(c): for i in range(c): for j in range(c): a_blk = A[i*bm:(i+1)*bm, d*bk:(d+1)*bk] b_blk = B[d*bk:(d+1)*bk, j*bn:(j+1)*bn] C[i*bm:(i+1)*bm, j*bn:(j+1)*bn] += a_blk @ b_blk return C def comm_group_size(P, dim): """单台设备每次层同步的通信对象数""" if dim == 1: return P - 1 if dim == 2: return 2 * (int(P**0.5) - 1) return 3 * (int(round(P**(1.0/3))) - 1) def main(): np.random.seed(42) A = np.random.rand(64, 64) B = np.random.rand(64, 64) Y_ref = A @ B Y2 = matmul_summa_2d(A, B, 8) Y3 = matmul_3d(A, B, 4) print("2D(8x8) 误差=%.2e" % np.max(np.abs(Y2 - Y_ref))) print("3D(4^3) 误差=%.2e" % np.max(np.abs(Y3 - Y_ref))) for name, dim in [("1D", 1), ("2D", 2), ("3D", 3)]: print("%s 单设备通信对象数=%d" % (name, comm_group_size(64, dim))) if __name__ == "__main__": main()
C[i*bm:(i+1)*bm, j*bn:(j+1)*bn] += a_blk @ b_blk设备在属于自己的输出块上做局部乘加,所有 k 轮累加后就是完整结果。a_blk = A[i*bm:(i+1)*bm, k*bk:(k+1)*bk]行广播:取到 A 的第 k 列块,模拟 SUMMA 中沿行的广播。b_blk = B[k*bk:(k+1)*bk, j*bn:(j+1)*bn]列广播:取到 B 的第 k 行块,模拟沿列的广播。for d in range(c):3D 的深度循环,每一层算一部分和,最后累加得到完整结果。return 2 * (int(P**0.5) - 1)2D 单设备通信对象 = 同行邻居 + 同列邻居,共 2(√P−1) 个。return 3 * (int(round(P**(1.0/3))) - 1)3D 单设备通信对象 = 三个轴向的邻居,共 3(c−1) 个。
常见误区
误区2D 要两轮 AllReduce,3D 要三轮,通信次数变多了,网络肯定更忙、训练更慢。
正解关键不在次数而在规模。1D 一次全员大会,P 台设备每台要跟 P−1 台对表;2D 两轮小组会,每轮每台只跟 √P−1 台邻居说话;3D 三轮,每组只有 P^{1/3}−1 个邻居。就像 60 人开会每人要说 59 句话,远不如四场 4 人小组会每人说 3 句话省力。总通信量从线性降到开方、立方根量级,网络明显更轻松。
为何常见:只数了通信次数,忽略了每次通信的参与设备数和单次通信量才是决定总开销的关键。
误区3D 通信量最低,所以所有场景都应该用 3D 张量并行。
正解3D 的深度维度要复制权重副本,显存占用放大 P^{1/3} 倍,而且网格坐标、通信原语都更复杂。显存本来就紧的模型可能直接放不下,小规模集群的收益又被额外开销吞掉。选维度要看集群规模和显存预算,“最省通信”不等于“最快训练”。
为何常见:只盯着通信量一个指标,忽视了显存冗余和工程复杂度这两个同等重要的约束。
误区数据并行和张量并行都是把矩阵切成块分给多张卡,2D/3D 只是切得更细。
正解数据并行是每张卡持有完整模型副本、各算不同的训练数据,梯度再同步;张量并行是把同一个权重矩阵切开,多张卡协作算同一次矩阵乘。2D/3D 改变的是矩阵乘法分布式算法本身(如 SUMMA),设备间的关系从“各干各的”变成“按网格协作”,通信模式完全不同。
为何常见:两者都叫“并行”又都涉及切分,初学者容易把“切数据”和“切模型”混为一谈。
误区把矩阵块切得越小,每块数据越少,通信自然越少。
正解通信量主要由通信组的大小(参与 AllReduce 的设备数)决定,而不是单块大小。1D 哪怕切成 64 块,一次 AllReduce 仍是 64 台全员参与;2D 切成 8×8 后,每轮只有 8 台邻居参与。决定通信量的是组织方式(站在哪、跟谁说话),不是块切得多细。
为何常见:直觉上“块小 = 数据少 = 通信少”,但 AllReduce 的开销大头在参与设备数,而非单次传输的字节数。
面试题
Q1. 2D 张量并行相对 1D 张量并行最大的改进是什么?
- A.增加单卡的计算峰值
- B.缩小了通信组的规模← 正确答案
- C.减少模型的总参数量
- D.完全消除网络通信
答案:B。2D 并行把 P 台设备排成 p×q 网格,一次全员 AllReduce 变成行、列两轮小组 AllReduce,单次通信参与设备从 P 降到 √P。单卡算力由硬件决定,总参数量不因切分方式改变,通信只能降低无法消除。
Q2. 2D 切分中,设备网格 p×q 与总设备数 P 的关系是?
- A.P 等于 p 加 q
- B.P 等于 p 乘 q← 正确答案
- C.P 等于 p 除 q
- D.P 等于 p 减 q
答案:B。网格按行列排列,总设备数是行列的乘积,这是 2D 并行的基本坐标关系。加、减、除都与网格布局矛盾,无法形成二维坐标。记住了 P=pq,后面算通信量才不会算错。
Q3. 按 C₁D=2PL 估算,P=1024 时一次层同步的通信量约为?
- A.约为 2048L← 正确答案
- B.约为 1024L
- C.约为 64L
- D.约为 32L
答案:A。直接代入 C=2×1024×L=2048L。1D 并行里 P 每翻一倍,通信量就翻一倍,这正是它在千卡集群中成为瓶颈的原因。选了小数值的同学可能混淆了 √P 量级的 2D 公式。
Q4. 3D 张量并行相比 2D 多出的主要代价是?
- A.权重数据的总量增加
- B.显存冗余与编程复杂度← 正确答案
- C.模型精度会显著下降
- D.梯度计算完全停止
答案:B。3D 沿深度维度复制权重副本,显存占用放大 P^{1/3} 倍,同时立方体网格的编程复杂度更高。权重总量由模型定义不变,3D 并行不改变计算图精度,梯度更新也照常进行,所以 A/C/D 均不对。
Q5. 千卡集群中 1D 张量并行通信占比高的根本原因?
- A.显卡算力不够用
- B.全员通信规模太大← 正确答案
- C.训练数据批量太小
- D.优化器种类太多
答案:B。1D 的 AllReduce 每次都是全员参与,设备数 P 越大,单次通信的参与方越多、总流量越大。算力、BatchSize、优化器都不是通信占比高的直接原因,组织方式才是——千人大会自然比小组会慢。
Q6. 2D 张量并行的两轮通信分别发生在哪些设备之间?
- A.同行设备之间的通信← 正确答案
- B.同列设备之间的通信← 正确答案
- C.对角设备之间的通信
- D.斜线方向的设备通信
答案:AB。2D 并行先做行方向 AllReduce(同行 √P 台邻居),再做列方向 AllReduce(同列 √P 台邻居),两轮小组会替代一轮全员会。对角与斜线都不是 2D 网格定义的行/列通信方向,不存在对应的通信原语。
Q7. 当 P=512 时,按 C₂D=4√P·L、C₃D=6P^{1/3}·L 计算,3D 通信量约为 2D 的?
- A.约为 2D 的四倍
- B.约为 2D 的两倍
- C.与 2D 几乎相等
- D.约为 2D 的一半← 正确答案
答案:D。√512≈22.6,C₂D≈90.5L;512^{1/3}=8,C₃D=48L,48/90.5≈0.53。通信组从 23 台缩到 8 台,总通信量几乎减半。若误选其他项,通常是开方或立方根算错,或漏掉了系数。
Q8. 3D 并行中,深度维度带来的内存冗余因子是?
- A.P 的立方根倍← 正确答案
- B.P 的平方根倍
- C.与设备数 P 成正比
- D.与设备数 P 无关
答案:A。3D 把设备排成 c×c×c 的立方体,深度方向上每个权重块有 c 份副本,c=P^{1/3},所以内存冗余因子是 P 的立方根。这是 3D 用显存换通信的核心代价,也是它不适合小规模集群的原因。
Q9. 下列哪些场景适合采用 2D/3D 张量并行?
- A.千卡级大模型预训练← 正确答案
- B.单卡小模型的微调
- C.通信密集的长序列训练← 正确答案
- D.完全无通信的单机推理
答案:AC。2D/3D 的核心价值是降低大规模集群中全员通信的开销,千卡预训练和长序列(激活值大、通信密集)正是典型场景。单卡微调没有跨设备通信,单机推理也不需要并行,用了只会徒增复杂度。
Q10. SUMMA 2D 算法每步中,沿行与列方向广播的对象分别是?
- A.先广播 A 块再广播 B 块← 正确答案
- B.先广播 B 块再广播 A 块
- C.同时广播梯度和权重
- D.只广播最终的输出结果
答案:A。SUMMA 每轮固定一个共享维度下标 k,实现上先沿行广播 A 的第 k 列块,再沿列广播 B 的第 k 行块,然后各设备本地乘加。梯度与权重属于反向传播的通信,只广播输出无法完成矩阵乘法,因此 B/C/D 均不成立。