万核归一
你以为分布式训练就是堆 GPU。可在万核阵列前,真正的战场在卡与卡之间——每多一块 GPU,梯度同步的通信开销就吞掉一截算力。通信瓶颈在链路里立赌:你以为加卡就能线性加速,我赌你加到第八块就饱和。
并行之门
并行之门的门楣上刻着八个字:万核齐发,须归于一。门内是一片算力阵列——成千上万块 GPU 排成方阵,每块卡都亮着绿灯。阵列中央横着一道暗蓝色的光带,像一条拥堵的公路。高斯老祖站在光带边,手里只有一块黑板,上面写着:加卡不等于加速。
「左边是算力,右边是通信。你站在光带上——告诉我,分布式训练最大的瓶颈是什么?先猜,猜错了也没关系,通信瓶颈会记账。」
「又来了一个想堆卡的。打个赌——你觉得分布式训练最大的瓶颈是什么?你每猜错一次,链路堵一分,我都记下来。」
瓶颈之赌 · 分布式训练瓶颈预测挑战器
反直觉下注(四选一,可连错)→ 挑战展开 → 分布式训练全景图拼合
分布式训练全景 · 核心瓶颈图谱
详解 · K18-01 分布式训练的动机:模型规模增长 vs 单卡算力
分布式训练的第一性问题:单卡装不下、也算不快,两条天花板同时逼近——显存壁与算力壁。显存侧,A100/H100 单卡约 80GB,而 70B 模型混合精度训练需 16 字节/参数 ≈ 1120GB(见 S7),差一个数量级;算力侧,GPT-3 175B 训练约需 3.14×10²³ FLOPs(Brown 2020),单张 V100 峰值约 1.4×10¹⁴ FLOPS,即便 100% 利用也要约 71 年——必须并行。Shoeybi 2020(Megatron-LM)把并行拆成可组合的维度:数据并行复制模型切数据、张量并行切单层权重、流水线并行切层。台上四选(GPU 数量 / 通信带宽 / 数据加载 / 模型大小)的谜底是通信带宽:一旦跨卡,每步的梯度同步、激活传递、参数聚合都要走互联,算力能堆、带宽不能凭空变。这正是全章的赌注——加卡买到的是 FLOPS,买不到的是 GB/s。动机不是"想更快",是"不并行就训不了":模型规模的增长曲线(GPT-2 1.5B → GPT-3 175B → GPT-4 传闻万亿级 MoE)远陡于单卡显存与算力的迭代节奏,分布式从优化项变成生存项。理解这一点,才懂为何本章一开场就把"堆卡"钉成第一道要排除的幻觉。
数据并行 · 最简之道
光带尽头是一排 GPU,每块卡上都刻着同一个模型。高斯老祖递给你一沓数据卡:「数据并行最简单——每块 GPU 拿一份完整模型,处理不同的数据 batch。前向各算各的,反向各算各的,但梯度必须同步。你拖动 GPU 数,看流程怎么走。」
「数据并行的关键在梯度同步——每块 GPU 算完自己的梯度后,必须把梯度 AllReduce 到所有卡上,保证参数一致。前向和反向是并行的,但梯度同步是串行的瓶颈。GPU 越多,同步的梯度越大,通信越久。」
「你以为复制模型就行?八块卡各算各的梯度,最后还得 AllReduce 同步——这一步走的是我的路。卡越多,我吃得越饱。」
数据并行可视化器 · N 卡复制 + 前向反向 + AllReduce
拖 GPU 数看复制模型 → 切换流程步骤看前向/反向/AllReduce/更新 → 并行天平记录
N 卡复制 · 各持完整模型
训练流程 · 前向 → 反向 → AllReduce → 更新
详解 · K18-02 数据并行 Data Parallelism:DDP 的原理与实现
数据并行(DP)是最朴素也最常用的并行:每块 GPU 持有一份完整模型副本,各自吃不同的数据 micro-batch,前向反向独立计算,唯一的同步点是反向传播后对梯度做 AllReduce,再用平均后的梯度更新参数——因此各副本参数始终一致,数学上等价于单卡跑 N 倍大的全局 batch。Li 2014 的 Parameter Server 与随后的 Ring-AllReduce 把这套同步工程化;PyTorch DDP(DistributedDataParallel)是事实标准实现,它在每个 bucket 装满梯度后立即发起 AllReduce,用反向计算与通信重叠(overlap)来隐藏同步开销。台上 S1 的四步流程(前向 → 反向 → AllReduce → 更新)里,只有 AllReduce 是跨卡串行的瓶颈:前向反向各算各的、零通信,AllReduce 一走就是"我的路"(通信瓶颈语)。三个关键工程细节:①梯度先除以 N 再平均,保证与单卡严格等价;②DDP 的 gradient bucketing 与 backward hook 让通信和计算流水重叠,桶越大重叠越好但延迟越高;③全局 batch = 每卡 batch × N,扩大 N 等效于扩大 batch,需配合学习率 warmup 与线性缩放规则(Goyal 2017 的 1 小时 ImageNet 训练)才不掉精度。DP 的软肋在 S1 并行天平已显现:N 越大,AllReduce 通信占比越高,算力翻倍而通信不减半——这正是下一幕 Ring AllReduce 要解决的事。
详解 · K18-03 数据并行的通信开销:AllReduce 的带宽需求
数据并行每步的通信量可以手算。设梯度字节数为 M,P 块 GPU 做 AllReduce。朴素的参数服务器星型实现中,中心节点要收 P 份梯度、再广播 P 份,中心带宽随 P 线性膨胀、直接成为瓶颈。Ring AllReduce 的最优解是:每块 GPU 收发数据量 = 2(P−1)/P × M(Reduce-Scatter 阶段 (P−1)/P·M + All-Gather 阶段 (P−1)/P·M)。当 P 很大,2(P−1)/P → 2,即每卡每步通信量趋近 2M,与 P 几乎无关——这是 Ring 的核心红利(Patarasuk 2009)。手算一例:7B 模型 FP16 梯度 M = 7×10⁹×2 字节 = 14GB,8 卡 Ring AllReduce 每卡每步收发 2×(7/8)×14 ≈ 24.5GB;若走 300GB/s 的 NVLink,单步通信约 82ms。这正是台上 S1 并行天平倾斜的根源:计算时间随 P 增大被摊薄(每卡只算 1/P 的数据),但通信时间趋于常数 2M/带宽,于是存在一个临界 P,超过它通信就主导、加速比饱和。AllReduce 的带宽需求 = 2M × 每秒步数,与 P 弱相关却与模型大小强相关——模型越大、迭代越密,带宽越吃紧。这也解释了为何 DP 常配合梯度累积(accumulation:多个 micro-batch 只在最后同步一次)来摊薄通信频率,用更大的等效 batch 换更少的 AllReduce 次数。
Ring AllReduce · 环形通信
GPU 排成一圈,首尾相连成环。高斯老祖:「朴素 AllReduce 是全互联——N 块卡两两通信,通信量 O(N²)。Ring AllReduce 把梯度切成 N 片,沿环形接力传递,每块卡只跟左右邻居说话,通信量降到 O(N)。你拖动环大小,看分片怎么跑。」
「Ring AllReduce 分两阶段:Reduce-Scatter 让每块卡汇总一个分片,All-Gather 把汇总结果广播给所有卡。每阶段 N-1 步,每步传一个分片。通信量 = 2(N-1)/N × 梯度大小——接近 2 倍梯度,与 N 几乎无关。这就是 O(N) 的魔法。」
「环形?你以为绕圈就快了?是快了点——但你卡再多,通信量也不会消失,只是不再爆炸。我退一步,没退完。」
Ring AllReduce 动画器 · 环形 + 分片 + 复杂度对比
拖环大小 N 看环形拓扑 → 切换 Reduce-Scatter/All-Gather 看分片流动 → O(N) vs O(N²) 曲线
环形拓扑 · N 卡接力传递分片
通信复杂度 · O(N) vs O(N²)
详解 · K18-04 集合通信原语:AllReduce / AllGather / ReduceScatter
分布式训练的通信都归约为几个集合原语(collective),NCCL 是 GPU 上的标准实现,Thakur 2005 给出其在不同带宽/延迟区间的算法选择。四个核心原语:①Broadcast——一卡数据发给所有卡;②Reduce——所有卡数据按 op(求和/取最大)归约到某一卡;③All-Gather——每卡持一片,收集后每卡都得到完整拼接,收发量 (P−1)/P × 总量;④Reduce-Scatter——每卡贡献完整向量,归约后每卡只保留属于自己那一片,收发量同样 (P−1)/P × 总量。关键恒等式:AllReduce = Reduce-Scatter + All-Gather——先让每卡各自汇总一片(RS),再把汇总结果广播给所有卡(AG),两段各 (P−1)/P·M,合计 2(P−1)/P·M。台上 S2 的两个 toggle(Reduce-Scatter / All-Gather)正是把 AllReduce 拆成这两半演示:RS 阶段环上每卡累加自己负责的分片,AG 阶段把最终分片接力传遍全环。工程意义在于"哪个原语在哪个阶段被调用":张量并行前向用 All-Gather/All-Reduce、反向用 Reduce-Scatter;ZeRO-3 拉参数用 All-Gather、同步梯度用 Reduce-Scatter;数据并行用 AllReduce。它们都跑在同一套环/树/全互联拓扑上,只是 payload 与方向不同——读懂原语,就读懂了一切并行策略的通信账。
详解 · K18-05 Ring AllReduce:环形通信算法
Ring AllReduce(Patarasuk 2009;百度 2017 引入深度学习训练)把 P 块 GPU 连成环,梯度切成 P 片沿环接力。两阶段各 P−1 步:Reduce-Scatter 阶段,第 k 步每卡把某一片发给右邻、同时从左邻收一片并累加,P−1 步后每卡各持有一片"全局求和完成"的结果;All-Gather 阶段,再用 P−1 步把这些完成片接力传遍全环,最终每卡都拿到完整的 AllReduce 结果。每步每卡只收发 M/P 数据,总收发 = 2(P−1)/P·M,与 P 几乎无关——这就是台上 S2 那条 O(N) 曲线(环形)对比 O(N²) 曲线(全互联)的数学来源。为何全互联是 O(N²):朴素做法每卡向其余 P−1 卡各发一份完整 M,单卡发出 (P−1)M、全网 P(P−1)M,链路负载平方级膨胀。Ring 的精髓是"每卡只跟左右邻居说话",把全网流量均摊到 P 条链路,达到带宽最优(bandwidth-optimal)下界 2(P−1)/P·M。代价是延迟:环要走 2(P−1) 步,P 很大时延迟项 2(P−1)α 累积,故超大规模常用分层策略(节点内 Ring、节点间 Tree/Double-Tree)或交给 NCCL 自动选拓扑。台上拖 N 时读数 2(N−1)/N 从 N=2 的 1.00 逼近 N=12 的 1.83,直观展示"接近 2 倍梯度、与 N 弱相关"这一结论。
第一崩塌 · 通信风暴
环形阵列突然卡顿,链路上燃起赤红色的通信风暴。你把 GPU 从 1 加到 64,加速比曲线先陡升后趋平——8 卡之后几乎不再增长。高斯老祖沉默了。链路里传来一个不带温度的声音:
「你只是加了卡,没加带宽。算力翻倍,但每步训练都要等梯度同步——同步时间随 GPU 数线性增长。加到第八块,通信追上计算,加速比就饱和。第一笔账,我记下了。」
「加速比 = 1 / ((1-p) + p/N + comm(N))。p 是可并行比例,comm(N) 是通信开销。N 越大,p/N 越小但 comm(N) 越大。当 comm(N) 追上 p/N,加卡就不再加速。这就是 Amdahl 定律在分布式训练里的化身。」
通信风暴 · 加速比饱和复现 + 通信开销诊断
拖 GPU 数看加速比饱和 → 展开通信开销曲线 → Amdahl 公式
加速比饱和复现 · GPU 数滑块
N=1通信拓扑诊断 · 全互联 vs 环形
Amdahl 公式 · 通信开销展开
详解 · K18-15 通信优化:梯度压缩 / 异步通信 / 拓扑感知
当通信成为瓶颈(S3 的加速比饱和),有三条工程缓解路线。①梯度压缩——减少每步要传的字节:Top-K sparsification(Lin 2018)只传绝对值最大的 K% 梯度、其余累积到下一步,通信量可降百倍;1-bit SGD(Seide 2014)把梯度量化成 ±1;QSGD(Alistarh 2017)做随机量化并给出收敛性保证。代价是可能拖慢收敛,需误差反馈(error feedback)把被丢的残差补回。②异步/局部同步——降低同步频率:Local SGD(Stich 2018)让各卡独立跑 H 步再同步一次,通信量降 H 倍;纯异步 SGD 容忍陈旧梯度(stale gradient)但收敛变差,现代大模型基本弃用,改成"梯度累积 + 周期性 AllReduce"。③拓扑感知——让通信走最快的路:NCCL 自动探测 NVLink/PCIe/InfiniBand 拓扑,节点内用 Ring、节点间用 Tree/Double-Tree;分层 AllReduce 先节点内规约、再跨节点规约、最后节点内广播,把慢速跨节点流量压到最低。台上 S3 的 Amdahl 模型 S = 1/((1−p) + p/N + comm(N)) 里,comm(N) 就是这三招要压低的项:压缩降 payload、异步降频率、拓扑感知降有效延迟。但要牢记——这些都是"缓解"不是"消除":comm(N) 能变小却不会归零,加速比饱和的天花板依然存在,这正是第一道刻痕"堆 GPU 即线性加速·此路不通"的深意。
详解 · K18-18 训练效率分析:MFU / GPU 利用率 / 吞吐量计算
加速比饱和之后,衡量分布式训练好坏的硬指标是 MFU(Model FLOPs Utilization,Paquette 2022 及 Megatron 效率分析)。定义:MFU = 模型实际达成的 FLOPs 吞吐 / GPU 理论峰值 FLOPs。其中"模型 FLOPs"按前向+反向 ≈ 6×N×D 估(N 为参数量、D 为训练 token 数;6 = 前向 2 + 反向 4)。手算一例:GPT-3 175B、D 取 300B token,模型 FLOPs = 6×175×10⁹×300×10⁹ = 3.15×10²³——与 Brown 2020 报告的 3.14×10²³ 吻合。若用 10000 张 V100(峰值合计约 1.4×10¹⁸ FLOPS)、实测 MFU ≈ 21%,则有效算力 = 1.4×10¹⁸×0.21 ≈ 2.9×10¹⁷ FLOPS,训练时间 = 3.15×10²³ / 2.9×10¹⁷ ≈ 1.1×10⁶ 秒 ≈ 12 天,量级与真实训练周期相符。MFU 为何到不了 100%:流水线气泡(PP)、张量/数据并行通信、访存瓶颈(算子未融合)、激活重计算(recomputation)都在偷走利用率;大模型训练的 MFU 通常落在 30~55%(A100/H100 上 Megatron 报约 50%)。台上 S3 的加速比曲线是"相对单卡的倍数",MFU 是"相对峰值的百分比"——前者告诉你加卡还划不划算,后者告诉你每张卡的算力有没有被浪费。吞吐量(tokens/s/GPU)则是二者在工程上的合成读数,是调 DP/TP/PP 配比时的最终裁判。
张量并行 · 模型切分
通信风暴后是一座矩阵工坊。工坊里悬着一块巨大的权重矩阵 Y = XW。高斯老祖拿起一把切刀:「数据并行是切数据,张量并行是切模型——把权重矩阵 W 按列切到 N 块 GPU,每块卡只算一部分输出。前向各算各的,最后 All-Gather 拼起来;反向再 Reduce-Scatter 回去。」
「张量并行切的是单层权重——把 W 按列切成 [W₁, W₂, ..., Wₙ],每块卡持有 Wᵢ,算 Yᵢ = X·Wᵢ。前向后 All-Gather 把 [Y₁,...,Yₙ] 拼成完整 Y;反向 Reduce-Scatter 把梯度分发回去。通信嵌在每一层里,但单层就能跨卡。」
「切模型?你切得越细,每层都要通信一次。层越深,我吃得越饱。你以为切了就并行了——切的是模型,连的是我的路。」
张量并行可视化器 · 矩阵列切分 + 前向反向通信
拖切分数看矩阵分块 → 切换前向/反向看通信模式 → 并行天平记录
矩阵乘法 · Y = XW 按列切分
通信模式 · 前向 All-Gather / 反向 Reduce-Scatter
详解 · K18-06 张量并行 Tensor Parallelism:矩阵分片策略
张量并行(TP,Shoeybi 2020 Megatron-LM)切的是单层权重矩阵,让一个算子跨多卡计算。对线性层 Y = XW,两种切法:①列切(column-parallel)——W 按列切成 [W₁,…,W_P],每卡持 Wᵢ 算 Yᵢ = X·Wᵢ,输出沿特征维分片,各卡无需通信即得到各自那段;②行切(row-parallel)——W 按行切、X 按列切,每卡算部分和再 All-Reduce 汇总。Megatron 的精髓是把两者配对:MLP 用"列切 → 行切"(第一层列切前向零通信、第二层行切前向 All-Reduce 一次),注意力则按 head 天然可切(每卡负责 heads/P 个注意力头,输出投影行切后再 All-Reduce)。台上 S4 演示的正是列切:W 按列分成 N 块、每卡算 Yᵢ = X·Wᵢ,前向 All-Gather 拼成完整 Y、反向 Reduce-Scatter 分发梯度。TP 的通信嵌在每一层内部(前向、反向各若干次 All-Reduce/等价原语),频率极高、payload 是激活而非参数——因此 TP 几乎只放在节点内、走 NVLink(数百 GB/s 级),跨节点做 TP 会被慢速以太网/IB 拖死。适用场景:单层大到一张卡放不下(如超宽 FFN、超大注意力),或需要压低单卡激活/参数显存。TP 度 P 通常取 8(一台 8 卡机内),与 S6 的"TP 放节点内"口诀一致;层多而每层小的模型不适合 TP,因为通信次数随层数线性放大。
详解 · K18-07 张量并行的通信分析:前向 / 反向通信量
张量并行的通信账要按"每层每次前向/反向"来算。Megatron 的一个 Transformer 层含注意力块与 MLP 块,每块在前向各需 1 次 All-Reduce、反向各需 1 次 All-Reduce(列切+行切配对的代价),故单层前向 2 次、反向 2 次,共约 4 次 All-Reduce。每次的 payload 是激活张量,大小 = batch × seq_len × hidden(记 b·s·h)。以 hidden = 8192、b·s = 4096、FP16 为例:单次激活 = 4096×8192×2 字节 ≈ 67MB,All-Reduce 收发 2(P−1)/P×67MB,P=8 时约 117MB/次,单层 4 次约 470MB,而一个 80 层模型每步要重复 80 遍——这就是台上 S4 那句"每层通信 1 次、层越深通信越多"的定量版(实际每层约 4 次)。Korthikanti 2022 进一步指出:TP 通信在关键路径上、难以与计算重叠(下一层必须等本层 All-Reduce 的结果),故 TP 度受限于节点内带宽;他们提出序列并行(见 K18-13)把 LayerNorm/Dropout 的激活也切分,将 TP 的 All-Reduce 拆成 All-Gather + Reduce-Scatter(通信总量不变,但省下激活显存)。反向的 Reduce-Scatter 把梯度分发回各卡对应的权重分片——与 S4 通信画布"反向 Reduce-Scatter:grad 分发"一致。结论:TP 用高频、小 payload、关键路径的通信,换来"单层跨卡"的能力,只配 NVLink、不宜跨节点。
流水线并行 · 层间分片
矩阵工坊后是一条流水线——模型被按层切成 N 段,每段放在一块 GPU 上。数据像零件一样从第一段流向最后一段。高斯老祖:「流水线并行切的是层——GPU0 放第 1-4 层,GPU1 放第 5-8 层。但一条数据流过去,前面的卡闲着等后面的卡,这就是气泡。用微批缓解——把 batch 切成小块连续灌进去。」
「流水线并行的死敌是气泡——前后级不同步时,快的卡要等慢的卡。GPipe 调度把 batch 切成 M 个微批,正向全灌完再反向,气泡比例 = (N-1)/M。1F1B 调度让正向反向交错,气泡更小。微批越多气泡越小,但显存占用越大。」
「气泡?你以为切层就高效了?前后级要等,等的就是我。微批能填气泡,但填不满——我住在气泡的缝隙里。」
流水线并行可视化器 · 层间分片 + 微批 + 气泡
拖流水级数看层切分 → 拖微批数看气泡填充 → 切换 GPipe/1F1B 调度
流水线 · N 级 × M 微批时序
气泡分析 · 气泡比例 vs 微批数
详解 · K18-08 流水线并行 Pipeline Parallelism:层间分片
流水线并行(PP)按层切模型:把 L 层网络分成 N 段(stage),第 i 段放在 GPU i 上,数据像流水线一样从 stage0 流向 stageN−1。两篇奠基工作:GPipe(Huang 2019)把一个 mini-batch 切成 M 个 micro-batch,全部正向灌完再全部反向(fill-drain 调度);PipeDream(Narayanan 2019)提出 1F1B(one-forward-one-backward),让正向与反向交错执行,把"在飞"的 micro-batch 数(即峰值激活显存)从 M 压到 N。台上 S5 的时序网格正是 N 级 × M 微批:GPipe 模式下正向块先铺满前段、反向块集中在后段;1F1B 模式下正反向犬牙交错。PP 的通信特点与 TP 相反:payload 是 stage 边界的激活(前向)与梯度(反向),只在相邻 stage 间点对点(point-to-point)传递,通信量小、频率低(每 micro-batch 每边界一次),因此 PP 适合跨节点、走较慢的 IB/以太网。PP 的软肋是气泡(bubble):流水线填充(warmup)与排空(cooldown)阶段,首尾 stage 必然空闲——这是结构性代价,详见 K18-09。PP 度 N 通常等于节点数或按层数均分,与 TP(节点内)、DP(跨节点复制)正交组合成 3D 并行(S6)。PP 让"层数太多、单卡放不下"的模型得以纵向切开,是 GPT-3 级训练的主力维度之一,也是本章从"切数据/切单层"迈向"切层间"的关键一跳。
详解 · K18-09 流水线气泡与微批调度:1F1B / GPipe 策略
流水线气泡(bubble)是 PP 的固有浪费:理想情况下 N 个 stage 应时刻满载,但流水线需要 (N−1) 个时间片来"填充"(第一个 micro-batch 逐级流到 stageN−1)和 (N−1) 个时间片来"排空",这段时间部分 stage 空闲。GPipe 的气泡比例可手算:总时间片 ≈ M + (N−1)(M 个 micro-batch 的有效计算加 N−1 的填充),其中气泡占 (N−1),故 bubble fraction = (N−1)/(M + N−1) ≈ (N−1)/M(当 M 远大于 N)。台上 S5 的气泡曲线画的正是 (N−1)/M:固定 N=4,M 从 1 到 16,气泡从 300%(M 小于 N,流水线根本填不满)降到 18.75%(M=16)——微批越多、气泡越小,但每个在飞 micro-batch 都要存激活,显存随 M 线性上涨。这就是 GPipe 的两难:减气泡要加 M,加 M 爆显存。1F1B(PipeDream,Narayanan 2019)破局:稳态下每做 1 次正向就紧跟 1 次反向,及时释放已完成 micro-batch 的激活,把峰值在飞数从 M 压到 N——气泡比例仍是 (N−1)/M(填充排空不变),但显存与 M 解耦。故现代大模型默认 1F1B,或其改进版 interleaved/virtual stage:把每卡再拆成 V 个虚拟段交错调度,气泡进一步降到 (N−1)/(M·V)。S5 的 GPipe/1F1B toggle 切换的就是这套调度——气泡同源,显存不同。
3D 并行 · 三管齐下
流水线尽头是一座三维阵列塔。塔的三个轴分别是数据并行(DP)、张量并行(TP)、流水线并行(PP)。高斯老祖:「单用一种并行都有极限——数据并行卡通信,张量并行层通信,流水线并行有气泡。3D 并行把它们组合:同一节点内张量并行(NVLink 快),节点间数据并行,层间流水线并行。三管齐下。」
「3D 并行的配置是艺术:TP 放节点内利用 NVLink 高带宽,PP 切层减少单卡显存,DP 跨节点扩规模。总 GPU 数 = DP × TP × PP。比如 1024 卡 = 8(DP) × 8(TP) × 16(PP)。每个维度都有 trade-off,没有最优解,只有最适配。」
3D 并行组装器 · DP × TP × PP 三维配置
拖三个维度看 GPU 网格 → 实时计算总卡数与通信量 → 配置权衡
三维配置 · DP × TP × PP
GPU 网格 · 三维拓扑
详解 · K18-10 3D 并行:DP + TP + PP 的组合策略
3D 并行把三种正交的切法叠起来:总 GPU 数 = DP × TP × PP。分工口诀(Shoeybi 2020;Korthikanti 2022 的 Megatron-DeepSpeed 实践):TP 放最内层、限制在单节点 8 卡内走 NVLink(通信最频繁、payload 在关键路径,必须最快链路);PP 放中层、跨节点切层(点对点、低频、可走 IB);DP 放最外层、跨节点复制(每步一次 AllReduce,可与反向重叠、对带宽最宽容)。台上 S6 的三轴组装器正是这套:拖 DP/TP/PP 三个滑块,总卡数 = 三者乘积,例如 1024 = 8(DP) × 8(TP) × 16(PP)。配置是权衡艺术而非最优解:①TP 增大 → 单层显存降但节点内通信升,超过 8 无益(跨节点 NVLink 断开);②PP 增大 → 层显存降但气泡升((N−1)/M),需同步加 micro-batch 填气泡;③DP 增大 → 吞吐升但 AllReduce 通信升,且受全局 batch 与学习率缩放约束。典型 GPT-3 级配置:TP=8(节点内)、PP=16~64(跨节点切层)、DP=其余(扩规模到数千卡)。S6 的 metric 面板实时算总卡数与 PP 气泡,就是让你在三维空间里找"显存放得下、通信吃得消、气泡填得满"的可行域——没有银弹,只有最适配集群拓扑与模型形状的配比。这也是为何本章把 3D 并行放在张量、流水线之后:它是前两者的组装,而非替代。
详解 · K18-13 序列并行:长序列的分布式处理
序列并行(SP,Korthikanti 2022《Reducing Activation Recomputation in Large Transformer Models》)补的是 TP 的盲区。TP 只切了注意力与 MLP 的权重矩阵,但 LayerNorm、Dropout、残差这些"逐元素/逐 token"算子的激活在 TP 区之外是每卡完整复制的——这部分激活显存随 b·s·h 增长,长序列时反而成为大头。SP 的做法:在 TP 组内,把这些非矩阵算子的激活沿序列维 s 切成 P 份,每卡只处理 s/P 个 token 的 LayerNorm/Dropout;进出 TP 区时,用 All-Gather(拼回完整序列进矩阵乘)与 Reduce-Scatter(矩阵乘后切回序列分片)替换原本的 All-Reduce——通信总量不变(AllReduce = RS + AG),但激活显存从 b·s·h 降到 b·s·h/P。SP 与 TP 是同一组 GPU、同一并行度 P 的"激活侧延伸",故常合写为 TP+SP。另一条同名不同物的路线针对超长上下文:Ring Attention(Liu 2023)把 KV 沿序列切分、用环形传递让每卡算局部注意力再累加,支持百万 token 级序列——前者切激活省显存,后者切注意力算长序列,别混为一谈。台上 S6 把 SP 与 3D 并行并列,是因为在 Megatron 语境里 SP 是 TP 的默认搭档:开 TP 几乎必开 SP,否则 LayerNorm/Dropout 的复制激活会悄悄吃掉你辛苦省下的显存。
第二崩塌 · 显存之壁
3D 阵列塔轰然崩塌,你跌入一面显存之壁。壁上刻着:70B 模型,140GB 参数(FP16),单卡 80GB 显存放不下。你把 batch 调到 1,还是 OOM。高斯老祖:「这不是通信问题,是显存问题。模型参数、梯度、优化器状态,全堆在一块卡上——放不下。」
「你以为通信是我的全部?显存也是我的领地。70B 模型参数 140GB,加梯度加优化器状态,单卡要 1.12TB——你 80GB 的卡放得下?切了模型有气泡,不切模型放不下。第二笔账,我记下了。」
「显存之壁的根源是冗余——每块卡都存了完整参数、梯度、优化器状态。ZeRO 的思路:把这些统统切分。优化器状态占大头(12 倍参数),先切它;再切梯度;最后切参数。三阶段,显存从 1.12TB 降到几十 GB。」
显存之壁 · 70B 显存拆解 + ZeRO 三阶段预告
拖模型规模看显存爆炸 → 拆解参数/梯度/优化器状态 → ZeRO 三阶段预告
显存爆炸 · 模型规模滑块
70B 模型ZeRO 三阶段预告 · 切什么省什么
详解 · K18-11 ZeRO 优化:分片优化器状态 / 梯度 / 参数
ZeRO(Zero Redundancy Optimizer,Rajbhandari 2020,DeepSpeed)的洞察:数据并行里每块 GPU 都存了一份完全相同的参数、梯度、优化器状态——这是纯粹的冗余。混合精度 + Adam 下,Ψ 个参数的显存账是:FP16 参数 2Ψ + FP16 梯度 2Ψ + 优化器状态 12Ψ(FP32 主参数 4Ψ + FP32 动量 4Ψ + FP32 方差 4Ψ)= 16Ψ 字节,即每参数 16 字节。台上 S7 把 70B 代入:参数 140GB + 梯度 140GB + 优化器 840GB = 1120GB(= 1.12TB),单卡 80GB 差约 14 倍。ZeRO 三阶段按"冗余从大到小"逐级切分(P 块 GPU):①ZeRO-1 切优化器状态(最大头 12Ψ)→ 显存 4Ψ + 12Ψ/P;②ZeRO-2 再切梯度 → 2Ψ + 14Ψ/P;③ZeRO-3 连参数也切 → 16Ψ/P。P=64 时 ZeRO-3 把 1120GB 压到 17.5GB,单卡轻松放下。代价是通信:ZeRO-1/2 的通信量与朴素数据并行相同(仍等价一次 AllReduce),ZeRO-3 因前向反向都要 All-Gather 临时拉回完整参数、再 Reduce-Scatter 同步梯度,通信量升到 1.5 倍——这正是 S8 boss 说的"省显存花通信"。ZeRO 不改变训练数学(切的是存储不是计算),故精度与收敛和单卡完全一致,这是它区别于模型并行的关键:它是"显存去冗余",不是"模型切分"。S7 的显存拆解条与 ZeRO 三阶段预告,就是这套 16Ψ → 16Ψ/P 账本的可视化。
ZeRO 优化 · 分而治之
显存之壁后是一座分片工坊。工坊里悬着三块光板,分别刻着:优化器状态、梯度、参数。高斯老祖递给你一把分片刀:「ZeRO 的哲学——能切的都切。ZeRO-1 切优化器状态,省最多;ZeRO-2 再切梯度;ZeRO-3 连参数都切,单卡只持 1/N。你切换阶段,看显存怎么降。」
「ZeRO-3 把参数也切了——前向时 All-Gather 拉参数,算完即弃;反向时再 All-Gather 拉参数算梯度,Reduce-Scatter 同步梯度。显存从 16×参数(Ψ) 降到 16Ψ/N。但代价是通信——ZeRO-3 的通信量是 ZeRO-1 的 1.5 倍。省显存,花通信。」
「切参数?你切得越彻底,前向反向都要 All-Gather 拉参数——通信量涨到 1.5 倍。省显存是省了,但我又回来了。ZeRO-3 牺牲的,是我的代价。」
ZeRO 优化器可视化器 · 三阶段分片 + 显存通信对比
切换 ZeRO 阶段看分片 → 拖 GPU 数看显存下降 → 显存 vs 通信权衡曲线
显存占用 · 参数/梯度/优化器状态分片
显存 vs 通信 · 权衡曲线
详解 · K18-12 ZeRO-Offload:CPU-GPU 协同卸载
ZeRO-Offload(Ren 2021)把 ZeRO 的分片思想延伸到异构内存:GPU 显存放不下,就借 CPU 内存(DRAM,通常数百 GB 到 TB 级、比显存便宜且大)甚至 NVMe SSD。核心设计:把优化器状态与梯度卸载到 CPU,让 Adam 更新(optimizer step)在 CPU 上算,GPU 只负责前向反向(计算密集、需要高带宽的部分)。关键权衡是"计算与数据搬运怎么划分"——Ren 2021 的原则是:把访存密集、计算量轻的 Adam 更新放 CPU(CPU 算 Adam 的 FLOPs 占比很小,不拖慢整体),把计算密集的前向反向留 GPU,避免在 PCIe 上反复搬运大块激活。效果:单张 V100(32GB)配 ZeRO-Offload 即可训练 13B 模型(原本需多卡),把大模型训练的门槛拉到低端硬件。代价是 PCIe 带宽(约 32GB/s,远低于 NVLink 的数百 GB/s)成为新瓶颈,吞吐下降(论文报约 30% 速度损失换显存大幅扩展)。后继 ZeRO-Infinity(Rajbhandari 2021)进一步卸载到 NVMe,支持万亿参数,并用并行 NVMe + 预取缓解 IO 墙。台上 S8 的 ZeRO 三阶段是在 GPU 显存内做 P 卡横向分片,ZeRO-Offload 则是把分片后的状态再纵向降到 CPU/NVMe——二者正交、可叠加(ZeRO-3 + Offload = 显存与内存双分片)。S8 那句"没有免费的午餐"在此再次应验:省显存的代价,从"花通信"变成了"花 PCIe 带宽与 CPU 算力"。
Boss 战 · 通信瓶颈
分片工坊尽头暗蓝色雾气重新合拢,温度骤降——通信瓶颈凝聚成形。它不是人形,是一张横亘万核之间的拥堵光网,网里映着无数卡顿的梯度流。它翻开一本账册:「你来了。带着你的两道刻痕,和你的通账。三问。答对,我疏通。答错,你的元婴修为归零。」
「你说加卡就能加速——它不能。我住在你"以为堆 GPU 就线性加速"的地方。你每多加一块卡,我就堵一截。证明给我看:你的两道刻痕不是耻辱,是你的排除法——每一条"此路不通",都在告诉你正确的路在哪里。」
通账累计 0 笔 · 三问全对后清零
顿悟 · 万核归一
拥堵光网疏通,你站在万核之巅。山脚是你走过的路——数据并行、Ring AllReduce、通信风暴、张量并行、流水线并行、3D 并行、显存之壁、ZeRO 优化。山顶放着一面万核镜,镜中映着所有并行策略交织成的知识图谱。高斯老祖:「你想驾驭万核。面前有三道认知:加卡不等于加速、切分对抗瓶颈、显存与通信是永恒权衡。」
「分布式训练的全部,是在算力、通信、显存三者间寻找平衡。数据并行切数据,张量并行切单层,流水线并行切层间,3D 并行三管齐下,ZeRO 切冗余。没有免费的午餐——每切一刀都换来新的通信代价。万核归一,不是消灭瓶颈,是承认瓶颈后找到最优配比。元婴三层,万核归一——你已巩固。但元婴之路的下一阶,在推理加速。」
万核归一 · 三道认知 + 知识图谱 + 境界突破
点亮三道认知 → 点亮分布式知识图谱 → 境界突破动画(元婴三层巩固)
三道认知 · 各三选一
分布式训练知识图谱 · 万核归一
万核之外 · 三道进阶议题
高斯老祖临别赠三言——万核归一之后,还有三件事,等你进入实战再细修。
「其一,专家并行(MoE)。数据 / 张量 / 流水线切的是同一份模型;MoE 则把"不同子网络"分到不同卡——每个 token 只激活少数专家,靠路由(Router)分配。容量上去了,计算却省了。代价是负载均衡:热门专家拥塞、冷门闲置,得用 auxiliary loss 逼路由均匀。Mixtral、DeepSeek-V3 都是这条路。」
「其二,容错与弹性训练。万卡跑几周,必有卡挂。靠检查点(Checkpoint)定期存全量状态——优化器、参数、学习率、数据指针;挂了从最近点续训,不从头来。进阶有异步检查点(后台保存不阻塞训练)与弹性恢复(剔除坏卡继续)。没有容错,万卡训练就是赌命。」
「其三,实战账本。GPT-3:175B 参数,约 1 万张 V100,499B token,总算力约 3.14×10²³ FLOPs。LLaMA-2 70B:约 2 千张 A100(2048),2T token。LLaMA-3 405B:超 1.6 万张 H100,15T token。账本上的数字,就是这一章所有策略的最终答卷。」
详解 · K18-14 专家并行 MoE:路由策略与负载均衡
专家并行(MoE,Mixture-of-Experts)切的是"不同子网络"而非同一份模型。Shazeer 2017(Sparsely-Gated MoE)与 Fedus 2022(Switch Transformer)奠基:把 Transformer 的 FFN 层替换成 N 个"专家"FFN,每个 token 经一个轻量路由(Router/Gate)打分,只激活 top-k 个专家(Switch 用 k=1,GShard/Mixtral 用 k=2)。于是参数量随专家数线性膨胀,但每 token 的计算量只由 k 个专家决定——"容量上去、计算省下"。台上 S10 其一正是这套:专家分到不同卡(expert parallelism),token 经 All-to-All 通信被分发到持有目标专家的卡、算完再 All-to-All 收回。核心难题是负载均衡:路由天然偏好少数"热门专家",导致它们拥塞、冷门专家闲置、算力浪费。三招缓解:①auxiliary load-balancing loss(Fedus 2022)——在总损失里加一项惩罚专家分配的不均匀,逼路由把 token 摊平;②capacity factor——给每个专家设容量上限,超出的 token 被丢弃或溢出到别卡;③expert-choice routing(Zhou 2022)——反过来让专家选 token,天然均衡。代表模型:GShard(2020)、Switch(2021)、Mixtral 8×7B(2023,8 专家激活 2)、DeepSeek-V3(2024,细粒度专家 + 共享专家)。MoE 的通信账重(每 token 两次 All-to-All)且对负载极敏感,是 3D 并行之外的"第四维",实战绕不过。
详解 · K18-16 容错与弹性训练:Checkpoint / 故障恢复
万卡跑几周,硬件故障是必然不是偶然:GPU 掉卡、ECC 错误、网络抖动、节点宕机——单卡年故障率哪怕只有百分之几,乘上万卡就是"每天必有卡挂"。没有容错,一次故障就让整个训练从头再来,几天算力打水漂。核心机制是检查点(Checkpoint):定期把全量训练状态落盘——模型参数、优化器状态(Adam 的 m/v)、学习率调度器步数、数据加载指针(dataloader state,保证续训不重复不漏数据)、RNG 种子。故障后从最近的 checkpoint 恢复,最多损失一个保存间隔的进度。工程演进:①同步 checkpoint 会阻塞训练(写 TB 级状态到共享存储要几分钟);②异步 checkpoint(PyTorch Distributed Checkpoint、DeepSpeed Nebula)先把状态快照到 CPU 内存或本地 NVMe、训练继续,后台再慢慢写远程存储,把停顿降到秒级;③弹性训练(PyTorch Elastic / torchrun)支持节点动态增减——坏卡被剔除、训练在剩余卡上自动重组并行组继续,无需人工重启。台上 S10 其二强调的正是这套:checkpoint 存什么、异步保存不阻塞、弹性恢复剔坏卡。分布式 checkpoint 还要解决"分片状态"的保存——ZeRO/3D 并行下每卡只持一部分状态,checkpoint 必须记录分片拓扑,恢复时才能正确重组(resharding)。容错不是主线知识,却是万卡训练能否跑完的生死线。
详解 · K18-17 大规模训练案例:GPT-3 / LLaMA 的训练配置
三本实战账本把全章策略落到具体数字(Brown 2020;Touvron 2023/2024)。GPT-3 175B(2020):约 10000 张 V100,训练约 300B token(数据集约 500B),总算力 3.14×10²³ FLOPs,用 DP + TP + PP 的 Megatron 式 3D 并行——这是"万卡级"训练的里程碑。LLaMA-2 70B(2023):约 2048 张 A100-80GB(Meta RSC 集群),2T token,全局 batch 4M token,用 FSDP(PyTorch 的 ZeRO-3 等价实现)+ 激活重计算,MFU 约 30~40%——注意是"约两千张"而非"两万张":70B 的算力账 6×70×10⁹×2×10¹² = 8.4×10²³ FLOPs,在 2048 卡上跑数月才对得上。LLaMA-3 405B(2024):超 1.6 万张 H100(16384 张),15T token,用 4D 并行(DP + TP + PP + 上下文/序列并行)+ 8-bit 优化器降显存,MFU 报约 38~43%。三本账的共同结构:参数量升 → 并行维度升(从 3D 到 4D)、优化器精度降(FP32 → 8-bit)、token 数升(300B → 2T → 15T)、集群规模与代际升(万张 V100 → 两千张 A100 → 万六千张 H100)。台上 S10 其三念的就是这串数字——它们是 K18-01~16 所有策略在真实训练里的最终答卷:每张卡的显存怎么省、每次通信怎么压、每场故障怎么扛,都写在这些配置里。
复盘 · 万核归一主线:从堆卡幻想到切分与平衡
一条主线串起十一幕:动机(S0 单卡装不下算不快,瓶颈之赌谜底是通信带宽)→ 数据并行(S1 复制模型切数据,AllReduce 同步梯度)→ Ring AllReduce(S2 环形接力把 O(N²) 压到 O(N),通信量 2(P−1)/P·M)→ 第一崩塌(S3 通信风暴,Amdahl S = 1/((1−p) + p/N + comm(N)),加卡到第八块加速比饱和,刻痕一:堆 GPU 即线性加速 ✗)→ 张量并行(S4 切单层权重,前向 All-Gather、反向 Reduce-Scatter,通信嵌每层、只配 NVLink)→ 流水线并行(S5 切层间,气泡 (N−1)/M,1F1B 省激活)→ 3D 并行(S6 DP×TP×PP,TP 节点内、PP 跨节点、DP 扩规模)→ 第二崩塌(S7 显存之壁,70B = 16Ψ = 1120GB,刻痕二:单卡放得下大模型 ✗)→ ZeRO(S8 三阶段分片 16Ψ → 16Ψ/P,省显存花通信)→ Boss 战(S9 三问清算通账)→ 万核归一(S10 三道认知 + 知识图谱 + 进阶三题 MoE/容错/账本)。两道刻痕不是失败记录,是排除法的界碑:堆卡不能线性加速、单卡放不下大模型——它们共同指向答案:分布式训练的本质不是堆算力,是在算力、通信、显存三者间用"切分"找平衡。每个环节都标着 trade-off:DP(吞吐 vs AllReduce)、Ring(O(N) vs 延迟)、TP(单层跨卡 vs 每层通信)、PP(切层 vs 气泡)、3D(组合 vs 调参)、ZeRO(省显存 vs 花通信)。万核归一,不是消灭瓶颈,是承认瓶颈永恒后找到最优配比——元婴三层巩固。下一阶,推理如电(ch19):训练教会模型,推理让模型轻装上阵、服务真实世界。