base-llm 1.4.3 深入理解transformer

Transformer 来自2017年Google研究团队的名为《Attention is All You Need》的论文。其思想抛弃了传统RNN和卷积网络,整个模型基于注意力机制来构建。它凭借出色的并行计算能力极大提升了训练效率,更有效地捕捉了文本中长距离依赖关系,为后续Bert、GPT等大规模预训练模型的诞生提供了架构基础。

一、 自注意力机制

1.1 自注意力与交叉注意力的区别

区别: 信息的来源和流动方向,交叉注意力用于对齐和聚合两个不同序列之间的信息,自注意力用于理解和重构单个序列内部的依赖关系。
交叉注意力: Query来自解码器(带边当前目标序列状态), key和value 来自编码器的所有输出(代表完整的源序列信息)。生成目标序列的每一步时,从源序列中寻找最相关的信息。
自注意力机制: 信息在同一个序列内部,Query,Key,Value都来自输入序列。目的是为了捕捉输入序列内部的依赖关系,重新计算序列中每个词元的表示,使其包含更丰富的上下文信息。

1.2 自注意的计算过程

(1)生成Q,K,V向量:对输入序列的每个词元,获取其词嵌入向量Xi,分别与其可学习的,在整个模型中共享的权重矩阵相乘,生成该词元专属的向量。


image.png

这三个矩阵的作用是:将原始的词嵌入向量投影到不同的、专门用于注意力计算的表示空间中,赋予模型更大的灵活性。

(2)注意力分数: query和所有词元的key向量计算点积,得到注意力分数


image.png

(3)缩放与归一化:用softmax做归一化,对score除以根号dk(dk是key的向量维度)。


image.png

缩放因子根号dk的目的: 首先向量维度越大,导致点积结果的方差就会越大,导致softmax函数的结果可能会极小,从而导致梯度消失,影响模型学习。

(4)加权求和:权重对所有词元的value进行加权求和,得到i个词元经过注意力计算后得到的新表示zi.


image.png

二、多头注意力

目的: 一组Q,K,V的权重矩阵,只能表示一个视角。通常文本可能会表达多层次的关系。
为了让模型能够综合利用不同维度和视角提出的信息。Transformer提出多头注意力机制。
思想: 并行执行多次自注意力计算,每一次计算都是一个独立的head,有自己的权重矩阵,并且可以学习去关注一种特定类型的上下文关系。

具体步骤:
(1)并行计算:假设有h个头,就初始化h组QKV权重矩阵
(2)独立注意力:每个头单独计算注意力,生成矩阵zi
(3)拼接与投影: 将多头的输出矩阵进行拼接
(4)最终输出: 拼接后的矩阵乘以一个新的权重矩阵Wo,惊奇投影回原始的输入维度,得到多头注意力机制的最终输出。

简单理解就是:将输入维度,拆分成多个组,也就是多头,每个头有单独计算自己的注意力,拼接后乘以一个权重矩阵,最后输出多头注意力矩阵。通过拆分,不同的头可以自发地学习到不同的关注模式。

GQA(分组查询注意力) 的思想是Query拆分成多头,KV拆分成多个组,多个头共享一个组的KV权重。


image.png

三、Transformer 整体结构

image.png

Transformer的Encoder和Decoder都是由N各功能相同的layer堆叠而成。

3.1 编码器(Encoder)

编码器作用: 理解和消化输入的整个序列,为序列中的每个词元生成一个复函上下文信息的表示编码器层由两个子层构成(多头注意力层和位置前馈网络)。每个子层的输出乧经过了残差链接(Add)与层归一化(Norm)处理。所以,一个编码器层内部的数据流可以表示为x->Sublayer1(x)->Add&Norm->Sublayer2(...)-> Add&Norm。

多头注意力层:是双向的自注意力,也就是一个词元能看到序列中所有其他词元,包括自己,前边和后边的。因为双向性,编码器非常擅长理解完整的输入文本,并为每个词元生成一个深度融合了上下文信息的表示。因此大量堆叠编码器层而构建的模型(Encoder-Only架构),如BERT,在文本分类、命名实体识别等自然语言理解任务上取得了巨大成功。

3.2 解码器(Decoder)

解码器层包括三个子层(带掩码的多头注意力层,交叉注意力层和位置前馈网络)。每个子层之间仍然采用了残差链接和层归一化。

关键特性:

  • 子层1: 带掩码的自注意力

    • 解码器生成序列时必须是自回归的,也就是用之前的值预测当前值,不能往后看。
    • 在并行的自注意力计算中,引入掩码,将为了的词掩码,设置成极小的值,当softmax后,该位置权重会变为0,从而保证模型的单向性。
    • 自注意力机制,是为了分析自己已经写过的内容。
  • 子层2: 交叉注意力

    • key和value来自编码器最终输出,query来自解码器前一个子层(即带掩码的自注意力层)的输出。
    • 这一层允许编码器生成每个词元是,能够关注到输入序列的所有部分,从而有针对性的提取所需信息。
  • 子层3: 位置前馈网络(FFN)
    为模型提供非线性变换能力

  • 大模型应用: 大量堆叠解码器层而构建的模型,如GPT系列,由于其天然的自回归生成能力,引领了LLM发展浪潮。

3.3 组件解析

3.3.1 位置前馈网络

