ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

27届大模型面试准备(十七):分布式训练全攻略——数据/流水/张量并行、DeepSpeed ZeRO、FSDP、Megatron

2026/8/7 16:50:12 拓冰建站 浏览量
27届大模型面试准备(十七):分布式训练全攻略——数据/流水/张量并行、DeepSpeed ZeRO、FSDP、Megatron

27届大模型面试准备(十七):分布式训练全攻略——数据/流水/张量并行、DeepSpeed ZeRO、FSDP、Megatron

前两篇讲完了"推理怎么快"(A15)和"对齐怎么做"(A16),这一篇回到最底层——怎么把一个数十亿到数万亿参数的模型真正训起来。单张卡装不下、算不动,就必须分布式。覆盖三大并行策略(数据/流水线/张量)+ 显存优化(ZeRO、激活重算、混合精度)+ 三套主流框架(DeepSpeed / FSDP / Megatron-LM)的取舍。每节给:原理 → 图解 → 代码片段 → 面试速答 + 高频追问。配合 A18(LoRA/PEFT 省显存)一起看,刚好从"大训练"走到"小微调"。


一、为什么必须分布式:一张卡装不下一个模型

一个 7B 模型,仅权重(FP16)就约 14 GB;训练时还要存优化器状态(Adam 的 momentum+var 是参数的 2 倍 FP32≈4 倍参数量)、梯度、激活值。粗略估算训练显存:

训练显存 ≈ 参数×2(FP16) + 参数×4(优化器 FP32 状态) + 参数×2(梯度) + 激活 = 参数 × 8 + 激活 7B 模型: 7e9 × 8 Bytes ≈ 56 GB ← 单张 80G A100 也吃紧,且还没算激活 175B 模型: 175e9 × 8 ≈ 1.4 TB ← 必须用成百上千张卡切分

结论:模型要么"切参数"(模型并行),要么"切数据"(数据并行),要么两者叠加。

并行的总思路 ┌──────────────┬──────────────┬──────────────┐ │ 数据并行 DP │ 流水线并行 PP │ 张量并行 TP │ │ 复制模型,切样本│ 切层到不同卡 │ 单层内切矩阵 │ └──────────────┴──────────────┴──────────────┘ 组合 => 3D 并行(DP×PP×TP)

二、数据并行(Data Parallelism, DP)

最直觉:每张卡持有完整模型副本,喂不同的数据分片,各自算梯度,然后全规约(all-reduce)求平均再同步更新。

GPU0: 模型副本 + 数据A ─┐ GPU1: 模型副本 + 数据B ─┤→ all-reduce(梯度) → 同步更新每卡的模型 GPU2: 模型副本 + 数据C ─┤ GPU3: 模型副本 + 数据D ─┘

优点:实现简单、通信量小(只在每步同步梯度)。缺点:每张卡都要存完整模型 + 完整优化器状态,显存不节省,模型一大就爆。

PyTorch 原生 DDP(DistributedDataParallel)最小骨架:

importtorch.distributedasdistfromtorch.nn.parallelimportDistributedDataParallelasDDPdist.init_process_group("nccl")# 初始化通信后端rank=dist.get_rank();world=dist.get_world_size()sampler=DistributedSampler(dataset,num_replicas=world,rank=rank)loader=DataLoader(dataset,sampler=sampler,batch_size=8)model=DDP(model.cuda(),device_ids=[rank])forx,yinloader:loss=model(x,y).lossloss.backward();optimizer.step();optimizer.zero_grad()

面试速答:DP 为什么不能省显存?因为它复制的是"整个模型 + 优化器状态",每卡独立存一份,参数没被切分,只是数据被切分了。

高频追问
1. DP 和 DDP 区别?DP 是单进程多线程、GIL 受限、已淘汰;DDP 是多进程、NCCL 通信、主流。
2. all-reduce 的通信瓶颈?梯度总量 = 参数量×2 字节,卡多时成瓶颈,引出梯度压缩/通信计算重叠。


三、流水线并行(Pipeline Parallelism, PP):按层切

把模型的不同层分到不同卡上,数据像流水线一样流过:

GPU0: 第 1~4 层 ──▶ GPU1: 第 5~8 层 ──▶ GPU2: 第 9~12 层 ──▶ GPU3: 第 13~16 层 输入 中间激活 中间激活 输出

朴素实现有"气泡"(bubble):GPU0 算完第一批要等后面全跑完才能接第二批,算力空转。解决方案是微批次(micro-batch)+ 调度

GPipe(前向全跑完再反向) 1F1B(一次前向一次反向交错) t: F0 F1 F2 F3 B3 B2 B1 B0 F0 F1 F2 F3 B3 B2 B1 B0 ← 仍有大气泡 1F1B 改进: F0 F1 F2 B0 F3 B1 ... 气泡明显缩小

PyTorch 用torch.distributed.pipeline.sync.Pipe或手动rpc;主流是结合 DeepSpeed/Megatron 的 1F1B 调度。

