想象一下:你要跟队友一起爬一座雪山,每个人都要背全套装备——帐篷、睡袋、氧气瓶、急救包。队员越多,带进山的装备就越多,哪怕大家走的是同一条路。大模型训练也是一样:每一张 GPU 显卡都像一个登山队员,都要背上完整的模型参数、梯度和优化器状态。当模型大到 70 亿参数时,光是单卡要背的“装备”就超过 120GB,连一块 80GB 的 A100 都装不下。ZeRO 做的事情,就是把原来“每人一套”的装备,改成“全队合一套、按人头分着背”——谁需要哪件装备,再通过对讲机喊一声,从队友那里借过来用。这样一来,每个队员的背包轻了数倍,整支队伍却能爬上更高的山。这篇文章,我们就从这三张卡的故事讲起,看看 ZeRO-1、ZeRO-2、ZeRO-3 是怎么一步一步把“备用氧气瓶”“路况笔记”和“帐篷杆”都摊到每个人肩上的,以及每一级省下的显存到底有多少。

岗位关联

对 AI 从业者来说,ZeRO 是训练百亿乃至千亿参数大模型的核心显存技术。掌握它的分级原理与通信代价,能帮你在实际项目中快速选型 DeepSpeed 配置,避免“显存爆了不知道砍谁”的窘境。

目录
  1. 可视化演示
  2. 显存四件套
  3. 基线数据并行
  4. ZeRO-1切优化器
  5. ZeRO-2切梯度
  6. ZeRO-3切参数
  7. 通信换显存
  8. 工程落地
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

展示ZeRO三阶段如何将优化器状态、梯度和参数分片到多GPU,交互调节GPU数量和阶段观察显存变化。

本节配有交互动效(进入视口后自动加载,约 3KB)。

ZeRO-1:优化器状态分区 参数(2ψ)与梯度(2ψ)全量保留 优化器状态(12ψ)按N分片 显存 = 2ψ + 2ψ + 12ψ/N 优化器状态分片,显存降至~4x

显存四件套

登山队出发前,队长要统计每个人的负重:帐篷、睡袋、氧气瓶、急救包,一样都不能少。模型训练也一样,一张卡要装下四样东西:模型参数(帐篷)、梯度(路况笔记)、优化器状态(氧气瓶+急救包),以及中间激活值(爬坡时随手堆的物资站)。在这四样里,最沉的不是帐篷,而是氧气瓶——也就是 Adam 优化器里保存的动量 m 和方差 v。

为什么氧气瓶这么沉?因为混合精度训练时,每一份参数都要同时维护 FP16 和 FP32 两种形态:FP16 参数副本 2 字节、FP16 梯度 2 字节、FP32 主权重 4 字节、FP32 动量 4 字节、FP32 方差 4 字节。加在一起,平均每个参数要占 16 字节。也就是说,一个 70 亿参数的模型,单卡想存下全量训练状态,需要 7.5 × 10⁹ × 16 ≈ 120GB——一块 80GB 的 A100 都塞不进去。

这就是第一课:显存不是被“模型大小”吃掉的,而是被“训练状态全家桶”吃掉的。其中优化器状态一家就占了 12ψ,是绝对的大头。

回到我们的登山队:氧气瓶和急救包(Adam 状态)比帐篷加睡袋还沉好几倍。谁要是能把氧气瓶的重量降下来,谁就捏住了显存的七寸。

Mbase=16ψ\displaystyle M_{\text{base}} = 16\psi
这个公式告诉你:混合精度 Adam 训练下,单卡需要 16 字节/参数 的显存。ψ 是参数量,16 是六份状态之和。
  1. 参数量符号$\psi$ 表示模型总参数量。比如 7.5B 模型,就是 $\psi = 7.5 \times 10^9$。
  2. 六份状态的字节数混合精度下每个参数对应 6 份存储,合计 $(2 + 2 + 4 + 4 + 4) = 16$ 字节。
  3. 结果含义$M_{\text{base}}$ 是单卡存全量训练状态所需显存,$\psi=7.5B$ 时约为 120GB。

基线数据并行

