Transformer架构

1.前向更新和反向传播

前向传播

反向传播梯度推导

假设输出为y^​=[0.85,0.15],我们假设真实标签为 y=[1,0](即真实类别为"买"),使用交叉熵损失函数

2. 词向量

one-hot独热编码、ID计算和稠密词向量:

独热编码内存占用高,浪费资源;且无法丈量余弦相似度

**ID编码:**有时我们直接把词映射成整数 ID,再喂入神经网络查词嵌入表。若只用 ID 而不学习 embedding(例如直接输入到可解释模型或规则系统),问题与 one-hot 类似:

无法表达词间相似度:ID 仅是索引,2 与 5 的数字大小无任何含义。

维度问题:需要再转成 one-hot 才可与线性模型结合,否则模型无法区分词。

离散特征:模型对未见词 ID 处理困难,泛化差。

而ID + 嵌入表本质上就等价于稠密词向量:ID 用来查表,获得 dense embedding,再参与后续计算。所以优势依旧是语义压缩与稠密计算。

稠密词向量把每个词映射成一个低维、连续实数向量(几十到几百维常见),这些向量通过训练让相似词在向量空间里距离更近、方向更相似。常见训练方法有 Word2Vec、GloVe、fastText,以及现代 Transformer 模型里的词嵌入层。

Transformer基础内容

与过去的方法对比:

RNN、LSTM:

  • 串行计算效率低

  • 只有一层,无法关注深层次的语义特征

  • 长距离信息丢失

第一步:文本到词嵌入

分词算法 Tokenization

大模型(LLM)如 ChatGPT 的一个基础步骤是将输入文本切分为机器可处理的基本单元------词元(Token)。分词(Tokenization)直接影响模型对不同语言文本的理解和处理效率。然而人类语言的结构各异:例如英文等使用空格分隔单词的语言,相对容易定义"词"边界;但中文等无空格语言中如何确定词边界则是难点。

总结LLM 中常用的分词方法(如 字节对编码Byte Pair Encoding,BPE、词片段WordPiece、SentencePiece/Unigram 等),阐述其原理和处理不同语言(特别是英文与中文)的策略差异,并比较它们在多语言语料上的表现,以及对模型训练、推理效率和语义理解准确性的影响。

常用的子词分词算法

当前的大型语言模型几乎清一色采用**子词级**的分词算法,以在完整单词和单字符之间取得平衡。子词分词的共同思想是:将词汇拆解为频繁出现的子单元,从而**压缩序列长度**并缓解未登录词问题,同时控制词表规模。

①字节对编码(BPE)

字节对编码 (Byte-Pair Encoding, BPE) 最初用于文本压缩,后被引入 NLP。BPE 从初始字符集开始,**迭代**将文本中最频繁的相邻符号对合并为新符号,重复该过程直到达到预定词汇大小。例如,"hello"最初分成字⺟ h e l l o ,BPE可能先合并频繁的 he 和 lo 成新符号,得到he l lo ,进一步合并得到 hel lo ,乃至最终整体作为 hello 一个词元。

再举一个例子,假设语料中高频出现单词 "newer" 和 "wider",初始词表为单字符。

这个过程持续进行,直到达到预设的词表大小或没有足够高频的对可以合并。

现代 LLM 常用一种变体称为**字节级 BPE** (byte-level BPE)。它以 256 个字节作为基本单元,确保任何 Unicode 文本都能表示。具体做法是将输入文本的每个字符拆解为 UTF-8 字节序列(例如,汉字"中"可能表示为3个字节 \xE4\xB8\xAD ,而英文字⺟ 'A' 则是单个字节 \x41 ),然后对字节序列执行 BPE 合并。这使得初始词表固定为256个符号(对应单字节的所有可能取值),无需预先收集全部字符。OpenAI 的 GPT-2 模型即采用字节级 BPE,其词汇表大小为50,257(包含256个基础字节、一个文本终止符,以及通过50,000次合并学习得来的新符号)。

BPE 分词具有多方面优点:

  1. 可逆且无损:能够准确无误地将词元序列还原回原文本。

  2. 通用适用:可处理训练语料中未见过的任意新文本(因为能回退到字节或字符级别)。**例如**,一个从未见过的专有名词 "Xylophonetron",如果词表中没有它,BPE 也能将其分解为如"Xy" , "lo" , "phone" , "tron" 或更细的片段,甚至单字节,而不会报错。

  3. 压缩高效:相比直接用字节表示文本,词元序列更短------平均每个词元相当于约4个字节内容。这降低了模型处理同一文本所需的步数。

  4. 保留常见子词:模型能将高频词缀或词根作为独立词元反复看到,例如英语中常见的后缀 ing 或前缀 un- 通常被作为一个子词(如 "unknowingly" 可能切分为 "un" , "know" , "ing" ,"ly" ),使模型在多种单词中学习到它的含义和用法,有助于**泛化**和理解语法。

②WordPiece 词片段算法

WordPiece 是另一种广泛使用的子词分词算法,最早用于机器翻译,后被 BERT 等模型采用。它与BPE 的过程相似,也是从字符集出发迭代合并符号,但**选择何种符号对进行合并的策略略有不同**。具体而言,WordPiece 并不总选择全局频次最高的符号对合并,而是评估合并后对语言模型整体概率的提升,选择**能最大化似然(或互信息)**的合并对。直观来说,WordPiece 在执行合并时会考虑若两个符号经常一起出现且单独出现时反而少见,则更有价值将它们合并。

③SentencePiece 与 Unigram 子词模型

以上 BPE 和 WordPiece 算法都**默认输入已按空格等分隔出词**。在许多亚洲语言中不存在空格分词,自然也无法简单套用空格预处理

Google 提出的 SentencePiece 工具提供了更通用的解决方案:**将输入视为原始字符流,不假定空格存在**。SentencePiece 会将空格也当作一种普通符号(通常用特殊字符 或Unicode的U+2581表示空格)加入初始字符集,然后使用 BPE 或基于**单字节图模型**的 Unigram 算法训练分词模型。**例如**,对于句子 "I love NLP.",SentencePiece 可能将其切分为:

其中 (下划线或元字符)代表空格,从而将空格也纳入子词构建过程。这样,SentencePiece 实现了与语言无关的子词分词,适用于中文等无显式分隔符的语言。

特别地,**Unigram** 子词模型(Kudo等人 2018 提出)是 SentencePiece 支持的另一种算法。其思想与BPE相反:不通过合并规则逐渐扩大词元,而是从一个大型候选词表开始,**逐步移除**不合适的符号来缩小词表。Unigram 首先假定一个很大的初始词典,然后基于语料统计一个语言模型损失函数,迭代删除对整体概率贡献最小的那部分符号。如此迭代直到达到目标词表大小。 与 BPE 不同,Unigram **不唯一决定**新文本的切分方式------在给定词表下往往存在多种切分可能,但训练时每个子词被赋予一个概率,解码时通常选取其中概率最大的切分。这种方式增加了灵活性。例如词表含 hug和单字⺟时,单词 hugs 既可切分为 "hug" , "s" ,也可切为 "h" , "ug" , "s" ,算法会选择概率更高的方案。**再如**,对于 "New York",如果词表中有 "New" , "York" , "NewYork" ,Unigram 可能会根据概率选择将 "New York" 作为一个整体词元,或者分为 "New"和 " York" (假设空格被编码进York)。

无空格语言的特殊性

中文没有空格分词这一天然标记,一个句子通常是连续的字符序列。这给基于空格的传统子词算法带来挑战。如果某两个字符在语料中经常相邻出现,即使其实跨越了词边界,它们也可能被合并进词表。

谷歌的 bert-base-chinese 模型选择直接将**所有中文字符拆成单字**进行 WordPiece。因此BERT 中文模型实际上没有产生真正的"词片段",而是退化为**字符级**分词。例如,词表中可能同时包含 "学" 和 "##学" 。这导致词表中**包含数千个毫无用处的子词符号**

针对同时包含多种语言的训练语料,主流做法是训练一个**通用的多语言子词词表**。例如谷歌的多语言 BERT (mBERT) 对104种语言采用一个 **110k 大小的共享 WordPiece 词汇**。即便如此,某些语种由于缺乏足够的合并机会,许多词仍被切成字符序列。Facebook 的 XLM-RoBERTa 模型针对100种语言,使用了 高达250,000 个词元的 SentencePiece 分词。在模型使用阶段,共享词片段仍能帮助模型在不同语言间迁移知识,例如相同的数字(如 123 )、专有名词(如 Paris 在英文和法文中拼写相同)或部分代码片段在多语言中可以共享同一个词元及其表示向量。

分词算法对于模型效率的影响

词表大小和序列长度是影响模型训练与推理效率的两个关键因素。

如果词表过大,模型的**嵌入层和输出层维度**将非常大。**例如**,一个拥有10万词元的词表,若嵌入维度为768,则仅嵌入层就有 100,000 * 768 个参数。

如果词表过小(例如采用字符级分词),则**序列长度**会大幅增加。**例如**,对于句子"Tokenization is important.",字符级分词可能产生超过20个词元:

分词对于语义理解准确性的影响

