AI技术干货|深入探索如何微调大型预训练模型(下篇)
金博士| 流媒体网| 2024-03-18
【流媒体网】摘要:深入探索高级的训练器(Trainer)API。

  本文导读:本篇是“基于开源大模型库快速实现AI应用”系列教程的一部分。在前一篇《深度解析Transformer大模型管道背后的原理》中,我们通过一个实例详细展示了如何结合模型和分词器,来复现《开源Transformer模型实现NLP文本应用》中提到的管道(pipeline)功能。文章还深入探讨了分词器的工作原理,并在文末讲解了如何用大模型处理多句子,以及相关的注意事项。

  本文将进一步引导读者,展示如何针对特定数据集优化预训练模型。我们首先会介绍如何获取开源项目中的各类基础数据集,为微调工作打下坚实基础。之后,我们将深入探索高级的训练器(Trainer)API,这为模型微调提供了一个便捷的接口。同时,为了满足特定需求,本文也会指导您如何实现自定义的训练循环。鉴于当前的训练任务常在分布式环境下完成,我们还会介绍如何借助特定的加速库来简化这一流程,使之适应各种硬件配置。整体而言,本章的目标是为您提供一整套工具和方法,帮助您更有效地利用预训练模型,在各类任务上实现更佳表现。

  关键词:预训练模型、模型微调、训练器、优化器、动态填充、数据整理函数

  前文回顾:AI技术干货|深入探索如何微调大型预训练模型(上篇)

  AI技术干货|深入探索如何微调大型预训练模型(中篇)

  7. 使用Trainer API微调模型

  Transformers为我们提供了一个Trainer类,方便我们对其所支持的任何预训练模型进行微调。在完成前一部分的数据预处理工作后,你只需要简单地设置Trainer就可以开始了。其中,最具挑战性的可能是为Trainer.train()方法配置运行环境,因为如果仅在CPU上运行,速度会相对较慢。如果你还没准备好GPU,可以考虑使用Google Colab,它为用户提供了免费的GPU或TPU资源。

  以下代码假设你已经按照前文的步骤完成了相关操作。为了方便理解,我们再回顾一下之前所做的准备工作:

  from datasets import load_dataset

  from transformers import AutoTokenizer, DataCollatorWithPadding

  raw_datasets = load_dataset("glue", "mrpc")

  checkpoint = "bert-base-uncased"

  tokenizer = AutoTokenizer.from_pretrained(checkpoint)

  def tokenize_function(example):

  return tokenizer(example["sentence1"], example["sentence2"], truncation=True)

  tokenized_datasets = raw_datasets.map(tokenize_function, batched=True)

  data_collator = DataCollatorWithPadding(tokenizer=tokenizer)

  7.1. 训练

  在开始定义Trainer之前,我们首先需要配置一个TrainingArguments类。这个类中包含了Trainer在训练和评估过程中所需的所有超参数。

  7.1.1. TrainingArguments介绍

  Hugging Face的Transformers库为训练和微调Transformer模型提供了一个简洁且功能强大的接口。其中,TrainingArguments类是一个中心组件,它定义了训练过程中的各种参数和设置。这个类大大简化了用户与训练循环之间的交互,让用户能够轻松地自定义训练过程。

  1. 定义

  TrainingArguments类是一个用于存储与训练相关的所有参数的容器。这些参数包括学习率、批大小、训练轮数、日志设置、模型保存路径等。

  2. 主要参数

  learning_rate:学习率。

  per_device_train_batch_size:每个设备的训练批大小。

  num_train_epochs:训练的总轮数。

  logging_dir:日志保存的目录,用于TensorBoard可视化。

  logging_steps:每隔多少步记录一次日志。

  save_steps:每隔多少步保存一次模型。

  eval_steps:每隔多少步评估一次模型。

  output_dir:模型和训练结果的保存目录。

  evaluation_strategy:评估策略,例如“每轮”或“每步”。

  warmup_steps:学习率预热的步数。

  weight_decay:权重衰减。

   ... 还有许多其他参数。

  3. 如何使用

  用户只需创建一个TrainingArguments实例,并设置所需的参数。然后,这个实例可以传递给Trainer类,以便在训练过程中使用。

  from transformers import TrainingArguments

  args = TrainingArguments(

  output_dir="./results",

  per_device_train_batch_size=16,

  num_train_epochs=3,

  logging_dir="./logs",

  logging_steps=10,

  )

  4. 灵活性

  TrainingArguments类提供了大量的参数,可以用于微调训练过程。这为用户提供了很大的灵活性,使其能够根据具体任务的需要进行定制。

  5. 与Hugging Face生态系统的集成

  与TrainingArguments紧密集成的Trainer类提供了一个高级的训练接口。用户可以轻松地结合使用这两个类,进行模型的训练和微调。

  总之,Hugging Face的TrainingArguments类为用户提供了一个直观且功能丰富的方式来定义和控制训练过程中的各种参数。它与Transformers库中的其他组件无缝集成,使得训练和微调Transformer模型变得非常简单和高效。

  7.1.2. 定义训练器-Trainer

  您需要提供的主要参数是一个目录路径,用于保存训练过程中的模型和各个阶段的检查点。对于其他参数,您可以使用默认设置,这对于基本的模型微调已经足够了。

  from transformers import TrainingArguments

  training_args = TrainingArguments("test-trainer")

  第二步是定义我们的模型。就像在前面的教程一样,我们将使用AutoModelForSequenceClassification类,有两个标签:

  from transformers import AutoModelForSequenceClassification

  model = AutoModelForSequenceClassification.from_pretrained(checkpoint, num_labels=2)

  您会注意到,您在实例化这个预训练模型后会收到一个警告。这是因为BERT没有在分类句子对上进行预训练,所以预训练模型的头部已被丢弃,取而代之的是一个适合序列分类的新头部。警告表示一些权重没有被使用(对应于被丢弃的预训练头)而另一些权重被随机初始化(对应于新头部)。它得出的结论是鼓励您训练模型,这正是我们现在要做的。

  一旦我们有了模型,我们可以通过传递到现在为止构造的所有对象——model、training_args、训练和验证数据集、我们的data_collator和我们的tokenizer来定义一个Trainer:

  from transformers import Trainer

  trainer = Trainer(

  model,

  training_args,

  train_dataset=tokenized_datasets["train"],

  eval_dataset=tokenized_datasets["validation"],

  data_collator=data_collator,

  tokenizer=tokenizer,

  )

  注意,当您像我们这样传递tokenizer时,Trainer使用的默认data_collator将是我们之前定义的DataCollatorWithPadding,所以您可以在此调用中跳过data_collator=data_collator这一行。

  要在我们的数据集上微调模型,我们只需要调用Trainer的train()方法:

  微调的过程现在开始了,如果您使用的是GPU,整个过程应该只需几分钟。但是,您可能注意到,尽管每500步都会报告训练损失,但它并没有显示模型的具体表现,也没有告诉您模型的好坏程度。造成这种情况的原因主要有两点:

  • 我们没有指定让Trainer在训练过程中进行评估。要做到这一点,我们可以通过将`evaluation_strategy`设置为"steps"(意思是每隔一定的`eval_steps`次就进行一次评估)或者"epoch"(表示在每个训练周期结束后进行评估)。

  • 我们也没有为Trainer提供一个`compute_metrics()`函数。这个函数的目的是在评估时计算某个指标。如果没有这个函数,评估时只会显示损失值,而这个值并不容易让我们直观地了解模型的表现。

  下面我们会对上述过程逐步进行完善。

VIP专享文章,请登录或扫描以下二维码查看

“码”上成为VIP会员
没有多余的门路、套路
只有简单的“值来值往”一路!

深度分析、政策解读、研究报告一应俱全
极致性价比,全年精彩内容不容错过!
更多福利,尽在VIP专享


分享到:
版权声明:凡注明来源“流媒体网”的文章,版权均属流媒体网所有,转载需注明出处。非本站出处的文章为转载,观点供业内参考,不代表本站观点。文中图片均来源于网络收集整理,仅供学习交流,版权归原作者所有。如涉及侵权,请及时联系我们删除!