ChatGPT 的组件:Transformer 模型结构

目录

Transformer 结构

稀疏 Transformer

稀疏 Transfomer 的思想基础

稀疏 Transformer 原理

多头(multi-head)注意力机制

Normalization 正规化

Dropout 机制

ResNet 残差模块

Linear Feed-forward 全连接层

总结


第 5 节中,我们介绍了注意力机制的工作原理,它是目前最流行的神经网络模型的灵魂机制。而相应的包裹注意力机制的实体形式,就是 Transformer 模型结构组件,我们本节重点介绍一下 Transformer。

Transformer 结构

Transformer 结构组件主要包括如下模块。

其中,(�1,�2,...,��,...,��)(x1​,x2​,...,xi​,...,xn​)就是上一节中输入的 token embedding,它是一个(������×����������)(ltoken​×lembedding​)大小的矩阵,其中,������ltoken​是输入文本的 token 个数,GPT3 中这个长度是 4097,意味着输入给 GPT3 模型的最长输入文本的 token 数总共可以有 4097 个,而����������lembedding​是每一个 token 的 embedding 维度,GPT3 中这个长度是 12280。

而图中深蓝色的 attention 模块就是上一节中介绍的 Self-Attention,它是 Transformer 模型的核心操作。除此之外,还包括扩展参数模块 Feed-Forward 层,而在每一层的前后又包括了浅蓝色 norm 层和 dropout 层。在模型的最后,还包括输出结果层 linear 层,softmax 即用于计算交叉熵的损失函数层(第 8 节介绍)。

在 GPT3 模型以及此后的各种模型中,Self-Attention 使用的并非如第 5 节所介绍的原始自注意力结构,而是一种稀疏的注意力结构,又称稀疏 Transformer(Sparse Transformer) 。

对于以上模型结构,我们一一展开介绍。

稀疏 Transformer

稀疏 Transfomer 的思想基础

Sparse Transformer 的核心实际上是 Sparse Self-Attention (稀疏自注意力机制)。我们依然使用第 5 节中的例子来介绍:

请补全这条语句:掘金社区是一个便捷的技术交流______

在这条文本中,想要补全最终的语句,应当参考前文的信息,而前文总共 14 个字,对空格处影响最大的是掘金两个字,而像形容词便捷的,系词是一个都不是最关键的影响因素。换句话说,我们应当设计一种注意力机制,让模型能够在输出空格字符的时候,最大限度地注意到掘金两个字。

如果我们根据原始的 Self-Attention 计算,假设得到的注意力权重计算结果如下形式:

��������� = (0.371,0.167,0.174,0.236,0,0,0,0.19,0,0,0.23,0,0,0)Attention = (0.371,0.167,0.174,0.236,0,0,0,0.19,0,0,0.23,0,0,0)

在这个注意力权重向量中,共有 14 个元素值,加和为 1,每一项对应输入的一个字符。可以看到,掘金社区四个字对应的权重最高,而中间很多的字符实际上对后续填补什么字影响极其微小。其实,计算这些不重要的 token 的注意力权重完全是可以规避掉的。

另一方面,Self-Attention 的计算公式为:

���������(�,�,�)=�������(�����)�Attention(Q,K,V)=softmax(dq​​QKT​)V

这是一个矩阵乘法,其中涉及矩阵乘法计算���QKT。在 ChatGPT 这样的模型中,矩阵的维度非常大,这个计算量也相当大,时间复杂度在�(�2)o(n2),其中�n是矩阵维度。如果可以避免计算某些不重要位置的注意力权重值,那么这个计算量会小很多,减少计算耗时,提高模型的计算效率。

稀疏 Transformer 的本质,就是选择不计算某些 token 位置的注意力值

稀疏 Transformer 原理

所谓稀疏(Sparse),就是不计算某些位置 token 的注意力权重值,保留想要计算的 token 位置。那么,我们可以事先定义一组 token 的位置的索引,�=(�1,�2,...,��,...,��)S=(S1​,S2​,...,Si​,...,Sn​),这些是我们想要计算的若干个 token 位置。例如,我们要计算第 14 个位置时,保留的索引位置包括�14=(0,1,2,3,5,7,10,13)S14​=(0,1,2,3,5,7,10,13)。对应了掘、金、社、区、一、便、技、流这几个字。

接下来,我们计算时就可以充分考虑待计算的索引位置,忽略不计算的索引位置。

��� = (����)� ∈ ��KSi​​ = (WK​xj​)j ∈ Si​​

在这个公式中,其中内部 ����WK​xj​表示注意力机制中 K 的转换运算,而这里表示运算过程中,仅抽取那些在索引中的位置的 embedding 进行计算。这样一来,矩阵计算量就变少了。同理,对于 �V矩阵也有相同的操作:

��� = (����)� ∈ ��VSi​​ = (WV​xj​)j ∈ Si​​

那么,�Q 矩阵可不可以减少呢?答案是不行的。