分词质量直接关系到模型对文本语义的表征能力。

一方面,子词分词有助于模型理解组成词的含义。另一方面,**错误的分词**可能割裂语义或引入噪声。

对于中文等每字都有一定含义的语言,完全的字符级分词(例如,中文词"学习"在字符级分词中是"学" 和 "习" 两个独立的词元)保证不损失细粒度信息,但也**牺牲了词级语义**。有研究发现,在特定领域对中文进行**术语级别**的分词(例如,将 "人工智能" 作为一个整体词元),有助于提高下游任务表现。

Embedding 词嵌入模型

本篇内容关于词嵌入(embedding)模型训练方法的理论讲解,包括经典模型(如Word2Vec、GloVe)和现代transformer模型(如BERT、GPT)中的词嵌入机制。

经典词嵌入模型
①Word2Vec 模型(Skip-gram 与 CBOW)

Word2Vec 是一种将单词映射为连续向量的无监督学习方法,通过大规模语料学习词的分布式表示。Word2Vec 有两种主要架构:Skip-gram 和 Continuous Bag-of-Words (CBOW)。两者的核心区别在于预测方向不同:

Skip-gram 模型:给定中心词 预测其周围的上下文词。模型输入一个词的 one-hot 编码,经过嵌入层得到该词的向量表示,然后用这个向量去预测在一定窗口内出现的上下文单词。Skip-gram 假设每个上下文词的预测是独立的,从而将多词预测拆解为若干二分类问题。这一架构实际上是一个浅层神经网络:一层隐藏层(即词嵌入层)和输出层,用于输出预测的上下文词分布。

实现方式:Skip-Gram模型同样包括输入层、隐藏层和输出层。但在这里,输入层只接收中心词的one-hot编码,隐藏层同样通过权重矩阵转换为密集向量,而输出层则尝试为上下文中的每个词分配概率。

CBOW 模型:与 Skip-gram 相反,CBOW 是给定上下文 预测中心词。模型在一个窗口内获取当前词左右的上下文词(通常取平均或拼接它们的向量),输入到隐藏层,再预测中间的目标词。因此,CBOW 利用周围词的信息来推断当前词。两种模型都通过大量文本数据训练,使得语义相似的词在向量空间中距离更近。训练得到的词向量可用作其他 NLP 任务的特征输入,或进一步微调用于特定任务。

CBOW模型通常包括输入层、隐藏层和输出层。输入层接收上下文词的one-hot编码,隐藏层通过权重矩阵将输入转换为低维的密集向量,输出层则使用softmax函数来预测目标词的概率分布。

②GloVe模型

另一种经典词嵌入方法是 Stanford 提出的 GloVe (Global Vectors)。与Word2Vec的预测式方法不同,GloVe 属于基于计数 (count-based) 的模型。它利用全局的词共现统计来学习词向量,其核心思想是:利用词对在整个语料中的共现频次信息,让词向量的线性关系能够反映这些统计关系。

GloVe 首先遍历语料库构建一个共现矩阵 XX:矩阵的每一行对应词汇 wiw_i,每一列对应上下文词wjwjw_j,矩阵元素 XijX_{ij} 表示词 wiw_i 和 wjwjw_j 在一定窗口内共现的次数。这一矩阵融入了全语料的统计信息,而不仅仅是局部窗口。直接用共现矩阵行向量作为词表示虽然蕴含语义,但维度极高且稀疏,需要降维处理。GloVe 的训练目标正是对共现矩阵做加权因子的矩阵分解/重构:学习一个低维词向量表示,使得任意两个词向量的点积可以近似反映它们在语料中的共现频率。

种方法使得GloVe能够同时捕捉到语言的局部和全局统计特性,为其在处理自然语言处理任务时提供了显著的优势。

基于Transformer的词嵌入机制

随着深度学习的发展,Transformer 架构的预训练语言模型(如 BERT、GPT 系列)成为新一代的词表示方法。这些模型不再将词向量视为静态参数,而是通过大型神经网络在给定上下文中动态地产生词的表示(即动态上下文嵌入)。不过,在Transformer模型的输入层,同样存在一个词嵌入模块,它负责将离散的文本输入映射为模型后续计算可用的连续向量表示。与传统模型不同,Transformer 的输入嵌入通常包含多种信息:

Token Embedding(词元嵌入):即每个输入标记(通常是词或子词)的基本向量表示。和Word2Vec 类似,Transformer 模型内部也有一个可训练的词表嵌入矩阵,用于将每个词ID映射成对应的向量。例如,BERT 的词汇表大小为约 30k,每个 token 对应一个 768 维向量;GPT-3 的词表更大(数万个 BPE子词)每个也映射到例如 12288 维向量。训练开始时这些向量通常随机初始化,在预训练过程中逐渐更新。