登山队的原始方案很简单粗暴:每个队员都背一整套装备,谁也别想偷懒。数据并行(DP)就是这个思路——每张卡都复制一份完整的模型参数,喂进去不同批次的数据,各自前向反向算出梯度,然后所有人把梯度拿来求平均(这一步叫 all-reduce,可以理解为全体队员对着对讲机报数,最后每个人都知道平均路况),再用平均后的梯度更新各自的参数。

这个方案的问题肉眼可见:卡越多,总显存越大。N 张卡就要 N 份完整的 16ψ,一点共享都没有。还是那个 7.5B 模型,用 64 张卡做数据并行,总显存需求是 64 × 120GB ≈ 7.7TB。而实际上每张卡的有效计算贡献无非是多吃了一份数据,显存却被复制了 64 份——这是一笔非常不划算的买卖。

登山队这才发现:与其每个人背同样的氧气瓶进山,不如在山脚建一个共享营地,把装备按人头分好,谁要用再来领。这个从“人手一套”到“全队一套”的转变,正是 ZeRO 的出发点。

对登山队来说,这个方案意味着 64 个人背 64 套氧气瓶进山,结果路上还有 63 套是纯浪费。队长开始琢磨:能不能把氧气瓶拆开,一人背一罐,用的时候再互相借?

MDP(N)=16Nψ\displaystyle M_{\text{DP}}(N) = 16N\psi
数据并行把单卡 16ψ 的负担乘以卡数 N。显存随卡数线性增长,这就是“每人一套装备”的代价公式。
  1. 单卡基线$16\psi$ 是上一节算出的单卡训练状态全量显存。
  2. 乘以卡数$N$ 为 GPU 数量,数据并行要求每卡都有一份完整副本,所以乘法生效。
  3. 线性增长的含义加卡只能增加吞吐,不能摊薄单卡显存负担,甚至总显存需求反而爆炸。

ZeRO-1切优化器

队长的第一个主意是拿最沉的氧气瓶开刀:把全队 12ψ 的 Adam 优化器状态均匀切成 N 份,每人只负责保管其中一份。训练的时候,每张卡的反向传播照常算出完整梯度,但不需要保留完整梯度——先通过一次 reduce-scatter(全体队员各自报数,最后每个人手里只剩一组平均数的一部分,也可以理解为“把平均路况按路段分给每个人记录”),让自己拿到属于自己那一段的平均梯度,然后立刻用它更新自己保管的那份优化器状态。

这一步切分只动了优化器状态,参数和梯度仍然是每卡全量,所以显存公式变成了 4ψ + 12ψ/N。拿 7.5B、64 卡来算:参数 2ψ(15GB)+ 梯度 2ψ(15GB)+ 优化器分片 12ψ/64(约 1.4GB),每卡约 31.4GB——从 120GB 直接砍到 31.4GB,省掉了四分之三。更妙的是,通信量并没有增加:原来的梯度 all-reduce 被拆成 reduce-scatter(通信量 2ψ)和更新后的梯度 all-gather(通信量 2ψ),总量依然是 2ψ,与基线持平。

ZeRO-1 的朴素智慧是:最重的东西不要人人带一份,而是人人各带一部分。氧气瓶从 90GB 的“人均负重”变成 1.4GB 的“人均份额”,登山队员的背包瞬间轻了四分之三。

氧气瓶问题解决了,但登山队的背包里还有一厚摞路况笔记(梯度)——那也是每人一份全量的。队长眯起眼睛:下一刀,砍它。

MZeRO-1=4ψ+12ψN\displaystyle M_{\text{ZeRO-1}} = 4\psi + \frac{12\psi}{N}
ZeRO-1 把 Adam 优化器状态(12ψ)切成 N 份,只有参数和梯度还保持全量。N 越大,省得越多。
  1. 保留的全量部分$4\psi$ = FP16 参数副本 $2\psi$ + FP16 梯度 $2\psi$,这两样不动。
  2. 切分的主体$\frac{12\psi}{N}$ 是 Adam 的 FP32 主权重、动量、方差三样各 4ψ,合计 12ψ,被均匀切成 N 份。
  3. 代入实例$\psi=7.5B, N=64$ 时,$M_{\text{ZeRO-1}}=30+1.4\approx 31.4\text{GB}$。

