想象你是市中心一家大饭店的后厨总管,今晚接到一笔史无前例的大单:两百桌客人同时点一锅要慢炖十二小时的佛跳墙。食材管够、灶台(GPU)也有几十口,可问题是,没有任何一口锅能单独装下这锅汤。这正是训练千亿参数大模型的日常。 于是你请来两位传奇大厨。第一位叫 Megatron,成名绝技是“分刀”:把一整头牛按部位切开,十几位帮厨同时各烧一块,出锅再拼成完整大菜,这就是张量并行与流水线并行。第二位叫 DeepSpeed,成名绝技是“分料”:他重新设计了后厨的物资分发逻辑(ZeRO 技术),让每位帮厨只背一小份食材和调料,谁需要谁去取,再没人傻乎乎地扛着整头牛跑来跑去。 单请其中一位都有致命短板:Megatron 刀法再好,帮厨们依然每人背着一整套调料箱;DeepSpeed 分料再精,却没法把一道菜拆成多条流水线同时开火。于是业界的最优解诞生了——把两位大厨请进同一间厨房:Megatron 负责切菜摆盘,DeepSpeed 负责分料调度,这就是 Megatron 与 DeepSpeed 的组合方案。本文就带你走进这间“梦幻后厨”,看两位大厨如何握手、怎么分工、工单怎么写、闹矛盾时如何调解。

岗位关联

对 AI 从业者的价值:掌握这套组合方案,你就能像总厨一样把几十上百张 GPU 排布得井井有条,从容驾驭千亿参数大模型训练,这是分布式训练领域最值钱的工程能力。

目录
  1. 可视化演示
  2. 框架认知:两位大厨的成名绝技
  3. 集成方式:让两位大厨同台合作
  4. 并行策略:后厨的分工体系
  5. 配置编写:菜单工单怎么写
  6. 内存优化:帮厨的负重管理
  7. 兼容问题:大厨之间的摩擦
  8. 训练流程:后厨开火的日常
  9. 实际应用:点单选型的智慧
  10. AI 应用场景
  11. Python 演示
  12. 常见误区
  13. 面试题

可视化演示

展示3D并行GPU拓扑(TP×PP×DP)、ZeRO各阶段显存切分及框架集成工作流,支持模式切换与并行度调节。

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

3D并行GPU拓扑结构 蓝色组为张量并行(TP)切分同一层权重,节点内NVLink高速通信 紫色链为流水线并行(PP)切分层间,数据流跨节点传递 总GPU = TP × PP × DP 3D并行将模型切分到三个维度,充分利用节点内带宽和跨节点互联

框架认知:两位大厨的成名绝技

普通后厨接大单的做法是:每口锅都配齐一整份食材和调料,八口锅同时开工——这就是“纯数据并行”。问题在于每口锅都要背一头整牛的食材,冰箱(显存)立刻爆满。两位传奇大厨正是冲着这个痛点来的。

NVIDIA 的 Megatron(Megatron-LM)最擅长“分刀”,也就是把一个巨型 Transformer 模型按层内矩阵切开,让多位帮厨同时各算一块再拼起来——学名叫张量并行(Tensor Parallelism);按层数切成前后接力段,则叫流水线并行(Pipeline Parallelism)。微软的 DeepSpeed 最擅长“分料”,它的 ZeRO 技术不再让每位帮厨背全份调料,而是把梯度和优化器状态这类“调料”按人头分开,谁要用谁去取。

Megatron 的分刀是高强度通信的体力活:每算一层,参与切分的卡之间就要做一次数据汇聚(all-reduce)。DeepSpeed 的 ZeRO 则分三档循序渐进:ZeRO-1 只分优化器状态,ZeRO-2 再把梯度分掉,ZeRO-3 连参数都按需取用。一个管“切”,一个管“省”,天生互补。先看看模型本身有多重:

算下来,一个 1750 亿参数的模型光权重就有约 326GB,再算上梯度和优化器状态,任何一个帮厨单肩都扛不动——这就是为什么“分刀”和“分料”必须同时上阵。

模型体积(GB)=Ψ×2 字节230\text{模型体积(GB)} = \dfrac{\Psi \times 2\ \text{字节}}{2^{30}}
这条公式算的是模型在 fp16 半精度下的“裸重”,不包含梯度与优化器。
  1. Ψ参数量:模型拥有的参数个数,千亿模型约 $1.75 \times 10^{11}$。
    Ψ=1.75×1011\Psi = 1.75 \times 10^{11}
  2. ×2 字节fp16 半精度下每个参数占 2 字节。
    2 字节=16 bit2\ \text{字节} = 16\ \text{bit}
  3. ÷2³⁰ 换算把字节数换算成 GB。
    230=1,073,741,8242^{30} = 1{,}073{,}741{,}824

集成方式:让两位大厨同台合作

现实中把两位大师请进同一间厨房,并不需要你重写菜谱。经典的组合套路是:以 Megatron 为主干,它负责模型定义与并行分组(刀法归它管);DeepSpeed 以“外聘总管”的身份接管训练循环,文件改动集中在少量代码与一份配置上。

集成的关键动作是调用 deepspeed.initialize:把 Megatron 构建好的模型以及它的模型并行工具 mpu(model parallel utilities)一起交进去,DeepSpeed 会在后台重新组织进程组,并返回一个包了 ZeRO 能力的 model_engine。之后用 model_engine.backward 和 model_engine.step 替代 PyTorch 原生写法即可。

这里有一个新手最容易晕的点:Megatron 负责刀法的通信组(TP/PP 组),DeepSpeed 负责分料的通信组(DP 组),两套分组必须严格对齐,否则就会“菜切好了但料送错人”。数据并行度由总卡数÷(TP×PP) 决定,于是全局 batch 藏着一个连环乘法:

集成完成后的后厨风貌是:Megatron 还是那位主厨,DeepSpeed 成了帮厨总管,菜谱不动、锅不动,只是“谁来切、谁来存、谁传菜”被安排得明明白白。

Bglobal=Bmicro×Gaccum×DsizeB_{\text{global}} = B_{\text{micro}} \times G_{\text{accum}} \times D_{\text{size}}
一个“批大小”参数背后是三个数的乘法,改配置时务必三处一起看。
  1. B_global全局 batch:所有卡每更新一次消耗的样本总数。
    BglobalB_{\text{global}}
  2. B_micro每卡微批:单张 GPU 一次前向送入的样本数。
    BmicroB_{\text{micro}}
  3. G_accum梯度累积步数:攒几次微批梯度后才更新一次参数。
    GaccumG_{\text{accum}}
  4. D_size数据并行度:总卡数除以 TP×PP,代表“同时做几桌一样的菜”。
    Dsize=NGPUTsize×PsizeD_{\text{size}} = \dfrac{N_{\text{GPU}}}{T_{\text{size}} \times P_{\text{size}}}

并行策略:后厨的分工体系

梦幻后厨能接两百桌大单,靠的是三套分工同时运转。第一套是张量并行(T):把同一个 Transformer 层的权重矩阵沿列切开,四张卡各持一块,前向时互相传递中间结果——好比四人合切一头牛,各切部位最后拼盘。第二套是流水线并行(P):模型按层数切段,第一段算完传给第二段——好比佛跳墙的接力炖煮工序。

第三套是数据并行(D):每个“分刀+流水线”的副本完整跑一份训练数据,梯度定期汇合——好比四桌客人点同样的菜,四组厨师按同一菜谱并行开火。在组合方案里,D 同时也是 ZeRO 分料的分配基数:D 越大,每卡负重越小。

三种并行度之间有一个铁一般的乘法关系,所有 GPU 数必须恰好等于三个数的乘积,不能多也不能少:

有了这把“乘法的尺子”,后厨排班就有据可依:想加桌数就加 D,想加菜量就加 T 或 P,但总数必须凑齐,否则就会有人闲着、有人累趴。

NGPU=Tsize×Psize×DsizeN_{\text{GPU}} = T_{\text{size}} \times P_{\text{size}} \times D_{\text{size}}
总卡数固定时,三者此消彼长:TP 加大会增加通信,PP 加大会增加气泡,DP 变小则 ZeRO 失效。
  1. N_GPU总卡数:手头能用的 GPU 总数,是排班的硬约束。
    NGPU=T×P×DN_{\text{GPU}} = T \times P \times D
  2. T_size张量并行度:通信最频繁,尽量不跨机器节点。
    Tsize∈{1,2,4,8}T_{\text{size}} \in \{1, 2, 4, 8\}
  3. P_size流水线并行度:按层数切段,适合跨节点省带宽。
    Psize=总层数每段层数P_{\text{size}} = \dfrac{\text{总层数}}{\text{每段层数}}
  4. D_size数据并行度:由除法得到,专供 ZeRO 分料使用。
    Dsize=NGPUTsize×PsizeD_{\text{size}} = \dfrac{N_{\text{GPU}}}{T_{\text{size}} \times P_{\text{size}}}

配置编写:菜单工单怎么写

两位大厨同台后,后厨靠一张工单统一步调——这张工单就是 ds_config.json。工单里最重要的三类参数:一是 batch 三件套(train_batch_size、train_micro_batch_size_per_gpu、gradient_accumulation_steps),三者遵守上一节的乘法关系;二是 ZeRO 分料开关(zero_optimization.stage)与 CPU offload;三是训练策略(fp16、梯度裁剪 gradient_clipping、学习率调度器)。

学习率调度是工单里最容易抄错的部分。DeepSpeed 内置的 WarmupCosineLR 分两段走:前 $T_w$ 步从 0 线性升到峰值,之后按余弦曲线衰减到最小值。早段“小火预热”是为了避免开局大火把菜烧糊,中后段“文火收汁”则让模型稳定收敛:

工单写得好,前厅后厨节奏一致;写不好,轻则显存溢出,重则模型不收敛——两位大厨的脾气,全靠一纸工单来哄。

