图 1:ZeRO 三级阶梯,每上一级多切一种状态。
先说明属性:这是一篇经典题解析,题目出自本地历史面试资料整理,与任何公司的当前招聘无关。「ZeRO 三个阶段各切什么」是大模型训练方向的高频考点,答案本身一句话能背完,但面试官真正想听的是:为什么这些状态值得切,以及切了之后通信上付出了什么。
先算基线:数据并行的显存到底浪费在哪。
普通数据并行下,每张卡都完整保存一份模型状态。以混合精度训练加 Adam 优化器为例,设参数量为 N,每卡要扛的静态显存大约是 16N 字节:fp16 参数 2N、fp16 梯度 2N,再加上优化器状态 12N——Adam 要存 fp32 主参数副本 4N、一阶动量 m 4N、二阶动量 v 4N。注意这个比例:优化器状态占 12N,是全部静态显存的四分之三,参数本体反而只是零头。
n 张卡就存了 n 份一模一样的 16N,这就是 ZeRO 眼中的「冗余」。2019 年的 ZeRO 论文(arXiv:1910.02054)把核心思想说得很直白:每张卡只保存模型状态的 1/n,全集群合起来恰好一份,省出来的显存用来装更大的模型。
Stage 1:先切最肥的优化器状态。
第一刀砍向占比最大的那块。Stage 1 把优化器状态(fp32 主参数、m、v)按卡均分,每张卡只负责更新自己那 1/n 参数对应的状态。梯度仍然 AllReduce 后全量保留,参数也仍然每卡全量。每卡静态显存从 16N 降到约 4N + 12N/n。论文的关键结论是:这一阶段的通信量与普通数据并行相同,等于白捡显存。
Stage 2:梯度也只留自己那份。
既然每张卡只更新 1/n 的参数,那它只需要这 1/n 参数对应的梯度。Stage 2 在反向传播中把梯度按归属切分:一张卡算出别人的梯度就直接规约掉,只保留自己负责的那一份。每卡静态显存降到约 2N + 14N/n,通信量依然与数据并行持平。到这一步,8 卡集群已经把 16N 摊到了约 4N 以内。
Stage 3:连参数本体也切了。
最激进的一刀:fp16 参数本身也按卡分片,每张卡只存 1/n。前向、反向算到某一层时,临时从其他卡把该层参数 AllGather 回来,用完即释放;下一层再重复这个动作。每卡静态显存降到 16N/n,卡越多单卡越省,模型规模可以随卡数近似线性扩展。代价是通信明显更频繁——参数要「边算边取」,论文给出的量级是通信量较基线增加约五成,本质是用带宽换显存。
用一段脚本把三阶段的账算清楚。
下面用 Node.js 22.15.0 实测(node zero.js),按论文示例取 N=7.5B、n=64:
function perGPU(N, n, stage) {
const param = 2 * N; // fp16 参数
const grad = 2 * N; // fp16 梯度
const optim = 4 * N + 4 * N + 4 * N; // fp32 主参数 + m + v
const base = param + grad + optim;
const s1 = param + grad + optim / n; // 只切优化器状态
const s2 = param + (grad + optim) / n; // 再切梯度
const s3 = (param + grad + optim) / n; // 参数也切
return [base, s1, s2, s3][stage];
}
const N = 7.5e9, n = 64, GB = 1024 ** 3;
for (const s of [0, 1, 2, 3])
console.log(`Stage ${s}: 每卡 ${(perGPU(N, n, s) / GB).toFixed(1)} GiB`);
实测输出:
Stage 0: 每卡 111.8 GiB
Stage 1: 每卡 29.2 GiB
Stage 2: 每卡 15.5 GiB
Stage 3: 每卡 1.7 GiB
64 卡时 Stage 3 把每卡静态显存压到基线的约 1/64,数字与论文的「随数据并行度线性下降」吻合。
图 2:三阶段对照矩阵,Stage 越高切得越狠、通信越勤。
答题时把「怎么选」补上才是完整答案。
工程上的取舍很直接:Stage 1、2 通信量不增,属于稳赚,大多数场景够用;只有单卡实在放不下参数本体时才上 Stage 3,用通信换规模。如果显存还是不够,DeepSpeed 还提供了把状态继续下放到 CPU 内存甚至 NVMe 的 offload 路线(ZeRO-Offload / ZeRO-Infinity),那是「内存补显存」的另一层兜底。
回到面试现场,建议的结构是:先摆基线账 16N 并指出优化器状态占四分之三,再按「优化器状态 → 梯度 → 参数」的顺序讲三阶段各自切什么、每卡剩多少,最后主动补一句通信代价与选型原则。只背「Stage 1 切优化器、Stage 2 切梯度、Stage 3 切参数」是及格线;讲清「为什么先切优化器状态」和「Stage 3 的参数是边算边取的」才是加分项。你在实际训练里开到过 Stage 几?通信开销有没有成为过瓶颈?欢迎聊聊。