PAI-Rapidformer提供了丰富的模型训练加速方法,您只需要安装Rapidformer专属镜像,即可通过黑盒或者白盒化的方式对模型训练进行优化。本文为您介绍如何使用Rapidformer优化PyTorch版的Transformer模型训练。
前提条件
- 已安装Rapidformer镜像,详情请参见安装Rapidformer镜像。
- 已学习了解Rapidformer训练参数配置,详情请参见参数配置指导。
- 已学习了解Rapidformer的API接口使用,详情参见Rapidformer API。
背景信息
Rapidformer可通过黑盒或者白盒化的方式对模型训练进行加速:
- 黑盒化加速
利用Rapidformer提供的CLI,可以在不接触代码的情况下通过简单的配置就能实现对模型训练的加速能力,使用黑盒化加速的前提是需要对数据和模型进行注册。应用实践示例如下:
- 白盒化加速
利用Rapidformer提供的CLI,用户可以在不接触代码的情况下对任务进行加速。除此之外,Rapidformer还为特定用户提供了基于模版的代码自定义模式,用户可以高度灵活的在代码模版中进行数据或者模型的自定义,然后通过
--user-script
参数传给Rapidformer的CLI来进行加速。应用实践示例如下:- 借助Data/Model Hub的白盒化加速示例
- 不借助Data/Model Hub全自定义加速(更加灵活)
黑盒化加速:加速微调Huggingface模型
黑盒化加速:加速预训练Huggingface模型
白盒化加速:基于Finetuner代码模版的Huggingface模型微调
下面介绍利用Rapidformer提供的Finetuner代码模版快速构建Huggingface微调任务。在代码模版中有四个函数需要关注:
- 制作数据的
train_valid_test_datasets_provider
- 构造模型、优化器、学习率调节器的
model_optimizer_lr_scheduler_provider
- 前向运算逻辑的
run_forward_step
- 进行边train边eval计算精度的
run_compute_metrics
class MyFintuner(Finetuner):
def __init__(self, engine):
super().__init__(engine=engine)
# 获取训练/验证/测试数据集
# 输入:无
# 输出:三个对象以及一个对象函数
def train_valid_test_datasets_provider(self):
return train_dataset, valid_dataset, test_dataset, collate_f
# 创建模型/优化器/学习率规划器
# 输入:无
# 输出:三个对象
def model_optimizer_lr_scheduler_provider(self):
return model, optimizer, lr_scheduer
#编写前向逻辑
# 输入:batch 或者 iterator,model
# 输出:loss
def run_forward_step(self, batch_or_iterator, model):
return loss
#编写验证集评估逻辑, 微调专用
# 输入:model,验证集数据加载器
# 输出:metric对象
def run_compute_metrics(self, model, eval_dataloader):
return metric
熟悉以上自定义的代码模版后,请先参考黑盒化加速:加速微调Huggingface模型示例,准备好数据集和模型,再进行以下步骤。
白盒化加速:基于Pretrainer代码模版的Huggingface模型预训练
利用Rapidformer提供的Pretrainer代码模版快速构建Huggingface模型预训练任务时,在代码模版中有以下几个个函数需要关注:
- 制作数据的
train_valid_test_datasets_provider
- 构造模型、优化器、学习率调节器的
model_optimizer_lr_scheduler_provider
- 前向运算逻辑的
run_forward_step
熟悉以上自定义的代码模版后,请先参考黑盒化加速:加速微调Huggingface模型示例,准备好数据集和模型,再进行以下步骤。
白盒化加速:用户自定义Trainer的Huggingface模型微调
针对用户自定义Trainer的程序,Rapidformer提供非常有限的加速能力,比如Apex优化器、模型状态切分、计算图优化等。由于混合精度训练涉及到对用户训练过程较多的修改,因此我们推荐您使用上面提供的基于代码模版的方法来实施对训练程序的加速。以下针对一个典型的huggingface微调代码进行侵入式的加速。
huggingface微调代码示例如下。
import torch
from datasets import load_dataset, load_metric
from torch.utils.data import DataLoader
from transformers import (
AdamW,
AutoModelForSequenceClassification,
AutoTokenizer,
get_linear_schedule_with_warmup,
BertForSequenceClassification,
)
tokenizer = AutoTokenizer.from_pretrained("bert-base-cased")
datasets = load_dataset("glue", "mrpc")
metric = load_metric("glue", "mrpc")
def tokenize_function(examples):
# max_length=None => use the model max length (it's actually the default)
outputs = tokenizer(examples["sentence1"], examples["sentence2"], truncation=True, max_length=None)
return outputs
tokenized_datasets = datasets.map(
tokenize_function,
batched=True,
remove_columns=["idx", "sentence1", "sentence2"],
)
model = AutoModelForSequenceClassification.from_pretrained("bert-base-cased", return_dict=True)
optimizer = AdamW(params=model.parameters(), lr=args.lr, correct_bias=True)
lr_scheduler = get_linear_schedule_with_warmup(
optimizer=optimizer,
num_warmup_steps=args.lr_warmup_iters,
num_training_steps=args.train_iters
)
device = torch.device("cuda", args.local_rank)
for epoch in range(args.epochs):
model.train()
for step, batch in enumerate(train_dataloader):
batch.to(device)
outputs = model(**batch)
loss = outputs.loss
loss.backward()
optimizer.step()
lr_scheduler.step()
optimizer.zero_grad()
model.eval()
for step, batch in enumerate(eval_dataloader):
batch.to(device)
with torch.no_grad():
outputs = model(**batch)
predictions = outputs.logits.argmax(dim=-1)
metric.add_batch(
predictions=engine.gather(predictions),
references=engine.gather(batch["labels"]))
eval_metric = metric.compute()
print("epoch {}: {}".format(epoch, eval_metric))
这段代码存在一些问题,比如不支持数据并行训练、优化器也比较慢、不支持混合精度训练等。以下借助Rapidformer提供的API来对这段示例自定义代码进行改造。白盒化加速:基于Pretrainer代码模版的Megatron模型预训练
熟悉了上面的白盒化加速:用户自定义Trainer的Huggingface模型微调实践,您可以进一步更加灵活的绕过Data、Model Hub,在函数train_valid_test_datasets_provider
中编写自定义数据的创建逻辑, 在函数model_optimizer_lr_scheduler_provider
中编写自定义创建模型的逻辑,同时在run_forward_step
中自定义的前向逻辑。