注意力机制
基础注意力机制
注意力机制的公式如下所示:
其中,各个矩阵的尺寸分别为:
-
Q矩阵,尺寸为
-
K矩阵,尺寸为
-
V矩阵,尺寸为
首先Q和K的转置做矩阵乘法,的尺寸为,随后除固定值后,计算softmax函数(softmax函数是每行独立做,而不是全矩阵做),最后和矩阵V做乘法,最终的结果尺寸为,具体的过程如下图所示:Q、K、V矩阵中,每个行矩阵都对应一个Token,表示了Q和K矩阵每个行矩阵的相关度,经过除定值和softmax函数(功能类似于归一化),并使用相关度和V矩阵相乘,最终得到Y矩阵中的每个行向量。
自注意力机制和多头注意力机制
自注意力机制,就是Q、K、V全部来自同一个矩阵,如下所示:
即Q、K、V都来自一个输入X的线性变换,其中、、均为可训练的参数,尺寸为,其中embding为词嵌入矩阵的长度,而feature则对应注意力机制中的,在自注意力机制中,输入的Q、K、V矩阵和输出Y矩阵的尺寸均为。
多头注意力机制即构造多套W参数,并行多个自注意力机制,并最后将结果拼接后进行统一线性变换回来,如下所示:
其中,并行了多少套(图中的N)就是多少头注意力机制,图中就是N头注意力机制。
后向Mask
在GPT类的自回归模型中,不能基于后续的知识生成当前的输出,只能基于前序知识生成当前输出,就需要一个Mask矩阵,将后续知识的V矩阵掩蔽。Mask矩阵式一个上三件矩阵,矩阵中为1的部分应当被Mask为0,过程如下所示:
在生成Y0向量时,只能使用V0向量,而生成Y1向量时,可以使用前序的V0和V1向量。
GPT组件
GPT结构如下图所示,其核心组件包括:
-
解码器层(经典参数为层数为6层,多头为8头)
-
线性输出层
-
位置掩码和词嵌入
解码器层DecoderLayer
解码器层结构如下所示,包括一个残差连接的多头自注意力机制(带后向Mask)和残差链接的线性层:
在解码器层中,包括以下的可训练参数:
- 多头注意力层中,每个“头”用于生成Q、K、V的三个线性层矩阵
- 线性层中的线性矩阵参数
这里的前馈网络命名为FFN(Feedforward Network),是一个多Token共享的两层线性连接层,即对于每个Token,分别进行如下操作:
整体结构如下所示,注意每个位置的Token均共享一套参数:
线性输出层
线性输出层就是一个不带激活函数的线性层,实现词嵌入的逆过程,将词嵌入转换成每个词的可能性。举个例子,词库中包括10000个词,词嵌入压缩为512维向量,这个线性层就是将512维的词嵌入转换成10000维的每个词的概率向量。
词嵌入和位置编码
词嵌入和位置编码是对输入的预处理,可以认为是如下公式,其中EMBD表示词嵌入过程,PLACE表示位置编码过程,实际的Decoderlayer的输入是词嵌入和位置向量的和:
从正向角度看,词嵌入是一个查表行为,每个词都有一个对应向量。举例而言,一个包括10000个词的词库,词嵌入向量为512维,可以认为这是一个有10000个地址的查找表,每个表项都是一个512个向量。每输入一个词,都通过查表的方式查出对应的向量。且这是一个确定性的过程,输入相同的词,查出的向量时一致的。
在GPT中,位置编码的实现方式和词嵌入相同,都是通过训练生成的(Transform原版中有固定的公式),区别在于位置编码的输入是位置而不是词(Token),比较容易理解的公式表示如下所示:
1 | # init函数中 |
GPT的前向传播过程
GPT的前向传播是个自回归的过程。首先,Token中除了有含义的词外,还包括了几种特殊的Token:
- <sos>:表示一个句子的开始
- <eos>:表示一个句子的结束
- <pad>:表示没有Token,用于填充不满足长度的情况
对于任意一个句子,都可以表示为如下所示的情况:
基于上述表示,GPT的前向传播过程如下所示,每次生成1个Token,并将这个Token增加到下一次前传过程中,直到碰到<eos>字符或达到最大长度: