使用torch构建的transformer模型训练时怎么使用deepspeed进行多显卡并行训练
时间: 2025-07-21 22:56:34 浏览: 1
<think>我们正在使用DeepSpeed进行多GPU分布式训练。首先,需要安装DeepSpeed库(通常通过pip安装)。然后,对现有PyTorch代码进行修改,主要涉及初始化DeepSpeed引擎、配置DeepSpeed配置文件以及修改训练循环。
步骤:
1. 安装DeepSpeed: `pip install deepspeed`
2. 准备一个DeepSpeed配置文件(例如`ds_config.json`),用于设置训练参数(如优化器、混合精度、ZeRO阶段等)。
3. 修改训练代码:初始化DeepSpeed引擎,将模型、优化器、学习率调度器等交给DeepSpeed管理。
4. 使用DeepSpeed提供的分布式训练启动器启动训练。
以下是一个简化的步骤说明和代码示例:
步骤一:创建DeepSpeed配置文件(ds_config.json)
例如,我们使用ZeRO stage 1和混合精度训练:
```json
{
"train_batch_size": "auto",
"train_micro_batch_size_per_gpu": 4, // 每个GPU的batch size
"steps_per_print": 10,
"optimizer": {
"type": "AdamW",
"params": {
"lr": 5e-5,
"weight_decay": 0.01
}
},
"fp16": {
"enabled": true
},
"zero_optimization": {
"stage": 1
}
}
```
步骤二:修改训练代码
假设我们有一个Transformer模型(使用Hugging Face Transformers库)和训练循环。
原始PyTorch代码可能如下:
```python
import torch
from transformers import AutoModelForSequenceClassification, AutoTokenizer
model = AutoModelForSequenceClassification.from_pretrained("bert-base-uncased")
tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")
optimizer = torch.optim.AdamW(model.parameters(), lr=5e-5)
# 数据加载等...
for epoch in range(epochs):
for batch in dataloader:
inputs = tokenizer(batch["text"], padding=True, truncation=True, return_tensors="pt")
outputs = model(**inputs, labels=batch["labels"])
loss = outputs.loss
loss.backward()
optimizer.step()
optimizer.zero_grad()
```
使用DeepSpeed修改后的代码:
```python
import torch
import deepspeed
from transformers import AutoModelForSequenceClassification, AutoTokenizer
# 初始化DeepSpeed
model = AutoModelForSequenceClassification.from_pretrained("bert-base-uncased")
tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")
# 定义DeepSpeed引擎
# 注意:这里我们传递模型、优化器参数等,但优化器参数已经在配置文件中定义了,所以这里可以不用传递优化器,但也可以传递(如果配置文件中没有定义优化器,则这里必须传递)
# 我们这里使用配置文件,所以不传递优化器,而是让DeepSpeed根据配置文件创建
model_engine, optimizer, _, _ = deepspeed.initialize(
model=model,
model_parameters=model.parameters(),
config='ds_config.json' # 配置文件路径
)
# 数据加载器(注意:每个进程有自己的数据加载器,需要使用分布式采样器)
for epoch in range(epochs):
for batch in dataloader:
inputs = tokenizer(batch["text"], padding=True, truncation=True, return_tensors="pt")
# 将数据移动到当前设备
inputs = {k: v.to(model_engine.device) for k, v in inputs.items()}
labels = batch["labels"].to(model_engine.device)
outputs = model_engine(**inputs, labels=labels)
loss = outputs.loss
model_engine.backward(loss)
model_engine.step()
```
注意:在DeepSpeed中,我们使用`model_engine`来代替原来的模型和优化器。`model_engine`封装了模型、优化器以及分布式训练所需的功能。
步骤三:启动训练
使用DeepSpeed的启动器(类似于torch.distributed.launch):
```bash
deepspeed --num_gpus=2 train.py --deepspeed_config ds_config.json
```
其中,`--num_gpus`指定使用的GPU数量,`train.py`是训练脚本。
重要提示:
1. 数据加载器需要使用分布式采样器(`torch.utils.data.distributed.DistributedSampler`)来确保每个GPU处理不同的数据子集。
2. 在DeepSpeed中,梯度累积可以通过配置文件设置(`gradient_accumulation_steps`)。
3. 混合精度(fp16)也在配置文件中设置。
以上是一个基本的使用流程。对于更复杂的模型(如自定义模型),可能需要确保模型在多个GPU上正确分布(DeepSpeed会自动处理,但使用ZeRO stage 3时可能需要额外配置)。
参考DeepSpeed官方文档:https://www.deepspeed.ai/
根据上述引用,DeepSpeed是一个轻量级的PyTorch包装器,用户只需对代码进行少量修改即可实现分布式训练[^1][^2]。它特别适合大规模模型训练,如Transformer模型[^3]。
相关问题:
1. DeepSpeed的ZeRO优化有几个阶段?它们有什么区别?
2. 如何配置DeepSpeed以支持超大模型的训练(如ZeRO-Offload)?
3. DeepSpeed在训练Transformer模型时有哪些特有的优化?</think>### 在PyTorch中使用DeepSpeed进行Transformer多GPU分布式训练
以下是具体实现步骤(基于Hugging Face Transformers库):
#### 1. 环境安装
```bash
pip install deepspeed transformers
```
#### 2. 核心代码修改
```python
import deepspeed
from transformers import AutoModelForSequenceClassification, Trainer
# 初始化模型
model = AutoModelForSequenceClassification.from_pretrained("bert-base-uncased")
# DeepSpeed配置文件 (ds_config.json)
deepspeed_config = {
"train_batch_size": 32,
"gradient_accumulation_steps": 2,
"optimizer": {
"type": "AdamW",
"params": {
"lr": 5e-5,
"weight_decay": 0.01
}
},
"fp16": {
"enabled": True
},
"zero_optimization": {
"stage": 3, # 使用ZeRO-3优化
"offload_optimizer": {
"device": "cpu" # 显存不足时可启用CPU卸载
}
},
"activation_checkpointing": {
"partition_activations": True,
"contiguous_memory_optimization": True
}
}
# 创建DeepSpeed Trainer
trainer = Trainer(
model=model,
args=TrainingArguments(
per_device_train_batch_size=8,
output_dir="./results",
deepspeed="./ds_config.json" # 指定配置文件
),
train_dataset=train_dataset
)
# 启动训练
trainer.train()
```
#### 3. 关键配置说明
1. **ZeRO优化**:
- `stage=1`:优化器状态分区
- `stage=2`:优化器状态+梯度分区
- `stage=3`:优化器状态+梯度+参数分区(推荐大模型使用)[^3]
2. **混合精度训练**:
```json
"fp16": {"enabled": true}
```
3. **梯度累积**:
```json
"gradient_accumulation_steps": 2
```
#### 4. 启动命令
```bash
deepspeed --num_gpus 4 \
--master_port 29500 \
train.py \
--deepspeed ds_config.json
```
#### 5. 最佳实践
1. **显存优化**:
- 启用`offload_optimizer`将优化器状态卸载到CPU
- 使用`activation_checkpointing`减少激活值内存占用
2. **大模型训练**:
对于>10B参数的Transformer模型:
```json
"zero_optimization": {
"stage": 3,
"stage3_max_live_parameters": 1e9,
"stage3_param_persistence_threshold": 1e6
}
```
3. **性能监控**:
```bash
watch -n 1 nvidia-smi
deepspeed --num_gpus 4 train.py --deepspeed_config ds_config.json --deepspeed_metrics
```
> **注意**:DeepSpeed通过轻量级封装自动管理分布式训练、混合精度等技术,用户只需关注模型开发[^1]。对于GPT-3等百亿级参数模型,ZeRO-3技术可将显存需求降低到单卡的1/64[^3]。
---
### 相关问题
1. DeepSpeed的ZeRO-3优化如何实现参数分区?
2. 如何在DeepSpeed中实现梯度累积与混合精度的协同工作?
3. DeepSpeed相比原生PyTorch DDP有哪些性能优势?
4. 如何监控DeepSpeed训练过程中的显存和带宽利用率?
5. 在Transformer训练中,DeepSpeed的激活检查点技术如何减少显存占用?
[^1]: DeepSpeed自动管理包括分布式训练、混合精度、梯度累积等先进训练技术,使研究者专注于模型开发
[^2]: DeepSpeed的核心目标是让大规模模型训练变得更加普惠和高效
[^3]: 对于175B的GPT-3训练,通过ZeRO等技术可将显存需求分布到多卡
阅读全文
相关推荐


















