Transformer是近年来深度学习领域最重要的架构之一,它彻底改变了自然语言处理,也延伸到了计算机视觉、语音识别等领域。但很多人对Transformer的理解,只停留在"注意力机制"这个层面,对它的底层原理和架构细节,理解得不够深入。今天,我们来深入剖析Transformer的架构原理,从注意力机制到编码器解码器,从位置编码到前馈网络,一步步搞懂它的底层机制。
先说说Transformer的背景。Transformer,是2017年由Google Brain团队在论文《Attention Is All You Need》中提出的。在Transformer之前,自然语言处理的主流架构,是RNN(循环神经网络)和LSTM(长短期记忆网络),这些架构是按顺序处理序列的,一个词一个词地处理,这样有两个问题:一是无法并行计算,处理速度慢;二是长距离依赖问题,序列太长的时候,前面的信息容易丢失。
Transformer的出现,彻底改变了这一点。它完全基于注意力机制,不需要循环结构,可以并行计算整个序列,处理速度快,而且能很好地捕捉长距离依赖。Transformer提出之后,很快就成为了自然语言处理的主流架构,后来的BERT、GPT、T5等著名模型,都是基于Transformer的。
而且,Transformer的应用,已经远远超出了自然语言处理,延伸到了计算机视觉(ViT)、语音识别(Whisper)、多模态(CLIP)、蛋白质结构预测(AlphaFold)等领域,成为了一个通用的深度学习架构。
所以,理解Transformer的原理,对于学习深度学习和AI,是非常重要的。今天,我们就来深入剖析它的架构原理。
一、注意力机制:Transformer的核心
要理解Transformer,首先要理解注意力机制(Attention Mechanism),因为Transformer的核心,就是注意力机制。
1. 什么是注意力机制?
注意力机制,灵感来源于人类的视觉注意力。人类在看东西的时候,不会把注意力平均分配到整个画面,而是会把注意力集中在重要的部分,忽略不重要的部分。比如,你看一张照片,会首先注意到照片中的人,而不是背景。
注意力机制,就是让模型在处理信息的时候,也能像人类一样,把注意力集中在重要的部分,给重要的部分更高的权重,给不重要的部分更低的权重。
在自然语言处理中,注意力机制,就是让模型在处理一个词的时候,能够关注到句子中其他相关的词,给相关的词更高的权重,给不相关的词更低的权重。这样,模型就能更好地理解词与词之间的关系,更好地理解整个句子的意思。
比如,句子"我把苹果放在桌子上,因为它很新鲜",这里的"它"指的是"苹果",而不是"桌子"。注意力机制,就能让模型在处理"它"的时候,给"苹果"更高的权重,从而正确理解"它"指的是什么。
2. 自注意力机制(Self-Attention)
Transformer中用的,是自注意力机制(Self-Attention),也叫内部注意力机制。自注意力,就是序列中的每个词,都和序列中的所有词(包括自己)计算注意力,从而捕捉词与词之间的关系。
自注意力的计算过程,可以用三个矩阵来表示:Query(查询,Q)、Key(键,K)、Value(值,V)。这三个矩阵,都是由输入序列通过线性变换得到的。
计算过程是这样的:
- 用Query和Key计算注意力分数:
Attention(Q, K, V) = softmax(QK^T / sqrt(d_k))V - 具体来说,对于每个词的Query,和所有词的Key做点积,得到注意力分数。
- 把注意力分数除以sqrt(dk)(dk是Key的维度),进行缩放,防止点积太大导致softmax梯度消失。
- 用softmax函数,把注意力分数转换成注意力权重,权重之和为1。
- 用注意力权重,对所有词的Value进行加权求和,得到这个词的自注意力输出。
这个过程,可能有点抽象,举个简单的例子。假设句子是"我 爱 中国",三个词。对于"爱"这个词:
- 它的Query,和"我"的Key、"爱"的Key、"中国"的Key,分别做点积,得到三个分数。
- 假设分数是:和"我"的分数是2,和"爱"的分数是1,和"中国"的分数是3。
- 除以sqrt(d_k)之后,用softmax转换成权重,假设权重是:"我"0.2,"爱"0.1,"中国"0.7。
- 然后,用这三个权重,对三个词的Value加权求和,得到"爱"这个词的自注意力输出。
这样,"爱"这个词的输出,就融合了"我"和"中国"的信息,而且给"中国"更高的权重,因为"爱"和"中国"的关系更密切。
这就是自注意力的核心思想:每个词的表示,都融合了整个序列的信息,而且根据相关性,给不同的词不同的权重。
3. 多头注意力(Multi-Head Attention)
Transformer中,用的不是单头的自注意力,而是多头注意力(Multi-Head Attention)。多头注意力,就是把Q、K、V分成多个头,每个头独立计算自注意力,然后把多个头的结果拼接起来,再做一次线性变换。
为什么要用多头注意力呢?因为不同的头,可以关注不同的关系。比如,一个头关注语法关系,一个头关注语义关系,一个头关注指代关系,等等。多个头并行计算,可以捕捉更丰富的信息,让模型的表达能力更强。
多头注意力的计算过程:
- 把Q、K、V分别线性变换,然后分成h个头(h一般是8或者16)。
- 每个头,独立计算自注意力,得到每个头的输出。
- 把h个头的输出拼接起来,得到一个完整的输出。
- 对拼接后的输出,再做一次线性变换,得到最终的多头注意力输出。
多头注意力,是Transformer的一个重要设计,它让模型能够同时关注不同类型的关系,大大提升了模型的表达能力。
二、位置编码:让模型知道词的顺序
自注意力机制,有一个问题:它是对序列中的所有词,并行计算的,没有考虑词的顺序。也就是说,把句子中的词打乱顺序,自注意力的计算结果是一样的。但在自然语言中,词的顺序是非常重要的,"我打你"和"你打我",词是一样的,但意思完全相反。
所以,Transformer需要一种方式,让模型知道词的顺序,这就是位置编码(Positional Encoding)。
1. 什么是位置编码?
位置编码,就是给每个位置的词,加上一个位置信息,让模型知道这个词在序列中的位置。这样,模型就能区分不同位置的词,理解词的顺序。
Transformer用的位置编码,是正弦余弦位置编码,公式是这样的:
PE(pos, 2i) = sin(pos / 10000^(2i/d_model))PE(pos, 2i+1) = cos(pos / 10000^(2i/d_model))
其中,pos是词的位置,i是维度的索引,d_model是模型的维度。
这个位置编码,有几个特点:
- 每个位置,都有一个唯一的位置编码向量。
- 位置编码的每个维度,都是一个正弦或者余弦函数,不同的维度,频率不同。
- 对于任意一个固定的偏移k,PE(pos+k)可以表示成PE(pos)的线性函数,这样模型就能很容易地学习到相对位置关系。
2. 位置编码怎么用?
位置编码的用法很简单:把输入词的词嵌入(Word Embedding),和对应位置的位置编码,相加起来,作为Transformer的输入。
也就是说,输入 = 词嵌入 + 位置编码。
这样,每个词的表示,就既包含了词本身的语义信息,又包含了位置信息,模型就能同时理解词的语义和顺序。
为什么是相加,而不是拼接呢?因为相加可以保持维度不变,不需要增加模型的参数,而且实践证明,相加的效果很好。
3. 其他位置编码方式
正弦余弦位置编码,是原始Transformer用的方式。后来,人们又提出了很多其他的位置编码方式,比如:
- 可学习的位置编码:把位置编码当成可学习的参数,让模型自己学习。BERT用的就是这种方式。
- 相对位置编码:不编码绝对位置,而是编码词与词之间的相对位置。
- 旋转位置编码(RoPE):把位置信息编码到Query和Key的旋转中,在长序列中效果很好。LLaMA等大模型用的就是这种方式。
这些位置编码方式,各有优缺点,但核心思想都是一样的:让模型知道词的顺序,理解词与词之间的位置关系。
三、编码器:理解输入序列
Transformer的整体架构,是编码器-解码器(Encoder-Decoder)架构。编码器负责理解输入序列,解码器负责生成输出序列。我们先来说说编码器。
1. 编码器的结构
Transformer的编码器,由N层相同的编码器层堆叠而成(原始论文中N=6)。每个编码器层,包含两个子层:
- 多头自注意力层(Multi-Head Self-Attention)
- 前馈神经网络层(Feed-Forward Network)
每个子层,都有一个残差连接(Residual Connection),然后是层归一化(Layer Normalization)。
也就是说,每个子层的输出是:LayerNorm(x + Sublayer(x))
残差连接,是为了解决深层网络的梯度消失问题,让梯度可以直接传播,模型可以训练得更深。层归一化,是为了稳定训练,加速收敛。
2. 多头自注意力层
编码器中的多头自注意力层,就是我们前面讲的多头自注意力。它让序列中的每个词,都能关注到序列中的所有词,捕捉词与词之间的关系,从而更好地理解整个输入序列。
在编码器中,自注意力是双向的,也就是说,每个词都能关注到它前面和后面的所有词。这对于理解输入序列是很重要的,因为理解一个词,往往需要同时看它的上下文。
3. 前馈神经网络层
前馈神经网络层(Feed-Forward Network,FFN),是一个两层的全连接网络,中间有一个ReLU激活函数。公式是:FFN(x) = max(0, xW1 + b1)W2 + b2
前馈网络的作用,是对每个位置的表示,进行非线性变换,增加模型的表达能力。注意,前馈网络是对每个位置独立应用的,不同位置之间,参数是共享的。
原始Transformer中,前馈网络的中间层维度,是模型维度的4倍。比如,模型维度是512,中间层维度就是2048。
4. 编码器的整体流程
总结一下,编码器的整体流程是:
- 输入序列,转换成词嵌入,加上位置编码。
- 输入到第一层编码器层。
- 在编码器层中,先经过多头自注意力层,加上残差连接,层归一化。
- 然后经过前馈神经网络层,加上残差连接,层归一化。
- 第一层的输出,作为第二层的输入,重复上述过程。
- 经过N层编码器层之后,得到编码器的输出,也就是输入序列的表示。
编码器的输出,是一个和输入序列长度相同的序列,每个位置,都是一个包含了整个输入序列信息的向量。这个输出,会传给解码器,帮助解码器生成输出序列。
四、解码器:生成输出序列
说完了编码器,再来说说解码器。解码器负责生成输出序列,比如在机器翻译中,输入是英文,编码器理解英文,解码器生成中文。
1. 解码器的结构
解码器,也是由N层相同的解码器层堆叠而成(N=6)。每个解码器层,包含三个子层:
- 掩码多头自注意力层(Masked Multi-Head Self-Attention)
- 编码器-解码器注意力层(Encoder-Decoder Attention)
- 前馈神经网络层(Feed-Forward Network)
和编码器一样,每个子层,也都有残差连接和层归一化。
2. 掩码多头自注意力层
解码器中的自注意力,和编码器中的自注意力,有一个重要的区别:解码器中的自注意力,是掩码的(Masked),也就是说,每个词,只能关注到它前面的词,不能关注到它后面的词。
为什么要这样呢?因为解码器是用来生成输出序列的,生成的时候,是一个词一个词地生成的,从左到右。在生成第t个词的时候,只能看到前面已经生成的t-1个词,不能看到后面还没生成的词。如果能看到后面的词,就相当于"作弊"了,模型就不需要学习了,直接抄答案就行。
所以,解码器中的自注意力,要加一个掩码,把后面的词的注意力分数,设成负无穷,这样softmax之后,权重就是0,相当于看不到后面的词。
这就是掩码多头自注意力,它保证了解码器在生成的时候,只能看到已经生成的词,不能看到未来的词。
3. 编码器-解码器注意力层
解码器中的第二个子层,是编码器-解码器注意力层(Encoder-Decoder Attention),也叫交叉注意力(Cross-Attention)。
这个层,和自注意力不同。自注意力的Q、K、V,都来自同一个序列;而编码器-解码器注意力的Q,来自解码器的前一个子层的输出,K和V,来自编码器的输出。
也就是说,解码器在生成每个词的时候,用自己的Query,去关注编码器输出的所有Key和Value,从而从输入序列中,获取需要的信息。
比如,在机器翻译中,解码器在生成中文的某个词的时候,通过编码器-解码器注意力,关注到英文输入中对应的词,从而生成正确的翻译。
编码器-解码器注意力,是连接编码器和解码器的桥梁,它让解码器能够利用编码器对输入序列的理解,生成正确的输出序列。
4. 前馈神经网络层
解码器中的前馈神经网络层,和编码器中的一样,也是一个两层的全连接网络,对每个位置的表示进行非线性变换,增加模型的表达能力。
5. 解码器的输出层
经过N层解码器层之后,解码器的输出,还要经过一个线性层,把维度转换成词表大小,然后用softmax函数,转换成每个词的概率分布。
这样,对于每个位置,模型都会输出一个词表大小的概率分布,表示在这个位置,生成每个词的概率。生成的时候,选择概率最大的词,或者用采样的方式,选择一个词,作为这个位置的输出。
6. 解码器的整体流程
总结一下,解码器的整体流程是:
- 已经生成的输出序列,转换成词嵌入,加上位置编码。
- 输入到第一层解码器层。
- 在解码器层中,先经过掩码多头自注意力层,加上残差连接,层归一化。
- 然后经过编码器-解码器注意力层,加上残差连接,层归一化。
- 然后经过前馈神经网络层,加上残差连接,层归一化。
- 第一层的输出,作为第二层的输入,重复上述过程。
- 经过N层解码器层之后,经过线性层和softmax,得到输出词的概率分布。
解码器在生成的时候,是自回归的(Autoregressive),也就是说,生成第一个词,然后把第一个词作为输入,生成第二个词,再把前两个词作为输入,生成第三个词,以此类推,直到生成结束符。
五、Transformer的训练和推理
理解了Transformer的架构,再简单说说它的训练和推理。
1. 训练
Transformer的训练,一般用的是教师强制(Teacher Forcing)的方式。也就是说,在训练的时候,解码器的输入,是真实的输出序列( shifted right,也就是右移一位,前面加一个起始符),而不是模型自己生成的序列。这样,训练的时候,每个位置都能看到真实的前面的词,训练更稳定,收敛更快。
训练的损失函数,一般是交叉熵损失,计算模型预测的词的概率分布,和真实词之间的差距。
因为Transformer可以并行计算,所以训练的时候,整个输出序列可以并行计算,不需要像RNN那样一个词一个词地算,训练速度很快。
2. 推理
推理的时候,就不能用教师强制了,因为没有真实的输出序列。推理的时候,是自回归的,一个词一个词地生成:
- 输入起始符,解码器生成第一个词。
- 把起始符和第一个词,作为解码器的输入,生成第二个词。
- 把前面生成的所有词,作为解码器的输入,生成下一个词。
- 重复这个过程,直到生成结束符,或者达到最大长度。
推理的时候,因为是自回归的,不能完全并行,所以推理速度比训练慢一些。但可以用一些优化方法,比如KV缓存,把之前计算的Key和Value缓存起来,不需要每次都重新计算,大大提升推理速度。
六、Transformer为什么这么强大?
最后,总结一下,Transformer为什么这么强大,为什么能取代RNN,成为深度学习的主流架构。
1. 并行计算,训练速度快
RNN是按顺序处理的,一个词一个词地算,不能并行,训练速度慢。而Transformer的自注意力,是对整个序列并行计算的,所有词同时算,训练速度快很多,尤其是在长序列的情况下,优势更明显。
2. 长距离依赖,捕捉能力强
RNN处理长序列的时候,前面的信息,经过很多步的传递,容易丢失,长距离依赖的捕捉能力差。而Transformer的自注意力,每个词都能直接关注到序列中的所有词,不管距离多远,都能直接建立联系,长距离依赖的捕捉能力很强。
3. 表达能力强,可扩展性好
Transformer的多头注意力、前馈网络、残差连接、层归一化等设计,让它的表达能力很强,而且可以通过增加层数、增加维度、增加头数,很方便地扩展模型规模。后来的大语言模型,比如GPT-3、LLaMA、ChatGPT等,都是基于Transformer,通过扩大模型规模,获得了强大的能力。
4. 通用性强,适用范围广
Transformer最初是为自然语言处理设计的,但后来人们发现,它的架构很通用,可以用到很多领域,比如计算机视觉、语音识别、多模态、蛋白质结构预测等,都取得了很好的效果。这种通用性,让Transformer成为了一个通用的深度学习架构,也让它的影响力越来越大。
七、写在最后
Transformer,是深度学习领域的一个里程碑式的架构,它彻底改变了自然语言处理,也影响了整个AI领域。理解Transformer的原理,对于学习深度学习和AI,是非常重要的。
今天,我们从注意力机制、自注意力、多头注意力、位置编码、编码器、解码器、训练推理等方面,深入剖析了Transformer的架构原理。希望通过这篇文章,大家能对Transformer有一个更深入、更全面的理解。
当然,Transformer的内容,远不止这些,还有很多细节和变种,比如BERT的双向编码器、GPT的解码器-only架构、T5的编码器-解码器、ViT的视觉Transformer、各种位置编码、各种注意力优化等,都值得深入学习。但理解了原始Transformer的基本原理,再学习这些变种,就会容易很多。
AI的发展日新月异,新的模型和架构层出不穷,但Transformer,依然是当前AI的基石。理解了Transformer,就理解了当前AI的核心。
希望这篇文章,能对大家有所帮助。如果有什么问题或者不同的看法,欢迎在评论区交流。
评论(0)
暂无评论,快来抢沙发~
评论功能仅对会员开放,请先登录
登录