GPT-2 预训练模型及文本生成

3,896 阅读8分钟

OpenAI 在论文 Improving Language Understanding by Generative Pre-Training 中提出了 GPT 模型。GPT 模型是由单向 Transformer 的解码器构建的模型,OpenAI 团队在一个非常大的书籍数据集 the Toronto Book Corpus 上对其进行了无监督预训练。

而后,OpenAI 团队又提出了 GPT-2 模型,GPT-2 模型是 GPT 模型的后继,使用了更大的训练集训练,有更多的参数,是 GPT 模型的扩大版。GPT-2 的训练集为数量有 8 百万的网页,由研究人员从网络上爬取得到,大小共有 40 GB 的文本数据,训练任务为给出上文,使模型预测下一个单词。

由于 GPT 与 GPT-2 模型的差别就在于 GPT-2 使用了更多的训练数据,增加了模型参数,在具体结构上并无较大差异。所以,下面我们主要介绍实际表现更优异的 GPT-2 模型。

GPT-2 核心思想

根据研究发现,语言有灵活的表达能力,即能够将任务、输入、输出表示成一个字符串,并且模型可以用这种形式的字符串进行训练,学习相应任务。例如,在翻译任务中,一个训练样本可以被写成

(translate to french, english text, french text)

同样地,在阅读理解任务中,一个训练样本可以被写成

(answer the question, document, question, answer)

并且,人们可以用以上格式的多种任务的训练样本同时训练一个模型,使得该模型获得同时执行多种任务的能力。

于是 OpenAI 研究人员推测,一个具有足够能力的语言模型将学习到推理和执行训练样本中所展示出的任务,以便更好地预测它们。如果一个语言模型能够做到这一点,那么它实际上就是在进行无监督的多任务学习。于是研究人员决定通过分析语言模型在各种各样的任务上的性能来测试这种情况是否属实,这样便有了 GPT-2 的产生。

而且正如他们所推测的,GPT-2 在多种任务上的性能表现很好,具体如下图:

来源

所以 GPT-2 对于其他预训练模型的一个突破就在于,它能够在未针对特定下游任务进行训练的条件下,就在下游任务如:阅读理解、机器翻译、问答和文本概括上有很好的表现。这也表明了,在模型足够大,训练数据足够充足时,无监督训练技术也能训练出在多种下游任务上有很好表现的模型。

因为监督学习需要大量的数据,并且需要被仔细清理过的数据,想要得到这样的数据需要昂贵的人力成本。无监督学习可以克服这个缺点,因为它不需要人工标注,有大量现成的数据可以利用。这也表明了 GPT-2 模型研究的意义。

在了解了构建 GPT-2 模型的思想后,接下来我们将详细了解一下 GPT-2 模型的结构。

GPT-2 模型结构

GPT-2 的整体结构如下图,GPT-2 是以 Transformer 为基础构建的, 使用字节对编码的方法进行数据预处理,通过预测下一个词任务进行预训练的语言模型,下面我们从 GPT-2 的预处理方法出发,来一步步详细解析一下 GPT-2。

字节对编码

GPT-2 模型在数据预处理时使用了字节对编码(Byte Pair Encoding,简称 BPE)方法,BPE 是一种能够解决未登录词问题,并减小词典大小的方法。它综合利用了单词层面编码和字符层面编码的优势,举例来说,我们要对下面的字符串编码,

aaabdaaabac

字节对 aa 出现的次数最多,所以我们将它替换成一个没在字符串中被用过的字符 Z ,

ZabdZabac
Z=aa

然后我们重复这个过程,用 Y 替换 ab ,

ZYdZYac
Y=ab
Z=aa

继续,用 X 替换 ZY ,

XdXac
X=ZY
Y=ab
Z=aa

这个过程重复进行,直到没有字节对出现超过一次。当需要解码时,就将上述替换过程反向进行。

下面是一段 BPE 算法原文中对 BPE 算法的实现:

image.png

image.png

