1 云服务器上运行HelloDeepSpeed
1.1 基本环境安装
# 下载代码
git clone https://github.com/microsoft/DeepSpeedExamples.git
# 进入示例程序文件夹
cd DeepSpeedExamples/training/HelloDeepSpeed
# 创建虚拟环境并安装需要的库
conda create -n deepspeed python==3.10
pip install -r requirements.txt
# 注意安装的torch版本必须和平台支持的cuda版本相一致
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu116
其中 requirements.txt
在原本的基础上改为(按原来的transformers版本安装会报错):
deepspeed
datasets
tokenizers==0.15.2
transformers
tensorboard
fire==0.4.0
pytz==2021.1
loguru==0.5.3
sh==1.14.2
pytest==6.2.5
tqdm==4.62.3
1.2 不基于 deepspeed 引擎运行 train_bert.py
1.2.1 修改 train_bert.py
首先从huggingface上下载 wikitext/wikitext-2-v1
数据集,为 .arrow
格式。将数据集上传服务器,然后设置数据集本地读取,其中 ./dataset
是数据集存放目录。
# 源代码第237行左右读取数据集
wikitext_dataset = datasets.load_dataset("wikitext",
"wikitext-2-v1",
split="train")
# 更改后使用本地数据集
# wikitext_dataset = datasets.load_dataset("wikitext",
# "wikitext-2-v1",
# split="train")
wikitext_dataset = datasets.load_from_disk("./dataset")
从huggingface上下载tokenizers。将tokenizer上传到服务器,并设置更改使用本地的tokenizer,其中 ./tokenizer/roberta-base
是下载到本地的tokenizer。
# 源代码第243行左右设置tokenizer的获取
tokenizer = AutoTokenizer.from_pretrained(tokenizer)
# 更改后使用本地的tokenizer
# tokenizer = AutoTokenizer.from_pretrained(tokenizer)
tokenizer = AutoTokenizer.from_pretrained("./tokenizer/roberta-base")
1.2.2 修改 run.sh
加入服务器需要添加的环境、模块等。
#!/bin/bash
module load nvidia/cuda/11.6
module load mpich/3.4.1-gcc9.3
source activate deepspeed
python train_bert.py --checkpoint_dir ./experiment
1.2.3 运行
sbatch -p gpu -n 4 -N 2 --gres=gpu:4 run.sh
1.3 基于 deepspeed 引擎运行 train_bert_ds.py
1.3.1 修改 train_bert_ds.py
将数据集上传,然后设置数据集本地读取,其中 ./dataset
是从huggingface上下载的 wikitext/wikitext-2-v1
数据集,为 .arrow
格式
# 源代码第267行左右读取数据集
wikitext_dataset = datasets.load_dataset("wikitext",
"wikitext-2-v1",
split="train")
# 更改后使用本地数据集
# wikitext_dataset = datasets.load_dataset("wikitext",
# "wikitext-2-v1",
# split="train")
wikitext_dataset = datasets.load_from_disk("./dataset")
设置更改使用本地的tokenizer,其中 ./tokenizer/roberta-base
是下载到本地的
# 源代码第273行左右设置tokenizer的获取
tokenizer = AutoTokenizer.from_pretrained(tokenizer)
# 更改后使用本地的tokenizer
# tokenizer = AutoTokenizer.from_pretrained(tokenizer)
tokenizer = AutoTokenizer.from_pretrained("./tokenizer/roberta-base")
1.3.2 修改 run_ds.sh
加入服务器需要添加的环境、模块等。
#!/bin/bash
module load nvidia/cuda/11.6
module load mpich/3.4.1-gcc9.3
source activate deepspeed
deepspeed train_bert_ds.py --checkpoint_dir experiment_deepspeed $@
1.3.3 运行
sbatch -p gpu -n 4 -N 2 --gres=gpu:4 run_ds.sh
2 云服务器上基于deepspeed运行GAN
# 下载代码
git clone https://github.com/microsoft/DeepSpeedExamples.git
# 进入示例程序文件夹
cd DeepSpeedExamples/training/gan
# 创建虚拟环境并安装需要的库
conda create -n deepspeed python==3.10
pip install -r requirements.txt
# 注意安装的torch版本必须和平台支持的cuda版本相一致
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu116
# 加载mpi软件后,使用conda安装mpi4py,注意使用pip安装的话可能会报错。
module load mpich/3.4.1-gcc9.3
conda install mpi4py
其中 requirements.txt
在原本的基础上改为(按原来的transformers版本安装会报错):
deepspeed
datasets
tokenizers==0.15.2
transformers
tensorboard
fire==0.4.0
pytz==2021.1
loguru==0.5.3
sh==1.14.2
pytest==6.2.5
tqdm==4.62.3
3 云服务器上运行deepspeed后端的Communication Benchmarks
4 云服务器上运行deepspeed后端的GPT
5 DeepSpeed代码结构分析
使用DeepSpeed的基本结构:
import deepspeed
import argparse
from torchvision.models import AlexNet
# 读取命令行参数,必须加上“local rank”
parser= argparse.ArgumentParser()
parser.add_argument("--local_rank", type=int, default=-1, help="local_rank for distributed training on gpus")
parser.add_argument('--backend', type=str, default='nccl', help='distributed backend')
parser = deepspeed.add_config_arguments(parser) # 将添加一个["deepspeed", "deepspeed_config", "deepscale", "deepscale_config", "deepspeed_mpi"]组成的argument_group
args = parser.parse_args()
# 定义ds_config配置,json格式,根据需要修改
ds_config = {
"train_micro_batch_size_per_gpu": 64,
"optimizer": {
"type": "Adam",
"params": {
"lr": 0.0002
}
}
}
# 获取数据集
dataset = torchvision.datasets.CIFAR10(root=dl_path,
train=True,
download=False,
transform=transform)
dataloader = torch.utils.data.DataLoader(dataset, batch_size=batchSize, shuffle=True, num_workers=num_workers)
# 根据local_rank选择用于训练的卡
device = torch.device("cuda", args.local_rank)
# 初始化分布式训练环境
deepspeed.init_distributed()
# 初始化deepspeed环境下的模型
model = AlexNet(num_classes=10)
model_engine, optimizer, _, _ = deepspeed.initialize(args=args, model=model, model_parameters=model.parameters(), optimizer=optimizer, config=ds_config)
# 训练模型
for epoch in range(epochs):
for step, data in enumerate(dataloader, 0):
batch_data = data[0].to(device)
loss = model(batch_data) # 前向传播
model.backward(loss) # 反向传播
model.step() # 梯度更新
if step % print_every == 0:
print("Loss: {0:.4f}".format(loss))
使用DeepSpeed的pipeline结构:
import deepspeed
import argparse
from torchvision.models import AlexNet
# 读取命令行参数,必须加上“local rank”
parser= argparse.ArgumentParser()
parser.add_argument("--local_rank", type=int, default=-1, help="local_rank for distributed training on gpus")
parser.add_argument('--backend', type=str, default='nccl', help='distributed backend')
parser = deepspeed.add_config_arguments(parser) # 将添加一个["deepspeed", "deepspeed_config", "deepscale", "deepscale_config", "deepspeed_mpi"]组成的argument_group
args = parser.parse_args()
# 定义ds_config配置,json格式,根据需要修改
ds_config = {
"train_micro_batch_size_per_gpu": 64,
"optimizer": {
"type": "Adam",
"params": {
"lr": 0.0002
}
}
}
# 获取数据集
dataset = torchvision.datasets.CIFAR10(root=dl_path,
train=True,
download=False,
transform=transform)
dataloader = torch.utils.data.DataLoader(dataset, batch_size=batchSize, shuffle=True, num_workers=num_workers)
# 根据local_rank选择用于训练的卡
device = torch.device("cuda", args.local_rank)
# 初始化分布式训练环境
deepspeed.init_distributed()
# 初始化deepspeed环境下的模型
model = AlexNet(num_classes=10)
model = PipelineModule(layers=join_layers(model),
loss_fn=torch.nn.CrossEntropyLoss(),
num_stages=4,
partition_method="parameter",
activation_checkpoint_interval=0)
model_engine, optimizer, _, _ = deepspeed.initialize(args=args, model=model, model_parameters=[p for p in model.parameters() if p.requires_grad], training_data=trainset, optimizer=optimizer, config=ds_config)
# 训练模型
for epoch in range(epochs):
for step, data in enumerate(dataloader, 0):
batch_data = data[0].to(device)
loss = engine.train_batch() # 前向传播 + 反向传播 + 梯度更新
if step % print_every == 0:
print("Loss: {0:.4f}".format(loss))
6 参考文档:
- 官方文档:https://www.deepspeed.ai/tutorials/
- Huggingface教程:https://huggingface.co/docs/transformers/main/deepspeed
- 源代码:
- 示例程序代码:https://github.com/microsoft/DeepSpeedExamples/
- Megatron-DeepSpeed示例代码:https://github.com/microsoft/Megatron-DeepSpeed
- 知乎:https://zhuanlan.zhihu.com/p/630734624