GPT调教指南:让你的语言模型性能时时SOTA,资源已公开

共 5389字,需浏览 11分钟

 ·

2021-07-18 07:46



  新智元报道  

来源:外媒

编辑:Priscilla LQ

【新智元导读】有些语言模型虽然在一些快速实验中表现SOTA,对于任何真实应用部署,仍需特定训练,这就需要「微调」。本文提供了一份详细指南,教你如何微调常用语言模型,还会通过在twitter情感检测数据集上微调来比较其性能。


文本生成是一项有趣的NLP任务:输入提示→生成文本

 

△ T5文本到文本框架示例(来源:Google AI Blog)

 

在这一过程中,会用到某种形式的「序列到序列」这一王者模型,如语言模型——应用语言模型根据前面的句子预测接下来的单词。

 

近年来,这一研究领域非常热门,主要因为:1)有几个高性能的预训练模型可供使用; 2)NLP任务转化为「text-in text-out」问题比较容易。

 

T5开发者非常直观地呈现了这些,相同的模型可以用于语言翻译、文本回归、摘要等。


 

本文主要关注GPT-2,GPT-Neo和T5:

 

GPT-2: 它是OpenAI发布的一系列原始语言模型的第二次迭代。正是这一系列模型让GPT出名的。GPT即「Generative Pre-trained Transformer」,目前有3个版本(v1、 v2和 v3)。目前只有 GPT-1和 GPT-2是开源的,本实验将选择最新的版本。在技术方面,GPT-2的体系结构由Transformer架构的解码部分组成。

 

GPT-Neo: 该模型由EleutherAI开发,为了对抗GPT-3, 目前尚未开源,其架构与GPT-3相当类似,不过它的训练文本数据集是825 GB.

 

T5: 即「Text-to-Text Transfer Transformer」,是Google贡献的开源语言模型,展示了使用完整的编解码器架构(transformer)优于仅使用解码器(如GPT),因此T5保持了原有的transformer架构。

 

需要注意的是,每个模型都根据可调参数大小进一步发布了几个版本。本文选择的是117M 的 GPT-2,125M 的 GPT-Neo 和220M 的 T5。

 

3个模型对比如下,

 

 

情感检测任务和数据集

 

为了检验不同模型的性能,实验在对简单任务(情感检测)进行微调之后对比其准确性。

 

本测试用的是Twitter情感分析数据集,其中包含160万条推文,消极言论、积极言论均有。

 

△Twitter情感分析数据集下载地址:

https://www.kaggle.com/kazanova/sentiment140

 

为了提高计算效率,实验从中抽取了10000条推文,情感类型分布平均。

 

然后,用95%的数据训练模型,5%的数据用于测试目的。

 

为了公平比较,实验使用了相同的测试,并对所有三种模型进行分组训练。

 

最后,实验将对每个模型进行3次分别测试并对每个模型进行训练,这是一种复制3次验证试验的方法。

 

实验报告了个人和聚合(平均) f1宏评分,可用于模型的性能比较。

 

 

现在有一个问题,如何将情感检测任务转换成文本生成任务?

 

答案很简单,创建一个直观的提示符(带数据的模板) ,它可以反映出类似的表示如何在网络上发生。

 

即把一条推文作为输入,想要产生情感输出。

 

所以对于提示,实验把一条推文放在后,期待模型预测出情感,生成在下一行后面。

 

这种产生有效提示的过程叫「prompt engineering」,显示出了仅改变提示就能使语言模型表现更佳!

 

实验先从最简单的提示格式开始展示,有两种不同的提示,分别用于训练和测试,展示如下:

 

训练提示(我们希望模型学习这个「模式」来解决「任务」)

 

 

测试提示(现在我们希望模型已经学习了「任务」,因此可以完成「模式」)

 

 

因此,在测试过程中,作者只提取模型预测的、在后的单词,并将该单词作为预测的情感标签。

 

现在,实验开始!

 

微调GPT-2和GPT-Neo

 

由于GPT-2和 GPT-Neo 架构几乎相同,因此大多数微调代码保持不变。因此,为了简洁起见,作者只分享了 GPT-2的代码,但也将指出适用于 GPT-Neo 模型所需的更改。接下来就从处理数据集开始,首先创建一个 Pytorch,用它定义如何为训练准备数据。

 

 

这包括三个模块:

 

 标记和存储的数据的地方

 

:返回总数据集的长度。这是每个epoch内计算步长所必需的

 

:获取数据,然后返回

 

另外,(1) 在第8行,作者定义了用于将原始数字情感标签转换为文本标签的映射,(2)在第12行,作者将数据转换为我们决定的训练提示符,(3)在第14行,作者执行tokenization(将推文分割成token+用它们唯一的 id 替换它们)。

 

 

接下来,将数据与Dataset类连接起来。代码分解如下:

 