注意:�Q代表了要为哪些位置计算注意力权重,显然,我们应当为每一个位置 token 计算权重。然而,在为每一个位置计算注意力时,需要考察哪些位置,这就是�K的含义,这个位置则是可以稀疏的。

上图中共有 7 个 token 位置。其中,对于 �K 和 �V,分别只计算了第 1 和 3 个 token 的向量,其它位置的向量被忽略。这样就减少了计算量,仅抽取了部分的位置进行关注。由此,我们就得到了计算某一位置注意力权重的公式: ���������(�)=�������((����)�����)���attention(i)=softmax(d​(Wq​xi​)KSi​T​​)VSi​​。

这个式子就是上图的公式化表示,而把所有位置全部合并起来,就形成了完整的稀疏 Attention 计算公式: ���������������(�,�)=(���������(�))�∈{1,2,...,�}SparseAttention(X,S)=(attention(i))i∈{1,2,...,n}​。

在整个计算流程中,我们都在假设,已经事先确定了要保留哪些位置的索引 �=(�1,�2,...,��,...,��)S=(S1​,S2​,...,Si​,...,Sn​),用于计算注意力权重。那么,到底如何确定要保留哪些位置呢?

如前图中展示,保留的第 1 和 第 3 个 token 作为索引,其它位置则被丢弃了。一般来讲有两种常用的做法,跨步分解注意力机制(Strided Factorized Attention)  固定分解注意力机制(Fixed Factorized Attention) 。它们的原理如下图所示。

针对这幅图,我们首先看最左边这幅图,每次观察一行。深蓝色小方块代表当前要计算注意力的 token 位置,灰色部分的方块是指被忽略掉的 token,采用的是 Mask 方式(第 7 节中介绍,这里我们仅需知道这些 token 被忽略掉了,只关注蓝色方块即可)。而在每一个深蓝色方块的左侧代表了它在计算注意力时需要参考的 token 位置(浅蓝色),在传统 Transformer 中,每次计算都要参考左侧的所有位置。

例:掘金社区是一个便捷的技术交流______

传统 Transformer 实际上当计算空格 token 时,需要把前面的每一个字符掘金社区是一个便捷的技术交流全部考虑进去。

而在中间这幅图,它代表了跨步注意力机制,根据规则,当每次计算深蓝色方块的注意力时,首先需要纳入左侧临近的若干 token,然后在距离当前 token 较远位置的 token 每隔 3 个值参考一个。

例:掘金社区是一个便捷的技术交流______

跨步分解注意力机制中,实际上当计算空格 token 时,只需要计算字符社、个、技、术、交、流,以此预测字。

右侧的图中,不论计算哪一个位置,都需要观察一些固定的位置(浅蓝色)。

例:掘金社区是一个便捷的技术交流______

固定分解注意力机制中,实际上当计算空格 token 时,只需要计算字符区、便、术、交、流

读者可以参照上图,自行确定这些字符的索引位置,以加深理解。

需要说明的是,在选择哪些位置可以稀疏计算时,选择的方式方法完全可以自定义,有非常大的灵活性。上述的方法存在局限性,尤其是固定注意力机制。不论计算哪些位置的注意力,都默认忽略掉一些位置,很容易造成计算结果的错误(如上述例子中,最关键的掘金被忽略了)。所以,在 Transformer 模型中,又加入了多头注意力机制,用于综合多次 Attention 计算的结果。

多头(multi-head)注意力机制

前面讲述了制作一次注意力机制的全过程,所谓多头注意力机制,就是在模型中多做几次注意力机制,以期让模型能够注意到不同的信息。

如图所示,整个过程十分简单,设计了 N 次的注意力机制,把 N 次的结果拼接起来,就完成了输出。所谓拼接方式,如图中不同色度的绿色方块所示,假设两个注意力头计算的结果分别为�=[�0,�1,...,��]a=[a0​,a1​,...,am​],�=[�0,�1,...,��]b=[b0​,b1​,...,bn​],那么拼接后的结果就是������=[�0,�1,...,��,�0,...,��]concat=[a0​,a1​,...,am​,b0​,...,bn​]。

注意,图中仅仅展示了某一位置的 token 的计算结果,实际上的输入为所有 token embedding 构成的矩阵。

Normalization 正规化

如前 Transformer 结构图所示,在每一个 Attention 模块接入之前,都有一个 norm 模块。它是神经网络模型中常见的 Normalization 正规化模块。这里我们还是举一个例子来说明情况。

假设我们在输入稀疏 Self-Attention 模块之前,分别有 2 组具体的 token embedding 值, 维度都是 4 × 34 × 3,其中每一行代表一个 token 的 embedding 值,具体值情况如图所示。

我们观察上图表,可以看出,左侧表格矩阵中,所有元素的取值都介于 (−0.25,0.25)(−0.25,0.25) 之间,取值较为集中,分布较为均匀、稳定,而右侧表格矩阵中,所有元素取值都介于 (−3.05,3.05)(−3.05,3.05) 之间,取值波动较大,而且第二行中的 token embedding 分布又介于 (−0.2,0.2)(−0.2,0.2) 之间,取值波动又比较小,总体来看,分布不稳定,差异较大。

