AI大模型学习——Transformer模型原理
Transformer模型详解
前言
由于目前在科研生活中有接触到AI大模型,再加上对未来毕业后的发展考虑,于是决定开设一个专栏专门记录对AI大模型的学习。
第一篇先从Transformer的理解开始,参考的学习链接为: Transformer模型详解(图解最完整版)、【超详细】【原理篇&实战篇】一文读懂Transformer以及注意力机制综述。
学习参考资料是著名的Google团队的论文《Attention is All You Need》,这边也附上学习链接: 《Attention is All You Need》
一、Transformer是什么?
Transformer是一种用于自然语言处理(NLP)和其他序列到序列(sequence-to-sequence)任务的深度学习模型架构,它在2017年由Vaswani等人首次提出。Transformer架构引入了自注意力机制(self-attention mechanism),这是一个关键的创新,使其在处理序列数据时表现出色。
以下是Transformer的一些重要组成部分和特点:
1.自注意力机制(Self-Attention):这是Transformer的核心概念之一,它使模型能够同时考虑输入序列中的所有位置,而不是像循环神经网络(RNN)或卷积神经网络(CNN)一样逐步处理。自注意力机制允许模型根据输入序列中的不同部分来赋予不同的注意权重,从而更好地捕捉语义关系。
2.多头注意力(Multi-Head Attention):Transformer中的自注意力机制被扩展为多个注意力头,每个头可以学习不同的注意权重,以更好地捕捉不同类型的关系。多头注意力允许模型并行处理不同的信息子空间。
3.堆叠层(Stacked Layers):Transformer通常由多个相同的编码器和解码器层堆叠而成。这些堆叠的层有助于模型学习复杂的特征表示和语义。
4.位置编码(Positional Encoding):由于Transformer没有内置的序列位置信息,它需要额外的位置编码来表达输入序列中单词的位置顺序。
5.残差连接和层归一化(Residual Connections and Layer Normalization):这些技术有助于减轻训练过程中的梯度消失和爆炸问题,使模型更容易训练。
6.编码器和解码器:Transformer通常包括一个编码器用于处理输入序列和一个解码器用于生成输出序列,这使其适用于序列到序列的任务,如机器翻译。
一.注意力机制
Attention(注意力机制)是一种让模型“自动关注输入中重要部分”的方法。 简单理解就是我输入一句话,话里面的不同部分的重要程度并不一样,模型应该给予不同的权重,比如说:“我是科研天才”这句话,“是”这个字肯定没有“天才”这两个字更重要吧,所以后面这两个字的权重就要大一些。
起初的注意力机制将注意力汇聚的输出计算成为值的加权和。通过Query与Key的注意力汇聚(即,给定一个 Query,计算Query与 Key的相关性,然后根据Query与Key的相关性去和对应的Value进行相乘)实现对Value的注意力权重分配,生成最终的输出结果。
举一个简单的机器翻译的例子去理解,如下图所示。
Query:我们就可以将"我"看作成 Query,因为这就是我们当前需要查询的目标,即当前输入的特征表示。
Key:可以将每个单词的重要特征表示看作成 Key。
Value:每个单词本身的特征向量看作为 Value,Key的值,一般和 Key成对出现,也就是我们常说的"键-值"对。
步骤是:1.先根据 Query,Key计算两者的相关性(计算方式不同的机制不同,下文会介绍自注意力机制的计算方式),然后再通过 Softmax 函数得到注意力分数。 2.根据注意力分数进行加权求和,得到带注意力分数的 Value,以方便进行下游任务。
1.自注意力机制
我们从Attention机制的Self-Attention的公式开始说起:
Attention ( Q , K , V ) = Softmax ( Q K T d k ) V \text{Attention}(Q, K, V) = \text{Softmax}\left(\frac{QK^{\mathrm{T}}}{\sqrt{d_k}}\right)V Attention(Q,K,V)=Softmax(dkQKT)V
这个公式中的 Q、K 和 V 分别代表 Query(查询向量:理解为查询的“问题”)、Key(键:理解为关键词) 和 Value(值:理解为关键词对应的“解释”)。
1.1 前置准备
这边有一个Softmax的计算方式,我没有接触过,后面自己查询资料得到了他的计算公式: Softmax ( z i ) = e z i ∑ j = 1 n e z j \text{Softmax}(z_i) = \frac{e^{z_i}}{\sum_{j=1}^{n} e^{z_j}} Softmax(zi)=∑j=1nezjezi
用语言描述就是,先对每个数取指数,再除以所有指数的总和,使输出变成一组概率,而且是一行一行算,算的是某一个元素在这一行上的概率。
再开始理解注意力机制之前,回顾一下向量点乘:
x = [ x 0 , x 1 , ⋯ , x n ] \mathbf{x} = [x_0, x_1, \cdots, x_n] x=[x0,x1,⋯,xn]
y = [ y 0 , y 1 , ⋯ , y n ] \mathbf{y} = [y_0, y_1, \cdots, y_n] y=[y0,y1,⋯,yn]
向量点乘(Dot Product)定义为:
x ⋅ y = x 0 y 0 + x 1 y 1 + ⋯ + x n y n \mathbf{x} \cdot \mathbf{y} = x_0 y_0 + x_1 y_1 + \cdots + x_n y_n x⋅y=x0y0+x1y1+⋯+xnyn
向量点乘的几何意义是:
- 向量 x 在向量 y 方向上的投影再与向量 y 的乘积;
- 能够反映两个向量的相似度;
- 点乘结果越大,两个向量越相似(这个非常重要!!!)。
好的,现在基础知识有了,现在我们来看一下一个式子 Softmax ( X X T ) X \text{Softmax}(\mathbf{X}\mathbf{X}^{\mathrm{T}})\mathbf{X} Softmax(XXT)X
这边的X是输入句子的词向量组成的矩阵,每一个词一行,大致逻辑可以看下面这个图:
大致逻辑就是目标矩阵其实就是一个词的词向量与各个词的词向量的相似度,然后再利用Softmax的计算方法归一化。
在这个基础上,再进一步:
Softmax ( X X T ) X \text{Softmax}(\mathbf{X}\mathbf{X}^{\mathrm{T}})\mathbf{X} Softmax(XXT)X
将得到的归一化的权重矩阵与词向量矩阵相乘。得到经过加权求和之后的向量的新表示。
我们以权重矩阵第一行和X矩阵第一列举例,权重矩阵第一行代表,这个X矩阵第一行代表的单词never和其他的单词give和up的相似度,X矩阵的第一列的每个元素代表的是每个单词被分成三个部分后的第一个部分代表的值(在 embedding 中的 第 1 维的值)。
相当于这些值被加权求和了,加权求和得到的结果是never 的新向量表示的第 1 个维度,是由所有单词(never、give、up)的第 1 维按照注意力权重加权混合而得到的。(每一个单词的一维值都乘以了他和never的相似度),加权求和的结果就是:这个单词在某一维度上的新表示,这个新表示融合了它对其他所有词的注意力贡献。
1.2 Embedding操作
我们以Tokenizer为始,Tokenizer将文本转化为机器可读的 Token ID 序列。但是,这些简单的 ID 数字(如 [464, 9016, 2793, …])本身不包含任何语义信息。
现在模型能够知道 ID 9016 对应 “lowest”,但是模型不知道它与 ID 2793 对应的 “lower” 在意义上是相似的,而与 ID 4000 对应的 “banana” 是不相关的。
那么,要让机器真正理解语言的意义、上下文和关系,我们需要一个机制将离散的、毫无关联的 Token ID 转化为连续的、具有丰富语义信息的向量(Vector)表示。这个机制就是 Embedding(词嵌入或令牌嵌入)。这个向量中的“向”字,其实就是方向的意思,能不能有点深刻的理解这个“向”字了。
这边只做最简单的理解,具体Embedding的内容,看这个链接:Embedding深刻理解。
而这边为什么聊到这个,其实大家也发现了,我们做公式计算的基础是这是一个向量计算吧,前提我们得把比如“你好,我是神”这句话给他Embedding成向量。
1.3 q,k,v操作
假设输入序列的 embedding 为:
X = [ x 1 x 2 ⋮ x n ] X = \begin{bmatrix} x_1 \\ x_2 \\ \vdots \\ x_n \end{bmatrix} X= x1x2⋮xn
其中每个 ( x_i ) 是词向量(例如 768 维)。
自注意力机制中:
Q = X W Q Q = X W_Q Q=XWQ
K = X W K K = X W_K K=XWK
V = X W V V = X W_V V=XWV
这三条公式就是 Q、K、V 的全部来源。那么现在的疑问就是这个W矩阵是如何得到的。这些 W 都是模型训练过程中不断更新、优化的参数。 用一些神经网络和反向传播等方法,有兴趣可以仔细研究。
为什么需要这个W矩阵?其实理论上来说无需 W做线性变换,但效果会极差。我们来分析这个过程,首先关注q,k处理得到注意力分数。
在注意力机制里:
Q(Query) = 当前 token (这里的token就是X的一行) 想找的信息
K(Key) = 每个 token 所暴露出的“可被匹配的特征”
Q和K做点乘,根据点乘的几何意义,是不是代表相似度,相似度越高是不是代表,token想找的信息和暴露的可被匹配的特征类似。 为什么要除以 √d?:
1.因为 Q·K 点积的值会随着维度 d 增大而变得非常大,导致 Softmax 输出极端化(梯度爆炸),无法训练。
2.除以 √d 可以把数值缩回稳定范围,保证训练可控。
那么V是包含的信息的矩阵,X乘上Wv之后得到要提取的“要传递的信息”,也就是矩阵V。注意力分数乘上V就得到Attention矩阵。
注:这边我对为什么数字向量矩阵表示key不太理解,Copilot给了个解释,我觉得挺好,这边贴出,其实就是用不同的维度,不同维度有不同数值:

2.多头自注意力机制
多头注意力机制是在自注意力机制的基础上发展起来的,是自注意力机制的变体,旨在增强模型的表达能力和泛化能力。它通过使用多个独立的注意力头,分别计算注意力权重,并将它们的结果进行拼接或加权求和,从而获得更丰富的表示。
注意力头:每个 head 会从不同的角度理解同一句话。注意力头可以理解为以一个角度去生成注意力矩阵的一个通路。
二、Transformer 整体结构

Transformer 由 Encoder 和 Decoder 两个部分组成,Encoder 和 Decoder 都包含 6 个 block。如图,是一个Transformer用于中英翻译的流程。
第一步: 获取输入句子的每一个单词的表示向量 X,X由单词的 Embedding(Embedding就是从原始数据提取出来的Feature) 和单词位置的 Embedding(Transformer 本身没有顺序意识(不像 RNN/LSTM 有上下文顺序),所以必须额外告诉它每个词在句子中的位置) 相加得到。
第二步: 将得到的单词表示向量矩阵(如上图所示,每一行是一个单词的表示 x)传入 Encoder 中,经过 6 个 Encoder block 后可以得到句子所有单词的编码信息矩阵 C,如下图。

单词向量矩阵用 X(n×d) 表示,
- n 是句子中单词个数,
- d 是表示向量的维度。
第三步: 将 Encoder 输出的编码信息矩阵 C 传递到 Decoder 中。Decoder 会依次根据当前已翻译的单词1 ~ i翻译下一个单词i+1,如下图所示。

