自注意力机制中的矩阵乘法
在Tensorflow深度学习算法整理(二) 中,我们知道word2vec是通过训练出来的,这样可以得到一个初步的词向量,我们称为embedding。如果牵涉到具体的大模型厂商,如OpenAI或者智谱清言,那么它们的embedding方式都是不同的,但它们都是基于Transformer架构训练的,它们训练的语料不同,输出的词向量维度也不同。
在多模态大模型篇 中,我们将这些embedding输入自注意力机制中,会经过两个自注意力层,每一层的输出,都会经过一系列的矩阵运算。
其中会有三个矩阵(W^q,W^k)和(W^v)。我们这里就来讨论词向量(Token)跟这些矩阵相乘的意义。
其实向量与矩阵相乘的本质是一种空间变换
在上图中,左边的一组向量就是我们输入的Token,中间的部分就是矩阵,右边的一组向量就是Token空间变换后的一组新向量。
自注意力机制的运算过程如下图所示
这里的计算方式跟多模态大模型篇 稍微有一点区别,我们以该图为准。我们对自注意力层输入的是一个句子,也就是一组Token,同样可以拼接成一个词矩阵,如上图最左边的T。T与 (W^q,W^k)和(W^v)相乘,即进行了三次空间变换,得到了Q、K、V矩阵。这里的不同在于在softmax之前,A需要先除以(\sqrt{D_{out}})。
A是由(Q⋅K^T)得到的,现在我们取出Q的一行X和(K^T)的一列(Y^T)进行点乘。我们假设X和(Y^T)中的每一项都遵循多元标准正态分布
(X=X_1\ X_2\ ...)~N(0,I),即(X_i)~N(0,1),(X_i)彼此独立,协方差为0
(Y^T=Y_1\ Y_2\ ...^T)~N(0,I),即(Y_i)~N(0,1),(Y_i)彼此独立,协方差为0
则
(X⋅Y^T=\sum_{i=1}^{D_{out}}X_iY_i)
(X_iY_i)的期望是0,方差为1,推导如下(具体公式可以参考概率论整理(二) 中的方差)
(Var(X_iY_i)=E(X_i^2Y_i^2)-E^2(X_iY_i)=E(X_i^2)E(Y_i^2)-E^2(X_i)E^2(Y_i))
(=(Var(X_i)+E^2(X_i))(Var(Y_i)+E^2(Y_i))-E^2(X_i)E^2(Y_i)=(1+0)(1+0)-0=1)
对于(X⋅Y^T)来说,其方差为
(Var(X⋅Y^T)=\sum_{i=1}^{D_{out}}1=D_{out})
这代表了
(X⋅Y^T)~(N(0,D_{out}⋅I))
这个多元正态分布,它的期望是0,方差变成了(D_{out}⋅I),为了使其恢复到标准正态分布,所以 A需要先除以(\sqrt{D_{out}}),(\sqrt{D_{out}})就是标准差。
(A\over \sqrt{D_{out}})
softmax计算也不是将A的所有项都加到一起统一进行归一,而是逐行进行归一。
在还没有进行自注意力机制之前,我们输入的Token是有基础语义,具备了词义的,但是这个词义是字典里面的词义,是客观的词义,所有人拿到的字典都是相同的。当我们将这些Token组合成文章后,表达了不同的语义,此时具备了主观性。Token上下文的组织方式本身才给这段文字赋予了主观性的语义。
比如说美女这个词,词典里说的是长的好看的女性,如果下文是"今天晚上可以一起吃个饭吗?",那么美女这个词大概率是在表示这个人很好看。但如果下文是"麻烦,请让一让",此时美女这个词可能只是一个称谓。自注意力机制需要搞定的就是因为上下文关联而对词典中原本客观的语义进行调整和改变的幅度。
此时我们再来看Q、K、V这三个矩阵,那么V就是Token在词典里查出来的客观语义;(A=Q⋅K^T),(A'=softmax({A\over \sqrt{D_{out}}})),则A'表示的就是因为上下文关联而产生的修改系数。
上图中,Q矩阵中的每一行是一个Token,(K^T)矩阵中每一列是一个Token,矩阵与矩阵相乘其实就是将矩阵中的每一个向量跟另一个矩阵中的列向量分别相乘,向量与向量相乘得到的是标量。
我们将上图的(q_1)与(k_2)相乘(内积),有
(|q_1|⋅|k_2|⋅cosθ=a_{1,2})
其中θ是这两个向量的夹角。
内积代表的意义是这两个向量的相关性,如果这两个向量是正交的,即(θ=90^∘),则(a_{1,2}=0);如果θ=0,则这两个向量共线且方向一致,此时(a_{1,2})达到最大值。所以A里面存储的就是所有的Token两两的内积(包括某一个Token自己跟自己的内积),如果是正数就是正相关,如果是负数就是负相关,如果是0就是无关。
对A做softmax后,其实就是对每一个Token跟其他Token(包括自己)的内积做softmax,得到的是相关性的占比,也就得到了上下文关联而产生的修改系数,此时再乘以V
得出一个修正的V',它是在上下文中进行调整和改变了幅度的语义Token。其计算方式如下(以(v'_{2.2})为例)
交叉注意力机制
交叉注意力机制跟自注意力机制最不同的地方在于(W^q)和((W^k)、(W^v))输入的Tokens(也就是句子,词矩阵)是不一样的,在自注意力机制中只输入一个词矩阵T,而在交叉注意力机制中,在(W^q)端会输入一个词矩阵(T_1),在 ((W^k)、(W^v))端会输入一个词矩阵(T_2),得到一个最终的输出(T_3)。在Transformer中,(T_2)来自编码器,我们可以把它简单理解成来自自注意力机制的输出T;(T_1)来自于解码器,解码器包含有自注意力机制和交叉注意力机制两种,也就是说(T_1)也是来自于自注意力机制。
我们知道自注意力机制是调整Token在具体语境中的含义,而不再是词典中的含义。而交叉注意力机制的目的是进行潜空间的词向量的匹配,这里我们将自注意力机制修正后的Token称为潜空间的词向量。这里我们以翻译任务为例来说明
在上图中,(T_2)为"好久不见",(T_1)为"long time no see"。经过交叉注意力机制去进行匹配,看它们的词向量是否匹配,最后经过损失函数在模型中的反向传播调整模型参数去使得这两个词向量互相逼近。当然真正的翻译并非如此,把编码器中的词向量在解码器中翻译成对应语言的单词。因此中英文翻译绝非中文的字跟英文的单词之间的简单翻译,而是一个seq2seq的问题。
在编码器这一端,由于输入是固定的,如"好久不见",所以它是并行去进行矩阵运算的,但是在解码器这一端则是自回归的循环生成的方式
这个流程在多模态大模型篇 中已经多次提到,这里就不重复了。我们重新回到交叉注意力机制中,我们首先会解码器端输入一个开始符号,如上图中的<BOS>,该符号通过自注意力机制后得到一个词向量,该词向量会与(W^q)生成一个查询向量Q。在编码器端会将中文句子"好久不见"经过自注意力机制生成词矩阵(T_2),(T_2)会在交叉注意力机制中与(W^k)和(W^v)生成对应的键矩阵K和值矩阵V,Q会与K进行内积运算得到相关性的存储A,这里存储的是英文token和中文token的相关性,再进行softmax运算得到相关性权重A',(A'=softmax({A\over \sqrt{D_{out}}})),最终A'与中文的值V进行加权求和,这个加权求和的结果就包含了从中文句子中获取到的与当前要生成英文 token 相关的关键信息。注意该加权求和后的结果是一个向量,而不再是一个词矩阵,可以理解成做了扁平处理。
经过交叉注意力机制得到的包含中文相关信息的结果,会与解码器自身之前的信息(比如当前已经生成的 token 的信息,此时就只有 <BOS>
的相关信息)进行结合。这可能涉及到简单的拼接、相加等操作,将结果向量送入前馈神经网络,再经过softmax得到要预测的英文的token。再循环送入解码器去预测后面的英文token。
位置编码
位置编码的内容在多模态大模型篇 中也有介绍,我们这里来关注它在数学上的细节。
首先我们将表示位置的0、1、2、3...的自然数给升维到词向量相同的维度D,成为一个位置向量。
它的每一位由以下的分段函数来表示
填入到位置向量中,就是
(sin({1\over 10000^{2*0\over D}}t)) | (cos({1\over 10000^{2*0\over D}}t)) | (sin({1\over 10000^{2*1\over D}}t)) | (cos({1\over 10000^{2*1\over D}}t)) | ... | (sin({1\over 10000^{D-2\over D}}t)) | (cos({1\over 10000^{D-2\over D}}t)) |
---|
这种形式跟傅立叶级数很像,我们来看一下傅立叶级数 (有关傅立叶级数的内容可以参考高等数学整理 (三) 中的傅立叶级数)
周期函数f(x)的周期为P
(f(x)=A_0+\sum_{i=1}^∞(A_nsin({2iπ\over P}x)+B_ncos({2iπ\over P}x)))
将其展开就有
(f(x)=A_0+A_1sin(2π{1\over P}x)+B_1cos(2π{1\over P}x)+...+A_nsin(2π{i\over P}x)+B_ncos(2π{i\over P}x)+...)
y=Asin(ωx+φ),其中A为振幅,ω为角频率(单位时间内角度变化的快慢的物理量,单位为"弧度/秒"),φ为初相。
因为转一圈的弧度为2π,故y=Asin(ωx+φ)的周期
(P={2π\over ω})
则
(ω={2π\over P})
由于我们在高等数学整理 (三) 中是将f(t)的周期定义为2π,有
因此(f(x)=A_0+\sum_{i=1}^∞(A_nsin({2iπ\over P}x)+B_ncos({2iπ\over P}x)))与上式是等价的,只不过P=2π,i跟n是一个意思。