由两次线性变换和一个激活函数组成的全连接网络,独立于序列中的每一个位置。
作用: 特征变换,注意力子层主要包含softmax故意一花;每个位置的非线性主要有FFN提供(常见ReLU/GELU)
内部结构: 升维-激活-降维, 论文中中间层维度设置为4倍是经验值。


image.png

3.3.2 残差链接与层归一化(Add & Norm)

  • Add(残差链接) : 解决深度网络的模型退化问题。模型越深,在反向传播的时候梯度对浅层的影响越小,导致模型训练难以收敛。所以使用y=x+Subplayer(x)方式,让梯度能在1的基础上下波动,而不是趋于0,稳定了训练过程。
  • Norm(层归一化):用于稳定训练过程。独立地对每个样本的每个词元的特征向量(也就是hidden_size维度)进行标准化。使其均值为0,方差变为1.因为了科学系的参数,gama和beta,让模型自主学习最佳的数据分布。


    image.png

这使得模型既能享受到归一化带来的稳定性,又具备了根据任务需要恢复或调整原始分布的能力。相比Batch Norm (对一个批次中的所有样本的统一特征进行归一化) 相比,layer Norm 不受批次大小影响,更适合处理长度可变的自然语言序列。

简单理解: 层归一化是每个样本的所有维度上的归一化。 批归一化是多个样本的同一维度上的归一化。目标都是为了提高训练稳定性。

原论文采用 Post-LN(Subplayer-> Add->LayerNorm). 现在实现(如GPT系列)采用Pre-LN(layerNorm->Subplayer->Add),训练更稳定、更易加深,但功能等价。

3.4 位置编码

自注意力机制缺陷是位置无关性,因为计算完全并行,模型无法感知词元的顺序。Transformer在词嵌入向量输入之间,为他们加入了一个位置编码。
(1)可学习的位置编码

  • Encoder-only模型中常见;近年大型decoder类模型多采用相对/旋转类位置编码(如RoPE)
  • 实现: 创建一个embedding层,大小为[max_sequence_langth,hidden_size]。max_sequence_length是模型能处理的最大序列长度。训练时,模型会想学embedding一样,自动学习出每个位置最合适的向量表示。

(2)基于三角函数的固定编码

  • 原版Transformer论文中使用的方法
  • 使用不同频率的正弦和预先函数为每个位置生成一个独特的固定的编码向量


    image.png

    利用不同频率的正弦和预先函数,为d维编码向量的每一个维度计算一个特定的值。每个位置的pos和每个维度i的组合都是独一无二的。
    优势是不同位置的编码向量之间存咋以固定的线性关系,这可能有主域模型推断出词元之间的相对位置。主要有点是不需要训练,理论上可以外推到比训练时遇到的更长的序列。

简而言之: pos是词元位置, i是向量的维度索引(0-d/2). 通过2i和2i+1来区分就。d是词嵌入的维度。所以每个位置每个向量维度都是不一样的。embendding 经过乘以根号dim进行缩放后再加上位置编码。

绝对 vs 相对位置编码
上述两种都属于绝对位置编码,每个绝对位置分配一个特定编码,缺点是处理超长文本时可能存在泛化性问题。因此,现代大语言模型转而采用相对位置编码。这种方法不在关注词元的绝对位置关系,而是直接注意力计算中建模词元之间的相对距离(例如当前词与前两个词之间的关系),这被证明在处理长序列时更有效、更灵活。

3.5 注意力掩码

(1)因果掩码: 用于解码器的带掩码的自注意力子层,为了确包解码过程遵循自回归特性,即生成第i个词元时能依赖前i-1个词元的信息,让注意力权重矩阵程下三角矩阵形态,其他位置都屏蔽掉。主对角线以下的位置标记为可关注,主对角线以上标记为屏蔽。在softmax之前被屏蔽的注意力分数会被加上一个极大的负数,迫使其注意力权重归零,物理上切断了信息的向后传播路径。
(2)填充掩码: 应用于编码器和解码器的所有注意力层,目的是为了解决变长序列批次处理时的padding问题。在计算注意力分数的时候,不计算padding的位置。

这两种在加码器的自注意力层通常结合使用,确包模型既不会关注到未来的信息,也不会关注到填充位。

3.6 解码器推理与KV缓存

推理时,模型必须逐个生成词元,是一个自回归的过程。从[BOS]开始符,生成token1,再输入[BOS],token1,生成token2. 知道生成[EOS] 结果符或达到最大长度。

如果按照这个流程直接计算,效率会非常低下,因为在每次需要重新计算输入词的QKV向量并参与注意力计算。但事实上,输入词的key和value向量之前的步骤已经计算过了。
为了解决这种冗余计算,推理式会采用关键的优化技术:KV缓存。

  • 基本原理: 对于解码器的每一层,都缓存下载至当前时刻已经计算出的所有词元的key和value向量。
  • 工作流程: 在生成第t个词元时,模型只需要为当前输入的第t-1个词元计算出它自己的qt-1,kt-1,vt-1.然后从缓存中取出来历史的K和V的cache. 最后把新的追加到缓存中,并用qt-1于更新后完整的Kcache,Vcache进行注意力计算。

通过KV缓存,每次解码步骤计算量从O(T^2)相关,降低到只与序列长度O(T)线性相关,提高了文本生成速度。需要注意,KV缓存占用会随步数线性增长,在多层多头设置下需关注显存开销。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容