4、ZeRO系列技术演进:ZeRO-1/2/3原理、分片策略、通信开销分析、与数据并行/模型并行的关系

ZeRO(Zero Redundancy Optimizer)是微软 DeepSpeed 提出的显存优化技术族,其核心思想非常朴素:数据并行中每张卡都保存了完整的模型状态,而这些状态在训练过程中高度冗余。ZeRO 通过把优化器状态、梯度、参数按数据并行度切分到各卡,让每张卡只保留 1/N 的模型状态,从而在不改变计算语义的前提下大幅降低单卡显存占用。ZeRO-1/2/3 分别对应切分粒度的逐级加深。

一、核心原理:三块显存与三级分片

训练一个参数量为 Ψ 的模型,混合精度 Adam 训练时每卡显存主要由三部分构成:优化器状态(fp32 动量、方差、fp32 主权重,约 12Ψ 字节)、梯度(fp16,约 2Ψ 字节)、参数(fp16,约 2Ψ 字节)。ZeRO 的三级分片正是按这个顺序逐层切开:

  • ZeRO-1(Pos):只切分优化器状态,梯度与参数仍全量保留。显存从 16Ψ 降到约 4Ψ + 12Ψ/N。
  • ZeRO-2(Pos+g):在 ZeRO-1 基础上再切分梯度,显存降到约 2Ψ + 14Ψ/N。
  • ZeRO-3(Pos+g+p):进一步切分参数,显存降到约 16Ψ/N,接近线性扩展。

下图展示了三级分片在单卡上的显存构成变化,以及每级新增的通信环节:

ZeRO-1 / 2 / 3 单卡显存构成与通信环节 ZeRO-1 优化器状态 12Ψ/N 梯度 2Ψ(全量) 参数 2Ψ(全量) 通信:All-Gather 优化器状态 ZeRO-2 优化器状态 12Ψ/N 梯度 2Ψ/N 参数 2Ψ(全量) 通信:Reduce-Scatter 梯度 ZeRO-3 优化器状态 12Ψ/N 梯度 2Ψ/N 参数 2Ψ/N 通信:All-Gather 参数(前向/反向) 单卡显存随分片级别下降趋势 基线 DP:16Ψ ZeRO-1:4Ψ + 12Ψ/N ZeRO-2:2Ψ + 14Ψ/N ZeRO-3:16Ψ/N

二、分片策略与通信开销分析

分片越深,显存越省,但通信量也越大。理解通信开销的关键是区分通信量(Volume)与通信次数(Frequency)。ZeRO-1 只在优化器步做一次 All-Gather,通信量与基线 DP 相当;ZeRO-2 把梯度规约改为 Reduce-Scatter,通信量不变但省了显存;ZeRO-3 则在前向和反向中反复 All-Gather 参数,通信量约为 ZeRO-2 的 1.5 倍。

级别 切分对象 单卡显存 相对通信量 适用场景
ZeRO-1 优化器状态 4Ψ + 12Ψ/N 1.0× 显存略紧,通信敏感
ZeRO-2 优化器状态 + 梯度 2Ψ + 14Ψ/N 1.0× 最常用,性价比最高
ZeRO-3 优化器状态 + 梯度 + 参数 16Ψ/N 约 1.5× 超大模型,显存极限
经验法则:优先尝试 ZeRO-2。只有当 ZeRO-2 仍 OOM,或模型参数量超过单卡容量数倍时,才升级到 ZeRO-3。ZeRO-3 的通信放大在低带宽集群上可能抵消其显存收益。

三、与数据并行、模型并行的关系

ZeRO 本质上是数据并行的显存优化增强,而不是替代数据并行。它保留了 DP 的计算图与梯度语义,只是把冗余状态切片。与模型并行(TP/PP)的关系则是互补:

  • 与张量并行(TP):TP 切分单层内的矩阵运算,通信频繁且要求高带宽(通常限节点内 NVLink)。ZeRO-3 切分的是跨层的参数副本,通信可跨节点。两者可叠加,形成 TP+ZeRO-3 的 3D 并行。
  • 与流水并行(PP):PP 按层切分到不同设备,天然降低单卡参数。ZeRO-1/2 可与 PP 无缝组合,因为 PP 不改变每层内的 DP 冗余结构。
  • 与纯 DP 的区别:纯 DP 每卡显存随模型线性增长;ZeRO-3 下每卡显存随 DP 度 N 近似线性下降,使 DP 也能训练千亿参数模型。

四、实操配置与常见误区

在 DeepSpeed 中,ZeRO 级别通过 JSON 配置的 zero_optimization.stage 指定:

{
  "train_batch_size": 64,
  "zero_optimization": {
    "stage": 2,
    "offload_optimizer": {
      "device": "cpu",
      "pin_memory": true
    },
    "allgather_partitions": true,
    "overlap_comm": true,
    "reduce_scatter": true,
    "contiguous_gradients": true
  },
  "fp16": { "enabled": true }
}
常见误区:① 认为 ZeRO-3 一定比 ZeRO-2 快——实际上 ZeRO-3 通信更多,在带宽不足时反而更慢;② 开启 offload 后忘记 pin_memory,导致 CPU-GPU 拷贝成为瓶颈;③ 把 ZeRO 与 TP 混用时未调整 tensor_parallel 的 world size,造成分片维度冲突。

复盘来看,ZeRO 的演进路线是一条清晰的“用通信换显存”的曲线:ZeRO-1 几乎零额外通信代价,ZeRO-2 是当前工业界默认选择,ZeRO-3 则是显存极限下的最后手段。理解每一级切了什么、多付了什么通信,才能在真实集群带宽与模型规模之间做出正确取舍。