在Huggingface Transformers中使用DeepSpeed加速训练

Transformers 支持多种加速库,例如Fairseq使用的FairScale,这里只是使用了DeepSpeed,但加速方法不只一种

1. DeepSpeed

DeepSeed是一个针对大规模模型预训练和微调加速的一个库,由微软出品。
文档地址 https://www.deepspeed.ai/getting-started/
DeepSpeed对Huggingface Transformers和Pytorch Lightning都有着直接的支持
DeepSpeed加速使得微调模型的速度加快,在pre-training BERT的效果上,有着更快的计算速度,相较于原生的Huggingface Transformers有着接近1.5倍的加速
在Huggingface Transformers中使用DeepSpeed加速训练_第1张图片
在Huggingface Transformers中使用DeepSpeed加速训练_第2张图片

2. 配置

2.1 安装DeepSpeed及其前置安装

deepspeed需要使用mpi4py和cupy

pip install mpi4py deepspeed
conda install cupy

2.2 配置OpenMPI

DeepSpeed是直接支持大规模集群的,所以基于OpenMPI,在学校服务器上已经安装OpenMPI,由于我们没有写入/tmp文件夹的权限,所以我们需要对OpenMPI进行设置
唯一需要的设置是指定OpenMPI的temp文件夹位置
OpenMPI的配置文件有两个位置

  • $HOME/.openmpi/mca-params.conf 高优先级
  • $prefix/etc/openmpi-mca-params.conf 低优先级

所以需要在自己创建$HOME/.openmpi/mca-params.conf覆盖默认设置
设置一个有权限访问的temp文件夹

orte_tmpdir_base = /where/you/have/permission/tmp

如果是在AutoDL上,直接更改/tmp权限即可

chmod 777 /tmp

3. 使用

在Huggingface 中使用DeepSpeed只需要写DeepSpeed的配置文件即可

3.1 使用huggingface进行微调

官方教程https://huggingface.co/docs/transformers/tasks/language_modeling
总结下来的主要流程就是

  1. 加载模型与tokenizer,以xlmr为例子
from transformers import AutoTokenizer, AutoModelForMaskedLM

tokenizer = AutoTokenizer.from_pretrained("xlm-roberta-base")

model = AutoModelForMaskedLM.from_pretrained("xlm-roberta-base")
  1. 加载数据集

    对于数据集需要处理为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')
  1. 对数据集进行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)
  1. 定义Data Collator

    Data Collator将数据处理为batch输入

    from transformers import  DataCollatorForLanguageModeling
    data_collator = DataCollatorForLanguageModeling(tokenizer=tokenizer)
    
  2. 设置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()
    

3.2 在DeepSpeed中使用多卡训练

DeepSpeed是使用OpenMPI进行GPU通信,所以直接在huggingface Transformers中直接指定多GPU是无效的
需要写一个脚本,export CUDA_VISIBLE_DEVICES,再用Deepspeed启动训练

	export CUDA_VISIBLE_DEVICES=2,3
	deepspeed /where/your/finetuning/python/file

4. 在后续任务中使用微调的模型

由于微调后的模型没有保存tokenizer,huggingface模型加载必须在路径中有tokenizer相关文件,需要将tokenizer放入模型文件夹中 已经保存的infoxlm下载 info_xlm tokenizer,或者在huggingface官网下载

如果 在加载过程中出现http error 404,需要将微调好的文件夹重命名

参考资料

OpenMPI参数设置
Huggingface Document
DeepSpeed Document

你可能感兴趣的:(python,pytorch,深度学习,microsoft,神经网络)