在使用的过程中,翻译到单词 i+1 时,需要通过 Mask(掩盖) 操作遮住 i+1 之后的单词,防止模型“偷看未来”。
上图中,Decoder 接收了 Encoder 的编码矩阵 C。随后,Decoder 首先输入一个翻译开始符号 <Begin>,并预测第一个单词 “I”。接着,Decoder 输入 <Begin> 和已预测出的单词 “I”,继续预测下一个单词 “have”。 这一过程会不断重复:Decoder 每次都基于以往已经翻译出的单词,预测序列中的下一个单词。
以上就是 Transformer 在使用时的整体推理流程。 接下来会进一步介绍其中各个模块的细节。
3.Encoder和Decoder模块
3.1.Encoder模块

Transformer 的 Encoder block 结构是由 Multi-Head Attention, Add & Norm, Feed Forward 组成的。至于为什么6个block,其实就是6层训练,可以理解为多训练几次。
3.1.1 Add & Norm模块
这个模块有个核心公式如下:
LayerNorm ( X + MultiHeadAttention ( X ) ) LayerNorm ( X + FeedForward ( X ) ) \text{LayerNorm}(X + \text{MultiHeadAttention}(X)) \\ \text{LayerNorm}(X + \text{FeedForward}(X)) LayerNorm(X+MultiHeadAttention(X))LayerNorm(X+FeedForward(X))
其中:
X:模块的输入向量(矩阵),大小为 n × d
MultiHeadAttention(X):对 X 做多头注意力后得到的输出(也是 n × d)
FeedForward(X):前馈网络输出(还是 n × d)
注意:每一项输出都与 X 维度完全相同,因此可以相加。
3.1.1.1 Add模块
其实这个模块主要做了两件事,第一件事叫Add,即残差连接(就是加起来,只不过是把模块的输入 X 和模块的输出 F(X) 相加,这种加的模式叫残差连接罢了)。
就是这个LayerNorm括号里的部分,要么是Add上多头注意力处理后的输出,要么是Add上前馈网络输出,分析Encoder模块图,可以看出先进行多头注意力输出的Add和Norm,再进行前馈网络输出的Add和Norm。
如果要理解这个过程的话,复杂的数学推导就不分析了,可以理解为:我是美国人只会用刀叉,来了美丽的中国,学会了用筷子,那么看到不能丢到会刀叉的技能,“增强后的信息”与“原始信息”,把它们加起来,使模型不会把原始信息搞丢。
3.1.1.2 Norm模块
第二件事叫Norm , LayerNorm 的数学计算方式如下:
对于输入向量(或矩阵)中的每个 token 的 d 维向量:
设输入为:
x = [ x 1 , x 2 , … , x d ] x = [x_1, x_2, \ldots, x_d] x=[x1,x2,…,xd]
LayerNorm 的公式主要包含以下步骤:
① 计算均值 μ
对同一个 token 的所有特征求平均:
μ = 1 d ∑ i = 1 d x i \mu = \frac{1}{d} \sum_{i=1}^{d} x_i μ=d1i=1∑dxi
② 计算方差 σ²
同样对该 token 的 d 个维度:
σ 2 = 1 d ∑ i = 1 d ( x i − μ ) 2 \sigma^2 = \frac{1}{d} \sum_{i=1}^{d} (x_i - \mu)^2 σ2=d1i=1∑d(xi−μ)2
③ 归一化(让数据更稳定)
对每一个特征进行标准化:
x ^ i = x i − μ σ 2 + ϵ \hat{x}_i = \frac{x_i - \mu}{\sqrt{\sigma^2 + \epsilon}} x^i=σ2+ϵxi−μ
其中:
- ϵ 是一个很小的常数,用于防止除以 0。
④ 线性变换(可训练参数 γ、β)
LayerNorm 不仅做标准化,还会引入可学习参数 γ 和 β(与 BatchNorm 类似):
y i = γ x ^ i + β y_i = \gamma \hat{x}_i + \beta yi=γx^i+β
3.1.2 Feed Forward模块
这边Feed Forward模块,也就是FFN,就不仔细去讲他的原理和代码实现了。这边只关注它的作用:FFN 是对每个 token 的向量做“通道方向”的两层全连接 + 非线性变换,不改变形状,用来增强非线性表达与特征重构,配合注意力完成建模(注意力负责 token 间互动;FFN 负责 token 内部特征提取与重构)。
3.2 Decoder模块

上图红色部分为 Transformer 的 Decoder block 结构,与 Encoder block 相似,但是存在一些区别:
1.包含两个 Multi-Head Attention 层。
2.第一个 Multi-Head Attention 层采用了 Masked 操作。
3.第二个 Multi-Head Attention 层的K, V矩阵使用 Encoder 的编码信息矩阵C进行计算,而Q使用上一个 Decoder block 的输出计算(关注图中的带箭头的线条)。
4.最后有一个 Softmax 层计算下一个翻译单词的概率。
Decoder也是6个Block,可以理解为也是多层训练。
3.2.1 第一个Multi-Head Attention
刚才提到了说第一个Attention层有一个操作叫Masked操作,Mask就是“掩盖”,实际上顾名思义,我们回顾一开始提到的Decoder的工作内容就知道,我们进行工作的时候,先工作第i个词,再工作第i+1个词,我们需要通过第i个词,预测下一个词,这其实就是Transformer一个工作的底层逻辑,但是我们提供给Transformer的是一个完整的句子,我给了“have”,需要你预测出“a”,但我提供给你的是一个完整的句子“I have a cat”,你不遮盖到后面的部分,就像拿着答案抄写一样,啥也学不到。
第一步:是 Decoder 的输入矩阵和 Mask 矩阵,输入矩阵包含 “ I have a cat” (0, 1, 2, 3, 4) 五个单词的表示向量,Mask 是一个 5×5 的矩阵。在 Mask 可以发现单词 0 只能使用单词 0 的信息,而单词 1 可以使用单词 0, 1 的信息,即只能使用之前的信息。
第二步: 接下来的操作和之前的 Self-Attention 一样(暂时没有Mask矩阵参与),通过输入矩阵 X 计算得到 Q、K、V 矩阵。 然后计算 Q 和 K^T 的乘积:
第三步:按道理需要进行Softmax计算了,此时Mask矩阵出马了。结果Masked之后得到的矩阵再Softmax,再和V相乘,最后得到输出Z,输出Z包含的信息是根据遮盖的信息来的。


3.2.2 第二个Multi-Head Attention
Decoder block 第二个 Multi-Head Attention 变化不大, 主要的区别在于其中 Self-Attention 的 K, V矩阵不是使用 上一个 Decoder block 的输出计算的,而是使用 Encoder 的编码信息矩阵 C 计算的。
根据 Encoder 的输出 C计算得到 K, V,根据上一个 Decoder block 的输出 Z 计算 Q (如果是第一个 Decoder block 则使用输入矩阵 X 进行计算),后续的计算方法与之前描述的一致。
这样做的好处是在 Decoder 的时候,每一位单词都可以利用到 Encoder 所有单词的信息 (这些信息无需 Mask)。 而且,使 Decoder 在翻译每个词时,可以“随时查阅” Encoder 对整句输入的理解(用Encoder编码信息的原因),从而根据完整输入语义生成正确的下一个词。
3.2.3 Softmax 预测输出单词
Softmax 根据输出矩阵的每一行预测下一个单词:
总结
反正大致也是把Transformer的原理说清楚了,有一些数学推导有省略,但用于工程上的问题也足够了。
更多推荐



所有评论(0)