目录
2.1 Transformer Encoder Layer 的结构
2.4.1 Masked Multi-Head Self-Attention
2.4.2 Multi-Head Attention (Encoder-Decoder Attention)
面试者经常会问transform这个模型,一个典型的seq2seq结构。Transformer模型是在2017年为了解决传统序列到序列模型中长距离依赖问题而提出的,它通过自注意力机制显著提高了训练速度和并行性,但可能忽略了局部信息且对位置信息的编码相对简单。
传统的seq2seq模型使用循环神经网络(RNN)来处理序列数据,但RNN存在一些限制,如难以并行计算和难以捕捉长期依赖关系。Transformer则通过使用自注意力机制(self-attention)来解决这些问题。
Transformer模型由编码器和解码器组成。编码器将输入序列转换为一系列高维特征表示,而解码器则将这些特征表示转换为输出序列。编码器和解码器都由多个相同的层组成。每个层都包含一个自注意力子层和一个前馈神经网络子层。
自注意力机制允许模型在编码和解码过程中对输入序列的不同部分进行加权。它通过计算每个输入位置与其他位置之间的相关性得分,来决定每个位置的重要性。这样,模型可以更好地关注关键的上下文信息。
除了自注意力机制,Transformer还引入了残差连接和层归一化,来帮助模型更好地训练和优化。残差连接允许模型在不同层之间直接传递信息,层归一化则有助于减轻训练过程中的梯度问题。
Transformer模型的训练通常使用无监督的方式,如自编码器或语言模型。一旦训练完成,它可以用于各种序列到序列任务,如机器翻译、文本摘要、对话生成等。
Transformer 编码器(Encoder)
输入层:
- 输入:输入序列的词嵌入(Token Embeddings)和位置编码(Positional Encoding)。
- 输出:带有位置信息的词嵌入向量。
多头自注意力层(Multi-Head Self-Attention):
- 输入:带有位置信息的词嵌入向量。
- 输出:带有上下文信息的词嵌入向量。
- 计算过程:输入序列通过线性变换得到Query (Q)、Key (K) 和 Value (V) 矩阵,然后计算注意力得分并加权求和得到新的表示。
前馈神经网络(Feed-Forward Network):
- 输入:多头自注意力层的输出。
- 输出:经过全连接层处理的特征向量。
- 计算过程:通过两个线性层和一个激活函数(如ReLU)进行非线性变换。
残差连接与层归一化(Residual Connections & Layer Normalization):
- 输入:多头自注意力层和前馈神经网络的输出。
- 输出:经过残差连接和层归一化处理后的特征向量。
- 计算过程:在每个子层前后添加残差连接,并在每个子层输出后进行层归一化。
Transformer 解码器(Decoder)
输入层:
- 输入:目标序列的词嵌入和位置编码。
- 输出:带有位置信息的词嵌入向量。
Masked Multi-Head Self-Attention:
- 输入:带有位置信息的词嵌入向量。
- 输出:带有上下文信息的词嵌入向量。
- 计算过程:类似于编码器中的自注意力层,但会应用一个遮挡矩阵来确保每个位置只能看到前面的位置信息。
Multi-Head Attention (Encoder-Decoder Attention):
- 输入:Masked Multi-Head Self-Attention的输出作为Query (Q),编码器的输出作为Key (K) 和 Value (V)。
- 输出:带有编码器上下文信息的词嵌入向量。
- 计算过程:计算注意力得分并加权求和编码器的输出。
前馈神经网络(Feed-Forward Network):
- 输入:Multi-Head Attention层的输出。
- 输出:经过全连接层处理的特征向量。
- 计算过程:通过两个线性层和一个激活函数(如ReLU)进行非线性变换。
残差连接与层归一化(Residual Connections & Layer Normalization):
- 输入:Masked Multi-Head Self-Attention层、Multi-Head Attention层和前馈神经网络的输出。
- 输出:经过残差连接和层归一化处理后的特征向量。
- 计算过程:在每个子层前后添加残差连接,并在每个子层输出后进行层归一化。
最终输出
- 输出层:
- 输入:解码器最后一层的输出。
- 输出:目标序列的词的概率分布。
- 计算过程:通过一个线性层和softmax函数得到每个词的概率分布。
1 背景
试问几个问题,为什么提出了transform模型。RNN对于长时间序列(超过40)压缩到一个上下文向量中出现记忆退化现象,无法更好捕捉上下文信息。因此transform应运而生了。Transformer模型在2017年被google提出,直接基于Self-Attention结构,取代了之前NLP任务中常用的RNN神经网络结构,与RNN这类神经网络结构相比,Transformer一个巨大的优点是:**模型在处理序列输入时,可以对整个序列输入进行并行计算,不需要按照时间步循环递归处理输入序列。
下面是模型的结构:
BERT 使用多层双向 Transformer 编码器。它的自注意力层在两个方向上都执行自注意力。Google 发布了该模型的两种变体:
-
BERT Base: Transformers 层数 = 12, 总参数 = 110M
-
BERT Large: Transformers 层数 = 24, 总参数 = 340M
2 TransForm结构
了解了Transformer的宏观结构之后。下面,让我们来看看Transformer如何将输入文本序列转换为向量表示,又如何逐层处理这些向量表示得到最终的输出。
2.1 Transformer Encoder Layer 的结构
每个Transformer编码器层包含以下几个关键组件:
- 多头自注意力机制(Multi-Head Self-Attention)
- 前馈神经网络(Feed-Forward Network)
- 残差连接与层归一化(Residual Connections and Layer Normalization)
多头自注意力机制
encoder
多头自注意力机制是通过将输入序列映射到三个不同的矩阵来工作的:Query (Q) 矩阵、Key (K) 矩阵和 Value (V) 矩阵。这些矩阵是由输入序列的嵌入向量通过不同的线性变换得到的。
输入嵌入:
- 首先,输入序列的每个词被转换为其对应的词嵌入向量。
- 这些词嵌入向量还加上了位置编码以保留序列的位置信息。
线性变换:
- 在多头自注意力层中,每个词嵌入向量通过三个不同的线性变换(权重矩阵)分别生成 Query (Q) 向量、Key (K) 向量和 Value (V) 向量。
- 对于给定的输入向量 𝑥x,我们可以表示这些变换为:
- 其中 𝑊𝑄, 𝑊𝐾, 和 𝑊𝑉 是学习得到的权重矩阵。
多头:
- 为了增加模型的表达能力,多头自注意力机制通常会在不同的子空间上独立地计算多个注意力头。
- 每个注意力头都有其自己的 𝑊𝑄, 𝑊𝐾, 和 𝑊𝑉 权重矩阵。
- 这意味着对于每一个头,我们都会有一个 𝑄, 𝐾, 和 𝑉 矩阵。
注意力计算:
- 一旦得到了 𝑄, 𝐾, 和 𝑉 矩阵,就可以进行注意力计算。
- 注意力分数通过计算 𝑄Q 和 𝐾K 的点积来得到,然后通过 softmax 函数进行归一化。
- 归一化后的注意力分数与 𝑉V 矩阵相乘,以加权组合来自所有输入位置的值。
- 注意力分数以及当前头的输出:
头的拼接:
- 所有注意力头的输出会被拼接(concat)在一起,然后通过另一个线性变换来产生最终的注意力输出(当前conder的输出)。
2.1 输入处理
获取词向量: 和常见的NLP 任务一样,我们首先会使用词嵌入算法(embedding algorithm),将输入文本序列的每个词转换为一个词向量。实际应用中的向量一般是 256 或者 512 维。其次需要与位置编码位加操作;
在实际应用中,我们通常会同时给模型输入多个句子,如果每个句子的长度不一样,我们会选择一个合适的长度,作为输入文本序列的最大长度:如果一个句子达不到这个长度,那么就填充先填充一个特殊的“padding”词;如果句子超出这个长度,则做截断。最大序列长度是一个超参数,通常希望越大越好,但是更长的序列往往会占用更大的训练显存/内存,因此需要在模型训练时候视情况进行决定。
2.2 Self-Attention层
自我注意力机制的工作原理通常涉及到三个主要组件:查询(Query)、键(Key)和值(Value)。每个位置的输入都被转换为这三个向量。然后,查询向量与所有键向量进行点积计算,得到的分数经过softmax函数后表示为权重。这些权重随后用于加权求和所有的值向量,从而得到该位置的输出。
对于每一个输入向量a,经过蓝色部分self-attention之后都输出一个向量b,这个向量b是考虑了所有的输入向量对a1产生的影响才得到的,这里有四个词向量a对应就会输出四个向量b。
参数解释:
- 三个矩阵: W、Q、V是权重,要学习的。
- 你看三个矩阵乘以的都是向量a,这就是为什么叫Self-attenton;
- 本质上不就是一种映射关系,只不过经过一层Self-attenton之后的b,包含了更多的信息。
2.3 Layer Norm
ref: 为什么Transformer要用LayerNorm? - 知乎
这部分可能与batchNorm结合一起讲最好,我也被面试官问到。比如我们现在每一个样本有两个特征 身高x1,体重x2 。batchNorm是对所有样本x2放在一起然后进行归一化处理。而layerNorm是对一个样本的x1、x2放到一起进行归一化处理。
BatchNorm将不同样本相同维度的特征处理为相同的分布。其广泛使用在CV中,一个批次中样本是一个三通道(R、G、B)。有n个样本,每个样本有m个特征(通道),BatchNorm把所有样本通道进行归一会处理。针对同一个通道的特征跨越样本的方式进行归一化处理。
对于一个NLP模型,一个批次的输入包括若干个独立的句子,每个句子又由不定长度的词构成,句子中的每个词又被映射为固定长度的词向量。然后一个句子作为归一化的单位。(保留词与词之间的相对性)。
二者结果差异比较:
2.4 的意义
两个向量内积会随着维度的增加而变大,经过softmax之后防止进入饱和区,反向求导会有问题。
a:post layer Norm,
b:pre layer Nonm,
post layer norm。在原始的 transformer 中,layer normalization 是放在残差连接之后的,称为 post LN。使用 Post LN 的深层 transformer 模型容易出现训练不稳定的问题。如下图所示,post LN 随着 transformer 层数的加深,梯度范数逐渐增大,导致了训练的不稳定性。
pre layer norm。[7]改变 layer normalization 的位置,将其放在残差连接的过程中,self-attention 或 FFN 块之前,称为“Pre LN”。如下图所示,Pre layer norm 在每个 transformer 层的梯度范数近似相等,有利于提升训练稳定性。相比于 post LN,使用 pre LN 的深层 transformer 训练更稳定,可以缓解训练不稳定问题。但缺点是 pre LN 可能会轻微影响 transformer 模型的性能。大语言模型的一个挑战就是如何提升训练的稳定性。为了提升训练稳定性,GPT3、PaLM、BLOOM、OPT 等大语言模型都采用了 pre layer norm。
注意transformer 中使用的是post layer Nonm,先归一化然后再做残差;
2.4 decoder部分
上图红色部分为 Transformer 的 Decoder block 结构,与 Encoder block 相似,但是存在一些区别:
- 包含两个 Multi-Head Attention 层。
- 第一个 Multi-Head Attention 层采用了 Masked 操作。
- 第二个 Multi-Head Attention 层的K, V矩阵使用 Encoder 的编码信息矩阵C(最后一个 Encoder block 输出的矩阵就是编码信息矩阵 C)进行计算,而Q使用上一个 Decoder block 的输出计算。
- 最后有一个 Softmax 层计算下一个翻译单词的概率。
计算流程
假设输入和输出
- 假设我们有一个输入序列 𝑋 包含 N 个词,每个词的嵌入向量维度为 D。
- 解码器的输出序列 𝑌 包含 M 个词,每个词的嵌入向量维度也为 D。
2.4.1 Masked Multi-Head Self-Attention
2.4.2 Multi-Head Attention (Encoder-Decoder Attention)
多头的合并
对于每个注意力层(Masked Multi-Head Self-Attention 和 Multi-Head Attention),所有注意力头的输出会被拼接在一起,然后通过另一个线性变换来产生最终的注意力输出。
2.4.2 Masked操作
防止数据泄露;为了保证解码器在生成序列时不会“提前”看到未来的信息。在训练过程中,对于目标序列的每个位置,该位置之前的所有信息都应该被考虑进去,而之后的信息则应该被屏蔽掉。
2.4.3 Deceder生成 KV 矩阵
在Masked Multi-Head Self-Attention中,输入序列同样会经过线性变换来生成Query (Q)、Key (K) 和 Value (V) 矩阵。这些矩阵的生成方式与编码器相同,即:
这里是与编码器另外一个不同的点,这里的输入有两个来源一个来自当前decoder输入标签。其次来自于encoder的输出C。encoder对
这里的 Dec𝑖表示解码器第 𝑖 个位置的输出,Enc𝑗表示编码器第 𝑗个位置的输出。W 是计算的权重。