深夜的后厨里,一百多人的火锅宴马上开席。可牛腿太大、砧板太小,一个厨师切不完,锅也煮不下——你只能把食材分给好几个厨师,有人专切牛肉,有人专切蔬菜,有人专门调汤底,最后拼成整桌火锅。 大模型训练也是这个道理。模型动辄几百亿、上千亿参数,一张 GPU 的显存根本塞不下。Megatron-LM 的张量并行,就是那套“后厨分工法”:把权重矩阵像食材一样按行或按列切开,分给多张 GPU 各自计算,最后把结果拼接起来或加起来。听起来简单,但“怎么切、切哪一层、切完怎么通信”,每一步都有讲究。 这篇文章用火锅后厨的协作故事,把 Megatron-LM 张量并行在 Transformer 上的实战讲清楚——从切分原理、Attention 层与 MLP 层的并行方案,到通信设计和并行度配置,让你看完就能上手。
掌握张量并行是训练千亿级大模型的必经之路,无论你是工程师还是架构师,这一技能会让你真正理解多卡训练系统如何高效运转,并直接提升大模型项目的落地能力。
可视化演示
展示行并行如何将权重矩阵按行拆分到多GPU,每个GPU计算部分结果后通过All-Reduce聚合输出。
本节配有交互动效(进入视口后自动加载,约 3KB)。
行并行:权重矩阵按行拆分 权重W按行维度拆分为N份,每个GPU持有W_i 输入X按特征维度拆分,GPU_i持有X_i 各GPU独立计算Y_i=X_i·W_i后All-Reduce求和 Y = Σ(X_i · W_i) = X · W 行并行需All-Reduce通信,与列并行互补
并行原理
火锅店要招待上千人,可后厨只有一张砧板、一位厨师。一头百斤重的牛摆在面前,别说切完,光是搬上砧板就够呛。大模型训练就是这样:一个 1750 亿参数的模型,光参数就要占 700GB 显存,再加上梯度和优化器状态,一张 A100(80GB)连零头都放不下。
张量并行(Tensor Parallelism)的核心思想,就是把原本放在一个 GPU 上的权重矩阵,像切牛腿一样按维度切成多块,分给多个 GPU。每个 GPU 只存一份切片,计算时也各算各的,最后通过通信把结果合并。在 Megatron-LM 中,这种切分发生在每一个线性层内部,是“层内并行”——与流水线并行把不同层分给不同 GPU 的“层间并行”完全不同。
要理解切分,先得知道矩阵乘法的形状:输入 X 的形状是 (batch, d),权重 W 的形状是 (d, d_out),输出 Y = X·W。切分 W 有两个方向:按列切或按行切。这个选择决定了后续通信方式。
其中 $\Phi$ 是模型参数量(如 1750 亿),16 字节/参数约等于(参数 4 字节 + 梯度 4 字节 + Adam 优化器两份动量共 8 字节)。
当 $13\Phi \approx 2.8$ TB 时,单卡 80GB 显然装不下。于是后厨必须招人——把食材分给多个厨师,张量并行由此登场。每个 GPU 只扛一部分权重,大家合作把模型“扛”起来。
- 参数显存模型本身的权重参数每个占 4 字节(FP32),1750 亿参数就是 700GB。
- 梯度显存反向传播时每个参数对应一个梯度,同样占 4 字节。
- 优化器状态Adam 优化器为每个参数维护一阶动量和二阶动量,两份共 8 字节。
- 总显存三部分相加就是训练时的总显存需求。
切分方式
同样是切牛腿,“竖着切”和“横着切”出来的肉完全不同。张量并行切权重矩阵也分两种:列并行(Column Parallel)和行并行(Row Parallel)。记住一个口诀:列并行拼宽,行并行加和。
列并行:把权重矩阵 W 沿列方向切成两份,每份形状是 (d, d_out/2)。输入 X 完整复制给每个 GPU,各 GPU 计算 X·W₁ 和 X·W₂,得到的输出沿列方向拼接成完整 Y。这就像两个厨师各切了一种配菜,上桌时拼在同一盘子里。
行并行:把权重矩阵 W 沿行方向切成两份,每份形状是 (d/2, d_out)。输入 X 也要按列切分,GPU0 拿 X₁ 算 X₁·W₁,GPU1 拿 X₂ 算 X₂·W₂,两个结果逐元素相加才是最终 Y。这就像两个厨师各熬了一锅汤底,最后倒进同一个锅里混合。
在 Megatron-LM 中,并不是每个线性层都随便选一种切法,而是“列并行 + 行并行”成对使用。第一层用列并行把输出切宽,第二层用行并行把结果加回来,这样既避免了重复计算,又让通信量可控。
- 列并行权重 W 按列切分为 W₁ 和 W₂,X 与每个切片相乘,结果拼接。
- 列并行关键性质不需要额外的加法通信,每个 GPU 的输出拼起来就是完整结果。
- 行并行权重 W 按行切分,输入 X 也必须按对应维度切分,每个 GPU 算出部分和。
- 行并行关键性质最终结果需要对所有 GPU 的部分和做 AllReduce 相加。
Attention并行
火锅店点单时,三个服务员分工:一个记荤菜、一个记素菜、一个记主食,最后汇总成一份完整菜单。Transformer 的 Attention 层也是这个套路——它需要把输入 X 分别投影成 Q(查询)、K(键)、V(值)三个矩阵,就像三个服务员各记一类菜。
在 Megatron-LM 中,QKV 的投影矩阵(分别形状为 d×d)都使用列并行:每个 GPU 持有一部分 Q、K、V 的列切片。这样每个 GPU 可以独立计算自己的“那几列注意力分数”,互不干扰。
关键点在于多头注意力(Multi-Head Attention)的结构:假设模型有 16 个头,TP=2,那么 GPU0 负责头 0~7,GPU1 负责头 8~15。每个头在自己的 GPU 上独立计算,天然并行。
这个设计非常巧妙:Attention 的“多头”结构天然适合张量并行,每个头不需要跨 GPU 通信,只有在输出投影时才需要一次 AllReduce。就像三个服务员各记各的菜单,最后只需要汇总一次。
- QKV 列并行三个投影矩阵都按列切分,每个 GPU 只持有一部分投影权重。
- 多头切分注意力头均匀分配到各个 GPU,每个 GPU 独立算自己的头。
- 输出拼接所有头的结果沿特征维度拼接,得到完整的 Attention 输出。
- 输出投影行并行最后乘以输出权重矩阵 W^O 时,使用行并行——各 GPU 算一部分之后 AllReduce 相加。
MLP层并行
火锅的加工是流水线的:洗菜 → 切菜 → 调味 → 下锅。Transformer 的 MLP 层也像一条流水线:先线性扩展(把维度从 d_model 放大到 4 倍),再经过激活函数,最后线性压缩(从 4 倍维度降回 d_model)。Megatron-LM 对这条流水线的安排是:
第一个线性层(d_model → 4×d_model)用列并行:权重形状是 (d, 4d),按列切成 (d, 4d/p),每个 GPU 独立把输入映射到自己的那部分扩展维度。相当于几个厨师各自准备一部分配菜。
激活函数 GELU 是逐元素操作:每个元素独立计算激活值,不需要任何跨 GPU 通信。所以把 GELU 放在列并行之后,每个 GPU 在自己那部分数据上直接算,零成本。
第二个线性层(4×d_model → d_model)用行并行:权重形状是 (4d, d),按行切成 (4d/p, d)。每个 GPU 用自己那部分扩展维度计算部分输出,最后 AllReduce 相加。相当于把各人准备的配菜倒进同一口锅。
整个 MLP 层只需要一次 AllReduce(在第二层输出处),加上 Attention 输出投影的那一次,每个 Transformer 层恰好两个通信点。这就是 Megatron-LM 张量并行的高明之处:不追求零通信,而是把通信集中到最少必要的位置。
- 第一层列并行W₁ 形状为 (d, 4d),沿列切成 p 份,每个 GPU 持有一份 (d, 4d/p)。
- GELU 独立作用激活函数逐元素计算,不需要跨 GPU 通信。
- 第二层行并行W₂ 形状为 (4d, d),沿行切成 p 份,每个 GPU 持有一份 (4d/p, d)。
- AllReduce 求和行并行的输出需要对各 GPU 的部分结果求和,这就是每个 Transformer 层第二个通信点。
通信设计
火锅店上菜时,各厨师准备好的食材必须送到同一个桌上——这个“汇合”动作就是通信。在张量并行中,通信操作主要是 AllReduce:把每个 GPU 上的数据求和,然后把完整结果广播回每个 GPU。
列并行不需要 AllReduce(输出拼接即可),行并行则需要。这意味着 Megatron-LM 的通信点位置非常固定:Attention 输出投影处和 MLP 第二个线性层输出处,每个 Transformer 层恰好两个 AllReduce。
通信量有多大?核心公式是:每次 AllReduce 传输的数据量与批量大小 b、序列长度 s、隐藏维度 h 成正比,还与并行度 p 有关:
即每层两个 AllReduce,每个传输 4bsh 字节,乘以 (p-1)/p 的缩放因子。在 p=8 时,这个比例是 7/8,意味着大部分数据都要在网络中流动。
这里就引出了计算通信比(Arithmetic Intensity)的概念:GPU 算得快不快,得看计算量和通信量的比值。张量并行度越大,通信占比越高,当 p 超过节点内 GPU 数量时,跨节点通信会急剧拉低性能。这也是为什么张量并行度通常不超过 8——因为单机 8 卡正好用 NVLink 全互联。
实战中,通信发生在 GPU 之间,走 NVLink 带宽可达 600GB/s,而跨节点走 InfiniBand 网络通常在 50GB/s 左右。所以张量并行优先在单机内做,这是配置并行度的底层逻辑。
- AllReduce 定义把 p 个 GPU 上的向量逐元素相加,结果广播回所有 GPU。
- 通信量组成每个 Transformer 层两次 AllReduce,每次传输的数据是 4bsh 字节。
- 缩放因子(p-1)/p 表示 AllReduce 的总传输量与参与节点数的关系,p 越大,冗余通信越多。
并行度配置
火锅店开多大,请多少厨师,取决于店面大小和客流量。大模型训练也一样:GPU 总数、模型大小、单卡显存共同决定了并行策略。Megatron-LM 的完整方案是三维并行:数据并行(DP)+ 流水线并行(PP)+ 张量并行(TP)。
其中 D 是数据并行度,P 是流水线并行度,T 是张量并行度。比如使用 16 张 GPU,可以配 D=4、P=2、T=2,意思是:4 份数据并行 × 2 段流水线 × 每层 2 卡张量并行。三者层层嵌套,共同支撑超大规模训练。
张量并行度 T 怎么选?有几个实用参考:
1. T 不能超过单机 GPU 数。TP 通信频率高,跨节点做张量并行在效率上非常吃亏。所以 8 卡机器选 TP=8,4 卡机器选 TP=4。
2. T 的取值必须整除隐藏维度。例如 hidden_size=4096,TP=8 时每个 GPU 的切片是 512 维,能整除;如果 hidden_size=3072,TP=8 时 3072/8=384,也行;但如果 hidden_size 是 4096,TP=6 就除不尽,会出问题。
3. TP 与显存压力负相关:TP 越大,每卡存的权重切片越小,但通信开销越大。通常 TP=8 时通信占比已经很高,很少继续加大。
1. 三维并行关系:三者的乘积等于总 GPU 数。
2. TP 与隐藏维度约束:张量并行度必须能整除模型隐藏维度,否则切分不均。
3. 单机限制:TP 不超过单机 GPU 数,否则需要跨节点通信。
配置并行度就像火锅店排班:数据并行(多桌客人同时吃同样的火锅)、流水线并行(前厅和后厨分阶段配合)、张量并行(每桌火锅由多个厨师共同做)三者是不同维度的分工。MP 讲究“先组内、后组间”——先让张量并行在同一台机器内做完,再考虑机器之间的数据并行。
实战要点
火锅店真正营业前,还有一堆准备工作:刀要磨快、砧板要摆好、食材要按份量切准。Megatron-LM 张量并行上手的实战细节,同样藏在“切菜之前”。
权重切片加载:如果从 Hugging Face 加载一个完整模型再切分,内存瞬间爆炸。正确做法是将权重矩阵按目标并行度直接切片写入各卡。比如一个 (d, 4d) 的 MLP 第一层权重,TP=8 时每卡只存 (d, 4d/8)。加载时不要先在 CPU 上拼好完整矩阵,而是按切片索引直接读。
随机种子对齐:初始化时,如果每个 GPU 用不同的随机种子生成权重,切出来的切片就无法还原出与单卡一致的模型。Megatron 的解法是让所有 GPU 在初始化时使用相同的种子,各自计算全局权重中的对应切片,保证初始化的每个局部切片拼起来就是预期的全局权重。这一点在训练中断续跑(checkpoint 加载)时尤其重要。
显存布局:张量并行下,每张卡除了权重切片,还要存完整的中间激活值(因为输入 X 会复制或切分后在各卡上计算)。Megatron 的实践是在 forward 时用异步通信隐藏 AllReduce 的延迟,同时把激活重计算(Activation Checkpointing)和 TP 结合使用——每卡省下的显存远比多出的通信有价值。
最后还有一个容易被忽视的点:padding。当 hidden_size 不能被 TP 整除时,需要对维度做 padding(补零)到最近可整除值。Megatron 用 make_vocab_size_divisible_by 等参数处理这类对齐问题。切菜前先量好尺寸,才是好后厨。
- 权重切片公式每个 GPU 只保存全局权重的一个连续片段。
- 切分位置start 和 end 由 GPU 编号和并行度唯一确定。
- 种子对齐所有 GPU 使用相同种子初始化,再按切片位置各自生成对应片段。
AI 应用场景
预训练千亿参数大模型
阶段:模型训练(大规模预训练)
解决的问题:千亿参数模型无法放入单卡显存,数据并行单独撑不起单层超大的权重矩阵。张量并行把每个 Transformer 层内的矩阵运算拆到多张 GPU 上,配合数据并行和流水线并行,让 1750 亿参数的 GPT-3 类模型训练成为可能。
具体案例:某公司训练 1300 亿参数的中文大模型,使用 64 张 A100。配置 DP=4、PP=4、TP=4,TP=4 意味着每个 Transformer 层的 QKV 和 MLP 权重都切成 4 份,4 张 GPU 通过 NVLink 全互联,AllReduce 延迟控制在微秒级。
大模型推理服务部署
阶段:模型推理(在线服务)
解决的问题:推理时即使模型能放进一张卡,也会因为显存带宽受限导致单卡吞吐不足。张量并行可以把一次推理的前向计算分摊到多卡,降低单卡计算负载,提高整体吞吐。
具体案例:一个 70B 参数的对话模型部署时,使用 TP=2 的配置在两张 A100 上提供推理服务。每张卡只持有模型权重的一半,输入复制到两张卡,Attention 输出和 MLP 输出通过 AllReduce 合并,首 Token 延迟从 800ms 降到 450ms。
多机多卡训练任务调试
阶段:训练调试与性能调优
解决的问题:训练任务 loss 不收敛或速度上不去时,需要判断张量并行配置是否合理。张量并行通信量大,如果跨节点使用,网络会成为瓶颈。
具体案例:某工程师发现 16 卡跨 2 机训练时性能远低于预期,排查发现机器间只用了 100GbE 以太网而非 InfiniBand。将 TP 从 8 改为 4(每机一个 TP=4 组),DP 从 2 改为 4,性能提升了 1.8 倍。
Python 演示
# 模拟Megatron-LM张量并行的前向传播(2个GPU,NumPy实现)import numpy as np def gelu(x): """GELU激活函数(Megatron-LM使用的版本)""" return 0.5 * x * (1 + np.tanh(np.sqrt(2 / np.pi) * (x + 0.044715 * x**3))) def column_parallel_forward(x, w_local): """列并行:输入完整,权重切片,输出为局部片段""" return x @ w_local def row_parallel_forward(x_local, w_local): """行并行:输入切片,权重切片,输出为部分和""" return x_local @ w_local def concat_and_allreduce(gpu_outputs): """列并行结果拼接 + 行并行结果相加(模拟AllReduce)""" col_output = np.concatenate(gpu_outputs, axis=1) return col_output def main(): np.random.seed(42) batch, d_model, d_ff = 4, 8, 16 n_gpu = 2 x = np.random.randn(batch, d_model) w_fc1 = np.random.randn(d_model, d_ff) w_fc2 = np.random.randn(d_ff, d_model) # 单GPU基准结果 hidden_single = gelu(x @ w_fc1) y_single = hidden_single @ w_fc2 # 张量并行模拟(TP=2) dim_per_gpu = d_ff // n_gpu # 每个GPU负责的FFN维度 # 第一层:列并行 hidden_parts = [] for i in range(n_gpu): w_local = w_fc1[:, i * dim_per_gpu:(i + 1) * dim_per_gpu] hidden_parts.append(column_parallel_forward(x, w_local)) hidden_parallel = gelu(concat_and_allreduce(hidden_parts)) # 第二层:行并行 out_parts = [] for i in range(n_gpu): w_local = w_fc2[i * dim_per_gpu:(i + 1) * dim_per_gpu, :] x_local = hidden_parallel[:, i * dim_per_gpu:(i + 1) * dim_per_gpu] out_parts.append(row_parallel_forward(x_local, w_local)) y_parallel = sum(out_parts) # AllReduce求和 assert np.allclose(y_single, y_parallel), "并行结果与单卡不一致!" print("通过:2卡张量并行结果与单卡完全一致") print(f"输入形状: {x.shape}") print(f"输出形状: {y_parallel.shape}") if __name__ == "__main__": main()
column_parallel_forward实现列并行的局部计算:输入不变,只对权重的一列切片做矩阵乘法。row_parallel_forward实现行并行的局部计算:输入和权重都取对应切片,算出的部分结果最后靠 AllReduce 合并。concat_and_allreduce模拟两种合并方式:列并行的结果拼接在一起,而拼接后的数据继续参与后续的行并行。hidden_parallel = gelu(...)GELU 是逐元素操作,放在列并行之后,每个 GPU 独立计算,无通信。y_parallel = sum(out_parts)行并行的最终输出必须对各 GPU 的部分和做 AllReduce 相加,这一步缺了结果就错。np.allclose(y_single, y_parallel)用断言验证张量并行结果与单 GPU 完全一致,这是实现并行代码的标准自查手段。
常见误区
误区我觉得张量并行就是把模型权重文件切几份,每个 GPU 拿一份,然后各算各的。切的时候只要大概均分,每份大小差不多就行。
正解切分有严格的数学约束。列并行和行并行分别对应矩阵乘法的不同维度,切错了输出形状就对不上。而且输入也要相应处理——列并行要完整复制输入,行并行要把输入按特征维度切分。切分的本质是“保证数学等价”,不是“显存均分”。
为何常见:从“装下模型”的角度想,自然会认为只是存储上的均分。但没有从矩阵乘法的运算结构触发思考,忽略了切分维度与通信模式的绑定关系。
误区我觉得 TP=8 肯定比 TP=2 快,因为每个 GPU 只需要算 1/8 的活,并行度越高越好。
正解张量并行引入了 AllReduce 通信开销。TP 越大,通信量占总时间的比例越高。通信量公式中的 (p-1)/p 因子意味着 p=8 时有 7/8 的数据要在网络中流动。当通信耗时超过并行计算节省的时间,加速比反而下降。实际中 TP 通常不超过单机 GPU 数(1/2/4/8),超过后跨节点通信会急剧拖慢训练。
为何常见:直觉上以为“并行度=加速比”,忽略了通信的物理开销。单机内 NVLink 快,跨机器走网线慢,把 TP 开太大反而被通信拖死。
误区列并行和行并行最后不都是要产生一个完整输出吗?随便拼接或相加,结果应该一样。
正解完全不一样。列并行的输出是“宽度方向拼接”,形状是 (batch, d_out),每个 GPU 的输出是完整输出的一部分(沿特征维度展开);行并行的输出是“逐元素相加”,每个 GPU 的输出都是完整形状的部分和。如果把列并行改成相加,或把行并行改成拼接,结果形状和数值都会错。
为何常见:没有从矩阵乘法的性质出发理解“切片”如何还原为完整矩阵。拼宽 vs 加和对应的是矩阵乘法的列分割和行分割,二者不可互换。
误区反正都是把模型拆开放在多个 GPU 上,张量并行和流水线并行应该是一回事,只是名字不同。
正解二者完全不同。张量并行是层内切分:把每一层的权重矩阵拆到多卡,大家一起算同一层。流水线并行是层间切分:把不同层分给不同 GPU,GPU0 算完第一层传给 GPU1 算第二层。前者产生 AllReduce 通信,后者产生点对点张量传输(P2P)。Megatron-LM 把两者结合使用,先流水线分块,每块内部再做张量切分。
为何常见:都是从“把模型拆开”这个上层概念出发,没深入到底层切的是“层内”还是“层间”,导致概念混淆。
误区我想着并行前向传播能算对就行,反向传播梯度自然 BP 回去,不用额外处理。
正解反向传播同样需要张量并行感知。列并行层之前的输入梯度需要 AllReduce 求和(因为前向拼接的反操作是梯度拼接后再乘权重转置,等价于各 GPU 的部分梯度相加);行并行层之前的梯度则需要按列切分。Megatron-LM 设计的 f 和 g 通信对就是专门处理这种前向/反向通信对称性的。前向对了但梯度切分方式错,训练必崩。
为何常见:PyTorch 的自动求导让很多开发者“只写 forward 不管 backward”,但在自定义并行策略时,backward 的通信模式必须显式设计。
面试题
Q1. Megatron-LM 中列并行的输出如何合并?
- A.全部元素求和
- B.沿列方向拼接← 正确答案
- C.沿行方向拼接
- D.取所有GPU均值
答案:B。列并行把权重矩阵沿列切成多份,每个 GPU 的输出是完整输出的一部分(沿特征维度展开),合并时自然只需要拼接。就像火锅后厨里各厨师切好配菜拼在同一盘子里,而不是把所有菜倒进锅里煮烂。注意“拼”和“加”的本质差异。
Q2. MLP 层中的第一个线性层通常采用哪种并行方式?
- A.行并行
- B.列并行← 正确答案
- C.数据并行
- D.流水线并行
答案:B。第一个线性层把维度从 d_model 扩展到 4×d_model,相当于把输出“变宽”,用列并行让每个 GPU 只计算一部分扩展维度。就像洗菜后分给多个厨师各自切配,切好的原料拼起来就是完整配菜。
Q3. 训练 1750 亿参数模型(使用 Adam 优化器)时,参数+梯度+优化器状态最少需要多少显存?
- A.700GB
- B.350GB
- C.2.8TB← 正确答案
- D.1.4TB
答案:C。每个参数在训练时占 16 字节:参数 4 字节 + 梯度 4 字节 + Adam 的两份动量各 4 字节(共 8 字节)。1750 亿 × 16 字节 = 2800GB = 2.8TB。这就是为什么千亿模型必须依赖张量并行等分布式策略,单卡 A100(80GB)连零头都装不下。
Q4. 关于行并行(Row Parallel)的描述,以下正确的有哪些?
- A.权重矩阵按行切分← 正确答案
- B.输入需要按特征维度切分← 正确答案
- C.输出需要拼接合并
- D.输出需要AllReduce求和← 正确答案
答案:ABD。行并行中权重沿行切分,输入也要对应地按特征维度切分,每个 GPU 用一部分输入和一部分权重计算出“部分和”,最终必须 AllReduce 相加。C 选项是列并行的合并方式,行并行不是拼接。
Q5. Attention 层中的输出投影(Output Projection)采用什么方式?
- A.列并行拼接输出
- B.行并行AllReduce← 正确答案
- C.纯数据并行训练
- D.激活函数切分
答案:B。多头注意力的输出需要拼回 (batch, seq, d_model) 后再乘输出权重矩阵。Megatron-LM 对 Attention 输出投影用行并行,各 GPU 计算部分和之后 AllReduce。这样整层 Attention 只需要两次通信:输出投影处一次、MLP 第二层线性处一次。
Q6. Transformer 每个层内张量并行包含哪两个 AllReduce 通信点?
- A.Attention输出投影处← 正确答案
- B.MLP第一个线性层输入处
- C.MLP第二个线性层输出处← 正确答案
- D.Embedding层输入处
答案:AC。Megatron-LM 的设计原则是“列并行不需要通信,行并行需要 AllReduce”。Attention 输出投影(行并行)和 MLP 第二个线性层(行并行)恰好是每层的两个行并行点,因此每层恰好有两个 AllReduce。其他位置(QKV 投影、MLP 第一层)用的是列并行,不需要通信。
Q7. 在张量并行的反向传播中,列并行层之前的输入梯度需要做什么处理?
- A.直接拼接使用
- B.AllReduce求和← 正确答案
- C.不需要任何操作
- D.与权重做转置交换
答案:B。列并行前向把输出拼接,反向时梯度要先拼接再乘权重转置,这等价于各 GPU 上局部梯度的部分和做 AllReduce 求和。Megatron 的 f 函数处理这个对称性:前向是 identity,反向是 AllReduce。忘了这一步,梯度就少了一半,训练必然发散。
Q8. 张量并行通信量随并行度 p 增大的变化规律是?
- A.线性无限增大
- B.保持不变
- C.增大但增速放缓← 正确答案
- D.先增大后减小
答案:C。通信量公式 C = 8bsh × (p-1)/p 中,(p-1)/p 会随 p 增大趋向于 1,所以通信量增大但增速放缓。p=2 时是 0.5,p=4 时是 0.75,p=8 时约 0.875,再往上增长的绝对值已经很有限,但通信延迟等其他开销反而更突出。
Q9. Megatron-LM 的三维并行(3D Parallelism)包含哪些维度?
- A.数据并行← 正确答案
- B.流水线并行← 正确答案
- C.张量并行← 正确答案
- D.序列并行
答案:ABC。Megatron-LM 经典的三维并行是 DP×PP×TP:数据并行切 batch,流水线并行切 layer 层间,张量并行切层内权重。三者乘积等于总 GPU 数。序列并行是后来进一步优化激活显存的技术,不属于经典三维并行定义。
Q10. 当 TP=4 时,MLP 第一个线性层的全局权重形状为 d×4d,每个 GPU 上保存的权重切片形状是?
- A.d×d← 正确答案
- B.d/4×4d
- C.4d×4d
- D.4d×d
答案:A。列并行沿输出维度切分,4d 列分成 4 份,每份 d 列,所以每个 GPU 的切片形状是 d×d。注意这是列并行,不是行并行——输入维度 d 保持不变。类似地,如果 hidden_size=4096、TP=8,每卡就是 4096×512 的切片。