完全图解GPT-2:看完这篇就够了

完全图解GPT-2:看完这篇就够了

原文:illustrated-gpt2

作者:Jay Alammar

机器之心编译,参与:郭元晨、陈韵莹、Geek AI。

转自:完全图解GPT-2:看完这篇就够了(一)完全图解GPT-2:看完这篇就够了(二)

在过去的一年中,BERT、Transformer XL、XLNet 等大型自然语言处理模型轮番在各大自然语言处理任务排行榜上刷新最佳纪录,可谓你方唱罢我登场。其中,GPT-2 由于其稳定、优异的性能吸引了业界的关注。

今年涌现出了许多机器学习的精彩应用,令人目不暇接,OpenAI 的 GPT-2 就是其中之一。它在文本生成上有着惊艳的表现,其生成的文本在上下文连贯性和情感表达上都超过了人们对目前阶段语言模型的预期。仅从模型架构而言,GPT-2 并没有特别新颖的架构,它和只带有解码器的 transformer 模型很像。

然而,GPT-2 有着超大的规模,它是一个在海量数据集上训练的基于 transformer 的巨大模型。GPT-2 成功的背后究竟隐藏着什么秘密?本文将带你一起探索取得优异性能的 GPT-2 模型架构,重点阐释其中关键的自注意力(self-attention)层,并且看一看 GPT-2 采用的只有解码器的 transformer 架构在语言建模之外的应用。

作者之前写过一篇相关的介绍性文章「The Illustrated Transformer」,本文将在其基础上加入更多关于 transformer 模型内部工作原理的可视化解释,以及这段时间以来关于 transformer 模型的新进展。基于 transformer 的模型在持续演进,我们希望本文使用的这一套可视化表达方法可以使此类模型更容易解释。

第一部分:GPT-2 和语言建模

首先,究竟什么是语言模型(language model)?

何为语言模型

简单说来,语言模型的作用就是根据已有句子的一部分,来预测下一个单词会是什么。最著名的语言模型你一定见过,就是我们手机上的输入法,它可以根据当前输入的内容智能推荐下一个词。

在这里插入图片描述

从这个意义上说,我们可以说 GPT-2 基本上相当于输入法的单词联想功能,但它比你手机上安装的此类应用大得多,也更加复杂。OpenAI 的研究人员使用了一个从网络上爬取的 40GB 超大数据集「WebText」训练 GPT-2,该数据集也是他们的工作成果的一部分。

如果从占用存储大小的角度进行比较,我现在用的手机输入法「SwiftKey」也就占用了 50MB 的空间,而 GPT-2 的最小版本也需要至少 500MB 的空间来存储它的全部参数,最大版本的 GPT-2 甚至需要超过 6.5GB 的存储空间。

在这里插入图片描述

读者可以用 AllenAI GPT-2 Explorer 来体验 GPT-2 模型。它可以给出可能性排名前十的下一个单词及其对应概率,你可以选择其中一个单词,然后看到下一个可能单词的列表,如此往复,最终完成一篇文章。

使用 Transformers 进行语言建模

正如本文作者在「The Illustrated Transformer 」这篇文章中所述,原始的 transformer 模型由编码器(encoder)和解码器(decoder)组成,二者都是由被我们称为「transformer 模块」的部分堆叠而成。这种架构在机器翻译任务中取得的成功证实了它的有效性,值得一提的是,这个任务之前效果最好的方法也是基于编码器-解码器架构的。

在这里插入图片描述

Transformer 的许多后续工作尝试去掉编码器或解码器,也就是只使用一套堆叠得尽可能多的 transformer 模块,然后使用海量文本、耗费大量的算力进行训练(研究者往往要投入数十万美元来训练这些语言模型,而在 AlphaStar 项目中则可能要花费数百万美元)。

在这里插入图片描述

那么我们究竟能将这些模块堆叠到多深呢?事实上,这个问题的答案也就是区别不同 GPT-2 模型的主要因素之一,如下图所示。「小号」的 GPT-2 模型堆叠了 12 层,「中号」24 层,「大号」36 层,还有一个「特大号」堆叠了整整 48 层。

在这里插入图片描述

与 BERT 的区别

First Law of Robotics
A robot may not injure a human being or, through inaction, allow a human being to come to harm.