在神经网络模型的训练中,数据分布较为集中且均匀的话,有助于模型训练的快速推进和收敛,达到模型训练目的。相反,若数据分布分散,则模型训练困难,很容易过拟合。对于 ChatGPT 这样的大规模语言模型,尤其需要注意训练过程中数据的均匀分布,以此加速模型的稳定训练。

因此,在稀疏 Self-Attention 层之前,加入 norm 层,就是把分布松散的数据,整合为分布较为集中的数据。具体方法就是,假设我们待处理数据为 �=(�1,�2,...,��,...,��)x=(x1​,x2​,...,xi​,...,xn​),首先计算其均值和方差:

�= 1�∑��μ= n1​∑xi​

�2= 1�∑(�� − �)2σ2= n1​∑(xi​ − μ)2

然后,针对每一个值,都做一遍正规化(Normalization),embedding 就会都局限于一个稳定的分布内,方便模型的训练。

�^�= (�� − �)�x^i​= σ(xi​ − μ)​

由于这部分知识都是初中数学,这里就不再举例介绍。事实上,Normalization 一般分为 Batch Normalization、Layer Normalization 等。在 NLP 领域,常用的是 Layer Normalization,它就是指,针对每一条输入数据的所有数值元素做 norm 操作。

Dropout 机制

在 Transformer 结构图所示,在每一个 Attention 模块接入之前,都有一个 dropout 模块。这个模块的主要功能是防止模型在训练过程中的过拟合。

过拟合( O verfitting) ,是指模型在训练数据上表现良好,但在测试数据上表现较差的现象。简单来说,过拟合就是模型过于复杂,以至于在训练数据上表现得非常好,但在新数据上的泛化能力却很差。过拟合通常是由于模型过于复杂,或者训练数据过少导致的。当模型过于复杂时,它会尝试去适应训练数据中的每一个细节,甚至是噪声,导致在新数据上的表现不佳。而当训练数据过少时,模型可能无法学习到足够的特征,也会导致过拟合。

比如,一家公司宣布自己研发的 XX 大模型能够作诗、解数学题、翻译、文摘,以及回答各种各样的问题,也晒出了一些数据截图,表明自己的 XX 模型效果优异。

开放公测后,用户试用了一下,发现 XX 模型效果非常差,经常答非所问,给出错误答案。这就是典型的模型过拟合的表现。

因此,一个直观的解决模型过拟合的办法就是对模型进行简化。放在 Transformer 中,就是对某些计算结果进行随机地置 0 操作。具体来讲,假设 Attention 层输出了一组 token 矩阵,模型经过一个完全随机的 dropout 之后,其结果中的某些元素就被置为 0。

这样,就好像模型中的一些元素特征被人为屏蔽掉了,从而模型得到了简化。

在模型中,dropout 置 0 是随机进行的,但到底要把多少元素值置 0,需要预先人为设置一个概率值 dropout ratio,当这个值是 0 时,相当于所有元素都不置 0。在上图中,大致可以计算得到,dropout 率为5/12=0.4175/12=0.417。

ResNet 残差模块

在 Transformer 结构图中,Attention 模块的输入 embed 和输出结果有一个叠加,这种叠加操作被称为残差模块。之所以这么操作,主要是为了方便模型的训练过程中,梯度不会消失或爆炸。其本质目的在于顺利使模型完成训练,达到目标效果。具体细节会在第 8 节模型训练过程中做介绍。

Linear Feed-forward 全连接层

全连接层,就像在之前内容中为 Q、K、V 添加参数,实现了一个模型参数的扩增。针对一个 token 的输入��xi​,需要做一个矩阵乘法运算,公式表示其输出为��=���yi​=Wxi​,其中 �W 就是要学习的参数。这个步骤就是 Linear Feed-forward 层,中文名又叫线性全连接层,核心即矩阵乘法运算。这一步的主要作用在于为模型增加参数,增强模型的拟合能力。

Dropout 用于控制模型参数过多,过于复杂;而这里线性全连接层又在扩增参数,是否矛盾?

其实并不矛盾。增加线性全连接层,目标在于提升模型拟合能力的上限。而在这个很高的上限内,模型的训练浮动比较大,Dropout 主要用于控制模型能够顺利训练到位。

至此,本节介绍完了 Transformer 结构组件。把 Transformer 堆叠起来,就形成了 GPT 模型的雏形,这一部分在第7节介绍。

总结

  • Transformer 组件的核心结构就是 Self-Attention,组件的堆叠构成了 ChatGPT 的语言模型。
  • 自从 GPT3 模型之后(也包括 ChatGPT),使用的是 Sparse Transformer,它有助于减轻模型的计算量,加速模型的训练和使用。
  • Transformer 中用到了 Normalization、残差计算、线性层,以增强模型的拟合能力、适应性。

猜你喜欢

转载自blog.csdn.net/m0_68036862/article/details/131198352
今日推荐