Position Embedding(位置嵌入):Transformer 模型为了让模型感知序列中各 token 的位置信息,会为每个位置(例如第1位、第2位...第n位)赋予一个向量。这些位置嵌入与 tokenembedding 维度相同,在输入时与词向量相加。BERT 等模型采用可学习的绝对位置嵌入,即设定最大序列长度(如512),为每个位置索引学习一个向量。GPT-2/3 等模型也通常使用可学习的位置向量(有些变体使用相对位置编码,但原始GPT系列用的也是绝对位置嵌入)。位置嵌入提供序列顺序信息,Transformer 自注意力机制本身不保序,所以必须通过这种方式注入顺序感。需要注意的是,BERT 的位置嵌入是训练学习的,而非 Transformer 原论文那种固定的三⻆函数位置编码。

Segment Embedding(分段嵌入,也称句片嵌入):这是 BERT 模型中特有的设计,用于区分输入中的句子片段。BERT 在预训练时除了 Masked LM 外还用了一个"下一句预测 (Next SentencePrediction, NSP)"的任务。为此,它的输入可以是由两个句子拼接而成,中间用特殊标记 [SEP] 分隔。模型需要判别这两个句子是否前后相接。为了让模型知道每个 token 属于第几句,BERT 给每个 token 增加一个Segment A/B 向量(如句子A的所有 token 加上向量 EA,句子B的token 加上向量 EB)。Segment embedding 大小与词嵌入相同(例如 768 维),只有两种取值(句子A或B)。在输入时,同样与 token embedding、position embedding 相加。(对于只有单句的输入,BERT 将所有 token 都标记为段A)。值得一提的是,GPT 等单向生成模型一般不使用段嵌入,因为它们通常处理单个连续文本段,不需要区分句对。像 GPT-2 就没有引入额外的句片embedding。

上述三类向量逐元素相加形成每个输入 token 的最终嵌入表示。例如,对于句子 "The cat is on themat",BERT 在输入时会为 "The" 的 token embedding、它的位置0的position embedding、以及段A的segment embedding 三个向量求和,得到 "The" 在位置0的输入表示。这种表示方式在Transformer 模型中非常普遍,

每个输入 token 的 embedding = Token向量 + 位置向量 +(可选)段向量。

预训练任务与嵌入优化

在 Transformer 预训练模型中,词嵌入不是直接以 Word2Vec 那样的目标来训练的,而是作为模型整体的一部分,通过预训练任务的误差反向传播间接优化。以 BERT 为例,预训练包含两个任务:

MLM (Masked Language Modeling):随机遮盖掉输入序列中15%的Token,用特殊标记 [MASK] 替换,然后让模型根据上下文预测这些被遮盖的词。由于模型需要利用双向上下文填空,这逼迫了词嵌入和Transformer层去捕捉丰富的语义信息。被遮盖的词如果其初始embedding不好,模型就难以正确预测,于是在预测过程中,embedding 会通过梯度被调整得更能表示该词各种可能的语境意义。

NSP (Next Sentence Prediction):随机挑选语料中的句子对,50%概率是真正相邻句,50%概率是无关句,让模型判断句子B是否是句子A的下一句。为完成此任务,模型需要理解句间关系并利用segment embedding 来区别句A和句B。虽然后来有研究指出 NSP 任务对性能作用不大,但在原始 BERT 中,这一任务也参与了embedding的训练,让段嵌入也得到了调优。

GPT 系列则使用**Causal Language Modeling (自回归语言模型)**作为预训练任务:给定前文预测下一个词。模型以单向(从左到右)方式训练,将序列前面的 token 预测下一个 token 的概率,与实际词比较计算loss。在这种任务下,模型仅通过过去的上下文来调整embedding:因为若某词的embedding没有提供足够的辨析力,模型在预测下文时误差会增大,训练就会推动调整该embedding。GPT 没有特殊的段嵌入,其输入embedding = token + position 两部分。同理,像 GPT-3 等更大的自回归模型也是通过预测下一个词的大规模任务来训练embedding矩阵和Transformer层的。

相较静态嵌入的优势:基于 Transformer 的嵌入有几大明显优点:

①多义词处理:动态模型能够根据上下文赋予词不同的表示,解决了静态词向量无法区分多义现象的问题。例如英文中的 "apapppplplele" 在谈论水果时和谈论科技公司时,BERT 输出的向量是不同的,从而下游模型可以轻易地利用这种差异。

