训练过程:整体流程
🟠 teacher forcing 并行预测 · 有梯度 · 更新权重
🎯 架构功能讲解
训练 = 一次前向 + 损失计算 + 反向传播:
① Encoder 读源句「我爱水课」→ 源记忆;② Decoder 一次性读完整目标句 [I,love,easy,courses](teacher forcing);③ 输出层并行算 4 个位置的概率;④ 交叉熵损失衡量「预测 vs 真实」;⑤ 反向传播更新所有权重。
训练的关键:用真实目标词做输入(不依赖模型自己的预测),4 个位置可 GPU 并行。
训练数据流(一次前向)
源句「我爱水课」[0,1,2,3]Encoder 输入
↓ Self-Attn×2层
源记忆 ENC_OUT (4×4)K/V 之源
↓ K/V
目标句 [I,love,easy,courses] [4,5,6,7]Decoder 输入(完整整句)
↓ MaskedSelfAttn → CrossAttn → FFN ×2层
Decoder 输出 (4×4)4 位置并行
↓ Linear + Softmax
4×8 概率矩阵每个位置预测下一个词
↓ 交叉熵损失 + 反向传播
更新全部权重 ← 学习的本质loss 最小化
💡 训练 vs 推理第一印象:训练一次并行算 4 个位置;推理要跑 3 次 Decoder。训练有梯度,推理没有。
训练 ① Tokenization:每个字一个 token
文字 → 数字 ID
🎯 架构功能讲解
训练的第一步和推理完全相同:把文字映射成整数 ID。
源「我爱水课」→ [0,1,2,3](每字一个 token);目标「I love easy courses」→ [4,5,6,7](每词一个 token)。
训练与推理在此阶段没有任何区别。
| ID | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 词 | 我 | 爱 | 水 | 课 | I | love | easy | courses |
源序列[0,1,2,3] 我爱水课
∥
目标序列(训练给整句)[4,5,6,7] I love easy courses
💡 与推理的差异从这里开始:训练时目标序列一次性给全 4 个;推理时只给已生成的。
训练 ② Embedding:查表得到向量
ID → 4 维连续向量(E 是参数,训练时更新)
🎯 架构功能讲解
嵌入矩阵 E 是可训练参数:训练时梯度会更新它,让语义相近的词向量靠近。
查表 = 取 E 第 i 行。源序列取 E[0..3],目标序列取 E[4..7]。
训练与推理共用同一份 E(推理时冻结)。
d0
d1
d2
d3
我(0)
0.5
-0.3
0.8
0.1
爱(1)
-0.2
0.6
-0.1
0.4
水(2)
0.3
0.2
0.5
-0.4
课(3)
-0.6
0.1
0.3
0.7
I(4)
0.4
0.5
-0.2
0.3
love(5)
0.7
-0.1
0.6
-0.3
easy(6)
-0.5
0.4
0.2
0.6
courses(7)
0.1
-0.6
0.4
0.2
「我」= ID 0离散
➜ 取第 0 行 ➜
[0.5, -0.3, 0.8, 0.1]连续向量
💡 E 是参数:训练时反向传播会调整 E 的每一格——「我」的向量会和「I」的向量逐渐靠近(跨语言语义对齐)。
训练 ③ Positional Encoding:注入位置
sin/cos —— 自注意力没有顺序概念,必须显式告诉模型位置
🎯 架构功能讲解
自注意力对 token 顺序不敏感(打乱后 QK 点积不变)。必须注入位置信息才能区分「水课」和「课水」。
正弦/余弦编码是固定公式(非参数)——训练推理完全相同。X_in = E + PE 逐元素相加。
PE(pos, 2i) = sin(pos / 10000^(2i/d)) · PE(pos, 2i+1) = cos(pos / 10000^(2i/d))
d0 sin
d1 cos
d2 sin
d3 cos
pos0
0
1
0
1
pos1
0.8415
0.5403
0.0100
1.0000
pos2
0.9093
-0.4161
0.0200
0.9998
pos3
0.1411
-0.9900
0.0300
0.9996
Encoder X_in(源): 我=[0.5,0.7,0.8,1.1] 爱=[0.6415,1.1403,-0.09,1.4] 水=[1.2093,-0.2161,0.52,0.5998] 课=[-0.4589,-0.89,0.33,1.6996]
Decoder X_in(目标): I=[0.4,1.5,-0.2,1.3] love=[1.5415,0.4403,0.61,0.7] easy=[0.4093,-0.0161,0.22,1.5998] courses=[0.2411,-1.59,0.43,1.1996]
💡 固定 vs 可学:PE 是固定的(不是参数),Embedding E 是可学的(是参数)——这是两者的区别。
训练 ④ Self-Attention:Q/K/V 投影
每个 token 生成 Q、K、V —— 为「谁关注谁」做准备(Encoder L1)
🎯 架构功能讲解
自注意力核心:每个 token 用投影矩阵生成三个角色
Q:「我在找什么?」 K:「我是什么?」 V:「我携带什么?」
多头 h=2:两个视角,每头 dk=2。投影矩阵 W 是可训练参数。
训练与推理共用同一套计算(Encoder 完全相同)。
Q = X·WQᵀ K = X·WKᵀ V = X·WVᵀ
「我」Head1: Q=[1.10,-0.79](=0.5×(-0.3)+0.7×0.9+0.8×0.5+1.1×0.2 等)
Q1(我/爱/水/课)
1.10,-0.79
1.0688,-0.1863
-0.1774,-0.7433
-0.1584,1.8369
K1
0.57,-1.21
1.9344,-1.0211
0.1752,0.3043
0.7518,-1.0049
V1
-0.72,-1.04
-0.8076,-1.0539
-0.7756,0.0052
-0.5293,-0.1106
💡 类比:Q=问题(我想找谁),K=名片(我是谁),V=内容(我能提供什么)。先匹配名片,再加权内容。
训练 ⑤ Attention Score + Softmax 热力图
Q·KT/√dk → softmax → 注意力权重(Encoder 无掩码)
🎯 架构功能讲解
分数 = Qi·Kj(关注强度),÷√2 稳定数值,softmax 归一化为概率。
Encoder 自注意力无掩码——每个源词看到全句(理解源句的前提)。
热力图:「我」52.6% 看「爱」(主语→动词依赖);「课」68.9% 看「水」(「水课」强绑定)。
Q\K
0.202我
0.526爱
0.064水
0.208课
爱
0.183我
0.501爱
0.111水
0.205课
水
0.321我
0.245爱
0.152水
0.282课
课
0.092我
0.101爱
0.689水
0.118课
🔍 读图:每行和=1。Encoder 每个源词都能看到全部 4 个源词(无掩码)——这是与 Decoder 的关键区别。
训练 ⑥ 注意力输出 → 残差 → LN → FFN
A·V 混合信息 → Add&Norm → Feed-Forward(Encoder L1)
🎯 架构功能讲解
注意力输出 = 用权重 A 对全句 V 加权混合(上下文感知)。双头拼接 ×WO 融合。
Add 残差:原始输入加回,梯度抄近道,深层不退化。
Norm:每行标准化,稳定分布。
FFN:注意力搬信息,FFN 加工——升维 8、ReLU、降回 4。
O_我[0] = 0.2023×(-0.72)+0.5261×(-0.8076)+0.0639×(-0.7756)+0.2078×(-0.5293) = -0.7300
残差 X1 我: [0.5,0.7,0.8,1.1]+[0.4129,-1.4539,0.9665,0.7456] = [0.9129,-0.7539,1.7665,1.8456]
LayerNorm 我: μ=0.9428,σ²=1.0933 → [-0.0286,-1.6227,0.7878,0.8634]
FFN 我: 4→8[-0.1842,...,0.2173]→ReLU→8→4[-0.0699,-0.8135,-0.3056,-0.3782]
Encoder L1 输出 我: [0.2437,-1.6980,0.7259,0.7284]
X_in原始
+
AttnOut注意力
=
残差Add
→
LNNorm
→
FFN 4→8→4ReLU
→
L1 输出再残差+LN
训练 ⑦ Encoder L2 → 源记忆
第二层更全局 · 最终输出 = Cross-Attn 的 K/V 之源
🎯 架构功能讲解
Encoder 堆 2 层:L1 抓局部依赖(我→爱 0.53),L2 学全局语义(分布更均匀)。
最终输出 = 源句记忆 ENC_OUT:4 个向量每个含全句信息。
这个矩阵即将成为 Decoder 交叉注意力的 K/V——训练推理都一样,Encoder 只跑一次。
d0
d1
d2
d3
我
1.2296
-1.5587
0.1177
0.2114
爱
1.3092
-1.3839
-0.3915
0.4663
水
1.1040
-1.6261
0.2814
0.2406
课
1.2974
-1.4723
-0.1710
0.3460
🔑 源记忆 ENC_OUT:Decoder 交叉注意力反复查阅的 K/V 就是它。
训练 ⑧ 掩码:不许偷看未来
Decoder 自注意力专属 · 上三角 = -∞
🎯 架构功能讲解
生成是自回归的:写第 3 个词时绝不能看到第 4 个,否则训练时「抄答案」。
score 上三角加 -1e9(≈-∞),softmax 后权重归零。第 i 个 token 只能看 0..i。
掩码只用于 Decoder 自注意力;Cross-Attn 永不掩码。
I✓
✗
✗
✗
I✓
love✓
✗
✗
I✓
love✓
easy✓
✗
I✓
love✓
easy✓
courses✓
score_masked = score + M,M[i][j] = -1e9 (j>i) 或 0 (j≤i)
例(Head1 第 2 行 love):[1.1229, 1.5218, -1e9, -1e9] → softmax = [0.4016, 0.5984, 0, 0]
训练 ⑨ Decoder L1:掩码自注意力
整句输入 · 4 位置并行 · 学到目标语言内部结构
🎯 架构功能讲解
训练:Decoder 输入 = 完整目标句 [I,love,easy,courses]。
掩码自注意力学目标语言内部语法(I 后跟 love 的可能性)。
4 个位置一次并行算出(可 GPU 并行)——训练比推理快的原因。
📊 掩码生效:行 0(I)=[1,0,0,0] 只看自己;行 1(love)=[0.40,0.60,0,0] 只看 I+love;行 3(courses)无限制。每行和恒为 1。
Decoder L1 输出 DLN1b(4 行并行算出):
I: [0.2064,1.406,-1.3896,-0.2228] love: [0.3748,1.4684,-0.9695,-0.8737]
easy: [0.7886,0.8387,-1.6354,0.0081] courses: [1.2072,-1.3379,-0.5445,0.6752]
训练 ⑩ ⭐ Cross-Attention:翻译的桥梁
Q 来自 Decoder,K/V 来自 Encoder —— 词对齐
🎯 架构功能讲解
训练的灵魂:Q = Decoder 表示,K = V = Encoder 输出。
Decoder 用 Q 匹配源句所有 K,softmax 得「该参考源句哪些词」,对源句 V 加权求和。
⚠ 无掩码——每个目标词可自由看全部源词。
训练后生成「I」时权重集中到「我」=翻译对齐。
Q = Decoder LN[-0.33,-0.34]
×
K = Encoder 输出4×2
→ score
softmax 权重对源 4 词
×
V = Encoder 输出4×2
=
输出2维
score[I→我] = (-0.3327×0.8115 + (-0.3446)×0.8874)/√2 = -0.4072
softmax([-0.4072,-0.3399,-0.4126,-0.3744]) = [0.244, 0.261, 0.243, 0.252]
输出 = 0.244×V_我+0.261×V_爱+0.243×V_水+0.252×V_课 = [-1.8787, 1.3491]
Q\K
我0.24
爱0.26
水0.24
课0.25
love
我0.26
爱0.25
水0.24
课0.25
🔑 训练时 4 个 Q 并行对全部源词:训练后权重锐化为 I↔我、love↔爱 的对角对齐。
训练 ⑪ 输出层 + 交叉熵损失
4 位置 × 8 词概率 → 损失 → 反向传播
🎯 架构功能讲解
训练:Decoder 输出经 Linear(4→8)→ Softmax → 4×8 概率矩阵。
与真实目标比较,交叉熵损失 -ln P(目标词)。
损失反向传播更新所有权重 = 学习。
推理这里是 1×8、argmax、无梯度。
位置 0(应预测 I)的概率分布
| 位置 | 目标 | 预测(argmax) | p(目标) | 损失 -ln p |
| 0 | I | courses (0.284) | 0.239 | 1.43 |
| 1 | love | I (0.302) | 0.032 | 3.44 |
| 2 | easy | 水 (0.385) | 0.096 | 2.34 |
| 3 | courses | courses (0.563) ✅ | 0.563 | 0.57 |
🔁 训练循环:损失 → 反向传播 → 更新权重 → 下一轮。位置 3 已猜对(0.563);位置 1 损失最大(3.44)= 最需学习。这是训练与推理最本质的区别:训练有这一步,推理没有。
训练过程(静态全文)
📖 全部编号步骤 · 每个数字可手算复现
📌训练关键数字总表(可复现)
| 步骤 | 关键结果 |
|---|
| 嵌入+位置 | 我=[0.5,0.7,0.8,1.1] 爱=[0.6415,1.1403,-0.09,1.4] 水=[1.2093,-0.2161,0.52,0.5998] 课=[-0.4589,-0.89,0.33,1.6996] |
| Encoder L1 Q/K/V | Q1=[1.10,-0.79][1.0688,-0.1863][-0.1774,-0.7433][-0.1584,1.8369] |
| 注意力分数 | 我→爱 score=2.0750(最高),softmax A=0.526 |
| Encoder 输出 | 我=[1.2296,-1.5587,0.1177,0.2114] 爱=[1.3092,-1.3839,-0.3915,0.4663] |
| 掩码 softmax | love 行=[0.4016,0.5984,0,0](只能看 I+love) |
| Cross-Attn | I→源 softmax=[0.244,0.261,0.243,0.252] 输出=[-1.8787,1.3491] |
| 输出概率 | 位置0: I=0.239 位置1: love=0.032 位置2: easy=0.096 位置3: courses=0.563 |
| 损失 | 1.43 / 3.44 / 2.34 / 0.57 |
1训练总览
🎯 架构功能讲解
训练 = 一次前向 + 损失计算 + 反向传播:
① Encoder 读源句「我爱水课」→ 源记忆;② Decoder 一次性读完整目标句 [I,love,easy,courses](teacher forcing);③ 输出层并行算 4 个位置的概率;④ 交叉熵损失衡量「预测 vs 真实」;⑤ 反向传播更新所有权重。
训练的关键:用真实目标词做输入(不依赖模型自己的预测),4 个位置可 GPU 并行。
2① Tokenization
🎯 架构功能讲解
训练的第一步和推理完全相同:把文字映射成整数 ID。
源「我爱水课」→ [0,1,2,3](每字一个 token);目标「I love easy courses」→ [4,5,6,7](每词一个 token)。
训练与推理在此阶段没有任何区别。
3② Embedding
🎯 架构功能讲解
嵌入矩阵 E 是可训练参数:训练时梯度会更新它,让语义相近的词向量靠近。
查表 = 取 E 第 i 行。源序列取 E[0..3],目标序列取 E[4..7]。
训练与推理共用同一份 E(推理时冻结)。
4③ 位置编码
🎯 架构功能讲解
自注意力对 token 顺序不敏感(打乱后 QK 点积不变)。必须注入位置信息才能区分「水课」和「课水」。
正弦/余弦编码是固定公式(非参数)——训练推理完全相同。X_in = E + PE 逐元素相加。
PE(pos, 2i) = sin(pos / 10000^(2i/d)) · PE(pos, 2i+1) = cos(pos / 10000^(2i/d))
5④ QKV 投影
🎯 架构功能讲解
自注意力核心:每个 token 用投影矩阵生成三个角色
Q:「我在找什么?」 K:「我是什么?」 V:「我携带什么?」
多头 h=2:两个视角,每头 dk=2。投影矩阵 W 是可训练参数。
训练与推理共用同一套计算(Encoder 完全相同)。
Q = X·WQᵀ K = X·WKᵀ V = X·WVᵀ
「我」Head1: Q=[1.10,-0.79](=0.5×(-0.3)+0.7×0.9+0.8×0.5+1.1×0.2 等)
6⑤ 注意力分数
🎯 架构功能讲解
分数 = Qi·Kj(关注强度),÷√2 稳定数值,softmax 归一化为概率。
Encoder 自注意力无掩码——每个源词看到全句(理解源句的前提)。
热力图:「我」52.6% 看「爱」(主语→动词依赖);「课」68.9% 看「水」(「水课」强绑定)。
7⑥ 输出+FFN
🎯 架构功能讲解
注意力输出 = 用权重 A 对全句 V 加权混合(上下文感知)。双头拼接 ×WO 融合。
Add 残差:原始输入加回,梯度抄近道,深层不退化。
Norm:每行标准化,稳定分布。
FFN:注意力搬信息,FFN 加工——升维 8、ReLU、降回 4。
8⑦ Encoder L2
🎯 架构功能讲解
Encoder 堆 2 层:L1 抓局部依赖(我→爱 0.53),L2 学全局语义(分布更均匀)。
最终输出 = 源句记忆 ENC_OUT:4 个向量每个含全句信息。
这个矩阵即将成为 Decoder 交叉注意力的 K/V——训练推理都一样,Encoder 只跑一次。
9⑧ 掩码
🎯 架构功能讲解
生成是自回归的:写第 3 个词时绝不能看到第 4 个,否则训练时「抄答案」。
score 上三角加 -1e9(≈-∞),softmax 后权重归零。第 i 个 token 只能看 0..i。
掩码只用于 Decoder 自注意力;Cross-Attn 永不掩码。
10⑨ Decoder L1
🎯 架构功能讲解
训练:Decoder 输入 = 完整目标句 [I,love,easy,courses]。
掩码自注意力学目标语言内部语法(I 后跟 love 的可能性)。
4 个位置一次并行算出(可 GPU 并行)——训练比推理快的原因。
11⑩ 交叉注意力
🎯 架构功能讲解
训练的灵魂:Q = Decoder 表示,K = V = Encoder 输出。
Decoder 用 Q 匹配源句所有 K,softmax 得「该参考源句哪些词」,对源句 V 加权求和。
⚠ 无掩码——每个目标词可自由看全部源词。
训练后生成「I」时权重集中到「我」=翻译对齐。
12⑪ 输出层+损失
🎯 架构功能讲解
训练:Decoder 输出经 Linear(4→8)→ Softmax → 4×8 概率矩阵。
与真实目标比较,交叉熵损失 -ln P(目标词)。
损失反向传播更新所有权重 = 学习。
推理这里是 1×8、argmax、无梯度。
推理过程:自回归循环
🌸 一次生成一个词 · 拼回输入继续 · 无梯度
🎯 架构功能讲解
推理与训练的关键区别:
① 输入:每步只有已生成词(无 teacher forcing,用自己的预测喂回)
② 输出:每次只取最后位置的 1×8 概率,argmax 选一个词
③ 掩码:每步 1×1 → 2×2 → 3×3 逐步扩大
④ 梯度:无反向传播,权重冻结
⑤ Encoder:只跑一次,K/V 全程复用(工程上可 KV cache)
自回归循环动画
Encoder 输出(只算一次)我爱水课 → ENC_OUT
↓ K/V 复用
步1: [I] → 预测 ? 选 1 个词
→ love
步2: [I,love] → 预测 ? 选 1 个词
→ easy
步3: [I,love,easy] → 预测 ? 选 1 个词
→ courses
I love easy courses ✅ 生成完成
💡 为什么推理慢?训练 4 位置一次并行;推理要跑 3 次 Decoder 前向(长度 1→2→3),每次只算最后一个位置。KV cache 复用已算的 K/V 可提速。
推理第 1 步:输入 [I] → 预测第 2 词
🌸 目标应为 love · 完整跑一遍 Decoder
🎯 架构功能讲解
输入只有 [I](1 个 token)。掩码自注意力在长度 1 时无实际遮蔽(只看自己);Cross-Attn 仍查阅完整源句。
完整跑 Decoder(L1 掩码自注意力 → L2 → Cross-Attn → FFN),取最后位置 1×8 logits。
输入 X_inf1 = [0.4, 1.5, -0.2, 1.3](I 的嵌入+位置,仅 1 行)
Logits = [0.0021, -0.7482, 1.5302, -0.9323, -0.3281, -1.687, -0.3194, 1.7682]
Softmax = [0.0717, 0.0338, 0.3304, 0.0282, 0.0515, 0.0132, 0.052, 0.4192]
argmax → 预测「courses」(p=0.4192);目标应为「love」(p=0.0132) ✗
📊 解读:随机权重下猜「courses」——训练后应猜「love」。预测被拼回输入,错误会连锁。
推理第 2 步:输入 [I, love] → 预测第 3 词
🌸 目标应为 easy(假设第 1 步选对)
🎯 架构功能讲解
输入 [I, love](2 个 token)。掩码此时生效:位置 1(love)只能看 I 和 love。
与训练的联系:这一步结果 = 训练时「love」位置的结果(前面输入相同)——这就是 teacher forcing 与自回归的等价性。
只取最后位置 logits 做 argmax。
[I]已生成
+
[love]第1步预测
→
Decoder 前向L1→L2→Cross→FFN
→
取最后位置 logits1×8
→
argmax → easy预测
💡 掩码尺寸在变:训练时 4×4 一次算全;推理这步是 2×2。结果数学上等价——推理正确时与训练对应位置一致。
推理第 3 步:输入 [I, love, easy] → 预测第 4 词
🌸 目标应为 courses —— 句子生成完毕
🎯 架构功能讲解
输入 [I, love, easy](3 个 token)。最后一步——预测「courses」后句子完整。
一旦某步预测错会连锁错(错误传播)——工程上用 beam search 缓解。
训练时位置 3 已猜对 courses (0.563);推理第 3 步应得到相同结果。
Encoder: 我爱水课 → ENC_OUT(只算一次)
↓ K/V 复用
步1: [I] → love(随机权重预测 courses,训练后收敛)
步2: [I,love] → easy
步3: [I,love,easy] → courses
↓
输出: I love easy courses ✅
🎯 翻译达成:Encoder 理解源句、掩码自注意力保证自回归、Cross-Attn 词对齐、输出层逐词出词。
推理过程(静态全文)
📖 全部编号步骤 · 每个数字可手算复现
📌推理关键数字总表(可复现)
| 步骤 | 关键结果 |
|---|
| Encoder | 源句编码一次:我=[1.2296,-1.5587,0.1177,0.2114] 爱=[1.3092,-1.3839,-0.3915,0.4663] 水=[1.1040,-1.6261,0.2814,0.2406] 课=[1.2974,-1.4723,-0.1710,0.3460] |
| 步1 输入[I] | Logits=[0.0021,-0.7482,1.5302,-0.9323,-0.3281,-1.687,-0.3194,1.7682] → 预测 courses(0.419) |
| 步2 输入[I,love] | 掩码 2×2:位置 love 只能看 I+love;输出与训练位置2相同 |
| 步3 输入[I,love,easy] | 掩码 3×3;训练时位置3 预测 courses(0.563) ✅ |
| 完整输出 | I love easy courses ✅ |
1推理总览
🎯 架构功能讲解
推理与训练的关键区别:
① 输入:每步只有已生成词(无 teacher forcing,用自己的预测喂回)
② 输出:每次只取最后位置的 1×8 概率,argmax 选一个词
③ 掩码:每步 1×1 → 2×2 → 3×3 逐步扩大
④ 梯度:无反向传播,权重冻结
⑤ Encoder:只跑一次,K/V 全程复用(工程上可 KV cache)
2推理第1步
🎯 架构功能讲解
输入只有 [I](1 个 token)。掩码自注意力在长度 1 时无实际遮蔽(只看自己);Cross-Attn 仍查阅完整源句。
完整跑 Decoder(L1 掩码自注意力 → L2 → Cross-Attn → FFN),取最后位置 1×8 logits。
3推理第2步
🎯 架构功能讲解
输入 [I, love](2 个 token)。掩码此时生效:位置 1(love)只能看 I 和 love。
与训练的联系:这一步结果 = 训练时「love」位置的结果(前面输入相同)——这就是 teacher forcing 与自回归的等价性。
只取最后位置 logits 做 argmax。
4推理第3步
🎯 架构功能讲解
输入 [I, love, easy](3 个 token)。最后一步——预测「courses」后句子完整。
一旦某步预测错会连锁错(错误传播)——工程上用 beam search 缓解。
训练时位置 3 已猜对 courses (0.563);推理第 3 步应得到相同结果。