机器人第一法则

机器人不得伤害人类,或者目睹人类将遭受危险而袖手旁观。

GPT-2 是使用「transformer 解码器模块」构建的,而 BERT 则是通过「transformer 编码器」模块构建的。我们将在下一节中详述二者的区别,但这里需要指出的是,二者一个很关键的不同之处在于:GPT-2 就像传统的语言模型一样,一次只输出一个单词(token)。下面是引导训练好的模型「背诵」机器人第一法则的例子:

在这里插入图片描述

这种模型之所以效果好是因为在每个新单词产生后,该单词就被添加在之前生成的单词序列后面,这个序列会成为模型下一步的新输入。这种机制叫做自回归(auto-regression),同时也是令 RNN 模型效果拔群的重要思想。

在这里插入图片描述

GPT-2,以及一些诸如 TransformerXL 和 XLNet 等后续出现的模型,本质上都是自回归模型,而 BERT 则不然。这就是一个权衡的问题了。虽然没有使用自回归机制,但 BERT 获得了结合单词前后的上下文信息的能力,从而取得了更好的效果。XLNet 使用了自回归,并且引入了一种能够同时兼顾前后的上下文信息的方法。

Transformer 模块的演进

原始的 transformer 论文引入了两种类型的 transformer 模块,分别是:编码器模块和解码器模块。

编码器模块

首先是编码器(encoder)模块:

在这里插入图片描述

原始 transformer 论文中的编码器模块可以接受长度不超过最大序列长度(如 512 个单词)的输入。如果序列长度小于该限制,我们就在其后填入预先定义的空白单词(如上图中的 <pad>)。

解码器模块

其次是解码器模块,它与编码器模块在架构上有一点小差异——加入了一层使得它可以重点关注编码器输出的某一片段,也就是下图中的编码器-解码器自注意力(encoder-decoder self-attention)层。

在这里插入图片描述

解码器在自注意力(self-attention)层上还有一个关键的差异:它将后面的单词掩盖掉了。但并不像 BERT 一样将它们替换成特殊定义的单词 <mask>,而是在自注意力计算的时候屏蔽了来自当前计算位置右边所有单词的信息。

举个例子,如果我们重点关注 4 号位置单词及其前续路径,我们可以模型只允许注意当前计算的单词以及之前的单词:

在这里插入图片描述

能够清楚地区分 BERT 使用的自注意力(self-attention)模块和 GPT-2 使用的带掩模的自注意力(masked self-attention)模块很重要。普通的自注意力模块允许一个位置看到它右侧单词的信息(如下左图),而带掩模的自注意力模块则不允许这么做(如下右图)。

在这里插入图片描述

只包含解码器的模块

在 transformer 原始论文发表之后,一篇名为「Generating Wikipedia by Summarizing Long Sequences」的论文提出用另一种 transformer 模块的排列方式来进行语言建模——它直接扔掉了所有的 transformer 编码器模块……我们姑且就管它叫做「Transformer-Decoder」模型吧。这个早期的基于 transformer 的模型由 6 个 transformer 解码器模块堆叠而成:

在这里插入图片描述

图中所有的解码器模块都是一样的,因此本文只展开了第一个解码器的内部结构。可以看见,它使用了带掩模的自注意力层。请注意,该模型在某个片段中可以支持最长 4000 个单词的序列,相较于 transformer 原始论文中最长 512 单词的限制有了很大的提升。

这些解码器模块和 transformer 原始论文中的解码器模块相比,除了去除了第二个自注意力层之外,并无很大不同。一个相似的架构在字符级别的语言建模中也被验证有效,它使用更深的自注意力层构建语言模型,一次预测一个字母/字符。

OpenAI 的 GPT-2 模型就用了这种只包含编码器(decoder-only)的模块。

GPT-2 内部机制速成

Look inside and you will see, The words are cutting deep inside my brain. Thunder burning, quickly burning, Knife of words is driving me insane, insane yeah. ——Budgie

在我内心,字字如刀;电闪雷鸣,使我疯癫。——Budgie

接下来,我们将深入剖析 GPT-2 的内部结构,看看它是如何工作的。

在这里插入图片描述

