ZeRO 的全称是 Zero Redundancy Optimizer,核心思想是:在数据并行的基础上,把原本每张卡都重复保存的模型状态切分开,从而消除冗余、降低单卡显存占用。
在标准数据并行中,每张卡都保存一份完整的:
这三部分在所有卡上完全重复,冗余度极高。ZeRO 就是把这三部分依次切分到不同卡上,对应三个阶段:
切得越彻底,单卡显存占用越低,但通信开销也越大。
假设模型有 $\Psi$ 个参数,使用 Adam 优化器,混合精度训练。
标准数据并行下,每张卡需要保存:
合计每张卡约 $16\Psi$ 字节。如果模型有 10B 参数,每张卡光模型状态就要 160GB,单卡根本放不下。
ZeRO 要解决的就是这种冗余。
Stage 1 只切分优化器状态,包括:
假设有 $N$ 张卡,那么每张卡只保存 $1/N$ 的优化器状态。
每张卡显存从约 $16\Psi$ 降到:
当 $N$ 很大时,优化器状态占用大幅下降,每张卡显存趋近于 $4\Psi$。
Stage 1 的通信模式和标准数据并行基本一致:
所以 Stage 1 通信量增加不多,主要是参数广播。
Stage 2 在 Stage 1 基础上,进一步切分梯度。
每张卡只保存自己负责的那部分梯度,而不是完整梯度。
每张卡显存从约 $16\Psi$ 降到:
当 $N$ 很大时,每张卡显存趋近于 $2\Psi$。
Stage 2 使用 Reduce-Scatter 代替 All-Reduce:
Reduce-Scatter 的通信量和 All-Reduce 相当,但每张卡只需要存一部分梯度,所以显存下降,通信量没有明显增加。
Stage 3 在 Stage 2 基础上,进一步切分模型参数。
每张卡只保存自己负责的那部分参数,而不是完整模型。
每张卡显存从约 $16\Psi$ 降到:
合计约 $16\Psi / N$。
当 $N$ 很大时,单卡显存占用可以下降接近 $N$ 倍,这就是 ZeRO-3 能显著降低单卡显存占用的原因。
因为每张卡只保存部分参数,所以在计算某一层时:
反向传播类似,也需要按层 All-Gather 参数。
Stage 3 的通信开销上升,主要有三个原因:
第一,参数 All-Gather 次数多。 每一层前向都要 All-Gather 一次参数,反向还要再来一次。层数越多,All-Gather 次数越多。
第二,通信量随参数规模线性增长。 每层都要传输参数,整体通信量和模型参数量、层数都相关,远高于 Stage 1 和 Stage 2。
第三,计算和通信难以完全重叠。 虽然可以通过预取、流水线等方式重叠,但实现复杂,实际中很难完全隐藏通信。
所以 Stage 3 用通信换显存,显存降得最狠,但通信开销也最大。
可以用一个表来总结:
| 阶段 | 切分内容 | 每卡显存 | 通信特点 | 显存节省 |
|---|---|---|---|---|
| Stage 1 | 优化器状态 | 约 $4\Psi + 12\Psi/N$ | 与标准 DP 接近 | 中等 |
| Stage 2 | 优化器状态 + 梯度 | 约 $2\Psi + 14\Psi/N$ | 用 Reduce-Scatter 替代 All-Reduce | 较大 |
| Stage 3 | 优化器状态 + 梯度 + 参数 | 约 $16\Psi/N$ | 每层都要 All-Gather,通信量大 | 最大 |
省显存的原因:
通信开销上升的原因:
一句话总结:ZeRO-3 是用通信换显存,适合模型极大、显存极度紧张的场景。
这是一道很好的大模型训练系统面试题,适合考察候选人对显存优化和分布式通信的理解。它既能考察基础概念,也能延伸到工程权衡。如果候选人能把三个阶段的切分对象、显存变化、通信特点以及 ZeRO-3 的通信代价都讲清楚,基本可以判断其具备大模型分布式训练的扎实基础。
评论专区
评论加载中...登录后即可发表评论