ZeRO-2切梯度

队长的第二个主意是处理路况笔记:反正每张卡算完梯度后,真正用到的只有自己负责的那一段,那梯度也没必要全量保留。ZeRO-2 在前向/反向算出全量梯度后,用 reduce-scatter 把梯度均分成 N 份,每张卡只留下属于自己的那 1/N 段,然后立刻用它去更新自己保管的优化器状态分片——更新完,这一段梯度就可以释放了。也就是说,梯度显存从全量 2ψ 降到了 2ψ/N。

加上 ZeRO-1 已经切掉的优化器状态,ZeRO-2 的显存公式变成 2ψ + 14ψ/N。还是 7.5B、64 卡:参数 2ψ(15GB)+ 梯度分片 2ψ/64(0.23GB)+ 优化器分片 12ψ/64(1.4GB),每卡约 16.6GB。相比 ZeRO-1 的 31.4GB 又少了一半,相比基线 120GB 已经省下了 86%。

登山队此时的状态是:氧气瓶分着背、路况笔记分着记,只有帐篷还每人一顶。每人的背包已经很轻,但队长盯着帐篷——那是最后一坨全量重量。

路况笔记也不全量了。但队长还有最后一个念头:帐篷那么大,为什么不能让每个人只扛一根帐篷杆呢?

MZeRO-2=2ψ+14ψN\displaystyle M_{\text{ZeRO-2}} = 2\psi + \frac{14\psi}{N}
ZeRO-2 在 ZeRO-1 基础上再切掉梯度:全量只保留参数副本 2ψ,梯度 2ψ 和优化器 12ψ 都按 N 切分。
  1. 剩下的全量$2\psi$ 只指 FP16 参数副本,这是前向计算必须的全量参数。
  2. 切分的总量$\frac{14\psi}{N}$ = 梯度 $2\psi$ + 优化器状态 $12\psi$,合计 14ψ 均分。
  3. 通信不变ZeRO-2 的通信仍是 reduce-scatter 加 all-gather 一次系数汇总,总通信量约 $2\psi$,和基线同级。
  4. 代入实例$N=64$ 时每卡约 $15 + 1.64 \approx 16.6\text{GB}$。

ZeRO-3切参数

ZeRO-3 的答案是:连帐篷也拆了。模型参数被均匀切成 N 份,每张卡只保存自己负责的那 1/N 段参数。但问题来了:前向计算时,每一层都需要完整的权重。怎么办?答案是“用时借”——在计算某一层之前,所有卡通过一次 all-gather(全体队员把各自保管的零件广播一遍,拼成完整帐篷)把该层参数收集齐全,计算完再丢弃。反向传播时,为了算梯度,又得再 all-gather 一次该层参数。这就是 ZeRO-3 的典型特征:参数平时不存在显存里,用到哪层,哪层才“快递”过来。

显存公式变得极其干净:16ψ/N。7.5B、64 卡下每卡约 1.9GB,一张消费级显卡就能塞下 70 亿参数的训练状态。但这世界没有免费的午餐——参数每次前向、反向都要 all-gather,通信量相比基线增加了约 50%。也就是说,ZeRO-3 是用“喊话频率”换“背包重量”。

登山队最终实现了全员轻量化:每个人只扛一根帐篷杆、一瓶氧气、半页路况笔记,走到哪儿需要搭帐篷,就对讲机喊一声,队友把杆子拆过来,用完再还。整支队伍确实能爬更高的山了,只是山里的对讲机频道,明显热闹了不少。

不过,帐篷拆得越碎,搭帐篷时喊话的次数就越多。省下的显存,终究要用额外的通信时间来买单——这就是下一节的天平。

