Files
2026-05-16 17:16:51 +08:00

438 lines
9.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# DeepSpeed
## 概述
DeepSpeed是微软开发的深度学习训练优化库专注于大规模模型的分布式训练加速和显存优化。核心特性包括ZeROZero Redundancy Optimizer优化器、3D并行支持、混合精度训练等。
## ZeRO实现
### 核心架构
DeepSpeed的ZeRO实现分为三个阶段详见"数据并行与ZeRO"文档),这里重点介绍实现细节。
### ZeRO-1: 优化器状态分片
```python
# DeepSpeed ZeRO-1配置
{
"zero_optimization": {
"stage": 1,
"contiguous_gradients": true,
"reduce_scatter": true,
"allgather_partitions": true
}
}
```
**实现机制**
- 每个GPU持有优化器状态的1/N分片
- 梯度计算后执行Reduce-Scatter每个GPU只保留对应分片的梯度
- 参数更新只涉及本地分片
- 需要时通过AllGather重建完整梯度
### ZeRO-2: 梯度分片
```json
{
"zero_optimization": {
"stage": 2,
"stage1_param": false,
"stage2_param": false,
"stage2_cpu_offload": false,
"contiguous_gradients": true,
"overlap_comm": true
}
}
```
**额外特性**
- 梯度分片存储,避免完整梯度复制
- Overlap通信与计算利用CUDA Stream技术在反向传播时同步梯度
- Gradient accumulation支持
### ZeRO-3: 参数分片
```json
{
"zero_optimization": {
"stage": 3,
"stage3_param_persistence_threshold": 1e5,
"stage3_max_live_parameters": 1e9,
"stage3_max_reuse_distance": 1e5
}
}
```
**关键参数**
- `stage3_max_live_parameters`GPU上同时保持的最大参数分片数
- `stage3_param_persistence_threshold`超过此阈值的参数保持在GPU
### ZeRO-Inference
```python
# ZeRO-Inference配置
{
"zero_optimization": {
"stage": 3,
"stage3_offload_param": {
"device": "cpu"
}
},
"inference": {
"enabled": true
}
}
```
推理时将参数卸载到CPU通过动态加载满足计算需求。
## 3D并行配置
### 并行策略组合
DeepSpeed支持数据并行、流水线并行、张量并行的组合配置
```json
{
"parallelism": {
"tensor_parallel": {
"enabled": true,
"size": 8,
"mpu": "MegatronMPU"
},
"pipeline": {
"enabled": true,
"stages": 4,
"pipe_schedule": "GPipe"
},
"data_parallel": {
"degree": 32
}
}
}
```
### 设备映射
```python
# 假设有 256 个 GPU
# 配置: TP=8, PP=4, DP=8
# 总GPU需求: 8 × 4 × 8 = 256
# 数据并行度 = 总GPU数 / (TP × PP) = 256 / 32 = 8
data_parallel_size = 8
tensor_parallel_size = 8
pipeline_parallel_size = 4
# 模型切分
model = transformer_layer / pipeline_parallel_size # 每Stage 1/4层
layer = weight / tensor_parallel_size # 每GPU 1/8权重
```
### 通信域配置
```python
# 通信域层级
# 1. TP通信域张量并行all-reduce within 8 GPUs
# 2. PP通信域流水线并行send/recv between stages
# 3. DP通信域数据并行all-reduce across DP replicas
# DeepSpeed自动构建通信域
ds_config = DeepSpeedConfig(config)
```
## Gradient Checkpointing
### 原理
Gradient Checkpointing也称Activation Checkpointing通过在前向传播时不保存中间激活值而在反向传播时重新计算来节省显存。
```python
# DeepSpeed Gradient Checkpointing配置
{
"gradient_checkpointing": {
"enabled": true,
"checkpoint_every_n_steps": 1,
"contiguous": true,
"checkpoint_in_cpu": false
}
}
```
### 内存-计算权衡
```
标准前向:
- 前向计算: O(1)
- 激活存储: O(N) # N=层数
Checkpointing
- 前向计算: O(N) # 每层重新计算
- 激活存储: O(1) # 只保存输入输出
- 反向计算: O(N) # 重新计算中间激活
节省显存: ~70%(取决于模型结构)
额外计算开销: ~30%
```
### 与ZeRO结合
```python
{
"gradient_checkpointing": true,
"zero_optimization": {
"stage": 3
}
}
# ZeRO-3 + Checkpointing: 显存 ≈ 模型大小 / N + 激活 / N
```
## 混合精度训练支持
### BF16训练
```json
{
"bf16": {
"enabled": true,
"loss_scaling": "dynamic"
},
"fp16": {
"enabled": false
}
}
```
**关键特性**
- 前向/反向传播使用BF16
- 优化器状态保持FP32精度
- Loss scaling动态调整
- 支持ZeRO-3与BF16结合
### 混合精度流程
```
1. 前向传播: BF16
2. Loss计算: BF16
3. 反向传播: BF16梯度
4. 梯度转FP32: 用于优化器更新
5. 参数更新: FP32优化器 → FP16/BF16参数
```
### Loss Scaling
```python
# DeepSpeed自动loss scaling
class BF16Scaler:
def __init__(self):
self.loss_scale = None
self.scale_factor = 1.0
def set_scale(self, loss_scale):
self.loss_scale = loss_scale
def update_scale(self, found_inf):
# 发现inf时缩小scale
if found_inf:
self.loss_scale /= 2
else:
self.loss_scale = self.loss_scale # 保持或增长
```
## 训练配置示例
### 7B模型单节点多卡
```json
{
"train_batch_size": 32,
"train_micro_batch_size_per_gpu": 4,
"gradient_accumulation_steps": 8,
"steps_per_print": 10,
"zero_optimization": {
"stage": 3,
"offload_optimizer": {
"device": "cpu",
"pin_memory": true
}
},
"bf16": {
"enabled": true
},
"gradient_clipping": 1.0,
"WallClockBreakdown": true,
"memory_breakdown": false
}
```
### 65B模型多节点
```json
{
"train_batch_size": 1536,
"train_micro_batch_size_per_gpu": 1,
"gradient_accumulation_steps": 1536,
"parallelism": {
"tensor_parallel": 8,
"pipeline": 4,
"data_parallel": 64
},
"zero_optimization": {
"stage": 3,
"stage3_param_persistence_threshold": 1e5,
"stage3_max_live_parameters": 1e9
},
"bf16": {
"enabled": true
},
"通信优化": {
"overlap_comm": true,
"contiguous_gradients": true
}
}
```
## ZeRO-Stage 3关键技术细节
### 参数分片管理
```python
class ParameterShardingManager:
"""管理参数分片的加载和卸载"""
def __init__(self, model, device):
self.param_shapes = {} # 参数形状信息
self.param_offsets = {} # 分片偏移信息
self.param缓存 = {} # 已加载的分片
def get_param_shard(self, param, shard_id):
"""获取参数分片"""
shape = param.shape
num_shards = self.get_num_shards(shape)
# 计算分片范围
start = shard_id * (shape[0] // num_shards)
end = (shard_id + 1) * (shape[0] // num_shards)
return param[start:end].clone()
def load_param_async(self, param, shard_id):
"""异步加载参数分片到GPU"""
shard = self.get_param_shard(param, shard_id)
self.param_cache[param] = shard.to(device)
def scatter_param(self, param):
"""将参数分片分发到各GPU"""
# 使用集合通信
return self.all_gather(param)
```
### 通信重叠
```python
# Overlap策略反向传播与梯度同步重叠
backward_pass():
for layer in reversed(layers):
# 1. 计算本地梯度
grad = layer.compute_gradient()
# 2. 触发异步梯度同步
if should_sync(layer):
dist.all_reduce_async(grad, op=dist.ReduceOp.SUM)
# 3. 继续计算后续层梯度
next_layer.compute_gradient(grad)
# 等待所有同步完成
dist.synchronize()
```
### 混合分片策略
```python
# 部分参数使用不同分片策略
{
"zero_optimization": {
"stage": 3,
"param_sharding_strategy": "order_based",
"stage3_order": [
"embeddings",
"attention",
"mlp"
]
}
}
```
## DeepSpeed训练流程
```python
import deepspeed
# 1. 初始化DeepSpeed
deepspeed.init_distributed()
# 2. 创建模型
model = MyModel()
# 3. 创建优化器可选DeepSpeed内部创建
optimizer = torch.optim.Adam(model.parameters())
# 4. 初始化DeepSpeed
model_engine, optimizer, _, _ = deepspeed.initialize(
model=model,
optimizer=optimizer,
config=ds_config
)
# 5. 训练循环
while training:
# 前向
loss = model_engine.forward(batch)
# 反向
model_engine.backward(loss)
# 更新
model_engine.step()
```
## 与PyTorch FSDP对比
| 特性 | DeepSpeed ZeRO-3 | PyTorch FSDP |
|------|-----------------|--------------|
| 参数分片 | ZeRO-3分片 | Full Sharded |
| 通信模式 | AllGather + ReduceScatter | AllGather |
| CPU Offload | 原生支持 | 需要额外配置 |
| 优化器卸载 | 原生支持 | 部分支持 |
| 易用性 | 配置驱动 | 代码驱动 |
| 生态 | 成熟度高 | 官方维护 |
## 性能调优建议
1. **通信优化**:启用`overlap_comm``contiguous_gradients`
2. **内存优化**适当使用CPU卸载缓解GPU压力
3. **Batch Size**配合gradient accumulation调整
4. **通信带宽**确保使用高速互联NVLink
5. **混合精度**使用BF16而非FP16
## 常见问题
| 问题 | 解决方案 |
|------|---------|
| OOM错误 | 降低batch size或启用ZeRO-3 |
| 通信瓶颈 | 检查网络拓扑启用overlap |
| 精度问题 | 使用BF16检查loss scaling |
| 速度慢 | 调整num_workers增加warmup |