GPT-2 可以处理最长 1024 个单词的序列。每个单词都会和它的前续路径一起「流过」所有的解码器模块。

想要运行一个训练好的 GPT-2 模型,最简单的方法就是让它自己随机工作(从技术上说,叫做生成无条件样本)。换句话说,我们也可以给它一点提示,让它说一些关于特定主题的话(即生成交互式条件样本)。在随机情况下,我们只简单地提供一个预先定义好的起始单词(训练好的模型使用 <|endoftext|> 作为它的起始单词,不妨将其称为 <s>),然后让它自己生成文字。

此时,模型的输入只有一个单词,所以只有这个单词的路径是活跃的。单词经过层层处理,最终得到一个向量。向量可以对于词汇表的每个单词计算一个概率(词汇表是模型能「说出」的所有单词,GPT-2 的词汇表中有 50000 个单词)。在本例中,我们选择概率最高的单词「The」作为下一个单词。

但有时这样会出问题——就像如果我们持续点击输入法推荐单词的第一个,它可能会陷入推荐同一个词的循环中,只有你点击第二或第三个推荐词,才能跳出这种循环。同样的,GPT-2 也有一个叫做「top-k」的参数,模型会从概率前 k 大的单词中抽样选取下一个单词。显然,在之前的情况下,top-k = 1。

在这里插入图片描述

接下来,我们将输出的单词添加在输入序列的尾部构建新的输入序列,让模型进行下一步的预测:

在这里插入图片描述

请注意,第二个单词的路径是当前唯一活跃的路径了。GPT-2 的每一层都保留了它们对第一个单词的解释,并且将运用这些信息处理第二个单词(具体将在下面一节对自注意力机制的讲解中详述),GPT-2 不会根据第二个单词重新解释第一个单词。

更加深入了解内部原理

输入编码

让我们更加深入地了解一下模型的内部细节。首先,让我们从模型的输入开始。正如我们之前讨论过的其它自然语言处理模型一样,GPT-2 同样从嵌入矩阵中查找单词对应的嵌入向量,该矩阵也是模型训练结果的一部分。

在这里插入图片描述

每一行都是一个词嵌入向量:一个能够表征某个单词,并捕获其意义的数字列表。嵌入向量的长度和 GPT-2 模型的大小有关,最小的模型使用了长为 768 的嵌入向量来表征一个单词。

所以在一开始,我们需要在嵌入矩阵中查找起始单词 <s> 对应的嵌入向量。但在将其输入给模型之前,我们还需要引入位置编码——一些向 transformer 模块指出序列中的单词顺序的信号。1024 个输入序列位置中的每一个都对应一个位置编码,这些编码组成的矩阵也是训练模型的一部分。

在这里插入图片描述

至此,输入单词在进入模型第一个 transformer 模块之前所有的处理步骤就结束了。如上文所述,训练后的 GPT-2 模型包含两个权值矩阵:嵌入矩阵和位置编码矩阵。

在这里插入图片描述

将单词输入第一个 transformer 模块之前需要查到它对应的嵌入向量,再加上 1 号位置位置对应的位置向量。

堆栈之旅

第一个 transformer 模块处理单词的步骤如下:首先通过自注意力层处理,接着将其传递给神经网络层。第一个 transformer 模块处理完但此后,会将结果向量被传入堆栈中的下一个 transformer 模块,继续进行计算。每一个 transformer 模块的处理方式都是一样的,但每个模块都会维护自己的自注意力层和神经网络层中的权重。

在这里插入图片描述

回顾自注意力机制

语言的含义是极度依赖上下文的,比如下面这个机器人第二法则:

Second Law of Robotics
A robot must obey the orders given it by human beings except where such orders would conflict with the First Law.

机器人第二法则

机器人必须遵守人类给的命令,除非该命令违背了第一法则

我在这句话中高亮表示了三个地方,这三处单词指代的是其它单词。除非我们知道这些词指代的上下文联系起来,否则根本不可能理解或处理这些词语的意思。当模型处理这句话的时候,它必须知道:

  • 「它」指代机器人
  • 「命令」指代前半句话中人类给机器人下的命令,即「人类给它的命令」
  • 「第一法则」指机器人第一法则的完整内容