②深层语法语义信息:Transformer 模型的embedding只是第一层输出,更重要的是经过多层自注意力编码后,每个词最终得到的上下文向量,包含了对整句的理解。这种深层表示捕获了句法依存、长距离关系等信息,是静态embedding无法直接提供的。哪怕只取Transformer的第一层输出(相当于带语境的embedding),也已经比静态向量包含更多上下文线索。

③下游任务效果:大量实践表明,使用预训练模型(如BERT、GPT)的词表示,通过微调可以在各类NLP任务上取得远超以前静态向量+浅层模型的效果。上下文嵌入在问答、阅读理解、命名实体识别、机器翻译等任务中表现卓越,因为模型已经在预训练中学会了丰富的语言知识,微调时只需根据任务稍加调整。相较之下,使用Word2Vec这类静态向量通常需要配合额外的CNN/RNN等模型才能建模句子含义,效果和训练代价都不如预训练Transformer。

第二步:位置编码

第三步:多头自注意力

8×8注意力矩阵详解

第i行第j列的含义:在注意力矩阵中,第i行第j列的数值表示:

位置i的token(作为Query)对位置j的token(作为Key)的注意力权重

注意力机制的演进发展

Transformer通过多头注意力机制(Multi-Head Attention, MHA)实现了对序列数据长程依赖的建模,极大提升了模型性能。然而,随着模型规模和上下文长度的增加,标准MHA 在计算开销和内存占用方面的代价日益显著。为了解决这一瓶颈,研究者相继提出了注意力机制的改进变体,例如多查询注意力(Multi-Query Attention, MQA)分组查询注意力(Grouped-QueryAttention, GQA) 等,用于在尽可能保持模型性能的同时,提高效率、降低内存。进入 2024 年,出现了最新的创新机制多头潜在注意力(Multi-Head Latent Attention, MLA),进一步在大型语言模型(LLM)的推理速度和表示能力之间寻求突破性平衡。

①多头注意力 MHA

其核心思想是:通过并行地使用多个注意力头来关注输入序列中不同位置的关系,从而综合提取丰富的特征表示。

在标准MHA中,输入首先经过三个线性映射得到对应的查询(Query)、键(Key)和值(Value)向量;然后每个注意力头都会独立计算自注意力,即通过查询和所有键之间的相似度(通常用点积表示)得到注意力权重,再以加权和的形式汇总对应的值向量。由于有多个头,每个注意力头可以在不同的子空间里学习序列元素间不同类型的相关性,例如一个头可能关注语法结构,另一个头侧重长程依赖等。最后,各头的输出会被拼接,并通过一个线性变换得到最终的注意力输出。

MHA为每个注意力头维护独立的参数(W\^Q, W\^K, W\^V 和输出投影W\^O),使模型能够从多个⻆度同时关注输入序列。正因为有多头并行,模型可以同时捕捉局部依赖和全局依赖、语法信息和语义信息,从而极大提升表示能力。

问题:

在大模型中存在计算和内存劣势。具体来说,对于序列长度为n、隐藏维度为 d、注意力头数为 h 的情况,每一步注意力计算的复杂度约为 O(N^2 \cdot d),并随序列变长呈二次增长,处理长文本代价极高。

同时,在自回归生成场景下(如聊天模型逐字生成文本),为了避免每次重复计算,Transformer通常使用KV缓存(Key-Value Cache)保存过去所有标记的键和值。如果每个注意力头都保留一份键和值,那么KV缓存的大小将随注意力头数线性增长。当模型有几十个注意力头、上下文窗口扩展到数千甚至数万时,KV缓存占用的显存/内存惊人,

②分组查询注意力 GQA

本质上,GQA 是 MHA 和 MQA 之间的一种折中与泛化。在介绍GQA前,我们先简要说明MQA概念以便对比:

MQA 多查询注意力:

它让所有注意力头共享同一个键投影和值投影,即**"多个查询头,对应单组键和值"。这样,每层Transformer只需计算一组K和V向量,并让所有头共用它们,从而大幅减少计算和存储开销。研究表明,MQA可以将注意力层的KV缓存大小削减为原来的1/10甚至1/100,并使解码推理速度提高约12倍。

但MQA也有明显缺点:由于极大减少了独立的键值参数,它往往削弱模型表示能力**,导致生成质量下降,在某些场景下难以满足性能要求。此外,MQA模型需要从头训练,无法直接从现有MHA模型迁移,这也增加了尝试MQA的成本。

分组查询注意力(Grouped-Query Attention, GQA)是针对标准多头注意力的效率瓶颈提出的一种改进机制。