单向 Transformer 解码器结构

GPT-2 模型由多层单向 Transformer 的解码器部分构成,本质上是自回归模型,自回归的意思是指,每次产生新单词后,将新单词加到原输入句后面,作为新的输入句。其中 Transformer 解码器结构如下图:

来源

GPT-2 模型中只使用了多个 Masked Self-Attention 和 Feed Forward Neural Network 两个模块。如下图所示:

来源

可以看到,GPT-2 模型会将语句输入上图所示的结构中,预测下一个词,然后再将新单词加入,作为新的输入,继续预测。损失函数会计算预测值与实际值之间的偏差。

从上一节我们了解到 BERT 是基于双向 Transformer 结构构建,而 GPT-2 是基于单向 Transformer,这里的双向与单向,是指在进行注意力计算时,BERT会同时考虑被遮蔽词左右的词对其的影响,而 GPT-2 只会考虑在待预测词位置左侧的词对待预测词的影响。

通过上述数据预处理方法和模型结构,以及大量的数据训练出了 GPT-2 模型。OpenAI 团队由于安全考虑,没有开源全部训练参数,而是提供了小型的预训练模型,接下来我们将在 GPT-2 预训练模型的基础上进行实验。

GPT-2 文本生成

GPT-2 就是一个语言模型,能够根据上文预测下一个单词,所以它就可以利用预训练已经学到的知识来生成文本,如生成新闻。也可以使用另一些数据进行微调,生成有特定格式或者主题的文本,如诗歌、戏剧。所以接下来,我们会用 GPT-2 模型进行一个文本生成实验。

预训练模型生成新闻

想要直接运行一个预训练好的 GPT-2 模型,最简单的方法是让它自由工作,即随机生成文本。换句话说,在开始时,我们给它一点提示,即一个预定好的起始单词,然后让它自行地随机生成后续的文本。

但这样有时可能会出现问题,例如模型陷入一个循环,不断生成同一个单词。为了避免这种情况, GPT-2 设置了一个 top-k 参数,这样模型就会从概率前 k 大的单词中随机选取一个单词,作为下一个单词。下面是选择 top-k 的函数的实现,

image.png 下面引入 GPT-2 模型,我们将使用在 PyTorch-Transformers 模型库中封装好的 GPT2Tokenizer() 和 GPT2LMHeadModel() 类来实际看一下 GPT-2 在预训练后的对下一个词预测的能力。首先,需要安装 PyTorch-Transformers。

image.png 接下来使用 GPT2LMHeadModel() 建立模型,并将模型模式设为验证模式。由于预训练模型参数体积很大,且托管在外网,所以本次实验先从蓝桥云课镜像服务器下载预训练模型,本地实验无需此步骤。

image.png 运行结束后,我们观察一下模型生成的文本,可以看到,大致感觉上这好像是一段正常的文本,不过,仔细看就会发现语句中的逻辑问题,这也是之后研究人员会继续攻克的问题。

除了直接利用预训练模型生成文本,我们还可以使用微调的方法使 GPT-2 模型生成有特定风格和格式的文本。

微调生成戏剧文本

接下来,我们将使用一些戏剧剧本对 GPT-2 进行微调。由于 OpenAI 团队开源的 GPT-2 模型预训练参数为使用英文数据集预训练后得到的,虽然可以在微调时使用中文数据集,但需要大量数据和时间才会有好的效果,所以这里我们使用了英文数据集进行微调,从而更好地展现 GPT-2 模型的能力。

首先,下载训练数据集,这里使用了莎士比亚的戏剧作品《罗密欧与朱丽叶》作为训练样本。数据集我们已经提前下载好并放在蓝桥云课服务器中,可以通过以下命令下载。 !wget -nc "https://labfile.oss.aliyuncs.com/courses/1372/romeo_and_juliet.zip" !unzip -o "romeo_and_juliet.zip"

image.png

image.png

image.png

image.png

image.png

以上是购买的课程记录下来的过程,