DeepSpeed 的 自动调优(Autotuning) 功能是一个强大的工具,旨在通过自动搜索超参数空间来优化分布式训练性能。它可以帮助用户找到最佳的训练配置(如批次大小、微批次数量、ZeRO 参数、通信设置等),从而提高吞吐量、降低内存占用并提升训练稳定性。自动调优特别适合大规模模型(如 GPT、LLaMA)和复杂并行策略(如 ZeRO、流水线并行、专家并行)的训练场景。
本教程将全面讲解 DeepSpeed 自动调优的功能、配置方法、运行步骤、输出分析、优化建议和实际应用场景,包含详细的代码示例和调试技巧。
1. DeepSpeed 自动调优概述
1.1 功能
DeepSpeed 的自动调优通过以下方式优化训练性能:
- 超参数搜索:自动测试用户指定的超参数组合(如
train_micro_batch_size_per_gpu
、ZeRO 参数)。 - 性能评估:评估每组配置的吞吐量(样本/秒)、内存使用和稳定性。
- 最佳配置推荐:输出性能最佳的配置,供用户直接使用或进一步微调。
- 快速模式:支持快速搜索,减少调优时间。
1.2 适用场景
- 新模型训练:快速找到适合模型规模和硬件的配置。
- 多节点分布式训练:优化通信参数(如
allgather_bucket_size
)。 - 复杂并行策略:调整流水线并行(微批次数量)、专家并行(
ep_size
)或 ZeRO 参数。 - 资源受限环境:在低配硬件上优化内存和批次大小。
1.3 工作原理
- 搜索空间:用户在
ds_config.json
中定义超参数及其候选值。 - 试验执行:DeepSpeed 自动运行多个训练试验,测试每组配置。
- 性能指标:记录吞吐量、内存使用和训练稳定性。
- 结果保存:输出最佳配置到指定目录,生成日志和推荐配置。
2. 配置自动调优
自动调优通过 ds_config.json
中的 autotuning
字段配置。以下是关键配置项和说明。
2.1 配置结构
{
"autotuning": {
"enabled": true,
"fast": true,
"start_profile_step": 3,
"end_profile_step": 5,
"metric": "throughput",
"results_dir": "autotuning_results",
"exps_dir": "autotuning_exps",
"overwrite": false,
"percentile": 90,
"arg_mappings": {
"train_micro_batch_size_per_gpu": ["2", "4", "8", "16"],
"zero_optimization.allgather_bucket_size": ["1e8", "5e8", "1e9"],
"zero_optimization.reduce_bucket_size": ["1e8", "5e8", "1e9"],
"gradient_accumulation_steps": ["1", "2", "4"],
"pipeline_parallel.micro_batches": ["4", "8", "16"]
}
}
}
2.2 配置项说明
enabled
(布尔值):是否启用自动调优。设为true
激活。fast
(布尔值):启用快速模式,减少试验次数(适合初步调优)。start_profile_step
(整数):从第几步开始性能分析(避免 warmup 干扰)。end_profile_step
(整数):分析结束步数。metric
(字符串):优化目标,默认"throughput"
(吞吐量),可选"latency"
(延迟)。results_dir
(字符串):最佳配置保存目录(如autotuning_results
)。exps_dir
(字符串):试验日志保存目录(如autotuning_exps
)。overwrite
(布尔值):是否覆盖现有结果目录。percentile
(浮点数):吞吐量评估的分位数(如90
表示 90% 分位)。arg_mappings
(字典):超参数及其候选值,支持以下常见参数:train_micro_batch_size_per_gpu
:每 GPU 微批次大小。gradient_accumulation_steps
:梯度累积步数。zero_optimization.allgather_bucket_size
:ZeRO AllGather 缓冲区大小。zero_optimization.reduce_bucket_size
:ZeRO ReduceScatter 缓冲区大小。pipeline_parallel.micro_batches
:流水线并行微批次数量。moe.ep_size
:专家并行组大小。communication_data_type
:通信数据类型(如"fp16"
、"fp32"
)。
2.3 典型超参数选择
超参数 | 推荐候选值 | 适用场景 |
---|---|---|
train_micro_batch_size_per_gpu | [2, 4, 8, 16, 32] | 内存受限或吞吐量优化 |
gradient_accumulation_steps | [1, 2, 4, 8] | 小批次训练或稳定性优化 |
allgather_bucket_size | [1e8, 5e8, 1e9] | ZeRO Stage 3 通信优化 |
micro_batches | [4, 8, 16, 32] | 流水线并行效率优化 |
moe.ep_size | [1, 2, 4, 8] | 专家并行(MoE)优化 |
3. 运行自动调优
3.1 准备工作
-
环境设置:
- 确保 DeepSpeed 已正确安装(
pip install deepspeed
)。 - 配置 NCCL 环境(优化通信):
export NCCL_IB_DISABLE=0 export NCCL_ALGO=Tree export NCCL_BUFFSIZE=2097152
- 设置分布式训练环境:
export MASTER_ADDR=192.168.1.100 export MASTER_PORT=29500
- 确保 DeepSpeed 已正确安装(
-
模型和数据:
- 准备你的模型(PyTorch
nn.Module
)。 - 准备数据加载器或模拟数据。
- 准备你的模型(PyTorch
-
配置文件:
- 创建
ds_config.json
,包含autotuning
配置。 - 确保其他必要配置(如
train_batch_size
、fp16
)正确。
- 创建
3.2 代码示例
以下是一个完整的自动调优示例,优化 train_micro_batch_size_per_gpu
和 allgather_bucket_size
。
import deepspeed
import torch
import torch.nn as nn
# Define model
class SimpleModel(nn.Module):
def __init__(self):
super().__init__()
self.linear = nn.Linear(1000, 1000)
def forward(self, x):
return self.linear(x)
model = SimpleModel()
# DeepSpeed configuration
ds_config = {
"train_batch_size": 64,
"gradient_accumulation_steps": 4,
"fp16": {"enabled": True},
"zero_optimization": {
"stage": 3,
"offload_optimizer": {"device": "cpu"}
},
"autotuning": {
"enabled": True,
"fast": True,
"start_profile_step": 3,
"end_profile_step": 5,
"metric": "throughput",
"results_dir": "autotuning_results",
"exps_dir": "autotuning_exps",
"arg_mappings": {
"train_micro_batch_size_per_gpu": ["2", "4", "8"],
"zero_optimization.allgather_bucket_size": ["1e8", "5e8"]
}
},
"wall_clock_breakdown": True # Enable timing for analysis
}
# Initialize DeepSpeed
model_engine, optimizer, _, _ = deepspeed.initialize(model=model, config=ds_config)
# Training loop
data = torch.randn(64, 1000).to(model_engine.device)
for step in range(10):
output = model_engine(data)
loss = output.sum()
model_engine.backward(loss)
model_engine.step()
if model_engine.local_rank == 0:
print(f"Step {step}, Loss: {loss.item():.4f}")
3.3 运行命令
使用 deepspeed
命令运行:
deepspeed train.py --deepspeed_config ds_config.json
或使用 torch.distributed.launch
:
python -m torch.distributed.launch --nproc_per_node=4 train.py
3.4 输出
- 日志:每次试验的配置和性能指标:
[Autotuning] Trial 1: micro_batch=2, allgather_size=1e8, Throughput=100 samples/s [Autotuning] Trial 2: micro_batch=4, allgather_size=5e8, Throughput=120 samples/s [Autotuning] Trial 3: micro_batch=8, allgather_size=1e8, Throughput=115 samples/s [Autotuning] Best: micro_batch=4, allgather_size=5e8, Throughput=120 samples/s
- 结果文件:
- 保存到
autotuning_results/best_config.json
:{ "train_micro_batch_size_per_gpu": 4, "zero_optimization": { "allgather_bucket_size": 500000000 } }
- 试验日志存储在
autotuning_exps
。
- 保存到
4. 分析自动调优结果
4.1 理解输出
- 吞吐量:主要优化目标,单位为样本/秒(samples/s)。更高的吞吐量表示更好的性能。
- 内存使用:日志可能显示内存占用,帮助识别 OOM 风险。
- 稳定性:试验失败(OOM 或通信错误)会记录为无效配置。
4.2 使用最佳配置
- 直接应用:
- 将
autotuning_results/best_config.json
合并到ds_config.json
:{ "train_batch_size": 64, "train_micro_batch_size_per_gpu": 4, "zero_optimization": { "stage": 3, "allgather_bucket_size": 500000000 } }
- 将
- 进一步微调:
- 根据日志分析,调整候选值范围(如增加
train_micro_batch_size_per_gpu
到[4, 8, 16]
)。 - 重复调优以优化其他参数。
- 根据日志分析,调整候选值范围(如增加
4.3 可视化结果
- 使用 Python 脚本解析
autotuning_exps
日志:import json import glob logs = glob.glob("autotuning_exps/*.json") for log in logs: with open(log, "r") as f: trial = json.load(f) print(f"Trial: {trial['config']}, Throughput: {trial['throughput']}")
- 结合 TensorBoard 可视化吞吐量:
{ "tensorboard": { "enabled": True, "output_path": "logs/tensorboard" } }
5. 优化建议
5.1 配置优化
- 缩小搜索空间:
- 限制
arg_mappings
的候选值,如:{ "train_micro_batch_size_per_gpu": ["4", "8"] }
- 减少试验次数,加速调优。
- 限制
- 快速模式:
- 始终启用
"fast": true
进行初步调优。 - 必要时禁用
fast
进行全面搜索。
- 始终启用
- 分步调优:
- 先优化批次大小(
train_micro_batch_size_per_gpu
),再调通信参数(allgather_bucket_size
)。
- 先优化批次大小(
5.2 性能优化
- 通信:
- 启用 FP16 通信:
{ "communication_data_type": "fp16", "compress_communication": True }
- 优化 NCCL:
export NCCL_ALGO=Tree
- 启用 FP16 通信:
- 内存:
- 启用 ZeRO 卸载:
{ "zero_optimization": { "offload_optimizer": {"device": "cpu"}, "offload_param": {"device": "nvme"} } }
- 使用激活检查点:
{ "activation_checkpointing": {"partition_activations": True} }
- 启用 ZeRO 卸载:
- 计算:
- 启用 FP16/BF16:
{ "fp16": {"enabled": True} }
- 使用优化算子(
pip install deepspeed[ops]
)。
- 启用 FP16/BF16:
5.3 调试
- 启用日志:
export DEEPSPEED_LOG_LEVEL=DEBUG export NCCL_DEBUG=INFO export NCCL_DEBUG_FILE=nccl_log.txt
- 监控内存:
from deepspeed.utils import memory_status memory_status()
- 检查 OOM:
- 若试验失败,检查日志中的内存错误。
- 降低
train_micro_batch_size_per_gpu
或启用 ZeRO Stage 3。
- 通信失败:
- 检查 NCCL 日志(
nccl_log.txt
)。 - 确保
MASTER_ADDR
和MASTER_PORT
正确。
- 检查 NCCL 日志(
5.4 结合其他工具
- 挂钟时间细分:
{ "wall_clock_breakdown": True }
- 分析最佳配置的通信和计算时间。
- FLOPs 分析:
{ "flops_profiler": { "enabled": True, "profile_step": 1 } }
- 验证调优是否减少计算开销。
- PyTorch Profiler:
from torch.profiler import profile, ProfilerActivity with profile(activities=[ProfilerActivity.CUDA]): output = model_engine(data)
6. 实际应用场景与示例
6.1 优化 ZeRO Stage 3 训练
ds_config = {
"train_batch_size": 64,
"fp16": {"enabled": True},
"zero_optimization": {"stage": 3},
"autotuning": {
"enabled": True,
"fast": True,
"arg_mappings": {
"train_micro_batch_size_per_gpu": ["2", "4", "8"],
"zero_optimization.allgather_bucket_size": ["1e8", "5e8"],
"zero_optimization.reduce_bucket_size": ["1e8", "5e8"]
}
}
}
model_engine, _, _, _ = deepspeed.initialize(model=model, config=ds_config)
- 场景:优化 ZeRO Stage 3 的通信和批次大小。
- 输出:最佳
allgather_bucket_size
和train_micro_batch_size_per_gpu
。
6.2 优化流水线并行
ds_config = {
"train_batch_size": 64,
"pipeline_parallel": {
"enabled": True,
"pp_size": 2
},
"autotuning": {
"enabled": True,
"fast": True,
"arg_mappings": {
"train_micro_batch_size_per_gpu": ["2", "4", "8"],
"pipeline_parallel.micro_batches": ["4", "8", "16"]
}
}
}
model_engine, _, _, _ = deepspeed.initialize(model=model, config=ds_config)
- 场景:优化流水线并行的微批次调度。
- 输出:最佳
micro_batches
和批次大小。
6.3 优化 MoE 模型
from deepspeed.moe.layer import MoE
class MoEModel(nn.Module):
def __init__(self):
super().__init__()
self.expert = nn.Linear(512, 512)
self.moe_layer = MoE(hidden_size=512, expert=self.expert, num_experts=8)
def forward(self, x):
output, _, _ = self.moe_layer(x)
return output
model = MoEModel()
ds_config = {
"train_batch_size": 64,
"moe": {"num_experts": 8},
"autotuning": {
"enabled": True,
"fast": True,
"arg_mappings": {
"train_micro_batch_size_per_gpu": ["2", "4", "8"],
"moe.ep_size": ["1", "2", "4"]
}
}
}
model_engine, _, _, _ = deepspeed.initialize(model=model, config=ds_config)
- 场景:优化专家并行的
ep_size
和批次大小。 - 输出:最佳
ep_size
和train_micro_batch_size_per_gpu
。
7. 常见问题与解答
-
自动调优耗时长怎么办?
- 启用快速模式:
{ "autotuning": {"fast": True} }
- 减少候选值(如
[2, 4]
而非[2, 4, 8, 16]
)。 - 限制试验步数(
end_profile_step - start_profile_step
)。
- 启用快速模式:
-
试验失败(OOM 或通信错误)?
- 检查日志(
autotuning_exps
)定位失败配置。 - 降低
train_micro_batch_size_per_gpu
或启用 ZeRO 卸载:{ "zero_optimization": {"offload_param": {"device": "nvme"}} }
- 确保 NCCL 配置正确:
export NCCL_IB_DISABLE=0
- 检查日志(
-
吞吐量不理想?
- 分析
wall_clock_breakdown
日志,定位通信或计算瓶颈。 - 优化通信:
{ "communication_data_type": "fp16" }
- 增加
train_batch_size
或调整并行策略。
- 分析
-
如何验证调优结果?
- 使用最佳配置运行完整训练,检查吞吐量:
ds_config.update(json.load(open("autotuning_results/best_config.json"))) model_engine, _, _, _ = deepspeed.initialize(model=model, config=ds_config)
- 结合
flops_profiler
和memory_status
分析性能。
- 使用最佳配置运行完整训练,检查吞吐量:
-
多节点调优注意事项?
- 确保所有节点配置一致(
MASTER_ADDR
、MASTER_PORT
)。 - 优化通信参数(如
allgather_bucket_size
)。 - 使用高带宽网络(如 InfiniBand)。
- 确保所有节点配置一致(
8. 进阶用法
8.1 自定义超参数
ds_config["autotuning"]["arg_mappings"]["optimizer.lr"] = ["1e-3", "5e-4", "1e-4"]
- 功能:优化学习率。
8.2 动态调优
for param in ["train_micro_batch_size_per_gpu", "gradient_accumulation_steps"]:
ds_config["autotuning"]["arg_mappings"] = {param: ["2", "4", "8"]}
model_engine, _, _, _ = deepspeed.initialize(model=model, config=ds_config)
- 功能:分阶段调优不同参数。
8.3 结合性能分析
ds_config.update({
"wall_clock_breakdown": True,
"flops_profiler": {"enabled": True},
"print_memory_usage": True
})
model_engine, _, _, _ = deepspeed.initialize(model=model, config=ds_config)
- 功能:在调优时分析时间、FLOPs 和内存。
8.4 保存和复用
import json
best_config = json.load(open("autotuning_results/best_config.json"))
ds_config.update(best_config)
with open("optimized_ds_config.json", "w") as f:
json.dump(ds_config, f)
- 功能:保存优化配置供生产使用。
9. 学习资源
- DeepSpeed 文档:https://www.deepspeed.ai/docs/
- 自动调优教程:https://www.deepspeed.ai/tutorials/autotuning/
- GitHub 源码:https://github.com/microsoft/DeepSpeed
- DeepSpeed 示例:https://github.com/microsoft/DeepSpeedExamples
- Hugging Face DeepSpeed:https://huggingface.co/docs/transformers/main_classes/deepspeed