系统学习 AI 学习路径:从 GPU 运行时到推理、微调与 RAG 评估

fsdp

PyTorch FSDP:把参数、梯度和优化器状态分片到多卡,训练放不下的模型

补充说明

FSDP(Fully Sharded Data Parallel)把模型参数、梯度和优化器状态按数据并行组切分到各 GPU,前向/反向时按需 all-gather,计算完再释放。它适合单卡放不下、但又不想上张量并行的模型;和 DeepSpeed ZeRO-3 的目标类似,区别在实现、配置方式和生态集成。

FSDP 有两种常见形态:经典 FSDP wrapper 和 PyTorch 2.x 的 FSDP2(fully_shard)。FSDP2 使用 DTensor,支持更灵活的分片和 torch.compile,新项目优先评估 FSDP2。使用 FSDP 需要 torchrun 启动,不能直接用 python train.py 跑多卡。

常用示例

# 8 卡启动
torchrun --standalone --nproc_per_node=8 train_fsdp.py
import torch
from torch.distributed.fsdp import FullyShardedDataParallel as FSDP
from torch.distributed.fsdp import MixedPrecision, ShardingStrategy

model = MyModel().cuda()
mp = MixedPrecision(param_dtype=torch.bfloat16,
                    reduce_dtype=torch.bfloat16,
                    buffer_dtype=torch.bfloat16)

model = FSDP(
    model,
    sharding_strategy=ShardingStrategy.FULL_SHARD,
    mixed_precision=mp,
    device_id=torch.cuda.current_device(),
    use_orig_params=True,
)
# 按层 wrapping,避免一次性 all-gather 整个模型
from torch.distributed.fsdp.wrap import transformer_auto_wrap_policy
from torch.distributed.fsdp import FSDP

model = FSDP(
    model,
    auto_wrap_policy=transformer_auto_wrap_policy,
    sharding_strategy=ShardingStrategy.FULL_SHARD,
)

FSDP2 的写法:

from torch.distributed.fsdp import fully_shard

for layer in model.layers:
    fully_shard(layer)
fully_shard(model)

易错点与排错

相关命令

参考链接

读完自测

合上页面,先回答,再展开对照。

  1. FULL_SHARD 和 SHARD_GRAD_OP 的主要区别是什么?
  2. 为什么 FSDP 要按 Transformer block 做 auto wrap?
  3. FSDP 的 checkpoint 为什么不能直接 torch.save(model.state_dict())?
答案
  1. FULL_SHARD 在前后向后释放参数分片,显存最省但通信更多;SHARD_GRAD_OP 只分片梯度和优化器状态,参数常驻,通信较少、显存占用更高。
  2. 整模型作为一个 FSDP 单元会在 all-gather 时产生巨大峰值;按 block 分层可以在计算到该层时才聚合参数,降低峰值显存。
  3. FSDP 的 state_dict 是分片/DTensor 形式,直接保存可能只拿到局部参数;要用 FullStateDictConfig、LocalStateDictConfig 或分布式 checkpoint。
微信小程序码:扫码打开命令速查小程序

小程序版

微信扫码,随时查命令