Transformers 支持多种加速库,例如Fairseq使用的FairScale,这里只是使用了DeepSpeed,但加速方法不只一种
DeepSeed是一个针对大规模模型预训练和微调加速的一个库,由微软出品。
文档地址 https://www.deepspeed.ai/getting-started/
DeepSpeed对Huggingface Transformers和Pytorch Lightning都有着直接的支持
DeepSpeed加速使得微调模型的速度加快,在pre-training BERT的效果上,有着更快的计算速度,相较于原生的Huggingface Transformers有着接近1.5倍的加速
deepspeed需要使用mpi4py和cupy
pip install mpi4py deepspeed
conda install cupy
DeepSpeed是直接支持大规模集群的,所以基于OpenMPI,在学校服务器上已经安装OpenMPI,由于我们没有写入/tmp文件夹的权限,所以我们需要对OpenMPI进行设置
唯一需要的设置是指定OpenMPI的temp文件夹位置
OpenMPI的配置文件有两个位置
所以需要在自己创建$HOME/.openmpi/mca-params.conf覆盖默认设置
设置一个有权限访问的temp文件夹
orte_tmpdir_base = /where/you/have/permission/tmp
如果是在AutoDL上,直接更改/tmp权限即可
chmod 777 /tmp
在Huggingface 中使用DeepSpeed只需要写DeepSpeed的配置文件即可
官方教程https://huggingface.co/docs/transformers/tasks/language_modeling
总结下来的主要流程就是
from transformers import AutoTokenizer, AutoModelForMaskedLM
tokenizer = AutoTokenizer.from_pretrained("xlm-roberta-base")
model = AutoModelForMaskedLM.from_pretrained("xlm-roberta-base")
加载数据集
对于数据集需要处理为csv格式方便加载,加载的数据路径需要写为
data={
"train":"/train/file/path",
"valid":"/valid/file/path",
"test":"/test/file/path"
}
加载数据集方法为
from datasets import load_dataset
dataset = load_dataset('csv',data_files= data,on_bad_lines='warn', engine="python",delimiter='\t', encoding='utf-8')
对数据集进行tokenize
定义一个处理函数
tokenizer处理时需要将长度大于512的截断
xlmr系列的模型的max_length=512
def precess_data(data):
res = tokenizer(data['data'], truncation=True, max_length=512)
return res
processed_dataset = dataset.map(precess_data,batched=True)
定义Data Collator
Data Collator将数据处理为batch输入
from transformers import DataCollatorForLanguageModeling
data_collator = DataCollatorForLanguageModeling(tokenizer=tokenizer)
设置trainer
huggingfacetransformer 依靠Trainer进行训练,我们需要为Trainer设置参数,类似于fairseq的命令参数,也是在这里注入的deepspeed参数
参数详情信息参见 TainerArg
deepspeed参数保存在一个json文件中
deepspeed中的详细参数解释在deepspeed josn 参数
huggingface中设置的参数和deepspeed中参数为一样,如果不同,将会报错,如果在huggingface trainer参数中设置,可在deepspeed参数中将值设为auto
在json中不能写任何注释,就算是josn with comment (jsonc)也不能解析
{
"train_micro_batch_size_per_gpu":8,
"train_batch_size": "auto",
"gradient_accumulation_steps": 16,
"optimizer": {
"type": "ZeroOneAdam",
"params": {
"lr": 1e-5,
"weight_decay": 0.01,
"bias_correction": false,
"var_freeze_step": 1000,
"var_update_scaler": 16,
"local_step_scaler": 1000,
"local_step_clipper": 16,
"cuda_aware": false,
"comm_backend_name": "nccl"
}
},
"scheduler": {
"type": "WarmupLR",
"params": {
"warmup_min_lr": 0,
"warmup_max_lr": 1e-5,
"warmup_num_steps": 10000
}
},
"fp16": {
"enabled": true
},
"zero_optimization": {
"stage": 0
}
}
微调infoxlmr的参数为
deepspeed_config="/where/your/deepspeed/config"
training_args = TrainingArguments(
output_dir='./infoxlmr_finetune', # 保存位置
max_steps=100000,
per_device_train_batch_size=8,
gradient_accumulation_steps=16,
learning_rate=1e-5,
weight_decay=0.01,
warmup_steps=10000,
save_steps=5000,
fp16=True,
deepspeed =deepspeed_config
)
将参数注入Trainer中,并启动训练
trainer = Trainer(
model=model, # 要训练的模型
args=training_args, # Trainer参数
train_dataset=processed_dataset["train"],# 训练集
eval_dataset=processed_dataset["valid"], # 测试集
data_collator=data_collator, # Data Collator
)
trainer.train()
DeepSpeed是使用OpenMPI进行GPU通信,所以直接在huggingface Transformers中直接指定多GPU是无效的
需要写一个脚本,export CUDA_VISIBLE_DEVICES,再用Deepspeed启动训练
export CUDA_VISIBLE_DEVICES=2,3
deepspeed /where/your/finetuning/python/file
由于微调后的模型没有保存tokenizer,huggingface模型加载必须在路径中有tokenizer相关文件,需要将tokenizer放入模型文件夹中 已经保存的infoxlm下载 info_xlm tokenizer,或者在huggingface官网下载
如果 在加载过程中出现http error 404,需要将微调好的文件夹重命名
参考资料
OpenMPI参数设置
Huggingface Document
DeepSpeed Document