MZeRO-3=16ψN\displaystyle M_{\text{ZeRO-3}} = \frac{16\psi}{N}
ZeRO-3 把参数、梯度、优化器状态全部切分,每卡显存约等于全量显存除以卡数,是 ZeRO 的终极形态。
  1. 分子 16ψ混合精度训练状态六件套全部被纳入切分范围。
  2. 分母 N所有训练状态均匀分布在 N 张卡上,单卡承担 $1/N$。
  3. 实例$\frac{120\text{GB}}{64} \approx 1.9\text{GB}$,显存不再是大模型训练的第一瓶颈。

通信换显存

登山队发现,装备分摊到每个人头上之后,队伍虽然能轻装上阵,但队员之间的对讲机通话量急剧上升。ZeRO 的世界里,显存和通信就是这样一个跷跷板:每一级切分都省下一块显存,同时可能多出一笔通信账单。

先看账单明细。基线数据并行:每步要 all-reduce 一次梯度,每卡通信量约 2ψ。ZeRO-1 和 ZeRO-2:把 all-reduce 拆成 reduce-scatter + all-gather 两步,通信总量依然是 2ψ,所以和基线打平——这是 ZeRO-1/2 最划算的地方,显存省了,通信不涨。到了 ZeRO-3:除了梯度通信,每层参数在训练中被 all-gather 两次(前向一次、反向一次),额外多出参数规模的通信,总通信量约为基线的 1.5 倍。

这个 1.5 倍在高速互联的集群里也许只是多等几毫秒,但在千兆以太网或 PCIe 互联的廉价集群里,可能就是训练速度腰斩的导火索。所以选型时要想清楚:你的“山路”是高速公路(NVLink/IB)还是乡间小道(千兆网)?网络越好,越敢用 ZeRO-3。

对讲机喊话次数变多了,但每个队员的负重确实轻了。聪明的领队会根据山路条件做取舍:路好走就多喊话,路难走就少拆装备。

VZeRO-3=1.5 Vbase\displaystyle V_{\text{ZeRO-3}} = 1.5\,V_{\text{base}}
ZeRO-1/2 的通信量与数据并行持平,ZeRO-3 因为每层参数要 all-gather 两次,通信量约为基线的 1.5 倍。
  1. 基线通信量$V_{\text{base}} \approx 2\psi$,是每步梯度 all-reduce 的字节数。
  2. ZeRO-1/2 不变改成 reduce-scatter + all-gather 后,总量仍约 $2\psi$。
  3. ZeRO-3 的增量每层参数前向、反向各 all-gather 一次,额外增加约 $1\psi$ 量级的通信。
  4. 结论$V_{\text{ZeRO-3}} \approx 3\psi = 1.5 \times 2\psi$。

工程落地

理解了分级原理,落地的选型就变得像按体力分装备一样简单。如果训练的是 7B 以下的小模型,单卡显存够用,直接 ZeRO-1 甚至不用 ZeRO;如果模型到了 13B、33B 级别,ZeRO-2 通常是最佳性价比——显存省得明显,通信又不涨;当模型冲向 100B、1000B 时,必须上 ZeRO-3,同时配合流水并行和张量并行组成“组合拳”,把参数、梯度、优化器状态、激活值四大件全部摊开。

工程上还有两个常用搭配。第一是 offload:把优化器状态甚至参数卸载到 CPU 内存或 NVMe 硬盘,相当于给登山队请了一个山脚仓库管理员,GPU 只管算,存东西找仓库。第二是激活检查点(activation checkpointing):不保存每一层的激活值,反向时重新计算一遍,用算力换显存——这是应对长序列训练时激活爆炸的利器。在 DeepSpeed 里,这一切只需要在配置文件里写 "zero_optimization": {"stage": 3} 这样一行配置即可生效。

最后别忘了那个极限:卡数 N 趋于无穷时,ZeRO-3 每卡显存 16ψ/N 趋近于零,但这只是理论上的“行李消失术”。现实中通信不会归零,激活值也不会归零,所以别把 ZeRO 当成万能药,它只是显存管理这盘大棋里最关键的一步。

登山队明白了一个道理:装备可以无限拆细,但对讲机的频道总会拥堵。聪明的领队,会在背包重量和喊话频率之间,找到属于自己这支队伍的最佳平衡点。