ηt={ηmax⁡⋅tTw,0≤t<Twηmin⁡+12(ηmax⁡−ηmin⁡)(1+cos⁡π(t−Tw)T−Tw),Tw≤t≤T\eta_t =\begin{cases}\eta_{\max} \cdot \dfrac{t}{T_w}, & 0 \le t < T_w \\[10pt]\eta_{\min} + \dfrac{1}{2}(\eta_{\max} - \eta_{\min})\left(1 + \cos \dfrac{\pi (t - T_w)}{T - T_w}\right), & T_w \le t \le T\end{cases}
$T_w$ 是预热步数,$T$ 是总步数;预热段线性爬升,之后余弦衰减。
  1. 预热段前 $T_w$ 步学习率随步数线性增长。
    ηt=ηmax⁡×tTw\eta_t = \eta_{\max} \times \frac{t}{T_w}
  2. 余弦主体预热结束后从峰值按余弦曲线向最小值衰减。
    ηt=ηmin⁡+12(ηmax⁡−ηmin⁡)(1+cos⁡π(t−Tw)T−Tw)\eta_t = \eta_{\min} + \frac{1}{2}(\eta_{\max} - \eta_{\min})\left(1 + \cos \dfrac{\pi (t - T_w)}{T - T_w}\right)
  3. 预热步数通常设为总步数的 1%~5%,太小容易崩。
    Tw≈0.02×TT_w \approx 0.02 \times T
  4. 总步数由总训练 token 数除以全局 batch 得到。
    T=DtokensBglobalT = \frac{D_{\text{tokens}}}{B_{\text{global}}}

内存优化:帮厨的负重管理

后厨真正拥挤的不是灶台,而是帮厨的腰包(显存)。一个 130 亿参数的模型,纯数据并行下每张卡要背 16 份“单位重”的货:fp16 权重 2 份、fp16 梯度 2 份、Adam 优化器状态 12 份。而 Adam 状态占了大头,却恰恰是最容易被分掉的部分。

Megatron 的分刀先把模型重量除以 T(张量并行度);DeepSpeed 的分料再把梯度和优化器状态除以 D(数据并行度)。两者合力,每卡负重从 16 份骤降到约 2.25 份,这就是“显存算术”的魔力。组合下的每卡显存公式:

除 ZeRO 外,后厨还有三招减负:激活重计算(不存中间结果,反向时重算)、混合精度(fp16 计算 + fp32 主权重)、参数卸载(ZeRO-Offload 把优化器状态挪到 CPU 甚至硬盘)。负重轻了,同样的冰箱能冻的菜就多了——显存这个“硬通货”被两位大厨联手玩出了花。

Mper GPU=2ΨTsize+2ΨDsize+12ΨDsizeM_{\text{per GPU}} = \frac{2\Psi}{T_{\text{size}}} + \frac{2\Psi}{D_{\text{size}}} + \frac{12\Psi}{D_{\text{size}}}
三项分别是 fp16 模型、fp16 梯度、Adam 状态;T 来自 Megatron,D 来自 DeepSpeed。
  1. 模型项fp16 权重被张量并行切 T 份,每卡留 $1/T$。
    2ΨTsize\frac{2\Psi}{T_{\text{size}}}
  2. 梯度项ZeRO-2 起梯度按数据并行度 D 均分。
    2ΨDsize\frac{2\Psi}{D_{\text{size}}}
  3. 优化器状态项Adam 三份状态共 12Ψ,按 D 均分。
    12ΨDsize\frac{12\Psi}{D_{\text{size}}}
  4. 组合示例T=4、D=8 时,130 亿模型每卡约 35GB,80GB 卡轻松跑下。
    M=2×134+2×138+12×138≈35 GBM = \frac{2\times 13}{4} + \frac{2\times 13}{8} + \frac{12\times 13}{8} \approx 35\ \text{GB}

兼容问题:大厨之间的摩擦

两位大厨脾气都大,同台必有摩擦。最常见的一幕:DeepSpeed 的分料想连模型参数一起拆(ZeRO-3),Megatron 的分刀也正握着模型不放——两套拆分逻辑同时作用在参数上,就像两个人同时抢一把刀切同一块肉。

经典教训是 ZeRO-3 与张量并行不能无脑叠加:ZeRO-3 需要按需对参数做全收集(all-gather),张量并行又要对参数切分并高频汇聚,二者交织会产生海量集合通信,性能反而崩盘。官方推荐的组合是 ZeRO-1/2 + Megatron TP;要上 ZeRO-3 就别开 TP,或者依赖新版本框架的专门适配。同理,流水线只能用一套:Megatron 的 pipeline 与 DeepSpeed 的 pipeline engine 二选一。

另一个摩擦点是流水线气泡。流水线并行有先天空闲:上游炖着菜,下游只能干等。气泡占比随流水线段数增加而变大,公式如下:

理解了摩擦根源,调解方案就清晰了:要么别让两位抢同一把刀(ZeRO 选低档位配合 TP),要么给流水线多喂几批菜(加大 m)填满气泡——大厨之间没有真矛盾,只有没对齐的工单。

Bratio=Pstage−1m+Pstage−1B_{\text{ratio}} = \frac{P_{\text{stage}} - 1}{m + P_{\text{stage}} - 1}
$m$ 是每段每轮处理的微批数;微批越多,流水线越“满”,气泡越少。
  1. P_stage流水线段数:模型层被切成几段。
    PstageP_{\text{stage}}
  2. m微批数:每个流水段一轮推进几个微批。
    mm
  3. 比值含义段数多、微批少时气泡占比高,利用率跟着掉。
    段数↑, m↓⇒Bratio↑\text{段数} \uparrow,\ m \downarrow \Rightarrow B_{\text{ratio}} \uparrow

训练流程:后厨开火的日常

工单填好、分工排定,后厨正式开火。开火前要确认灶台(启动命令),开火后要紧盯火候(监控指标),打烊前要封存菜品(检查点),停电了要能快速恢复(断点续训)。

启动命令是老套路:deepspeed --num_gpus 64 pretrain_gpt.py 加上 --deepspeed_config ds_config.json,再叠一串并行参数,如 --tensor-model-parallel-size 4 --pipeline-model-parallel-size 2。开火后每天盯三样:吞吐(tokens/s)、损失曲线、梯度范数。想看一单生意多久出菜,可以算“总算力账”:

开火后的日常就是“盯火候、勤存档”。Megatron 存模型刀法的快照(模型权重),DeepSpeed 存优化器状态与 ZeRO 分片,两套检查点都要保存——恢复时才能无缝接上营业,不浪费已烧的柴火。

T训练=6×Ψ×DtokensNGPU×P单卡峰值×MFUT_{\text{训练}} = \frac{6 \times \Psi \times D_{\text{tokens}}}{N_{\text{GPU}} \times P_{\text{单卡峰值}} \times MFU}
分子是训练的总浮点运算量,分母是有效总算力;MFU 是算力利用率,通常只有 30%~50%。
  1. 6ΨD总运算量:前向+后向浮点运算的通用估算。
    Ctotal=6ΨDtokensC_{\text{total}} = 6 \Psi D_{\text{tokens}}
  2. 有效总算力卡数 × 单卡峰值 × 利用率。
    P有效=NGPU×P峰值×MFUP_{\text{有效}} = N_{\text{GPU}} \times P_{\text{峰值}} \times MFU
  3. 结果单位秒,除以 86400 得到天数。
    T天=CtotalP有效×86400T_{\text{天}} = \frac{C_{\text{total}}}{P_{\text{有效}} \times 86400}

实际应用:点单选型的智慧

不是所有餐厅都需要请两位大厨。家里开个小面馆(一两台机器),DeepSpeed ZeRO-Offload 一位就够;只有到“千亿大菜、几十口锅同时开火”的级别,才值得把两位都请上。选型铁律有三条:参数量决定要不要 Megatron(百亿以上考虑 TP/PP,千亿必上);卡数与单卡显存决定 ZeRO 档位(显存紧张就上 ZeRO-2/3,再加 offload);集群拓扑决定 T 的取值(TP 必须控制在单机内,跨机靠 PP)。

规模设计还有一个经验法则:训练 token 数约等于参数量的 20 倍,数据太少模型欠火候,数据太多浪费燃料:

梦幻后厨的终极智慧不是“想不想做”,而是“值不值得做”。小单请一位大厨,大单才开双厨联动——Megatron-DeepSpeed 组合就是专为“镇店大菜”而生的王牌阵容。

Dtokens=20×ΨD_{\text{tokens}} = 20 \times \Psi
这是“计算最优”的经验标尺,被多个百亿级模型验证过,可用来反推该准备多少数据。
  1. 20 倍常数在 70B~540B 规模上验证的经验值。
    D=20ΨD = 20\Psi
  2. 代入千亿模型1750 亿参数约需 3.5 万亿 token。
    D=20×1.75×1011=3.5×1012D = 20 \times 1.75 \times 10^{11} = 3.5 \times 10^{12}
  3. 反推训练时长把 D 代回上一节的 6ΨD 公式即可估算工期。
    T∝Ψ×DtokensT \propto \Psi \times D_{\text{tokens}}

AI 应用场景

千亿参数大模型从零预训练(以 BLOOM 176B 为例)

阶段:模型预训练

解决的问题:单框架都搞不定——纯 Megatron 负责切分但优化器显存仍吃紧,纯 DeepSpeed 省显存却缺乏张量/流水线并行能力。组合方案让 Megatron 提供分刀(张量/流水线并行),DeepSpeed 提供分料(ZeRO+工程化训练引擎),384 张 A100 也能稳定驾驭 1760 亿参数。

具体案例:2022 年 BigScience 项目使用微软开源的 Megatron-DeepSpeed 仓库,以约 3.5 万亿 token 完成 1760 亿参数模型 BLOOM 的训练,全程每卡显存峰值可控,验证了“双厨联动”跑千亿模型的可行性。

企业私有化百亿模型续训与微调

阶段:继续预训练 / 全参数微调

解决的问题:几十张 80GB 显卡,想把开源底座升级为行业模型。传统单卡训练直接 OOM;纯数据并行又因显存冗余无法扩大 batch。组合方案按“TP 限单机、PP 跨节点、DP 留足”的排班法,加上 ZeRO-2 与激活重计算,把显存压力压到单卡红线内。

具体案例:某金融公司用 32×A100 训练 130 亿参数行业模型,取 TP=8、PP=2、DP=2 并配合 ZeRO-2,每卡显存从估算的 194GB 降到 88GB 以内,配合 CPU offload 后顺利跑通 1000 亿金融语料续训,工期从预估的 60 天压到 35 天。

大模型训练集群算力评估与排期

阶段:方案设计与成本估算

解决的问题:老板问“1000 亿模型多久训完、要多少卡”,拍脑袋回答必然翻车。用 6ΨD 总算力公式结合 MFU≈40% 的实测系数,再叠加 Chinchilla 的 20× 数据法则,半小时就能给出靠谱的排期和数据准备量。

具体案例:某大模型创业公司在立项评审会上,用该估算方法给出“1750 亿模型、2000 张 A100、约 90 天”的预训练方案,与最终实际工期误差不到 15%,成功说服管理层批预算。

Python 演示

python32 行
"""Megatron-DeepSpeed 组合方案显存估算器依据 ZeRO 论文:每参数 16 字节 = fp16权重2 + fp16梯度2 + Adam状态12。"""  def memory_bytes(params, gpus, tp, pp, zero_stage):    """返回组合方案下每卡显存占用(GB)"""    dp = gpus // (tp * pp)          # 数据并行度由三乘关系除法得出    model = 2 * params / tp         # fp16 权重被 Megatron 张量并行切分    grad = 2 * params               # fp16 梯度    opt = 12 * params               # Adam 优化器状态(fp32 主权重+动量+方差)    if zero_stage >= 1:        opt = opt / dp              # ZeRO-1 起优化器状态按 DP 均分    if zero_stage >= 2:        grad = grad / dp            # ZeRO-2 起梯度按 DP 均分    if zero_stage >= 3:        model = model / dp          # ZeRO-3 连参数也按需均分    return (model + grad + opt) / (1024 ** 3)  def main():    params = 13 * 10 ** 9           # 130 亿参数模型    gpus = 32                       # 32 张 A100    print("TP  PP  DP | ZeRO | 每卡显存(GB)")    for tp, pp, zero in [(1, 1, 0), (8, 1, 2), (8, 2, 2), (8, 4, 2), (1, 1, 3)]:        dp = gpus // (tp * pp)        gb = memory_bytes(params, gpus, tp, pp, zero)        print(f" {tp}  {pp}  {dp:>2} | z={zero} | {gb:8.1f}")  if __name__ == "__main__":    main()
目的:复现正文第五节的显存公式,直观对比“纯 DP → 加 TP → 加 ZeRO”三种配置下每张卡的显存负担。
  1. dp = gpus // (tp * pp)数据并行度由总卡数除以 TP×PP 得出,这正是“三乘关系”的代码表达。
  2. model = 2 * params / tpfp16 权重被 Megatron 张量并行切 T 份。
  3. opt = 12 * paramsAdam 优化器状态占 12 字节/参数,是显存大头。
  4. if zero_stage >= 2: grad = grad / dpZeRO-2 起梯度按 DP 均分。
  5. if zero_stage >= 3: model = model / dpZeRO-3 连模型参数也按需均分。
  6. return (model + grad + opt) / (1024 ** 3)字节数除以 2³⁰ 换算成 GB。
  7. for tp, pp, zero in [(1, 1, 0), (8, 1, 2), (8, 2, 2), (8, 4, 2), (1, 1, 3)]遍历五种典型配置做对比实验。

常见误区

误区TP、PP、DP 全都开到最大,训练肯定最快,反正分工越细效率越高。

正解总卡数固定时三者此消彼长。TP 每次前向要做高频 all-reduce,通信极重;PP 有气泡开销;DP 太小则 ZeRO 分料失效。最佳实践是 TP 控制在单机内(4 或 8),PP 跨节点分段,DP 留足余量给 ZeRO。

为何常见:直觉上“分工越细越快”,忽略了卡间通信带宽这个隐形天花板。

误区ZeRO-3 拆参数 + Megatron 切参数,双重省显存,等于白赚一份内存。

正解两套机制都在往参数上下手,交织后每个 step 都要多次 all-gather 和 all-reduce,通信开销爆炸,实测性能反而下降。经典组合是 ZeRO-1/2 + Megatron TP;要上 ZeRO-3 就别开 TP,或依赖新版本框架的专门适配。

为何常见:两者都宣传“省显存”,初学者自然想叠加,看不到背后的通信代价。

误区配置文件里写 `train_batch_size=512`,那就是每张卡每次吃 512 个样本。

正解train_batch_size 是全局值,它等于每卡微批 × 梯度累积步数 × 数据并行度。同样写 512,DP=32 时每卡其实只吃 4 个样本;不搞清这点,学习率和 loss 曲线都会对不上。

为何常见:配置项只有一个数字,隐藏的乘法关系容易被忽略,抄作业时最容易踩。

误区DeepSpeed 就是做 ZeRO 的,接上它只为多塞点 batch,别的都是附赠品。

正解DeepSpeed 是一个完整的训练引擎,负责 deepspeed.initialize 之后的优化器、梯度裁剪、混合精度、学习率调度、检查点与断点续训,甚至通信压缩。在组合方案里它其实是“总管家”,ZeRO 只是它最出名的本事。

为何常见:宣传材料都聚焦“省显存”这个最大痛点,其他能力被光环掩盖。

误区组合方案一跑就崩,肯定是版本不兼容,升到最新版万事大吉。

正解大量报错(NCCL 超时、参数形状对不上)的根因是进程组没对齐:Megatron 的 mpu 与 DeepSpeed 的通信组必须使用同一套分布式初始化。版本要按官方文档锁配套版本,不是越新越好。

为何常见:错误信息深奥难懂,归因到“版本”最省事,但常常治标不治本。

面试题

Q1. Megatron 最出名的并行“刀法”是哪一项?

单选题 · easy

  • A.张量并行与流水线并行← 正确答案
  • B.纯 CPU 数据并行
  • C.显存自动迁移技术
  • D.分布式文件系统

答案:A。Megatron 的核心能力是张量并行(把模型层内切开)与流水线并行(按层切段),对应后厨的分刀。B 是普通的 CPU 训练,C、D 与模型并行无关。

Q2. DeepSpeed ZeRO 技术的主要优化目标是什么?

单选题 · easy

  • A.提升单卡算力
  • B.削减显存冗余← 正确答案
  • C.加速数据读取
  • D.简化模型结构

答案:B。ZeRO 通过把优化器状态、梯度乃至参数按 DP 均分,消除“每张卡都背全份”的显存冗余,相当于帮厨分料。它不改变模型结构,也不直接提升算力。

Q3. 共有 32 张 GPU,取 TP=4、PP=2,则数据并行度 DP 是多少?

单选题 · mid

  • A.2
  • B.4← 正确答案
  • C.8
  • D.16

答案:B。根据三乘关系 N=TP×PP×DP,DP=32÷(4×2)=4。DP 是 ZeRO 分料的基数,算错它,batch 和学习率都会跟着错。

Q4. 全局 batch=512、每卡微批=4、DP=32,梯度累积步数应为?

单选题 · mid

  • A.2
  • B.4← 正确答案
  • C.8
  • D.16

答案:B。由 B_global = B_micro × G_accum × D 得 G=512÷(4×32)=4。梯度累积就是“攒几次微批再更新一次”,攒少了显存爆,攒多了收敛慢。

Q5. 以下哪些属于 ds_config.json 中的常见配置项?

多选题 · mid

  • A.zero_optimization← 正确答案
  • B.gradient_clipping← 正确答案
  • C.scheduler 调度器← 正确答案
  • D.accuracy_topk

答案:ABC。zero_optimization 控制 ZeRO 档位,gradient_clipping 做梯度裁剪,scheduler 配置学习率调度,这三者都是 DeepSpeed 工单的常客。accuracy_topk 是评测代码里的指标,不属于训练配置。

Q6. 纯数据并行 + Adam 优化器(fp16 训练)下,每个参数共占多少字节显存?

单选题 · easy

  • A.2 字节
  • B.4 字节
  • C.16 字节← 正确答案
  • D.32 字节

答案:C。16 字节 = fp16 权重 2 + fp16 梯度 2 + Adam 状态 12(fp32 主权重、动量、方差各 4)。这也是“每卡背整牛”的由来,ZeRO 主要就是分掉这 12 字节的大头。

Q7. ZeRO-3 与 Megatron 张量并行同时开启的经典问题是什么?

单选题 · hard

  • A.参数被双重切分冲突← 正确答案
  • B.学习率自动归零
  • C.梯度消失严重
  • D.数据被重复采样

答案:A。ZeRO-3 按需收集参数,张量并行又把参数切分,两套机制同时作用在同一份权重上,造成海量集合通信,性能崩盘。经典做法是 ZeRO-1/2 配 TP,或 ZeRO-3 单独用。

Q8. 关于 Megatron-DeepSpeed 组合方案,说法正确的有哪些?

多选题 · mid

  • A.以 Megatron 为主干← 正确答案
  • B.DeepSpeed 接管训练← 正确答案
  • C.二者通信组需对齐← 正确答案
  • D.必须禁用数据并行

答案:ABC。组合以 Megatron 的模型与并行分组为主干,DeepSpeed 通过 initialize 接管训练循环,且两套进程组必须对齐。数据并行(DP)不仅不能禁用,还是 ZeRO 分料与全局 batch 计算的根基。

Q9. 用 6ΨD/(N×P×MFU) 估算训练时长时,MFU 通常取多少?

单选题 · hard

  • A.10% 以下
  • B.30%~50%← 正确答案
  • C.90% 以上
  • D.恰好 100%

答案:B。MFU 是算力利用率,实际训练中通信、气泡、显存搬运都会损耗算力,业界典型值在 30%~50%。按 100% 排期一定会延期,按 40% 估算最稳妥。

Q10. 关于流水线气泡公式 B=(P-1)/(m+P-1),以下说法正确的有哪些?

多选题 · extreme

  • A.段数 P 越大气泡越多← 正确答案
  • B.微批数 m 越大气泡越少← 正确答案
  • C.气泡可被完全消除
  • D.增大 m 需更多显存← 正确答案

答案:ABD。由公式可见 P 增大使比值变大,m 增大使比值变小;但气泡只能缓解不能消除,m 增大意味着同时驻留更多微批的激活,显存压力随之上升。这正是流水线并行“用显存换利用率”的权衡。