分布式微调:DDP、DeepSpeed 与 FSDP

单卡 07-01 显存优化 仍不够时,需要分布式微调。本篇从工程角度对比 DDP、DeepSpeed ZeRO、FSDP,说明与 SFTTrainer / LoRA 的组合方式;理论背景见 Math-04/20 §3

段末注释:DDP(Distributed Data Parallel,分布式数据并行)每卡持有一份完整模型,梯度 AllReduce 同步;FSDP(Fully Sharded Data Parallel,全分片数据并行)将参数/梯度/优化器状态分片到多卡。

系列索引:微调技术路线导读


一、何时需要多卡

场景 建议
7B LoRA SFT 多数单卡可训
7B 全参 SFT 多卡 ZeRO-3 / FSDP
13B+ LoRA 长 context 或多卡 DDP 提吞吐
70B QLoRA 多卡 + DeepSpeed

05-04 全参 vs PEFT:优先 PEFT,多卡常为吞吐而非唯一出路。


二、策略对比

策略 每卡模型 优化器/梯度 通信 典型用途
DDP 完整副本 完整 AllReduce 梯度 LoRA 多卡加速
ZeRO-1 完整 分片 中等 全参省 optimizer
ZeRO-2 完整 分片 + 梯度分片 较高 全参进一步省显存
ZeRO-3 分片 分片 大模型全参/QLoRA
FSDP 分片 分片 PyTorch 原生大模型

LoRA 微调:可训练参数少,DDP 往往足够(每卡完整基座 + 小 adapter)。
全参微调:ZeRO-2/3 或 FSDP。


三、DDP + SFTTrainer(LoRA 最常见)

acceleratetorchrun 启动:

1
accelerate launch --num_processes 4 train_sft.py

train_sft.py 内与普通单卡相同构造 SFTTrainerTrainingArguments 中:

1
2
3
4
5
6
SFTConfig(
per_device_train_batch_size=2,
gradient_accumulation_steps=4,
ddp_find_unused_parameters=False, # LoRA 常设 False
...
)

有效 global batch = per_device_batch × num_gpus × grad_accum

accelerate config 首次运行可交互生成 YAML(multi-GPU、mixed precision bf16)。


四、DeepSpeed ZeRO(全参 / 大模型)

ds_config.json 片段(ZeRO-2 示例):

1
2
3
4
5
6
7
8
9
10
11
{
"bf16": { "enabled": true },
"zero_optimization": {
"stage": 2,
"offload_optimizer": { "device": "none" },
"overlap_comm": true
},
"gradient_accumulation_steps": 8,
"train_batch_size": "auto",
"train_micro_batch_size_per_gpu": "auto"
}

启动:

1
deepspeed --num_gpus 4 train_sft.py --deepspeed ds_config.json

或在 SFTConfig(deepspeed="ds_config.json") 中指定。

ZeRO stage 适用
1 optimizer 分片;模型仍整卡
2 + 梯度分片;全参 7B–13B 常见
3 + 参数分片;70B 级

QLoRA + ZeRO-3 见 02-02 QLoRA


五、FSDP(PyTorch 原生)

通过 accelerate 的 FSDP 插件或 TrainingArguments

1
2
3
4
5
6
SFTConfig(
fsdp="full_shard auto_wrap",
fsdp_transformer_layer_cls_to_wrap="LlamaDecoderLayer", # 依架构改
bf16=True,
...
)
1
accelerate launch --config_file fsdp_config.yaml train_sft.py

选型:已用 Hugging Face 生态、希望少依赖 DeepSpeed 时选 FSDP;ZeRO 文档与社区案例仍更多。


六、LoRA 分布式注意点

说明
仅 adapter 同步 DDP 梯度 AllReduce 作用于可训练参数
ddp_find_unused_parameters LoRA 冻结基座时通常 False
checkpoint 仅 rank0 保存 adapter,避免重复写
学习率 global batch 变大时可 linear scaling lr(谨慎验证)

七、选型决策

1
2
3
4
5
6
LoRA SFT、显存够?
├─ 是,要更快 → DDP 多卡(提吞吐)
└─ 单卡 OOM → 07-01 单卡优化 → QLoRA
全参 SFT?
├─ 7B–13B → ZeRO-2 或 FSDP
└─ 更大 → ZeRO-3 + 可能 CPU/NVMe offload

八、常见踩坑

现象 对策
多卡 loss 不一致 检查 batch 整除、drop_last
仅 rank0 应 log trainer.is_world_process_zero()
DeepSpeed 与 PEFT 冲突 用 TRL 推荐版本组合;ZeRO-3 加载 adapter 有特殊流程
速度无提升 通信瓶颈;减卡数或增大 micro-batch

九、小结

  • LoRA 微调:优先 DDP 提吞吐。
  • 全参 / 超大模型ZeRO-2/3FSDP
  • 与单卡共用同一套数据与 08-01 评估 规范。

下一步:07-03 训练加速工具 | 07-01 显存优化

-------------本文结束感谢您的阅读-------------