lim⁡N→∞16ψN=0\displaystyle \lim_{N \to \infty} \frac{16\psi}{N} = 0
卡数越多,ZeRO-3 单卡显存越趋近于零。但通信开销和激活显存会阻止这个极限变成现实。
  1. 极限对象$\frac{16\psi}{N}$ 是 ZeRO-3 的每卡显存公式。
  2. N 趋向无穷理论上加卡就能无限摊薄显存,训练状态可以无限细分。
  3. 现实约束通信量不随 N 归零,激活值也不参与切分,所以极限只是“理论背包”,不是实际背包。

AI 应用场景

千卡集群训练千亿级大模型

阶段:大规模预训练

解决的问题:训练 175B+ 参数的模型时,基线数据并行需要每卡存储全量 16ψ≈2.8TB 训练状态,任何单卡都无法容纳。ZeRO-3 将全部训练状态切分到数千张卡上,配合流水并行和张量并行,让千亿模型训练成为可能。

具体案例:某大模型团队用 1024 张 A100 训练一个 175B 模型,采用 DeepSpeed ZeRO-3 + 流水并行。参数、梯度、优化器状态均分为 1024 份,每卡仅需承担约 2.7GB 的训练状态,配合高速 IB 网络将 1.5 倍通信开销控制在可接受范围。

单机四卡微调 13B 开源模型

阶段:监督微调(SFT)

解决的问题:普通团队只有 4 张 RTX 4090(每张 24GB),直接加载 13B 模型做 LoRA 微调或全参微调都会显存溢出。ZeRO-2 + offload 可以把优化器状态卸载到 CPU 内存,让 4 张消费级显卡跑起全参微调。

具体案例:算法工程师在 4×4090 机器上微调 13B Chat 模型,DeepSpeed 配置 stage: 2 并将优化器 offload 到 CPU。每卡显存从全量约 208GB 降到约 34GB,微调 batch size 从 1 提升到 4,训练吞吐提升 2.5 倍。

长序列训练对抗激活显存爆炸

阶段:长上下文训练/微调

解决的问题:训练 128K 长序列时,即便 ZeRO-3 把参数类显存压到极低,中间激活值依然会在单卡上堆积几 GB 到几十 GB。通过 ZeRO-3 搭配激活检查点,用“反向重新计算”换取激活显存的释放。

具体案例:某团队微调 7B 模型支持 128K 上下文,开启 ZeRO-3 + activation checkpointing 后,激活显存峰值从 40GB 降到 8GB,单卡总显存占用稳定在 22GB 以内,成功在 8 张 A100 上完成长序列微调。

Python 演示

python19 行
def estimate(params_b, gpus, gpu_mem_gb=80.0):    psi = params_b * 1e9    base = 16 * psi    stages = {        0: (base, 1.0),        1: (4 * psi + 12 * psi / gpus, 1.0),        2: (2 * psi + 14 * psi / gpus, 1.0),        3: (16 * psi / gpus, 1.5),    }    print("模型 {}B / {} 卡 / 单卡 {}GB".format(params_b, gpus, gpu_mem_gb))    for stage, (mem, comm) in stages.items():        per_gpu = mem        ok = "可行" if per_gpu <= gpu_mem_gb * 1e9 else "超显存"        print("  ZeRO-{}: 每卡 {:.2f}GB, 通信 {}x -> {}".format(            stage, per_gpu / 1e9, comm, ok)) if __name__ == "__main__":    estimate(7.5, 64, 80)    estimate(13, 4, 24)
目的:一个极简显存估算器,输入参数量、GPU 数和单卡显存,即可评估 ZeRO 四个 stage 是否可行。对应正文各小节的显存公式,可用于方案选型前的快速计算。
  1. psi = params_b * 1e9把“B”为单位的参数量换算成实际参数个数,后续所有显存公式都以它为基准。
  2. base = 16 * psi复现 16ψ 公式,混合精度训练状态下每个参数占用 16 字节。
  3. 1: (4 * psi + 12 * psi / gpus, 1.0)ZeRO-1 显存公式 4ψ + 12ψ/N,通信倍数保持 1.0。
  4. 2: (2 * psi + 14 * psi / gpus, 1.0)ZeRO-2 显存公式 2ψ + 14ψ/N,通信仍不涨。
  5. 3: (16 * psi / gpus, 1.5)ZeRO-3 全切分公式 16ψ/N,通信倍数 1.5。
  6. per_gpu / 1e9把字节换算成 GB,方便与 GPU 实际显存对比。
  7. estimate(7.5, 64, 80)示例:7.5B 模型 64 张 80GB 卡,输出会显示 ZeRO-0/1/2/3 各自是否可行。