GQA的核心思想是:将注意力头划分为若干组,每组内的多个头共享一套键/值投影,而不同组之间仍保持独立的键和值。换言之,GQA在"MHA每头独立"和"MQA所有头完全共享"之间提供了一个中间可调的选项。若将注意力头总数记为 h,我们可以设定一个分组数 G(1 ≤ G ≤ h):

当 $$G = $$ 时,每组只有一个头,相当于恢复标准MHA(每头各自一套K/V);

当 $$G = $$ 时,所有头同属一组,共用K/V,则退化为MQA;

而 $$1 < G < $$ 时,即为一般的GQA,每组内 $$\frac{h}{G$$ 个头共享键和值。

在实现上,GQA首先对查询头进行分组,然后按照组计算键、值向量:对于每组只投影一次键和一次值,并供组内所有头共同使用。但是每个头的查询向量仍然是独立的,这保证了组内不同头即使共享上下文表示,也可以通过不同的查询投影学习到各异的注意模式。在注意力计算阶段,属于同一组的多个头将针对相同的K/V集合计算注意力权重,但由于它们的查询Q不同,输出结果仍有差异。最终,各头输出与MHA一样被拼接并变换到输出。

总体而言,分组查询注意力作为Transformer注意力机制的演化产物,在实际大模型中取得了性能和效率的良好平衡,推动了LLM在有限计算资源下向更大参数、更长上下文发展。

③多头潜在注意力 MLA

MLA的目标是在保持模型强大建模能力的同时,进一步降低注意力计算中的存储和计算冗余,为超长序列建模和超大模型推理提供解决方案。

MLA 的关键思想是引入一个低维的潜在向量来代表注意力计算所需的信息,从而避免直接存储大维度的键、值矩阵。具体来说,给定当前层的输入表示 h_t(可以看作所有注意力头的输出拼接),MLA首先通过一个降维投影,将 h_t压缩到一个远小于原始维度 d的"潜在表示"c^{KV}_t。这个潜在向量可以被视为对当前序列状态的一种紧凑摘要,浓缩了所有注意力头需要"记忆"的关键信息。然后,当需要计算注意力时,模型再通过若干上投影矩阵,将这个潜在向量映射回高维空间,恢复出各注意力头所需的键和值向量。由于在推理阶段我们只需缓存和传递低维的潜在向量c^{KV}_t,而不再显式保存完整的K、V矩阵,因此KV缓存的存储需求将显著降低------------只与潜在向量维度 d_c 线性相关,而 d_c远小于原本h_n·d_h(所有头拼接后的尺寸)。

简单来说,MLA通过"先压缩、用时再解压"的策略,大幅缩减了注意力状态表示的冗余信息。

MHA、GQA、MLA 的对比分析

将三种注意力机制在计算效率、内存占用和学习能力等方面进行横向比较

计算复杂度与速度:GQA的推理速度明显快于MHA,接近MQA的水平。

内存占用(KV缓存):MHA内存占用最高,MQA最低(减少约一个数量级),GQA在两者之间可调,MLA则通过压缩达到与GQA相当或更优的缓存效率。

模型表示能力与效果:MHA ≈ MLA ≥ GQA >> MQA,即MHA和MLA在理想情况下提供最强的表达能力,GQA非常接近它们,而MQA相对逊色一些。

BN层

残差链接

原版 Transformer(Vaswani et al., 2017)把 LayerNorm 放在残差"之后"(Post-LN):

后来更常见的做法是放在残差"之前"(Pre-LN):

* 两种摆放都能工作,但在收敛速度、训练稳定性和深层网络表现上有不同的权衡。

FFN&残差链接

堆叠多层

Encoder、Encoder-Decoder和Decoder-only架构

①Decoder only架构 (GPT,QWEN,LLAMA模型)

②Encoder only架构 (Bert模型)

③Encoder-Decoder 架构 (T5模型)

为什么transformer架构好:

(1)并行效率快 (2)深入理解词与词之间的关系 (3)架构通用(跨模态,标准化)

举例说明注意力机制中的Q\K\V:

初始化三个矩阵:WQ、WK、WV。对输入矩阵 进行不同的线性映射

对于上文的输入矩阵"小明 喜欢 吃 苹果 吗"而言,X · WQ = Q、X · WK = K、X · WV=V

Q相当于提问矩阵、;K相当于标签矩阵;V相当于答案矩阵,存储的就是原内容的映射

Q · K^T 此时得到的是未归一化的标签矩阵

dk就是Embedding之后词向量的维度,也即K矩阵的维度,这里就是4

再进行softmax归一化,也即将矩阵转化为概率,和为一

如果不经过除以根号Dk的话,如【10,20,30】,经过softmax处理,几乎结果变为【0,0,1】,对应的梯度就几乎消失了,因此除以根号Dk,让softmax平缓的工作

关注的内容 * 关注的程度

原向量 -> 融合了整个句子信息的向量

多头注意力机制:让模型从多个角度看问题

整体架构理解

一:编码器输入

第一部分:输入的嵌入

input embedding:将离散的文本转化为连续的向量表示,使得神经网络能够处理文本信息

对于输入句子进行分词,分为Tokens,左上图

统计所有此构建词汇表,以及<pad>对齐不同长度句子,<sos>标记开始,<eos>标签标记结束

构建嵌入矩阵,其中的0,也即padding,把句子补充为一个长度,其中15*512维矩阵,15也即刚刚建立的词表大小为15,一个词对应一个矩阵(训练出来的)

把每一句话构成一个3*5*512维度的矩阵

第二部分:位置嵌入

位置编码的计算过程 d==512

每一个batch有3个句子、每一个句子长度是5个token、每个token有512维度向量

二:编码器层

第一部分:多头自注意力+残差连接与层归一化

多头自注意力的整体过程

1.创建多个自注意力头

对于K矩阵,首先让前面收到的输入数据X乘Wk矩阵,得到K矩阵,对于512维度向量,分割成8*64维度,也即8头子注意力,竖着平均切成8份

Q和V矩阵也同理

2.执行注意力计算 【含针对padding掩码的处理 (padding mask)】

Q · K^T 得到3*5*5的注意力得分矩阵,为了不让注意力关注padding,构建padding掩码矩阵。

也即有几个padding,后面就改为几列的极小数,如1e-9

然后按行计算softmax,再乘以V矩阵

3.多头注意力拼接

进行简单拼接,变成3*5*512,再经过一个线性层变成多头注意力的得分

4.残差连接与层归一化

第二部分:前馈神经网络+残差连接与层归一化

对上述的结构进行6次重复,学习更抽象的特征

三:解码器输入

第一部分:输入的嵌入

类似的,按照英文句子,去除<eos>位置结尾并在开头添加<sos>,构建英文词表,并组织成3*7*512维度的向量,每个批次三个句子、每个句子7个token,每个token有512维度

第二部分:位置编码

问题?为什么把整个英语句子都给解码器?------翻译过程

并非利用整个输入句子

最开始,仅有<sos>向量:使用该向量预测下一个向量steve

之后,利用预测到的steve和原有的<sos>向量进行预测,预测builds向量

如此往复,指导预测输出为<eos>,预测结束

下面这里是拆解的训练方法,并非实际训练过程。实际训练过程见解码器层

问题? 模型训练困境,一步错步步错?------教师强制策略

不管上一步是对是错,无视输出,使用正确答案预测下一个词

四:解码器层 ------ 两个注意力机制

第一部分:掩码多头自注意力(最大区别)+残差链接与层归一化

实际中,肯定不是像刚刚提到的分解模式,先给入<sos>,在给入<sos>,steve。而是将一个批次的向量一次给入,通过掩码多头自注意力机制进行处理:

如果不进行掩码,就会导致token泄露,看着答案输出答案。

区别主要体现在掩码

掩码多头自注意力计算流程

左上角:Q乘以K^T矩阵,并除以根号dK,得到初始的注意力分数

中上:利用padding掩码和多头自注意力掩码得到注意力掩码矩阵。实际使用相加的操作,蓝色和黑色都是很小的负数

右上:(初始的注意力分数 + 注意力掩码矩阵)* V矩阵 = 结果矩阵(head1)

第二部分:编码器-解码器注意力机制

链接中文理解 与 英文生成的桥梁

解码器当前正在生成的词作为Query

编码器输出的整个输入句子表示作为 Key/ Value

解码器在生成每个词时,都可以"查询"输入句子哪些部分最相关。让解码器主动从输入句子中取信息,而不是"闭眼猜"在生成每个词时动态对齐输入内容,找到最相关的词或短语

如下图,query矩阵来自解码器,其输入为经过maxked多头注意力和残差链接以及LN层,输入3*7*512,也即batch中有3句话,一句话7个token,每个token512层

key和value矩阵来自编码器,其输入为经过了6层编码器层的输出,也即完全学习了抽象特征的编码器的最后一层输出,如上图所示:输入3*5*512,也即batch中有3句话,一句话5个token,每个token512层

他们的输入大小不一致

两个注意力机制总结

五:输出

六:后话 K-V cache 与 分组多头注意力GQA

KV cache会把计算的中间过程保留下来,但是这样对于长上下文来说,占用的显存过大了,读取带宽也不允许,因此大多使用了GQA方法来缓解

主流大模型(如 Qwen 2.5、LLaMA)均采用Transformer Decoder-only架构。模型由24层Decoder层堆叠构成,各层结构高度一致。

单个 Decoder 层包含四个核心模块:

LayerNorm(层归一化):稳定数值分布

Masked Multi-Head Attention (掩码多头自注意力):建模上下文依赖

Residual Connection(残差连接):保证深层训练稳定

FFN/MLP层:进行非线性特征变换与知识重组

K-V cache 与 分组多头注意力GQA发生在(掩码多头自注意力)层

分的头的数量不一致,W分为28个头,K和V分为4个头,所以WQ是WK和WV列的7倍,没7个Q用一个k

得到28个头的输入向量,经过拼接变成4*3584,乘以一个Wo来汇总答案

获取到了"我"之后,继续进行上述的操作

大模型希望看到之前的信息,所以把上次计算的K cache和V cache保存在显存中,如下图黑色部分的内容

注意,如果不适用KV cache,在上图的"我"矩阵这里,想要知道前面的提示文本,就需要使用:"你是谁?我"这样一个5*3584维度的矩阵,而且随着序列的增长,还会有更多冗余计算(因为此时的KQV都已经确定了,"你是谁?我"这样一个5*3584维度的矩阵中的"你是谁?"这个4*3584的内容已经多次计算了)

而GQA的作用在于,如果不分组,也即一个Q对应一个K和一个V,那么要储存的就是4*3584维度的K_cache和V_cache,缩小了7倍的存储

前面也提到了:GQA 是 MHA 和 MQA 之间的一种折中与泛化。

问题:

在大模型中存在计算和内存劣势。具体来说,对于序列长度为n、隐藏维度为 d、注意力头数为 h 的情况,每一步注意力计算的复杂度约为 O(N^2 \cdot d),并随序列变长呈二次增长,处理长文本代价极高。

同时,在自回归生成场景下(如聊天模型逐字生成文本),为了避免每次重复计算,Transformer通常使用KV缓存(Key-Value Cache)保存过去所有标记的键和值。如果每个注意力头都保留一份键和值,那么KV缓存的大小将随注意力头数线性增长。当模型有几十个注意力头、上下文窗口扩展到数千甚至数万时,KV缓存占用的显存/内存惊人,
MQA 多查询注意力:

它让所有注意力头共享同一个键投影和值投影,即**"多个查询头,对应单组键和值"。这样,每层Transformer只需计算一组K和V向量,并让所有头共用它们,从而大幅减少计算和存储开销。研究表明,MQA可以将注意力层的KV缓存大小削减为原来的1/10甚至1/100,并使解码推理速度提高约12倍。

但MQA也有明显缺点:由于极大减少了独立的键值参数,它往往削弱模型表示能力**,导致生成质量下降,在某些场景下难以满足性能要求。此外,MQA模型需要从头训练,无法直接从现有MHA模型迁移,这也增加了尝试MQA的成本。

七:MLA ------ GQA 的优化

从GQA到MLA的低秩投影

GQA也可以看作低秩投影

MLA做的改进:结合dot-attention的恒等变换

MLA遇到的困扰及解决:如何兼容位置编码RoPE

MLA的小细节:对Q的低秩投影与显存优化

相关推荐
NAGNIP3 小时前
一文搞懂深度学习中的通用逼近定理!
人工智能·算法·面试
冬奇Lab4 小时前
一天一个开源项目(第36篇):EverMemOS - 跨 LLM 与平台的长时记忆 OS,让 Agent 会记忆更会推理
人工智能·开源·资讯
冬奇Lab4 小时前
OpenClaw 源码深度解析(一):Gateway——为什么需要一个"中枢"
人工智能·开源·源码阅读
AngelPP8 小时前
OpenClaw 架构深度解析:如何把 AI 助手搬到你的个人设备上
人工智能
宅小年8 小时前
Claude Code 换成了Kimi K2.5后,我再也回不去了
人工智能·ai编程·claude
九狼8 小时前
Flutter URL Scheme 跨平台跳转
人工智能·flutter·github
ZFSS8 小时前
Kimi Chat Completion API 申请及使用
前端·人工智能
天翼云开发者社区9 小时前
春节复工福利就位!天翼云息壤2500万Tokens免费送,全品类大模型一键畅玩!
人工智能·算力服务·息壤
知识浅谈9 小时前
教你如何用 Gemini 将课本图片一键转为精美 PPT
人工智能
Ray Liang10 小时前
被低估的量化版模型,小身材也能干大事
人工智能·ai·ai助手·mindx