这就是自注意力机制所做的工作,它在处理每个单词(将其传入神经网络)之前,融入了模型对于用来解释某个单词的上下文的相关单词的理解。具体做法是,给序列中每一个单词都赋予一个相关度得分,之后对他们的向量表征求和。

举个例子,最上层的 transformer 模块在处理单词「it」的时候会关注「a robot」,所以「a」、「robot」、「it」这三个单词与其得分相乘加权求和后的特征向量会被送入之后的神经网络层。

在这里插入图片描述

自注意力机制沿着序列中每一个单词的路径进行处理,主要由 3 个向量组成:

  1. 查询向量(Query 向量):当前单词的查询向量被用来和其它单词的键向量相乘,从而得到其它词相对于当前词的注意力得分。我们只关心目前正在处理的单词的查询向量。
  2. 键向量(Key 向量):键向量就像是序列中每个单词的标签,它使我们搜索相关单词时用来匹配的对象。
  3. 值向量(Value 向量):值向量是单词真正的表征,当我们算出注意力得分后,使用值向量进行加权求和得到能代表当前位置上下文的向量。

在这里插入图片描述

一个简单粗暴的比喻是在档案柜中找文件。查询向量就像一张便利贴,上面写着你正在研究的课题。键向量像是档案柜中文件夹上贴的标签。当你找到和便利贴上所写相匹配的文件夹时,拿出它,文件夹里的东西便是值向量。只不过我们最后找的并不是单一的值向量,而是很多文件夹值向量的混合。

将单词的查询向量分别乘以每个文件夹的键向量,得到各个文件夹对应的注意力得分(这里的乘指的是向量点乘,乘积会通过 softmax 函数处理)。

在这里插入图片描述

我们将每个文件夹的值向量乘以其对应的注意力得分,然后求和,得到最终自注意力层的输出。

在这里插入图片描述

这样将值向量加权混合得到的结果是一个向量,它将其 50% 的「注意力」放在了单词「robot」上,30% 的注意力放在了「a」上,还有 19% 的注意力放在「it」上。我们之后还会更详细地讲解自注意力机制,让我们先继续向前探索 transformer 堆栈,看看模型的输出。

模型输出

当最后一个 transformer 模块产生输出之后(即经过了它自注意力层和神经网络层的处理),模型会将输出的向量乘上嵌入矩阵。

在这里插入图片描述

我们知道,嵌入矩阵的每一行都对应模型的词汇表中一个单词的嵌入向量。所以这个乘法操作得到的结果就是词汇表中每个单词对应的注意力得分。

在这里插入图片描述

我们简单地选取得分最高的单词作为输出结果(即 top-k = 1)。但其实如果模型考虑其他候选单词的话,效果通常会更好。所以,一个更好的策略是对于词汇表中得分较高的一部分单词,将它们的得分作为概率从整个单词列表中进行抽样(得分越高的单词越容易被选中)。通常一个折中的方法是,将 top-k 设为 40,这样模型会考虑注意力得分排名前 40 位的单词。

在这里插入图片描述

这样,模型就完成了一轮迭代,输出了一个单词。模型会接着不断迭代,直到生成一个完整的序列——序列达到 1024 的长度上限或序列中产生了一个终止符。

第一部分结语:大家好,这就是 GPT-2

本文是 GPT-2 模型工作原理的一个概览。如果你还是对自注意力层内部深层的细节很好奇,请继续关注机器之心的系列文章。我们将引入更多可视化语言来试着解释自注意力层的工作原理,同时也是为了能够更好地描述之后基于 transformer 的模型(说的就是你们,TransformerXL 还有 XLNet)。

这篇文章中有一些过分简化的地方:

  1. 混用了「单词」(word)和「词」(token)这两个概念。但事实上,GPT-2 使用字节对编码(Byte Pair Encoding)方式来创建词汇表中的词(token),也就是说词(token)其实通常只是单词的一部分。
  2. 举的例子其实是 GPT-2 在「推断/评价」(inference / evaluation)模式下运行的流程,所以一次只处理一个单词。在训练过程中,模型会在更长的文本序列上进行训练,并且一次处理多个词(token)。训练过程的批处理大小(batch size)也更大(512),而评价时的批处理大小只有 1。
  3. 为了更好地组织空间中的图像,作者画图时随意转置了向量,但在实现时需要更精确。
  4. Transformer 模块使用了很多归一化(normalization)层,这在训练中是很关键的。我们在 The Illustrated Transformer 中提到了其中一些,但本文更关注自注意力层。
  5. 有时文章需要用更多的小方块来代表一个向量,我把这些情况叫做「放大」,如下图所示。