常见误区

误区“ZeRO 把参数切到多张卡上,那它不就是张量并行或流水并行吗?和模型并行是一回事。”

正解ZeRO 本质上是数据并行的显存优化方案。每张卡依然处理不同的 batch 数据,只是训练状态的存储从“每卡全量”变成“全网分片”。张量并行是把单层计算拆到多卡,流水并行是按层切分计算流程,这两者切割的是“计算图”,而 ZeRO 切割的是“存储副本”。实际大模型训练常把三者组合使用,但它们解决的问题各不相同。

为何常见:ZeRO-3 确实把参数全网分片了,看起来“很像模型并行”,初学者容易从表象归类,而忽略了每个并行策略切割的对象是计算还是存储。

误区“ZeRO-3 省显存最多,效果最好,所以不管什么场景我都直接开 stage 3 就行。”

正解ZeRO-3 的 1.5 倍通信开销在网络带宽不足时会让训练明显变慢。训练 7B 以下模型时,单卡显存通常够用,ZeRO-2 甚至 ZeRO-1 性价比更高;只有在模型大到单卡放不下全量训练状态时,ZeRO-3 才成为必选项。选型要看“当前瓶颈是显存还是带宽”,而不是盲目追求最高 stage。

为何常见:人容易把“省得更多”等同于“更好”,忽略了显存之外还有通信、延迟这些同样关键的成本维度。

误区“ZeRO-3 把参数都切完了,每卡只用 1.9GB,那再大的模型也能跑,显存问题彻底解决了。”

正解ZeRO-3 只切分了参数、梯度、优化器状态这三类“静态状态”,而中间激活值依然在前向过程中全量存在于显存里。训练长序列或大 batch 时,激活值可能轻松超过 30GB,照样爆显存。必须额外配合激活检查点、梯度累积等手段,才能把激活峰值压下来。

为何常见:显存公式 16ψ/N 太干净、太有说服力,让人忘了公式里根本没包含激活值这一大项。

误区“显存省下来了,每张卡可以塞更大 batch,训练应该又快又省。”

正解ZeRO 省显存不等于省时间。ZeRO-1/2 虽然通信量与基线持平,但新增的分片更新和 all-gather 同步都有额外延迟;ZeRO-3 更是直接多了 50% 通信量。省下来的显存如果用于增大 batch,可以提升吞吐,但通信开销会部分抵消收益。实际工程里经常要调优 batch、梯度累积步数和网络配置来找到吞吐最优解。

为何常见:人容易把“资源占用下降”直接等同于“性能提升”,忽略了分布式训练里通信常常是新的瓶颈。

面试题

Q1. 混合精度(FP16 + FP32 Adam)训练一个 7.5B 参数模型,单卡全量训练状态约需多少显存?

单选题 · easy

  • A.16GB
  • B.60GB
  • C.90GB
  • D.120GB← 正确答案

答案:D。基于 16ψ 公式,ψ=7.5B 时 16×7.5=120GB。其中优化器状态 12ψ=90GB,参数和梯度各 15GB。A 是把 16 字节误当 16GB,C 只是优化器状态那一份。

Q2. ZeRO-1 主要切分的是哪一部分训练状态?

单选题 · easy

  • A.模型参数副本
  • B.反向传播梯度
  • C.Adam 优化器状态← 正确答案
  • D.中间激活张量

答案:C。ZeRO-1 只切分最重的 Adam 优化器状态(12ψ),参数和梯度仍每卡全量。切梯度和切参数分别属于 ZeRO-2 和 ZeRO-3。

Q3. ZeRO-2 相比 ZeRO-1 额外切分了什么?