面试速答:PP 的气泡是什么、怎么消?气泡是流水线空闲等待。用 micro-batch 把大 batch 拆小、用 1F1B(一次前向接一次反向)调度,让各卡尽早开始反向,填充空闲。


四、张量并行(Tensor Parallelism, TP):层内切矩阵

当单层都装不下一层(如 175B 的某一层权重很大),要在单层内部把权重矩阵切到多卡,配合矩阵分块乘法。以 Megatron 的列式/行式切分为例:

Y = X · [W1 W2] # 一个线性层权重按列切成两半 GPU0 算 X·W1 ┐ GPU1 算 X·W2 ┴─▶ all-reduce 拼接 → 下一层 对 GELU/Softmax 等用行式切分,使激活不需要立即通信

TP 通信极频繁(每层都要 all-reduce),所以必须放在同一节点内(NVLink 高速互联),跨节点用 TP 会慢死。

面试速答:TP 和 PP 怎么选?TP 通信密、要高带宽域内(同机 NVLink);PP 通信稀、可跨节点。实际训练常 PP 跨节点、TP 在节点内,再加 DP 做数据切分 → 3D 并行。


五、显存优化的三把斧:ZeRO、重算、混合精度

5.1 ZeRO(Zero Redundancy Optimizer,DeepSpeed)

DP 每张卡都存完整优化器状态是浪费。ZeRO 把优化器状态/梯度/参数分片到各卡,用时再 gather:

阶段切分对象显存节省
ZeRO-1优化器状态约 4×
ZeRO-2+ 梯度约 8×
ZeRO-3+ 参数接近线性(与卡数成正比)

DeepSpeed 配置:

{"zero_optimization":{"stage":3,"offload_optimizer":{"device":"cpu"},// 把优化器状态卸载到 CPU,进一步省显存"overlap_comm":true}}

5.2 激活重算(Activation Recomputation / Gradient Checkpointing)

正常要存所有中间激活算梯度,显存大。重算策略:前向不存激活,反向时重新算一遍。用约 30% 额外算力换数倍显存节省:

fromtorch.utils.checkpointimportcheckpointdefforward(self,x):returncheckpoint(self.block,x)# 反向时重算该 block 的激活

5.3 混合精度(AMP)

用 FP16/BF16 存激活和计算,FP32 存主权重和梯度做更新,既快又稳(BF16 动态范围大,不易溢出,是训练首选)。

fromtorch.cuda.ampimportautocast,GradScalerwithautocast(dtype=torch.bfloat16):loss=model(x).lossloss.backward();optimizer.step()

六、三套框架怎么选

框架核心能力适合场景一句话
DeepSpeedZeRO 系列、CPU/NVMe offload、易用中大模型、显存紧张"省显存王者",单卡也能训大模型的功臣
FSDPPyTorch 原生全分片(类 ZeRO-3)想用纯 PyTorch 生态DDP 的精神续作,原生、轻量
Megatron-LMTP+PP 极致 3D 并行、超大规模千亿级以上、TPU/GPU 集群"超大规模专用",和 DeepSpeed 常组合

FSDP 最小骨架:

fromtorch.distributed.fsdpimportFSDP,MixedPrecisionmodel=FSDP(model,mixed_precision=MixedPrecision(param_dtype=torch.bfloat16),sharding_strategy="FULL_SHARD")# 等价于 ZeRO-3

面试速答:DeepSpeed 和 FSDP 怎么选?偏好纯 PyTorch、要轻量用 FSDP;要 offload、ZeRO 调参自由度、丰富功能用 DeepSpeed;超大模型常 Megatron(TP/PP) + DeepSpeed(ZeRO) 组合。


七、面试速答 + 高频追问清单(汇总)

速答 TOP 8:
1. 单卡装不下 → 必须并行;显存 = 参数×8 + 激活。
2. DP 切数据、PP 切层、TP 切矩阵。
3. PP 气泡用 micro-batch + 1F1B 消。
4. TP 通信密,放同机 NVLink 内。
5. ZeRO 分片优化器/梯度/参数,stage3 ≈ 线性省显存。
6. 激活重算用算力换显存。
7. BF16 训练优先(动态范围大)。
8. 3D 并行 = DP × PP × TP。

追问清单:
- 3D 并行里通信量最大的是哪维?如何排布到硬件拓扑?
- ZeRO-offload 把状态放 CPU,通信瓶颈在哪?
- TP 的 all-reduce 为什么每层都要?
- 混合精度下主权重为何保持 FP32?
- 千亿模型的实际并行配置一般怎么定(如 8 机 64 卡)?


八、下一篇预告

分布式训练讲完"怎么把大模型训起来",下一篇(A18)讲LoRA / QLoRA / PEPF 省显存微调全家桶——当你不想动全量参数、只想低成本适配下游任务时的标准做法。评论区告诉我你想先听哪个方向。