在这里插入图片描述

第二部分:图解自注意力机制

在前面的文章中,我们用这张图来展示了自注意力机制在处理单词「it」的层中的应用:

在这里插入图片描述

在本节中,我们会详细介绍该过程是如何实现的。请注意,我们将会以试图弄清单个单词被如何处理的角度来看待这个问题。这也是我们会展示许多单个向量的原因。这实际上是通过将巨型矩阵相乘来实现的。但是我想直观地看看,在单词层面上发生了什么。

自注意力机制(不使用掩模)

首先,我们将介绍原始的自注意力机制,它是在编码器模块里计算的。先看一个简易的 transformer 模块,它一次只能处理 4 个词(token)。

自注意力机制通过以下三个主要步骤来实现:

  1. 为每个路径创建查询、键和值向量。

  2. 对于每个输入的词,通过使用其查询向量与其它所有键向量相乘得到注意力得分。

  3. 将值向量与它们相应的注意力得分相乘后求和

在这里插入图片描述

1 创建查询、键和值向量

我们重点关注第一条路径。我们用它的查询值与其它所有的键向量进行比较,这使得每个键向量都有一个对应的注意力得分。自注意力机制的第一步就是为每个词(token)路径(我们暂且忽略注意力头)计算三个向量:查询向量、键向量、值向量。

在这里插入图片描述

2 注意力得分

计算出上述三个向量后,我们在第二步中只用查询向量和键向量。我们重点关注第一个词,将它的查询向量与其它所有的键向量相乘,得到四个词中的每个词的注意力得分。

在这里插入图片描述

3 求和

现在,我们可以将注意力得分与值向量相乘。在我们对其求和后,注意力得分较高的值将在结果向量中占很大的比重。

在这里插入图片描述

注意力得分越低,我们在图中显示的值向量就越透明。这是为了表明乘以一个小的数是如何削弱向量值的影响的。

如果我们在每一个路径都执行相同的操作,最终会得到一个表征每个词的向量,它包括了这个词的适当的上下文,然后将这些信息在 transformer 模块中传递给下一个子层(前馈神经网络):

在这里插入图片描述

图解掩模自注意力机制

现在我们已经介绍了 transformer 模块中自注意力机制的步骤,接下来我们介绍掩模自注意力机制(masked self-attention)。在掩模自注意力机制中,除了第二步,其余部分与自注意力机制相同。假设模型输入只包含两个词,我们正在观察第二个词。在这种情况下,后两个词都被屏蔽了。因此模型会干扰计算注意力得分的步骤。基本上,它总是为序列中后续的词赋予 0 分的注意力得分,因此模型不会在后续单词上得到最高的注意力得分:

在这里插入图片描述

我们通常使用注意力掩模矩阵来实现这种屏蔽操作。不妨想象一个由四个单词组成的序列(例如「robot must obey orders」(机器人必须服从命令))在语言建模场景中,这个序列被分成四步进行处理——每个单词一步(假设现在每个单词(word)都是一个词(token))。由于这些模型都是批量执行的,我们假设这个小型模型的批处理大小为 4,它将整个序列(包含 4 步)作为一个批处理。

在这里插入图片描述

在矩阵形式中,我们通过将查询矩阵和键矩阵相乘来计算注意力得分。该过程的可视化结果如下所示,下图使用的是与单元格中该单词相关联的查询(或键)向量,而不是单词本身:

在这里插入图片描述

在相乘之后,我们加上注意力掩模三角矩阵。它将我们想要屏蔽的单元格设置为负无穷或非常大的负数(例如,在 GPT2 中为 -10 亿):

在这里插入图片描述

然后,对每一行执行 softmax 操作,从而得到我们在自注意力机制中实际使用的注意力得分:

在这里插入图片描述