单选题 · easy

  • A.模型参数副本
  • B.反向传播梯度← 正确答案
  • C.Adam 优化器状态
  • D.训练样本数据

答案:B。ZeRO-2 在优化器状态基础上,把梯度也分区存储,用完即释放。参数切分是 ZeRO-3 做的事,训练样本数据从来不属于切分对象。

Q4. 64 卡训练 7.5B 模型,ZeRO-2 每卡显存约为多少?

单选题 · mid

  • A.约 30GB
  • B.约 17GB← 正确答案
  • C.约 8GB
  • D.约 2GB

答案:B。ZeRO-2 公式 2ψ+14ψ/N = 15 + 105/64 ≈ 16.6GB。A 是 ZeRO-1 的水平,D 是 ZeRO-3 的水平,C 没有对应任何标准档位。

Q5. ZeRO-3 在计算某层前向时,需要把分散在各卡上的该层参数收集齐全,这个操作叫什么?

单选题 · mid

  • A.Reduce-Scatter
  • B.All-Gather← 正确答案
  • C.All-Reduce
  • D.Broadcast

答案:B。参数是分片存储在各卡上的,计算前需要用 All-Gather 把所有人手里的零件拼成完整权重。Reduce-Scatter 用于梯度平均后分片,All-Reduce 是基线 DP 的整段梯度同步操作。

Q6. 关于 ZeRO-3 相比 ZeRO-2 的正确说法有哪些?

多选题 · mid

  • A.参数也被分区存储← 正确答案
  • B.前向反向都要通信← 正确答案
  • C.通信量显著增加← 正确答案
  • D.激活值不再占用显存

答案:ABC。ZeRO-3 把参数也切分了,平时不保有全量权重,前向和反向都要 All-Gather 参数,通信量约为基线 1.5 倍。但激活值不在切分范围内,D 说法错误。

Q7. 根据 DeepSpeed 论文,ZeRO-3 的总通信量约为基线数据并行的多少倍?

单选题 · hard

  • A.约 0.5 倍
  • B.约 1.5 倍← 正确答案
  • C.约 2.5 倍
  • D.约 3.0 倍

答案:B。基线 DP 每步通信约 2ψ(梯度 all-reduce),ZeRO-1/2 保持 2ψ 不变;ZeRO-3 额外增加参数 all-gather 通信,总通信量约为 1.5×基线。这是论文中的经典结论,也是选型时判断是否用 ZeRO-3 的关键依据。

Q8. 关于 ZeRO-1/2 通信量与基线数据并行的关系,正确的说法是?

单选题 · mid

  • A.与基线处于同一量级← 正确答案
  • B.通信量降低到一半
  • C.通信量直接翻倍
  • D.降低到原来四分之一

答案:A。ZeRO-1/2 把梯度 all-reduce 拆成 reduce-scatter 和 all-gather,总通信量仍约 2ψ,与基线持平。这是 ZeRO-1/2 性价比高的核心原因:显存省了,通信账单没涨。

Q9. 下列哪些技术可以和 ZeRO 组合使用以进一步降低显存?

多选题 · hard

  • A.激活检查点降激活← 正确答案
  • B.参数卸载到 CPU← 正确答案
  • C.梯度累积省显存← 正确答案
  • D.关闭混合精度训练

答案:ABC。激活检查点用重计算换激活显存,offload 把优化器状态/参数挪到 CPU,梯度累积通过分步更新降低峰值。混合精度是 ZeRO 显存估算的前提,关闭它会彻底改变公式,不是组合手段。

Q10. 实际训练 100B 以上模型时,关于 ZeRO-3 的说法正确的有?

多选题 · extreme

  • A.网络带宽必须充足← 正确答案
  • B.激活显存仍需关注← 正确答案
  • C.参数分区不再重要
  • D.通信开销可以忽略

答案:AB。ZeRO-3 的 1.5 倍通信依赖高速网络(如 IB)才能保证吞吐;激活值不参与切分,长序列下仍是显存杀手。参数分区是 ZeRO-3 的核心,通信开销是它的主要代价,C 和 D 表述相反。