Skip to content

分布式训练 (Distributed Training)


观察 DP/TP/PP/FSDP 四种并行策略如何切分模型和数据。

🖥️ 分布式并行可视化

4
Data Parallelism
数据并行:每卡完整模型,数据分片
GPU 0
完整模型
数据 1/4
GPU 1
完整模型
数据 2/4
GPU 2
完整模型
数据 3/4
GPU 3
完整模型
数据 4/4
✅ 优点
  • 实现简单
  • 通信量小
  • 扩展性好
❌ 缺点
  • 每卡需装下完整模型
  • 显存冗余
适用场景:模型小,数据多
💡 实际应用:3D 混合并行 (DP + PP + TP)
DP0
T0
T1
T0
T1
T0
T1
T0
T1
PP
DP1
T0
T1
T0
T1
T0
T1
T0
T1
PP
DP: 数据并行
PP: 流水线
TP: 张量并行
示例: 16 GPU = 2 DP × 4 PP × 2 TP | Llama 70B: 8 TP × 8 PP × 4 DP = 256 GPU

💡 调整 GPU 数量观察切分方式变化


一句话定义:分布式训练是将模型或数据分散到多个 GPU/节点上并行计算的技术,用于训练单卡装不下或训练时间过长的大模型。

  • 数据并行 (DP): 每卡完整模型,数据分片
  • 模型并行 (MP): 模型分片,每卡一部分
  • 流水线并行 (PP): 按层切分,流水线执行
  • 张量并行 (TP): 按张量切分,矩阵运算并行

并行方式类比适用场景
数据并行多条相同生产线模型小,数据多
流水线并行一条线分多个工序模型深,按层切
张量并行每个工序多人协作单层太大
混合并行大工厂综合管理超大模型

模型参数量FP16 显存 (仅模型)训练显存
7B70亿14 GB~60 GB
70B700亿140 GB~600 GB
175B1750亿350 GB~1.4 TB

A100 80GB 单卡根本装不下 70B 模型的训练!

GPT-3 (175B) 训练:
- 单卡 A100: ~355 年
- 1024 卡: ~34 天 ← 分布式训练

最简单的分布式方法:

┌─────────────────────────────────────────────────────┐
│ 数据并行 (DP) │
├─────────────────────────────────────────────────────┤
│ GPU 0: 完整模型 + 数据 batch 0 → 梯度 0 │
│ GPU 1: 完整模型 + 数据 batch 1 → 梯度 1 │
│ GPU 2: 完整模型 + 数据 batch 2 → 梯度 2 │
│ GPU 3: 完整模型 + 数据 batch 3 → 梯度 3 │
│ ↓ │
│ AllReduce (梯度同步) │
│ ↓ │
│ 所有 GPU 更新权重 │
└─────────────────────────────────────────────────────┘
梯度聚合
g=1Ni=1Ngig = \frac{1}{N} \sum_{i=1}^{N} g_i

所有 GPU 的梯度求平均后同步更新。

方法显存通信量复杂度
DDP每卡完整模型梯度
FSDP分片模型+梯度+优化器参数+梯度

按层切分模型:

┌────────────────────────────────────────────────────┐
│ 流水线并行 (PP) │
├────────────────────────────────────────────────────┤
│ GPU 0: Layer 0-7 ──┐ │
│ GPU 1: Layer 8-15 ──┼── 流水线执行 │
│ GPU 2: Layer 16-23 ──┼── (micro-batch) │
│ GPU 3: Layer 24-31 ──┘ │
└────────────────────────────────────────────────────┘
时间 →
GPU 0: [F0][F1][F2][F3][ ][ ][ ][ ][B3][B2][B1][B0]
GPU 1: [ ][F0][F1][F2][F3][ ][ ][B3][B2][B1][B0][ ]
GPU 2: [ ][ ][F0][F1][F2][F3][B3][B2][B1][B0][ ][ ]
GPU 3: [ ][ ][ ][F0][F1][F2][B2][B1][B0][ ][ ][ ]
F = Forward, B = Backward

问题: 流水线气泡(GPU 空闲时间)

切分单个矩阵运算:

┌────────────────────────────────────────────────────┐
│ 张量并行 (TP) │
├────────────────────────────────────────────────────┤
│ 矩阵 A × B = C │
│ │
│ 切分 B 为 [B1, B2]: │
│ GPU 0: A × B1 = C1 │
│ GPU 1: A × B2 = C2 │
│ 结果: C = [C1, C2] │
└────────────────────────────────────────────────────┘

大模型训练通常组合使用:

┌─────────────────────────────────────────────────────┐
│ 3D 并行 (DP + PP + TP) │
├─────────────────────────────────────────────────────┤
│ │
│ ┌─DP─┐ ┌─DP─┐ ┌─DP─┐ ┌─DP─┐ │
│ │ │ │ │ │ │ │ │ │
│ │ TP │ → │ TP │ → │ TP │ → │ TP │ ← PP │
│ │ │ │ │ │ │ │ │ │
│ └────┘ └────┘ └────┘ └────┘ │
│ │
│ 示例: 64 GPU = 8 DP × 4 PP × 2 TP │
└─────────────────────────────────────────────────────┘

import torch
import torch.distributed as dist
from torch.nn.parallel import DistributedDataParallel as DDP
def setup(rank, world_size):
"""初始化分布式环境"""
dist.init_process_group(
backend="nccl", # GPU 用 nccl
rank=rank,
world_size=world_size
)
torch.cuda.set_device(rank)
def train(rank, world_size):
setup(rank, world_size)
# 创建模型并移到对应 GPU
model = MyModel().to(rank)
# 包装为 DDP
model = DDP(model, device_ids=[rank])
# 分布式数据采样器
sampler = torch.utils.data.distributed.DistributedSampler(
dataset,
num_replicas=world_size,
rank=rank
)
dataloader = DataLoader(dataset, sampler=sampler, batch_size=32)
# 训练循环
for epoch in range(epochs):
sampler.set_epoch(epoch) # 确保每 epoch shuffle 不同
for batch in dataloader:
optimizer.zero_grad()
loss = model(batch)
loss.backward() # DDP 自动同步梯度
optimizer.step()
# 启动多进程
if __name__ == "__main__":
world_size = torch.cuda.device_count()
torch.multiprocessing.spawn(
train,
args=(world_size,),
nprocs=world_size
)

框架易用性功能适用场景
PyTorch DDP⭐⭐⭐⭐⭐数据并行简单多卡
PyTorch FSDP⭐⭐⭐⭐ZeRO-3大模型
DeepSpeed⭐⭐⭐全面超大模型
Megatron-LM⭐⭐3D 并行训练 GPT
Accelerate⭐⭐⭐⭐⭐封装各种后端快速上手



PyTorch 分布式教程

官方 DDP/FSDP 教程

阅读

DeepSpeed

微软大模型训练框架

GitHub

Megatron-LM

NVIDIA GPT 训练框架

GitHub