此分数表的含义如下:

  • 当模型处理数据集中的第一个示例(第一行)时,这里只包含了一个单词(「robot」),所以 100% 的注意力都在该单词上。
  • 当模型处理数据集中的第二个示例(第二行)时,这里包含了(「robot must」),当它处理单词「must」时,48% 的注意力会在「robot」上,而另外 52% 的注意力会在「must」上。
  • 以此类推

GPT-2 的掩模自注意力机制

接下来,我们将更详细地分析 GPT-2 的掩模自注意力机制。

模型评价时:一次只处理一个词

我们可以通过掩模自注意机制的方式执行 GPT-2。但是在模型评价时,当我们的模型每轮迭代后只增加一个新单词时,沿着先前已经处理过的路径再重新计算词(tokrn)的自注意力是效率极低的。

在这种情况下,我们处理第一个词(暂时忽略 <s>

在这里插入图片描述

GPT-2 保存了词「a」的键向量和值向量。每个自注意力层包括了该词相应的键和值向量。

在这里插入图片描述

在下一次迭代中,当模型处理单词「robot」时,它不再需要为词「a」生成查询、键和值向量。它只需要复用第一次迭代中保存的向量:

在这里插入图片描述

GPT-2 自注意力机制:1-创建查询、键和值

假设模型正在处理单词「it」。对于下图中底部的模块来说,它对该词的输入则是「it」的嵌入向量+序列中第九个位置的位置编码

在这里插入图片描述

Transformer 中的每个模块都有自己的权重(之后会详细分析)。我们首先看到的是用于创建查询、键和值的权重矩阵。

在这里插入图片描述

自注意力机制将它的输入与权重矩阵相乘(并加上一个偏置向量,这里不作图示)。

相乘后得到的向量从基本就是单词「it」的查询、键和值向量连接 的结果。

在这里插入图片描述

将输入向量和注意力权重向量相乘(之后加上偏置向量)得到这个词的键、值和查询向量。

GPT-2 自注意力机制:1.5-分裂成注意力头

在前面的示例中,我们直接介绍了自注意力机制而忽略了「多头」的部分。现在,对这部分概念有所了解会大有用处。自注意力机制是在查询(Q)、键(K)、值(V)向量的不同部分多次进行的。「分裂」注意力头指的是,简单地将长向量重塑成矩阵形式。在小型的 GPT-2 中,有 12 个注意力头,因此这是重塑矩阵中的第一维:

在这里插入图片描述

在前面的示例中,我们介绍了一个注意力头的情况。多个注意力头可以想象成这样(下图为 12 个注意力头中的 3 个的可视化结果):

在这里插入图片描述

GPT-2 自注意力机制:2-计算注意力得分

我们接下来介绍计算注意力得分的过程——此时我们只关注一个注意力头(其它注意力头都进行类似的操作)。

在这里插入图片描述

当前关注的词(token)可以对与其它键词的键向量相乘得到注意力得分(在先前迭代中的第一个注意力头中计算得到):

在这里插入图片描述

GPT-2 自注意力机制:3-求和

正如前文所述,我们现在可以将每个值向量乘上它的注意力得分,然后求和,得到的是第一个注意力头的自注意力结果:

在这里插入图片描述

GPT-2 自注意力机制:3.5-合并多个注意力头

我们处理多个注意力头的方式是先将它们连接成一个向量:

在这里插入图片描述

但是这个向量还不能被传递到下一个子层。我们首先需要将这个隐含状态的混合向量转变成同质的表示形式。

GPT-2 自注意力机制:4-投影

我们将让模型学习如何最好地将连接好的自注意力结果映射到一个前馈神经网络可以处理的向量。下面是我们的第二个大型权重矩阵,它将注意力头的结果投影到自注意力子层的输出向量中:

在这里插入图片描述

通过这个操作,我们可以生成能够传递给下一层的向量:

在这里插入图片描述

GPT-2 全连神经网络:第一层

在全连接神经网络中,当自注意力机制已经将合适的上下文包含在其表征中之后,模块会处理它的输入词。它由两层组成:第一层的大小是模型的 4 倍(因为小型 GPT-2 的大小为 768 个单元,而这个网络将有 768*4=3072 个单元)。为什么是 4 倍呢?这只是原始 transformer 的运行大小(模型维度为 512 而模型的第一层为 2048)。这似乎给 transformer 模型足够的表征容量来处理目前面对的任务。

在这里插入图片描述

GPT-2 全连神经网络:第二层-投影到模型的维度

第二层将第一层的结果投影回模型的维度大小(小型 GPT-2 的大小为 768)。这个乘法结果是该词经过 transformer 模块处理的结果。

在这里插入图片描述

你成功处理完单词「it」了!

我们尽可能详细地介绍了 transformer 模块。现在,你已经基本掌握了 transformer 语言模型内部发生的绝大部分情况了。回顾一下,一个新的输入向量会遇到如下所示的权重矩阵:

在这里插入图片描述

而且每个模块都有自己的一组权重。另一方面,这个模型只有一个词嵌入矩阵和一个位置编码矩阵:

在这里插入图片描述

如果你想了解模型中的所有参数,下面是对它们的详细统计结果:

在这里插入图片描述

出于某些原因,该模型共计有 1 亿 2,400 万个参数而不是 1 亿 1,700 万个。我不确定这是为什么,但是这似乎就是发布的代码中的数目(如果本文统计有误,请读者指正)。

第三部分:语言建模之外

只包含解码器的 transformer 不断地表现出在语言建模之外的应用前景。在许多应用程序中,这类模型已经取得了成功,它可以用与上面类似的可视化图表来描述。在文章的最后,让我们一起来回顾一下其中的一些应用。

机器翻译

进行翻译时,模型不需要编码器。同样的任务可以通过一个只有解码器的 transformer 来解决:

在这里插入图片描述

自动摘要生成

这是第一个训练只包含解码器的 transformer 的任务。也就是说,该模型被训练来阅读维基百科的文章(没有目录前的开头部分),然后生成摘要。文章实际的开头部分被用作训练数据集的标签:

在这里插入图片描述

论文使用维基百科的文章对模型进行了训练,训练好的模型能够生成文章的摘要:

在这里插入图片描述

迁移学习

在论文 Sample Efficient Text Summarization Using a Single Pre-Trained Transformer 中,首先使用只包含解码器的 transformer 在语言建模任务中进行预训练,然后通过调优来完成摘要生成任务。结果表明,在数据有限的情况下,该方案比预训练好的编码器-解码器 transformer 得到了更好的效果。

GPT2 的论文也展示了对语言建模模型进行预训练后取得的摘要生成效果。

音乐生成

音乐 transformer 采用了只包含解码器的 transformer 来生成具有丰富节奏和动感的音乐。和语言建模相似,「音乐建模」就是让模型以一种无监督的方式学习音乐,然后让它输出样本(我们此前称之为「随机工作」)。

你可能会好奇,在这种情境下是如何表征音乐的?请记住,语言建模可以通过对字符、单词(word)、或单词(word)某个部分的词(token)的向量表征来实现。面对一段音乐演奏(暂时以钢琴为例),我们不仅要表征这些音符,还要表征速度——衡量钢琴按键力度的指标。

在这里插入图片描述

一段演奏可以被表征为一系列的 one-hot 向量。一个 MIDI 文件可以被转换成这样的格式。论文中展示了如下所示的输入序列的示例。

在这里插入图片描述

这个输入序列的 one-hot 向量表征如下:

在这里插入图片描述

我喜欢论文中用来展示音乐 transformer 中自注意力机制的可视化图表。我在这里加了一些注释:

在这里插入图片描述

这段作品中出现了反复出现的三角轮廓。当前的查询向量位于后面一个「高峰」,它关注前面所有高峰上的高音,一直到乐曲的开头。图中显示了一个查询向量(所有的注意力线来源)和正要处理的以前的记忆(突出了有更高 softmax 概率的音符)。注意力线的颜色对应于不同的注意力头,而宽度对应于 softmax 概率的权重。

如果你想进一步了解这种音符的表征,请观看视频

结语

至此,我们的 GPT-2 的完全解读,以及对父类模型(只包含解码器的 transformer)的分析就到此结束了。希望读者能通过这篇文章对自注意力机制有更好的理解。在了解了 transformer 内部的工作原理之后,下次再遇到它,你将更加得心应手。

猜你喜欢

转载自blog.csdn.net/weixin_44966641/article/details/128525934