从"序列处理"到"大模型":Transformer 的演化与内核
引言:我们面对的最基本问题
在自然语言处理里,最基本的数据形式是 序列(Sequence)——即一串有先后顺序的符号。例如"我爱中国"是一个序列,"Hello world"也是一个序列。
模型处理序列时,需要完成两种性质不同的任务:
- 理解:捕捉序列中任意两个位置之间的关联。例如"小明...他"相隔很远,但指向同一个人。
- 生成:根据已知前缀,推算下一个最可能出现的符号。
在 Transformer 出现之前,主流方案是 RNN(循环神经网络)。它的处理方式是串行的:依次读入"我"、"爱"、"中国"。这导致两个根本性缺陷:
- 无法并行:每个时间步必须等前一个词计算完毕才能进行,训练效率极低。
- 长程遗忘:序列长度增加时(如 1000 个 token),开头的"小明"到末尾的"他",信息衰减严重,难以捕捉远距离依赖。
Transformer 要解决的核心矛盾是:如何在抛弃串行顺序的前提下,既能捕捉序列中所有位置之间的关联,又能高效地生成下一个词。
第一部分:核心解法 —— 让所有词"面对面"交流
1.1 核心直觉
最直接的思路是:让序列中的每一个词,在处理时都能直接访问序列中的所有其他词,并根据相关性分配不同的关注程度。
例如在"我爱中国"中处理"爱"时,模型需要能同时参考"我"和"中国",并让"我"获得比"中国"更高的关注度。
这一机制称为 注意力(Attention)。
1.2 具体如何计算:QKV 的角色划分
为了让"相关性"变得可计算,需要将词与词之间的关系转化为数学上的点积(相似度)。Transformer 为每个词设定了三个角色:
-
Query(查询,Q):当前词的"探测向量",用于衡量它与序列中其他位置的匹配程度。例如,"爱"的 Q 与"我"的 K 匹配度高于与"中国"的 K 匹配度,反映了两者之间更紧密的语法关系。
-
Key(键,K):每个词的"标签向量",用于被其他词的 Q 所匹配。不同词的 K 从不同侧面描述了自身角色(如"我"倾向于标记为主语信息,"中国"倾向于标记为宾语信息)。
-
Value(值,V):每个词的实际语义内容。当某个词对当前词的匹配度较高时,该词的 V 会在后续的加权求和中占据更大比重。
计算过程分为三步:
-
计算匹配度:当前词的 Q 与序列中所有词的 K 做点积,得到一组原始分数。分数越高,表示两个位置之间的关联越强。
-
缩放与归一化:将分数除以
√d_k(d_k 为每个注意力头的维度),使梯度在训练时保持稳定;然后送入 Softmax,转为总和为 1 的权重分布。这个 Softmax 权重就是注意力分布。 -
加权提取:用上述权重对序列中所有词的 V 做加权求和,得到当前词融合了上下文信息的新表示。
这就是 自注意力(Self-Attention)——之所以称"自",是因为 Q、K、V 全部来源于同一份输入数据。
关于 √d_k 缩放的作用:如果不做缩放,当 d_k 较大时,点积结果的方差随之增大,Softmax 的梯度会进入极小值区域(梯度消失),影响训练稳定性。除以 √d_k 将方差拉回到约 1,是确保深层网络稳定训练的关键细节。
1.3 为什么要"多头"
如果只做一组 QKV 计算,模型只能捕获一种"关系模式"。但语言中的关系是多维的:涉及语法结构(主谓宾)、语义相似(近义词)、指代关系(共指消解)等。
为了捕获多维关系,Transformer 并行运行多组独立的 QKV 计算,每组称为一个 注意力头(Head)。每个头关注不同的关系侧面,最终将所有头的输出拼接到一起,经过一个线性投影后得到更丰富的表示。
思维演练:以"我爱中国"为例——
- 头 1 可能捕获了"我"和"爱"之间的主谓关系
- 头 2 可能捕获了"爱"和"中国"之间的动宾关系
- 头 3 可能捕获了"我"和"中国"之间的所属或修饰关系
多头机制保证了模型理解的丰富性,使模型能同时从多个维度观察序列。
现代模型的演进:GQA(分组查询注意力):原始 Transformer 使用多头注意力(MHA),每个头有独立的 Q/K/V,计算量随头数线性增长。后续提出的 MQA(多查询注意力)让所有头共享 K/V,大幅降低推理时的 KV Cache 大小,但可能影响质量。目前主流方案是 GQA(Grouped Query Attention,如 LLaMA 2/3、GPT-4),它将头分为若干组,组内共享 K/V,在推理效率与模型质量之间取得了良好平衡。
到此,信息交换的核心机制已经建立。但仅有自注意力还不够——它在工程上存在若干问题,需要逐一解决才能堆叠为深层网络。
第二部分:工程稳定化 —— 让这套机制能"堆得很深"
2.1 问题一:模型无法区分顺序
自注意力并行计算,使得"我打你"和"你打我"在模型看来相同——因为它只计算词与词之间的相关性,不编码位置信息。
解决方案:位置编码(Positional Encoding)
在将词转为向量(Embedding)之后,叠加代表位置信息的向量,使每个词的向量既携带语义,又携带位置。
位置编码的演进:原始 Transformer 使用固定频率的正弦/余弦函数生成位置编码,优点是能将任意位置编码为连续向量。现代大语言模型(如 LLaMA、Qwen、GPT 系列)普遍采用 RoPE(旋转位置编码,Rotary Position Embedding),它不是简单地将位置向量"加到"词向量上,而是通过旋转变换直接修改 Q 和 K 的向量方向,使注意力天然包含相对位置信息。RoPE 的优势在于良好的外推能力——模型能在推理时处理比训练时更长的序列。
2.2 问题二:层数过深导致信息衰减
堆叠 12 层甚至更多网络层时,输入"中国"的信息经过层层变换,到最后一层可能已经大量丢失。
解决方案:残差连接(Residual Connection)
操作非常简单:将每个子层的输入直接加到该子层的输出上。
子层输出 = 子层功能(输入) + 输入
这为数据开辟了一条"直达通道"——无论后续变换多复杂,原始语义始终可以无损地传递到上层。在反向传播时,梯度也可以直接流回浅层,缓解梯度消失。
2.3 问题三:数值分布不稳定,导致训练梯度异常
多层网络叠加后,各层输出的数值范围可能急剧膨胀或衰减,导致梯度爆炸或消失,参数无法有效更新。
解决方案:层归一化(Layer Normalization)
在每个子层计算之后,将数据重新拉回标准分布(均值为 0,方差为 1),确保流入下一层的数据始终处在稳定的数值区间内。
注:归一化的位置有两种方案。原始 Transformer 采用 后归一化(Post-Norm)——残差连接之后再做归一化,缺点是训练初期梯度不稳定,需要 warm-up 阶段精细调节学习率。现代模型多采用 前归一化(Pre-Norm)——在子层计算之前先做归一化,残差连接之后不再归一化,训练更稳定,收敛更快。
2.4 问题四:自注意力是线性变换,表达能力有限
自注意力的本质是加权求和(线性变换)。如果模型只有自注意力,无论堆叠多少层,数学上仍等价于单层线性变换,无法拟合复杂的语言规律。
解决方案:前馈网络(FFN,Feed-Forward Network)
在每个自注意力子层之后,接一个独立的前馈网络:对每个位置分别做两步变换——先升维映射(通常是 4× 维度扩张),经非线性激活函数,再恢复原始维度。这一过程可以理解为对注意力聚合到的信息做"深度加工"和"抽象提炼"——注意力负责"收集信息",FFN 负责"思考信息"。
激活函数的演进:原始 Transformer 使用 ReLU。GPT-2 引入 GELU(高斯误差线性单元),训练收敛更平滑。当前主流大模型(如 LLaMA、PaLM、Gemini)普遍采用 SwiGLU——一种带门控机制的激活函数,在同等参数量下效果优于 GELU,虽略增参数量(FFN 从两层变为三层,因为门控引入了一个额外的线性变换),但收益显著,几乎是现代 LLM 的事实标准。
第三部分:宏观组装 —— 两种经典架构
有了上述所有稳定的组件(自注意力、位置编码、残差连接、层归一化、FFN),下一步是如何将它们组合为完整的网络架构。
经典 Transformer 全貌(原文架构图)
下面的流程图展示了 "Attention Is All You Need" 论文中提出的完整 Transformer 架构,包含编码器(上半部分)和解码器(下半部分)两大部分:
flowchart TB
Input["输入序列(如 我爱中国)"]
--> Embed1["Input Embedding + Positional Encoding"]
--> SA1["Multi-Head Self-Attention"]
--> AN1["Add & Layer Norm"]
--> FFN1["Feed-Forward Network"]
--> AN2["Add & Layer Norm"]
AN2 -.->|"编码器×N
输出 K/V 矩阵"| CA
Output["输出序列(如 I love China)"]
--> Embed2["Output Embedding + Positional Encoding"]
--> MSA["Masked Multi-Head Self-Attention
(因果掩码遮住未来位置)"]
--> AN3["Add & Layer Norm"]
--> CA["Cross-Attention
Q 来自解码器 · K/V 来自编码器"]
--> AN4["Add & Layer Norm"]
--> FFN2["Feed-Forward Network"]
--> AN5["Add & Layer Norm"]
AN5 --> Linear["Linear Layer(映射到词表维度)"]
--> Softmax["Softmax(转为概率分布)"]
--> Out["输出概率最高的词"]
3.1 经典架构(翻译任务):编码器 + 解码器
做中译英时,输入(中文)和输出(英文)是两种不同的语言,需要两套独立的处理单元。下面分别拆解每一部分。
编码器(Encoder)的内部构成与数据流
编码器的任务是将输入序列(如"我爱中国")逐层编码为一个丰富的语义表示矩阵。
编码器单层(共 N 层)的内部构成:
| 层序 | 组件 | 作用 |
|---|---|---|
| 第 0 层(输入层) | Input Embedding + Positional Encoding | 将 token 转为向量,叠加位置信息 |
| 第 1 步 | Multi-Head Self-Attention | 每个词与所有词交互,捕获上下文依赖 |
| 第 2 步 | Add & Layer Norm(残差 + 归一化) | 将注意力输出与原始输入相加后归一化 |
| 第 3 步 | Feed-Forward Network | 对每个位置独立做非线性映射 |
| 第 4 步 | Add & Layer Norm(残差 + 归一化) | 将 FFN 输出与 FFN 输入相加后归一化 |
逐层数据流(以"我爱中国"为例,d_model = 512):
-
Input Embedding:每个 token(我、爱、中国)被映射为一个 512 维的稠密向量。输入形状:
(3, 512)。 -
Positional Encoding:生成一个同样为
(3, 512)的位置向量,与词向量逐元素相加,得到携带位置信息的向量。 -
Multi-Head Self-Attention:将输入分别通过三个线性投影生成 Q、K、V(形状均为
(3, 512)),拆分为 8 个头(每个头维度 64),每个头独立计算注意力,输出拼接后通过线性投影恢复(3, 512)。这一步让"爱"获得了"我"(主语)和"中国"(宾语)的上下文信息。 -
Add & Layer Norm:将 Self-Attention 的输出与原始输入相加(残差连接),然后做 Layer Normalization。输出形状不变,仍为
(3, 512)。 -
FFN:对每个位置独立操作。先线性升维到
(3, 2048)(通常 4×d_model),经过 ReLU 激活,再线性降维回(3, 512)。 -
Add & Layer Norm:FFN 输出与 FFN 输入相加后归一化。
注意:上述第 1-6 步构成编码器的一层。在原始 Transformer 中,这一层重复堆叠 6 次(N=6),后一层的输入是前一层的输出。在现代大模型中(如 BERT),这一数字可达 12 层(base)或 24 层(large),甚至上百层。
编码器的最终输出:最后一层编码器输出的形状为 (序列长度, d_model),即 (3, 512)。这份矩阵蕴含了整句"我爱中国"的完整上下文语义。它将被传递给解码器,作为 Key 矩阵和 Value 矩阵——编码器不输出 Query,因为 Query 由解码器自己生成。
解码器(Decoder)的内部构成与数据流
解码器的任务是逐词生成目标序列(如" I love China")。与编码器相比,解码器多了两个关键机制:因果掩码(Causal Mask) 和 交叉注意力(Cross-Attention)。
解码器单层(共 N 层)的内部构成:
| 层序 | 组件 | 作用 |
|---|---|---|
| 第 0 层(输入层) | Output Embedding + Positional Encoding | 将已生成的 target token 转为向量 |
| 第 1 步 | Masked Multi-Head Self-Attention | 自注意力 + 因果掩码(只看已生成的词) |
| 第 2 步 | Add & Layer Norm | 残差 + 归一化 |
| 第 3 步 | Cross-Attention | 解码器查编码器:用自身 Q 去匹配编码器的 K/V |
| 第 4 步 | Add & Layer Norm | 残差 + 归一化 |
| 第 5 步 | Feed-Forward Network | 非线性变换 |
| 第 6 步 | Add & Layer Norm | 残差 + 归一化 |
逐层数据流(训练阶段,目标序列为 "I love China",已右移一位添加 <bos> 标记):
-
Output Embedding + Positional Encoding:将
<bos>、I、love 分别映射为(3, 512)的向量,叠加位置编码。 -
Masked Multi-Head Self-Attention:计算自注意力,但在 Softmax 之前,将每个位置右侧的未来位置置为
-inf(因果掩码)。例如,预测"love"时,"love"位置的注意力只能看到<bos>和 I,不能看到"China"。这是为了确保模型在训练时不会"作弊"偷看答案。 -
掩码的数学操作:对注意力分数矩阵
(3, 3),上三角部分填入-inf,使得 Softmax 后这些位置的权重为 0。 -
Add & Layer Norm:残差加归一化。
-
Cross-Attention(交叉注意力):这是连接编码器和解码器的关键桥梁。
- Q:来自解码器上一层的输出(解码器自身的语义)
- K 和 V:来自编码器最后一层的输出(输入序列的语义表示)
- 运算:解码器每个位置的 Q 与编码器所有位置的 K 做点积,Softmax 得到权重,加权提取编码器的 V。
- 效果:生成"love"时,解码器的 Q 会在编码器输出的"我 爱 中国"中搜索,发现"爱"的 Key 匹配度最高,因此从"爱"的 Value 中提取语义信息。
-
与 Self-Attention 的区别:Self-Attention 的 Q/K/V 都来自同一来源;Cross-Attention 的 Q 来自解码器,K/V 来自编码器。
-
Add & Layer Norm:残差加归一化。
-
FFN:与编码器相同,对每个位置独立做非线性映射。
-
Add & Layer Norm:残差加归一化。
解码器同样堆叠 N=6 层。最后一层的输出形状为 (目标序列长度, d_model),后续通过 Linear + Softmax 映射为每个位置下一个词的概率分布。
一张图看懂训练时的整体数据流
sequenceDiagram
participant Src as 输入序列
participant Enc as 编码器×N
participant Cross as 交叉注意力
participant Dec as 解码器×N
participant Out as 输出层
Note over Src,Out: 训练阶段完整数据流
Src->>Enc: "我爱中国" → Embedding + Positional Encoding
Enc->>Enc: Self-Attention(词间交互)
Enc->>Enc: Add & Norm + FFN + Add & Norm
Enc->>Enc: 重复堆叠 N 层
Enc->>Cross: 输出语义矩阵 → K, V
Note over Dec: 目标序列 " I love China"
Dec->>Dec: Embedding + Positional Encoding
Dec->>Dec: Masked Self-Attention(因果掩码)
Dec->>Cross: 输出 → Q
Cross->>Cross: Q × K(来自编码器)
Cross-->>Dec: 返回加权后的 V(来自编码器)
Dec->>Dec: Add & Norm + FFN + Add & Norm
Dec->>Dec: 重复堆叠 N 层
Dec->>Out: Linear → Softmax → 预测下一个词
3.2 现代架构(大模型,如 GPT):仅解码器(Decoder-Only)
在翻译任务中,输入和输出分属不同语言。但现代大语言模型处理的是同一语言的任务(如中文问答、代码生成),由此引出一个关键转变:
编码器不再是必需的。 因为输入(用户提问)和输出(模型回答)共享同一语义空间。仅用解码器即可完成所有工作:将包括提问和回答在内的全部文字拼成一个长序列,模型只做一件事——从左到右地"续写"。
仅解码器架构的内部构成
与标准解码器的区别在于:去掉了 Cross-Attention 层(因为没有编码器提供 K/V),只保留 Masked Self-Attention + FFN。
输入序列 → Embedding + Positional Encoding
→ Masked Multi-Head Self-Attention → Add & Norm
→ Feed-Forward Network → Add & Norm
→ 重复 N 层
→ Linear → Softmax → 输出概率分布
这就是 GPT 系列模型的基本结构。 每一层只有两个子层(自注意力 + FFN),比 Encoder-Decoder 更简洁。
训练数据构造详解
这是理解 GPT 类模型最关键的部分。以问答对"你好吗?我很好。"为例:
步骤 1:拼接为完整序列
将提示词和答案拼接成一个序列:
[CLS] 你好吗?[SEP] 我很好。[EOS]
(实际实现中可能没有 [CLS]/[SEP] 这类特殊标记,仅使用 <|endoftext|> 或类似分隔符,但原理相同。)
步骤 2:输入解码器
flowchart TB
subgraph 输入序列["完整输入序列"]
direction TB
T1["你"] --> T2["好"] --> T3["吗"] --> T4["?"] --> T5["我"] --> T6["很"] --> T7["好"] --> T8["。"]
end
T8 --> MASK["因果掩码(每个位置只看左侧)"]
MASK --> SA["Masked Self-Attention"]
SA --> FFN["FFN"]
FFN --> PRED["Linear + Softmax"]
步骤 3:滑动窗口生成多组训练样本
利用因果掩码的并行特性,模型在单次前向传播中同时学习多组"前缀→下一个词"的映射:
| 输入(已看到的内容) | 预测目标(下一个词) | 是否计算 Loss |
|---|---|---|
| 你 | 好 | ❌(提示词部分) |
| 你好 | 吗 | ❌ |
| 你好吗 | ? | ❌ |
| 你好吗? | 我 | ✅(答案部分) |
| 你好吗?我 | 很 | ✅ |
| 你好吗?我很 | 好 | ✅ |
| 你好吗?我很好 | 。 | ✅ |
关键直觉:一次前向传播、一个序列,同时产生了 7 个训练任务。模型既学到了"你好吗?→我很好"的问答知识,又学到了"你→好"这样的子词搭配。这正是 GPT 类模型训练效率高的原因——无需为每个预测单独构造一个样本。
步骤 4:Loss 遮盖
在反向传播时,计算 Loss 的位置被遮盖——只有答案部分的误差参与梯度计算。提示词部分虽然参与了前向传播(为后续词提供上下文),但不产生学习信号。
具体实现:构造一个 Loss Mask,序列 [0, 0, 0, 0, 1, 1, 1, 1],在计算交叉熵损失时,对应位置乘以 0 或 1。
推理时逐词生成的完整流程
用户输入"你好吗?"后,模型将其作为前缀,反复执行以下循环:
flowchart TB
START["用户输入:'你好吗?'"] --> EMB["词嵌入 + 位置编码
得到 (4, d_model) 的向量"]
EMB --> FORWARD["解码器前向传播
利用 KV Cache
(缓存已算过的 K、V 矩阵)"]
FORWARD --> LAST["取最后一个位置的输出向量"]
LAST --> LINEAR["Linear 层:映射到词表维度
如 (vocab_size=50000)"]
LINEAR --> SOFT["Softmax:转为概率分布"]
SOFT --> SAMPLE["选词策略
(Top-k / Top-p / Temperature)"]
SAMPLE --> APPEND["将选中的词追加到序列末尾"]
APPEND --> CHECK{"遇到 <eos>?
或达到最大长度?"}
CHECK -- 否 --> FORWARD
CHECK -- 是 --> DONE["输出完整序列"]
各步骤详细说明:
-
词嵌入 + 位置编码:将输入 token 映射为向量,叠加位置信息。输出形状
(输入长度, d_model)。 -
解码器前向传播:逐层经过 Masked Self-Attention → Add & Norm → FFN → Add & Norm,共 N 层。
-
取最后一个位置:因为我们需要预测的是"下一个词",只有最后一个位置代表的"当前已看到的所有内容"才是完整的上下文。
-
Linear 层:将
d_model维向量映射到vocab_size维,每个维度对应该词的原始得分(Logits)。 -
Softmax 转为概率:所有候选词的概率和为 1。
-
选词策略(见第四部分详述)。
-
追加到序列末尾:新词成为序列的一部分,下一次循环时序列长度增加 1。
KV Cache:让生成变快的关键优化
问题:上述第 2 步中,如果不做任何优化,每生成一个 token 都需要重新计算整个序列的注意力,计算量随序列长度平方增长——生成长度为 100 的序列,总计算量是 O(100³)。
观察:在逐 token 生成时,已生成位置的 Q、K、V 其实没有变化——因为模型参数固定,输入固定的 token 经过固定网络层,输出当然固定。
解决方案——KV Cache:
| 步骤 | 首次生成(前缀长度为 L) | 后续生成(每步) |
|---|---|---|
| 计算 | 计算全部 L 个位置的 Q/K/V | 只计算新 token 的 K 和 V |
| 缓存 | 将计算出的 K、V 矩阵存入缓存 | 将新的 K/V 追加到缓存末尾 |
| 注意力 | 使用缓存的全部 K、V 做注意力 | 使用全部缓存的 K、V + 仅新 token 的 Q |
效果:
- 每步的计算量从 O(L²) 降到 O(L)(L 为当前序列长度)
- 生成 n 个 token 的总计算量从 O(n³) 降到 O(n²)(严格来说是 O(∑L) 逐 token)
- 本文上方的流程图标注了"利用 KV Cache",正是指这一步
注意:KV Cache 以显存换速度。当序列很长时(如 32K token),K/V 矩阵会占用大量显存(约 2 × n_layers × d_model × seq_len × precision)。这也是 GQA 优化的动机——通过减少 K/V 头数来降低 KV Cache 的显存占用。
第四部分:最后的映射 —— Linear 和 Softmax 在做什么
无论哪种架构,在解码器的最后一步,模型都需要将抽象向量(高维浮点数)转换为具体的单词。
-
Linear 层:将解码器最后一层的输出向量映射到词典大小(Vocabulary Size)的维度。假如词典包含 5 万个词,Linear 层就输出一个 5 万维的向量,每个维度对应一个词的原始得分(Logits)。注:Linear 层不只在输出层出现——它遍布模型各处:生成 Q/K/V 时、FFN 内部的两个线性变换中,都依赖 Linear 层完成维度映射。
-
Softmax:将 Linear 输出的原始得分归一化为概率分布,所有词的概率之和为 100%。
-
选词策略:从概率分布中选出输出词。不同的策略会带来不同的生成效果:
- 贪婪解码(Greedy Decoding):取概率最高的词。确定性最强,但可能陷入重复或平庸。
- Top-k 采样:从概率最高的 k 个词中重新归一化后采样(k 通常取 40-100),避免低概率的"烂词"被选中。
- Top-p(核采样):从累积概率超过阈值 p 的最小词集合中采样(p 通常取 0.9-0.95),候选词数量动态变化——分布尖锐时自动缩小候选范围,分布平坦时自动扩大。
- Temperature 缩放:将 Logits 除以温度参数 T 后再做 Softmax。T < 1 使分布更尖锐(确定性增强),T > 1 使分布更平滑(多样性增强)。T → 0 趋近于贪婪解码。
实践中通常组合使用:先 Top-k 过滤 → 再 Top-p 过滤 → Temperature 调整后采样。
- 训练时的损失函数:将 Softmax 输出的概率分布与真实的下一个词做比较,使用 交叉熵损失(Cross-Entropy Loss) 计算误差:
Loss = -∑ log(p(correct_word))
直觉上,模型为正确词分配的概率越高,Loss 越低。通过反向传播,这一误差信号逐层回传,更新所有参数(包括注意力权重、FFN 权重、词嵌入等)。
第五部分:完整的闭环流程图
训练阶段(仅解码器模型示例)
flowchart TB
A["原始文本:'你好吗?我很好。'"]
--> B["词嵌入 + 位置编码"]
--> C["因果掩码(遮住未来位置)"]
--> D["Masked Self-Attention + Add & Norm"]
--> E["FFN + Add & Norm"]
--> F["重复堆叠 N 层"]
--> G["Linear → Softmax"]
--> H["交叉熵 Loss(仅计算答案部分的误差)"]
--> I["反向传播(更新所有参数)"]
推理阶段
flowchart TB
J["用户输入:'你好吗?'"]
--> K["词嵌入 + 位置编码"]
--> L["解码器前向传播(利用 KV Cache)"]
--> M["Linear → Softmax"]
--> N["选词策略(Top-k / Top-p / Temperature)"]
--> O["拼入序列末尾"]
--> P{"遇到结束标记
或达到最大长度?"}
P -- 否 --> L
P -- 是 --> Q["输出完整序列"]
附录:关键组件速查表
| 组件 | 解决的问题 | 工作原理 | 现代演进 |
|---|---|---|---|
| 自注意力 | 捕获序列中任意位置的关联 | Q 与各位置 K 做点积 → Softmax 加权 → 聚合 V | MHA → GQA / MQA |
| 交叉注意力 | 解码器从编码器提取信息 | 解码器 Q × 编码器 K/V | 仅 Encoder-Decoder 架构使用 |
| 位置编码 | 为并行计算的序列注入顺序信息 | 将位置向量叠加到词向量上 | 固定编码 → RoPE |
| 残差连接 | 深层网络中信息衰减 | 子层输出 = 子层(输入) + 输入 | 后归一化 → 前归一化 |
| 层归一化 | 数值分布不稳定 | 将每层输出拉回标准正态分布 | Post-Norm → Pre-Norm |
| FFN | 为线性注意力引入非线性表达能力 | Linear → 激活 → Linear | ReLU → GELU → SwiGLU |
| KV Cache | 自回归生成中的重复计算 | 缓存已算过的 K/V,只计算新 token | 推理阶段必备优化 |
| 因果掩码 | 训练时防止偷看未来词 | 将未来位置的注意力分数设为 -inf | 所有自回归模型必备 |
学习记录
本文内容整理自原始问答:https://chat.deepseek.com/share/q5540zsf4tn6xkvj89
参考链接 Transformer模型详解(图解最完整版) - 初识CV的文章 - 知乎
https://zhuanlan.zhihu.com/p/338817680
还没有评论,来第一个吧