小白也能看懂的Transformer解析
Transformer
Transformer 基于 “编码器 - 解码器” 结构,用于序列到序列(Seq2Seq)任务(如翻译)。核心组件包括:
- 输入层:Token Embedding + 位置编码
- Encoder:6 层(可配置),每层含 “多头自注意力”+“前馈网络”
- Decoder:6 层(可配置),每层含 “掩码多头自注意力”+“编码器 - 解码器注意力”+“前馈网络”
- 输出层:线性层 + Softmax(生成目标序列概率)
一、详细处理过程(以 “我爱你。→ I LOVE YOU.” 为例)
下面以 “我爱你。→ I LOVE YOU.” 的翻译任务为例,详细拆解 Transformer 架构的每一步处理过程:
1. 输入预处理:分词(Tokenization)
首先将输入文本拆分为最小单位(Token):
- 源语言(中文):“我爱你。” → 分词为
["我", "爱", "你", "。"](假设用字符级分词)- 目标语言(英文):“I LOVE YOU.” → 分词为
["<sos>", "I", "LOVE", "YOU", "." , "<eos>"]
在开头加<sos>(Start of Sequence,序列起始符),告诉模型 “从这里开始生成目标序列”;在结尾加
<eos>(End of Sequence,序列终止符),告诉模型 “生成到这里结束”。
2. Embedding 层:将 Token 转为向量
作用:将离散的 Token 映射为连续的低维向量(更容易捕捉语义信息)。
- 假设词表大小:中文 3000 字,英文 5000 词,嵌入维度
d_model=512(Transformer 默认,token被映射成的低维向量的维度)。- 过程:
- “我” → 查中文嵌入矩阵 → 得到向量
v1 ∈ R^512- “爱” → 向量
v2 ∈ R^512- “你” → 向量
v3 ∈ R^512- “。” → 向量
v4 ∈ R^512- 目标语言的
<sos>、“I” 等也通过英文嵌入矩阵转为 512 维向量。
3. 位置编码(Positional Encoding):注入顺序信息
Transformer 是并行处理序列的,需手动加入位置信息。
必要性?Transformer 是并行处理序列的(无循环结构),无法像 RNN 那样自然捕捉顺序,位置编码通过正弦余弦函数注入位置信息,让模型区分不同位置的 Token。
公式(正弦余弦编码):
其中
pos是 Token 位置(0,1,2,3),i是向量维度索引(0 到 512/2-1=255)。PE0,PE1,PE2,PE3
∈ R^512。
过程:
- 对 “我”(位置 0)的向量
v1加上位置 0 的编码 →v1 + PE0- 对 “爱”(位置 1)的向量
v2加上位置 1 的编码 →v2 + PE1- 以此类推,最终得到 带位置信息的输入向量序列:
[v1+PE0, v2+PE1, v3+PE2, v4+PE3]。
4. Encoder 层:提取源语言语义特征
Encoder 共 6 层,每层输出维度仍为 512,输入是 “带位置编码的嵌入向量”,输出是 “源语言语义特征矩阵”。
单 Encoder 层结构(核心两步)
Step 1:多头自注意力(Multi-Head Self-Attention)
作用:让每个 Token 关注序列中其他相关 Token(如 “爱” 会重点关注 “我” 和 “你”)。
- 拆分多头:将 512 维向量拆分为
h=8个头(每头512/8=64维)。- 计算注意力:对每个头,用 Query(Q)、Key(K)、Value(V)矩阵计算注意力权重:
其中
d_k=64(每头维度),防止内积过大。- 合并多头:将 8 头的输出拼接,通过线性层映射回 512 维。
- 示例:“我” 的向量经多头注意力后,会融合 “爱” 和 “你” 的信息,更准确表达 “我→爱→你” 的语义关联。
Step 2:前馈网络(Feed Forward Network)
作用:对每个 Token 的向量进行非线性变换(增强表达能力)。
- 结构:
Linear(512→2048) → ReLU → Linear(2048→512)。- 过程:每个 Token 的向量独立经过两层线性变换和激活函数,输出仍为 512 维。
残差连接与层归一化:每层的输出为
LayerNorm(x + Sublayer(x)),其中x是输入,Sublayer(x)是自注意力或前馈网络的输出(防止梯度消失,加速训练)。
5. Decoder 层:生成目标语言序列
Decoder 共 6 层,输入是 “目标语言的嵌入 + 位置编码”,输出是 “目标序列的概率分布”。
核心:结合 Encoder 的语义特征,逐步生成目标 Token。
单 Decoder 层结构(核心三步)
Step 1:掩码多头自注意力(Masked Multi-Head Self-Attention)
作用:确保生成第
t个 Token 时,只能关注前t-1个已生成 Token(防止 “偷看” 未来信息)。
- 掩码(Mask):对注意力矩阵的上三角部分(未来位置)填充
-∞,加上mask后Softmax 后变为 0,即:(二、关键问题延伸有详细掩码过程)- 示例:生成 “LOVE” 时,只能关注
<sos>和 “I”,不能关注 “YOU” 或 “.”。Step 2:编码器 - 解码器注意力(Encoder-Decoder Attention)
作用:让目标 Token 关注源语言中相关的 Token(如 “LOVE” 需关注源语言的 “爱”)。
- 计算方式:Q 来自 Decoder 的掩码注意力输出,K 和 V 来自 Encoder 的最终输出(源语言特征)。
Step 3:前馈网络:与 Encoder 相同,对向量进行非线性变换。
6. 输出层:生成概率分布
- 线性层:将 Decoder 最后一层的 512 维输出映射到目标语言词表大小(如 5000 维),得到每个 Token 的得分。
- Softmax:将得分转为概率分布(和为 1),例如:生成到
<sos>后,Softmax 输出可能为:P("I")=0.9, P("You")=0.05, ...
7. 解码搜索:从概率分布中选择 Token
虽然这个不属于架构中的一部分,但这个也涉及到对Transformer最后输出结果的不同处理方法。
生成目标序列时,需从概率分布中选择下一个 Token,常用两种方法:
-
1. 贪心搜索(Greedy Search)
原理:每次选择概率最高的 Token 作为下一个输出。
- 过程:
<sos>→ 选概率最高的 “I”- “I” → 选概率最高的 “LOVE”
- “LOVE” → 选概率最高的 “YOU”
- “YOU” → 选概率最高的 “.”
- “.” → 选概率最高的
<eos>,终止生成。
- 优点:速度快;
- 缺点:可能陷入局部最优(如错过整体更优的 “我爱你→I LIKE YOU”)。
- 过程:
-
2. 束搜索(Beam Search)
原理:保留 Top-K 个候选序列(束宽 K),每次扩展候选时选择总概率最高的 K 个。
- 过程(K=2):
<sos>→ 保留概率前 2 的候选:[<sos>I (0.9), <sos>You (0.05)]- 对每个候选扩展:
<sos>I→ 生成 “LOVE”(总概率 0.9×0.8=0.72)、“LIKE”(0.9×0.1=0.09)<sos>You→ 生成 “LOVE”(0.05×0.7=0.035)
- 保留前 2:
[<sos>I LOVE (0.72), <sos>I LIKE (0.09)] - 重复扩展,直到出现
<eos>,选择总概率最高的序列。
- 优点:生成质量更高(考虑全局最优);
- 缺点:速度比贪心慢(K 越大越慢)。
- 过程(K=2):
二、关键问题延伸
常见问题解答(敲重点!!!)
-
为什么需要多头注意力?
单头注意力只能捕捉一种关联模式,多头可并行学习不同的语义关联(如语法关联、语义关联),提升表达能力。
-
为什么需要线性层?
自注意力和前馈网络的输出维度是 512,而词表大小可能远大于 512(如 5000),线性层用于将 512 维向量映射到词表维度,才能通过 Softmax 生成每个 Token 的概率。
-
为什么 Decoder 的输入叫 outputs?
这是语境和任务视角差异导致的命名习惯,核心是 Decoder 处理的是 “目标序列的中间生成结果”—— 在 Seq2Seq 任务(如翻译)中:
从整体任务流程看:
- Encoder 输入是 “源序列”(如中文 “我爱你”),属于 “待处理的原始输入”;
- Decoder 的输入是 “目标序列的前缀”(如英文
<sos>I LOVE),而这个前缀本质是模型已经生成的部分输出(相对于最终完整输出<sos>I LOVE YOU.<eos>而言,前缀是中间输出)。本质是强调 “这是要生成的目标序列的输入形式”,而非字面意义的 “最终输出”。
-
Decoder 的输入通常会比 Encoder 的多一个 sos 符号吗?
通常如此,但核心是 “序列类型差异” 而非 “长度必然多 1”,具体:
- Encoder 输入的是 “源序列”(如
["我", "爱", "你", "。"]),无需额外符号 —— 源序列是完整的 “待理解文本”,模型只需直接编码其语义。- Decoder 输入的是 “目标序列”(如翻译任务的英文),必须在开头加
<sos>(Start of Sequence,序列起始符)—— 告诉模型 “从这里开始生成目标序列”;同时在结尾加<eos>(End of Sequence,序列终止符),告诉模型 “生成到这里结束”。
- Transformer 是监督学习吗?
取决于具体任务和训练方式:
- 当 Transformer 用于Seq2Seq 的有标签任务(翻译、对话生成、文本摘要)时,是监督学习;(绝大多数场景)
- 当用于单序列的自监督预训练(BERT、GPT 的预训练阶段)时,是自监督学习(属于无监督学习的子类)。
- 监督学习(“有标签、学映射”)
训练时有 “明确的输入 - 输出配对标签”。例如翻译任务中,每个源序列(中文 “我爱你”)都对应一个标注好的目标序列(英文 “I LOVE YOU.”);训练时,模型通过 “预测目标序列的每个 Token” 与 “真实标签” 的差异(如交叉熵损失)调整参数,学习从源序列到目标序列的映射 。
- 自监督学习
- BERT(基于 Transformer 的 Encoder):通过 “掩码语言模型(MLM)” 和 “下一句预测(NSP)” 训练 —— 无明确的 “输入 - 输出配对”,而是利用文本自身的上下文信息作为监督信号(自监督学习)。
- GPT(基于 Transformer 的 Decoder):通过 “因果语言模型(CLM)” 训练 —— 输入是文本前缀,预测下一个 Token,监督信号来自文本自身的 “下一个 Token”(自监督学习)。
-
Greedy Search /Beam Search与参数Tempreture/Top_K/Top_P的区别与联系
greedy search、beam search与temperature、top_k、top_p均为生成式模型(如 Transformer 解码器)的解码策略参数,但分属不同维度:前两者是 “序列生成的候选选择策略”,后三者是 “概率分布的调整策略”。以下是具体对应关系和参数含义:一、解码策略与参数的关联
解码策略 核心逻辑 与 temperature/top_k/top_p 的关联 Greedy Search 每次选择概率最高的 Token(局部最优)。 不直接依赖这三个参数,但可理解为: temperature=0(概率分布被 “硬化”,只保留最大值)、top_k=1(只保留 top1 候选)。Beam Search 保留 Top-K 个候选序列,每次扩展时选择总概率最高的 K 个(全局更优)。 同样不直接依赖这三个参数,本质是 “多候选并行扩展”,但可结合 top_k过滤低概率候选(如只从 top20 中选,加速计算)。二、temperature、top_k、top_p 的含义与作用
这些参数用于调整 Token 预测的概率分布,控制生成结果的 “随机性” 和 “多样性”,核心是对 Softmax 输出的概率进行后处理:
1.
temperature(温度):控制概率分布的 “陡峭程度”通过改变 t 控制概率分布的形状。t 越小,概率分布越陡峭(高概率更突出,低概率更被抑制);t 越大,概率分布越趋向均匀。
- 公式:对 Softmax 的输入(logits)进行缩放:
logits = logits / temperature,再做 Softmax。
temperature = 1:保持原始概率分布(默认值)。temperature → 0:概率分布被 “锐化”,高概率 Token 的概率趋近于 1,低概率趋近于 0(接近 greedy search,确定性高,多样性低)。例:原始概率[0.8, 0.1, 0.1]→ 经temperature=0.1处理后 →[≈1.0, 0, 0]。temperature > 1:概率分布被 “平滑”,高概率 Token 的概率降低,低概率升高(随机性增强,多样性高,但可能生成不合理内容)。例:原始概率[0.8, 0.1, 0.1]→ 经temperature=10处理后 →[0.35, 0.325, 0.325]。2.
top_k:只保留概率最高的前 K 个 Token
- 作用:过滤低概率候选,仅从概率排名前 K 的 Token 中采样(K 为超参数,如 10、50)。
- 例:若
top_k=2,原始概率[0.5, 0.3, 0.1, 0.1]→ 只保留前 2 个 Token,概率归一化后为[0.625, 0.375]。- 特点:简单高效,但可能漏掉低概率但重要的 Token(如 K=2 时,第 3 个 Token 即使有意义也会被过滤)。
3.
top_p(核采样,nucleus sampling):保留累积概率≥p 的最小 Token 集
- 作用:从高到低累加 Token 的概率,直到总和≥p(p 通常取 0.9、0.95),只从这个 “核” 中采样。
- 例:原始概率
[0.5, 0.3, 0.1, 0.1],若top_p=0.9:
- 累加前 2 个:0.5+0.3=0.8 < 0.9 → 继续加第 3 个:0.8+0.1=0.9 ≥0.9 → 保留前 3 个,概率归一化后为
[0.55, 0.33, 0.12]。- 特点:自适应调整候选数量(内容简单时候选少,复杂时候选多),比
top_k更灵活,兼顾多样性和合理性。
Mask 详细过程
- Encoder 中无需 Mask(可关注所有 Token);
- Decoder 的掩码自注意力用于防止 “偷看” 未来 Token,确保生成顺序合理,也符合人类从左到右说话和翻译的因果逻辑。
- 负无穷大 Padding:利用 Softmax (e^(-∞)=0) 的数学特性,将填充符的注意力权重严格清零,让模型只关注有效序列内容。
图示
生成第 3 个 Token(LOVE)时,
掩码之前:(原始注意力得分矩阵)
行(当前 Token)\ 列(被关注 Token) 0(<sos>) 1(I) 2(LOVE) 0(计算<sos>的注意力) 5.2 3.1 1.8 1(计算 I 的注意力) 2.9 4.7 2.3 2(计算 LOVE 的注意力) 3.5 5.1 4.2 掩码后:
行(当前 Token)\ 列(被关注 Token) 0(<sos>) 1(I) 2(LOVE) 0(计算<sos>的注意力) 5.2 -∞ -∞ (<sos>是第 1 个 Token,只能关注自己) 1(计算 I 的注意力) 2.9 4.7 -∞ (I 是第 2 个 Token,能关注<sos>和自己) 2(计算 LOVE 的注意力) 3.5 5.1 4.2 (LOVE 是第 3 个 Token,能关注前 3 个 Token) softmax后:(-∞经 Softmax 后变为 0,权重和为 1)
行(当前 Token)\ 列(被关注 Token) 0(<sos>) 1(I) 2(LOVE) 0(<sos>的注意力权重) 1.0 0.0 0.0 1(I 的注意力权重) 0.15 0.85 0.0 2(LOVE 的注意力权重) 0.12 0.65 0.23
三、相关知识扩展💡
分词技术
1. BPE (Byte Pair Encoding)
2. WordPiece
| 分词技术 | BPE | WordPiece |
|---|---|---|
| 原理 |
|
|
| 示例 | 原始数据 ["low", "lower", "newest", "widest"] 步骤1:字符拆分 l o w, l o w e r, n e w e s t, w i d e s t 步骤2:统计并合并最高频对 'e'+'s' 出现2次 → 合并为 'es' 词汇表: [es, ...] 步骤3:继续合并 'es'+'t' 出现2次 → 合并为 'est' 最终词汇表可能包含: l, o, w, e, r, n, est, ... | 原始数据 ["play", "playing", "player", "replay"] 步骤1:字符拆分 p, l, a, y, i, n, g, e, r 步骤2:计算所有可能合并的分数并合并最高分的子词 如 "play" → 保留为整体 步骤3:继续合并 最终可能得到: play, ##ing, ##er, re## |
| 应用 | GPT系列:GPT-2, GPT-3, GPT-4 RoBERTa BART | BERT系列 ALBERT ELECTRA |
对比总结
| 分词技术 | 词汇表控制 | 多语言支持 | 未知词处理 | 主要应用 |
|---|---|---|---|---|
| BPE | 合并次数 | 中等 | 良好 | GPT系列 |
| WordPiece | 合并次数 | 中等 | 良好 | BERT系列 |
| SentencePiece | 词汇大小 | 优秀 | 优秀 | 多语言模型 |
| Unigram[迭代优化词汇表] | 词汇大小 | 优秀 | 优秀 | 日语/中文 |
| BBPE[按字节] | 固定256 | 优秀 | 完美 | 多语言模型 |
| Character[按字符] | 固定 | 优秀 | 完美 | 字符级任务 |
| Whitespace[按空格] | 无控制 | 中等 | 差 | 传统NLP |
| Morphological[按语言学规则] | 无控制 | 语言特定 | 良好 | 语言学分析 |
位置编码
| 对比 | 传统正弦余弦位置编码 | 旋转编码(RoPE) |
|---|---|---|
| 位置信息类型 | 绝对位置(仅体现 “当前位置”) | 相对位置(体现 “位置差”,更符合语言逻辑) |
| 长序列适配性 | 差(长序列易位置混淆)位置足够大时会出现周期性重复(比如 pos=100 和 pos=100+2π 的 PE 向量相同) | 好(支持超长序列,无位置混淆)RoPE 的旋转角度随位置线性增长,即使 pos 很大,不同位置的角度也不会重复 |
| 计算与存储开销 | 需存储 PE 矩阵,有轻微额外开销 | 无额外参数,动态计算,效率高 |
| 序列长度灵活性 | 固定最大长度,扩展需重新处理 | 动态长度,支持预训练后扩展。旋转矩阵是通过位置 pos 动态计算的,无需预定义最大序列长度。 |
| 典型应用场景 | 短序列任务(如短文本翻译、情感分类) | 长序列任务(如长文档摘要、代码生成、对话) |
RoPE 已成为当前主流大模型(如 LLaMA、ChatGLM、Qwen)的默认位置编码方案,彻底取代了传统的正弦余弦编码。
-
正余弦位置编码
公式:
正弦和余弦函数的交替使用:
- 偶数维度 2i 使用正弦函数
- 奇数维度 2i+1使用余弦函数
- 隐含:可以线性变换表示相对位置(三角函数和差化积)(绝对位置推相对关系)
解释:
为不同维度创建了不同的波长:
- 当i=0时:10000^0=1,波长为2π,波长短,函数值变化快。有助于捕捉近距离关系。高敏感性。
- 当i=d_model/2-1时:10000(d_model-2)/d_model,波长为10000^2π,在很长的序列范围内,高维度的编码值几乎恒定,有助于学习长距离依赖关系。
局限性:
- 假设嵌入维度为2,m是位置索引。在二维直角坐标系看,取初始embedding向量为[1, 1], 加上位置编码后其实每个位置所表示的向量的变化是杂乱无章的,并且没有模长也在变化。
- 基于正弦位置编码的大模型,在输入长度超过模型训练定义的最大长度,困惑度会显著上升。
-
旋转位置编码(Rotary Position Embedding, RoPE)
传统的输入就是token和位置编码的简单相加。(这个是否不合理?)
因此RoPE通过旋转操作来结合两者。(模长表语义信息不变,旋转多少表示位置变化多少)
公式:
解释:
可以把 Q/K 向量看作平面上的 “向量”,位置
pos越大,向量旋转的角度越大。两个 Token 的位置差越大,它们的 Q/K 向量旋转后的 “夹角” 越大,注意力权重就越能体现 “位置远近”—— 比如 “我”(pos0)与 “你”(pos2)的位置差比 “我” 与 “爱”(pos1)大,旋转后 Q/K 的夹角更大,注意力权重会更小(符合 “距离越远,关联越弱” 的直觉)。嵌入维度高维度(>2)的情况:
把向量拆分成若干二维块,每块独立以不同的角速度进行旋转,以 512 维为例:
1)512 维向量可拆分为 256 个 2D 子空间:
- 第 1 个 2D 子空间:维度 0 和维度 1;
- 第 2 个 2D 子空间:维度 2 和维度 3;
- ...
- 第 256 个 2D 子空间:维度 510 和维度 511。
2)基础频率
为每个 2D 子空间定义独特的基础频率(i 是子空间索引):
当 d_model}}=512 时,第 0 个子空间(维度 0-1)的 W_0 = 10000^{0} = 1),第 1 个子空间(维度 2-3)的 W_1 = 10000^{-2/512}≈0.99),以此类推,越往后的子空间 W_i 越小。
优点:
解决了传统正弦位置编码的痛点:在输入长度超过模型训练定义的最大长度,困惑度不会显著上升。
图示参考链接:
注意力机制
- MHA(多头注意力):多个注意力头各自独立维护专属的 Key(K)和 Value(V),能充分捕捉不同维度的特征关联。
- MQA(多查询注意力):所有注意力头共享同一组 Key(K)和 Value(V),仅查询(Q)各自独立,以减少 KV 的存储量和传输带宽开销。
- GQA(分组查询注意力):多个注意力头分组共享 Key(K)和 Value(V),是 MHA 与 MQA 之间的平衡方案,兼顾表达能力与效率。
MQA(多查询注意力)和 GQA(分组查询注意力)通过优化 KV 的共享方式,减少了计算量和内存占用,从而能提升长上下文推理时的吞吐量(处理数据的速度)和显存使用效率。
- Transformer 中 KV Cache 的存储计算
- 在 Transformer 的注意力机制中,KV Cache 用于存储之前计算过的 Key(K)和 Value(V)
- KV Cache 的存储量需要考虑批量大小(B)、注意力头数(H)、每头维度(D_h)、上下文长度(L),并且要保存 K 和 V 两份数据,使用fb16(2B/elem)单个浮点数占2个字节:
- 单位转换
- 计算数值:
更多推荐


其中

















所有评论(0)