第4-8行:从加载数据集开始。数据集可以下载(https://www.kaggle.com/kazanova/sentiment140)并在第4行修改本地路径。接下来,只对相关列设为子集,并且重命名。在第 8 行,作者实验采样了1万条推文。

 

第10-13行:将数据拆分为训练和测试,分别为95%和5%. 使用「stratify」标志,让拆分在情感类别中均匀分布。

 

第16行:将数据传递给「Sentiment Dataset」。可以对测试数据做同样的事情,测试时只是以原始形式返回了测试数据。

 

 

现在准备训练模型。代码分解如下:

 

第10-13行:加载分词器,添加一些特殊的标记,用来表示推文的不同部分,最后加载模型。

 

请注意,第5行已经定义了模型名称:GPT-2. 另外,添加特殊标记是为了让模型学习提示的开始和结束。这有助于稍后的测试阶段,因为我们不希望模型继续写下一个单词,但模型应该知道什么时候停止书写。要实现这一点,可以设置「eos_token」,训练模型在分类标签后进行预测。

 

第16行:用之前定义的函数加载和准备数据集。

 

第21-24行:为训练过程设置配置。简而言之,定义了模型的保存位置和时间、训练时间的长度和日志保存的位置,以及使用「batch_size」、「warmup_steps」和「weight_decay」的训练策略。

 

第27-31行:连接模型与训练数据集,开始训练。在「data_collator」中定义了如何处理训练数据。collator 中的前两个元素是「input_ids」——经过标记的提示和「attention_mask」——一个简单的1/0向量,表示已标记向量的提示和填充部分。

 

最后一部分非常有趣,将输入数据作为标签传递,而不仅仅是情感标签。这是因为我们正在训练一个语言模型,因此希望模型能够学习提示的模式,而不仅仅是情感类标签。

 

从某种意义上说,该模型是在学习预测输入推文的单词+提示中结构化的情感,并在此过程中学习情感检测任务。

 

训练即将开始。计算机不同,耗费的时间也不一样。 

 

 

最后对测试块进行了定义,获取训练过的模型并将其应用于保留的测试数据。以下是代码分解:

 

第5行:在模型上开启评估模式。

 

第8-15行:对于每个测试数据,首先会准备提示,但一个很不同的地方就:不包括情绪标签,因为这是我们希望模型预测的内容。另外,我们希望模型能够预测情感标签「eos_token」,然后通过输出「eos_token」来中断操作。最后,标记测试提示。

 

第17行:接受测试提示并预测下一组单词。这个函数中有很多参数,定义了如何预测下一个词。

 

第20-30行:从解码预测文本开始,即,将预测的标记id重新转换为文本。然后我们提取预测的情感标签并将所有相关信息存储到列表中。

 

第33-37行:首先将所有提取的信息合并到pandas dataframe中,提高可读性,然后使用sklearn包中的「f1_score」函数来计算完整模型的性能。

 

在运行GPT-2代码,并在数据集拆分代码中执行三次不同的「random_state」操作时,我们观察到该模型实际上能够像预期那样进行完美预测。它能够预测标签,然后使用「eos_token」中断执行。

 

f1宏评分为81.7%. 这与实验预料中的专用情感检测模型执行的效果进行了比较,这进一步强调了在NLP中,使用文本生成模型进行迁移学习非常容易。

 

GPT-Neo兼容代码

 

为了让GPT-2代码适用于GPT-Neo,必须做出以下修改

 

  • 导入「GPTneoForCausalLM」
  • 将「model_name」设置为「EleutherAI/gpt-neo-2.7B」(从任何可用大小的模型中选择)
  • 加载模型时使用
    「GPTNeoForCausalLM」代替「GPT2LMHeadModel」。
 
运行GPT-Neo修改后的代码,并遵循相同的训练策略,f1宏评分为 80.7%
 

微调T5


T5的架构与GPT不同,T5保持原始的Transformer架构,而GPT仅保留解码器部分。
 
为训练 T5,作者使用了一个名为SimpleT5的wrapper package,它删除了训练阶段中大部分模板。虽然训练时的句法会发生变化,但整体流程和直觉仍然保持不变。
 
下面是数据部分。
 
 
从上图可以看出,大部分代码与实验之前为GPT模型所做的相同。
 
但一个最大的变化是无需Dataset一类,因为SimpleT5直接在pandas dataframe上工作。因此,团队加载数据,进行一些初始预处理,拆分数据并返回pandas dataframe。
 
无需标记创建Dataset,岂不妙哉?
 
值得注意的是,无需为此包创建提示格式。这样能够将输入的推文和情感标签分离到不同的列中,这里分别是「source_text」和「target_text」。
 
 
加载和训练模型也非常简单,只需3行代码即可完成。
 
 
下一步就是在测试数据集上测试微调的T5模型。
 
如图可见,推理部分也非常简单:第 11 行使用了predict函数并只传递「source_text」来获取预测的情感标签。
 
稍后会将其与「original_label」进行比较,生成第18行的性能分数。
 
在运行 T5 代码并遵循与之前相同的训练策略时,f1宏评分为80.7%.
 

研究结果

 
汇总所有结果就能得出以下表格:
 
 
要补充一点:在这一过程中,作者没有涉及超参数
 
作者认为,要是再加上即时工程方法,只需使用这两种方法,就可以进一步提高所有模型的性能指标
 
虽然 GPT-2 可能这一轮测试中表现更佳,但上面的表格也确实显示了文本生成模型的整体实力。三个模型在情感检测任务上都表现得非常好,只需要进行几个时期的训练。
 
即使这个实验是为单个任务完成的,作者仍然希望这能展示将TG模型用于全新的任务是有多容易。
 
在某种程度上,如果可以将NLP问题转化为文本生成问题,那预训练的模型就不会失败,或者说至少不会彻底失败。
 
各位读者感兴趣的话也不妨试着执行一下,看看会不会有更高的分数。

参考资料:

https://towardsdatascience.com/guide-to-fine-tuning-text-generation-models-gpt-2-gpt-neo-and-t5-dc5de6b3bc5e

GPT资源:http://mohitmayank.com/a_lazy_data_science_guide/natural_language_processing/GPTs.html#finetuning-gpt-2-for-sentiment-classification

T5资源:http://mohitmayank.com/a_lazy_data_science_guide/natural_language_processing/T5.html#t5-finetuning




浏览 39
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报