第 2 课:Transformer 模型结构全景

第 1 课搞清楚了"为什么要 Transformer",这一课把 Transformer 的骨架拆开——Encoder 塔怎么理解输入、Decoder 塔怎么生成输出、两者之间怎么传递信息。

🎯 学完这 6 步你将能够:
① 画出原始 Transformer 的 Encoder-Decoder 双塔结构图
② 说清 Encoder 的 Self-Attention 和 Decoder 的 Masked Self-Attention 为什么不一样
③ 理解 Cross-Attention 怎么把 Encoder 的输出"喂"给 Decoder
🗺 本课路线(1 个任务 · 4 组约束 · 6 个部件;约束之间是并列支链,不是单向递进)
1任务:把「I love you」翻成「我爱你」 — 必须先读完整个输入(理解),再逐词写出(生成),这就要求结构分成 Encoder 与 Decoder 两座塔
↓
2约束一 · 输入侧:词与词要互相参照 — 两座塔里的第一座 Encoder 要让每个词都看全句,这就要求把 Self-Attention 与 FFN 各配一个残差子层、叠成一层,再堆 N 层
↓
3约束二 · 生成侧:既要看已写的,又要回看输入 — Decoder 于是在自己的 Self-Attention 之外多接一个 Cross-Attention,且自身注意力必须加 mask 防止偷看未来
↓
4约束三 · 深度:堆到 6 层要训得起来 — 层数一深,梯度与尺度都会失控,因此每个子层之后都要接 残差连接与 LayerNorm
↓
5约束四 · 顺序:并行不能丢词序 — Self-Attention 对所有位置一视同仁、本身没有顺序信息,这就要求额外注入 位置编码(sin/cos 多频率)
↓
6拼起来:一句话走完两座塔 — 于是把上述部件按 Encoder / Decoder 各堆 6 层,「I love you → 我爱你」的每一步都能追到上面哪一条约束
Encoder-DecoderSelf-AttentionCross-AttentionResidualLayerNormSinusoidal
1
要同时做到"读懂整句"和"逐词写出",为什么结构必须分成 Encoder 与 Decoder 两座塔?
提示:先看这两种动作各自需要什么信息
▾
知识背景
Transformer 出自 "Attention Is All You Need"(Vaswani et al., Google, 2017)。原论文为机器翻译设计:Encoder 编码源语言(英语),Decoder 生成目标语言(法语)。架构由 N=6 层 Encoder 堆叠 + N=6 层 Decoder 堆叠组成。后来 BERT 只用 Encoder,GPT 只用 Decoder,但原始结构是 Encoder-Decoder 双塔——这是理解 Transformer 全貌的起点。

先看任务本身:把「I love you」翻成「我爱你」,目标端要逐词产出。而"我"和"爱"这两个位置对输入的要求方向相反——一个要求"整句都已读过",一个要求"绝不能提前看到后面"。这就要求结构把这两种可见范围分开,也就是分成 Encoder 与 Decoder 两座塔。

就像同声传译岗位的分工:一个人先把整段话听完记牢,另一个人再逐句往外说——前者在论文里叫 Encoder,后者叫 Decoder。

🧮 从任务约束推出两座塔(源句 3 个词)
Step 1:任务对"可见范围"提出两个相反要求
要产出的词必须看见绝不能看见
"我"(第 1 个)I / love / you —— 整句 3 个源词—
"爱"(第 2 个)I / love / you"你"(自己还没生成)
"你"(第 3 个)I / love / you—(已是最后一个)
源句侧要"全可见",目标侧要"绝不看未来"——同一组注意力权重做不到两者兼顾。
Step 2:硬用一座塔,会坏在哪
阶段若允许看未来若禁止看未来
训练学到 P(我 | I love you 全句)学到 P(我 | 只有前缀)
推理只能拿到前缀(未来词尚不存在)与训练一致
结果训练与推理输入分布不一致 → 输出崩坏一致
一座塔既要读全句、又不能看未来,两者直接冲突——所以必须按可见范围分成两座塔。
Step 3:两座塔各自的职责,来自上面两条要求
塔可见范围因为要满足运行次数
Encoder双向,每个词看全部词源句侧"全可见"1 次
Decoder单向,Masked(只看左边)目标侧"绝不看未来"逐词,3 次
Step 4:代价——两座塔要花多少层计算
塔前向次数层数层计算次数
Encoder161 × 6 = 6
Decoder3(3 个词)63 × 6 = 18
合计——18 ÷ 6 = 3 倍
源句越长,这个差距越大;这也是后续用 KV Cache(把已算过的键和值存下来复用)把 Decoder 的重复计算压下去的原因。
🎯 两座塔在参数上差多少

Decoder 每层比 Encoder 多一个 Cross-Attention(4 个 512×512 投影矩阵):单层从 3.15M 增到 4.20M,6 层共多 6.3M 参数。而 FFN 始终占每层参数的大头(67%)——Self-Attention 并不是参数最多的部件。

🧮 参数账(原始 Transformer base 配置)
组件参数量占 Encoder 一层比例
Multi-Head Self-Attention(4 个投影矩阵)4 × 512² ≈ 1.05M33%
FFN(两个线性层)2 × 512 × 2048 ≈ 2.10M67%
LayerNorm(2 个,各 512 缩放 + 偏置)2 × 1024 ≈ 2K可忽略
Encoder 一层合计≈ 3.15M100%
Decoder 一层(多 Cross-Attention)额外 4 × 512² ≈ 1.05M—
Decoder 一层合计≈ 4.20M—
6 层 Encoder + 6 层 Decoder6 × 3.15M + 6 × 4.20M ≈ 44.1M—
+ Embedding(与输出层共享权重)+ 位置编码(正弦函数,无参数)V × 512 = 18.94M—
总计(V = 37000 BPE)≈ 44.1M + 18.9M ≈ 63M嵌入层与输出层共享权重,只计一份
此处按 V=37000 逐项相加得 ≈63M;原论文报告的 base 总参数约 65M,差额(约 2M)来自词表取整、LayerNorm 与各线性层偏置,本表未逐项计入。
AI 助教
👋 对这张卡片有疑问?我会用具体数字和计算例子来回答。
2
为什么 Encoder 一层非要按「Self-Attention → Add&Norm → FFN → Add&Norm」这个顺序来堆?
提示:先看这一层里两个子层各自"处理"了什么,再看每个子层处理前后多做了哪一步。
▾
知识背景
Encoder 每一层由两个子层组成。第一个是 Multi-Head Self-Attention(多头自注意力),第二个是 Position-wise FFN(逐位置前馈网络)。每个子层后面紧跟 Add(残差连接)+ LayerNorm。"Position-wise"意思是 FFN 对序列中每个位置的向量独立应用相同的变换——同一层内所有位置共享 FFN 参数,但不同位置独立计算、互不影响。

上一张卡片看了双塔结构。现在拆开看 Encoder 一层内部:两个子层,每个子层都是"处理 → 加回 → 归一化"的三部曲:

就像一条流水线:所有工位先互相通气一遍(Self-Attention 做信息融合),每个工位再各自加工(FFN 做非线性变换)——论文里就是 Self-Attention → Add & Norm → FFN → Add & Norm 这个顺序。

为什么要"加回"再"归一化"?因为网络越深,数值尺度越会逐层放大、梯度也越会逐层衰减——这两步就是为深网络准备的稳定器。

子层 1:Self-Attention
输入 x → Multi-Head Self-Attention(x) → 残差加法 x + Attention(x)。最后再过一层 LayerNorm。

子层 2:FFN
LayerNorm 输出 → FFN(两个线性层 + ReLU) → 残差加法 → LayerNorm。

🧮 以句子 "我 爱 你"(3 个词,示例维度 d_model=4)走查 Encoder 一层——原论文真实配置是 d_model=512,这里为便于手算压到 4 维
Step 1:输入 Embedding + 位置编码 → x(形状 [3, 4])
位置词向量(d_model=4)
pos1我[1.0, 0.5, 0.2, 0.8]
pos2爱[0.3, 1.2, 0.7, 0.1]
pos3你[0.6, 0.4, 1.1, 0.9]
Step 2:子层 1 — Self-Attention(双向,每个词看全部词)
"爱"的 Q 和所有 K 做点积(包括"我""爱""你"三个词的 K),得到注意力分数 → 加权求和 V → 输出 attention_out,形状仍是 [3, 4]。
Step 3:Add & Norm — 残差 + LayerNorm
x' = LayerNorm(x + attention_out)。残差保证了即使 Attention 层学到的东西很少(接近零),信息也不会丢失——x 本身会直接穿过去。
位置x(原始)+ attention_out= 求和→ LayerNorm → 输出
pos1[1.0, 0.5, 0.2, 0.8][0.3, 0.1, 0.2, 0.4][1.3, 0.6, 0.4, 1.2][1.109, -0.718, -1.239, 0.848]
pos2[0.3, 1.2, 0.7, 0.1][0.5, 0.3, 0.4, 0.2][0.8, 1.5, 1.1, 0.3][-0.285, 1.313, 0.4, -1.427]
pos3[0.6, 0.4, 1.1, 0.9][0.2, 0.1, 0.3, 0.5][0.8, 0.5, 1.4, 1.4][-0.577, -1.347, 0.962, 0.962]
Step 4:子层 2 — FFN(两个线性层,对每个位置独立计算)
W1: [4, 8](升维),b1: [8],ReLU;W2: [8, 4](降维),b2: [4](本例为便于手算把 d_ff 取到 2×d_model=8;原论文配置是 d_ff=4×d_model=2048)。注:W1/W2/b1/b2 的具体数值未列出,本行中间值与 ffn_out 为示意值;而上面 Step 3 与下面 Step 5 的归一化结果均由公式真实复算,可自行验算。
位置输入 x'→ W1×x'+b1 → ReLU→ W2×(...)+b2 = ffn_out
pos1[1.109, -0.718, -1.239, 0.848][2.1, 0, 1.8, 0, 0.5, 3.2, 0, 1.1][0.4, 0.2, -0.1, 0.6]
pos2[-0.285, 1.313, 0.4, -1.427][1.5, 0, 2.0, 0, 0.3, 2.8, 0, 0.9][0.3, 0.5, 0.1, 0.4]
pos3[-0.577, -1.347, 0.962, 0.962][1.8, 0, 1.5, 0, 0.2, 2.5, 0, 0.8][0.2, 0.3, 0.0, 0.7]
Step 5:再次 Add & Norm → Encoder 一层输出
output = LayerNorm(x' + ffn_out),形状 [3, 4]。一层 Encoder 计算完毕。
位置x'(子层1输出)+ ffn_out→ LayerNorm → Encoder 输出
pos1[1.109, -0.718, -1.239, 0.848]+[0.4, 0.2, -0.1, 0.6][1.509, -0.518, -1.339, 1.448] → [0.997, -0.64, -1.304, 0.947]
pos2[-0.285, 1.313, 0.4, -1.427]+[0.3, 0.5, 0.1, 0.4][0.015, 1.813, 0.5, -1.027] → [-0.304, 1.457, 0.171, -1.325]
pos3[-0.577, -1.347, 0.962, 0.962]+[0.2, 0.3, 0.0, 0.7][-0.377, -1.047, 0.962, 1.662] → [-0.634, -1.261, 0.62, 1.275]
🎯 关键洞察

Self-Attention 做的是"信息融合"——各位置的词互相交流;FFN 做的是"信息加工"——每个位置独立地对融合后的信息做非线性变换。两者配合:先融合、再加工、每一层加深理解。

AI 助教
👋 对这张卡片有疑问?我会用具体数字和计算例子来回答。
3
Decoder 既要看自己已写的、又要回看输入——为什么这需要两个注意力子层,一个不够?
提示:先分清「问题(Q)从哪来」与「答案(K/V)从哪来」——这两者可以是不同来源。
▾
知识背景
Decoder 和 Encoder 最大区别有两点。① 多了 Cross-Attention。它也叫 Encoder-Decoder Attention。② Self-Attention 加了 Mask(Causal Mask,第 1 课已讲过)。Cross-Attention 的 Q 来自 Decoder 当前层输入,K 和 V 来自 Encoder 的最后一层输出——这是 Encoder 和 Decoder 之间唯一的信息通道。6 层 Decoder 每一层都独立地从 Encoder 最后一层获取 K 和 V(不是级联)。

上一张卡片拆解了 Encoder 的内部四步。Decoder 一层 = 三个子层(比 Encoder 多一个),区别在哪?因为生成时它要同时干两件事:一边看自己已经写出的内容,一边去查已读完的输入,所以比 Encoder 多出一个 Cross-Attention。

就像做翻译时的两个动作:先回想自己已经译出的半句(Masked Self-Attention),再回头翻原文找对应说法(Cross-Attention)——这两个动作在论文里就是 Decoder 的 两个注意力子层。

子层 1:Masked Self-Attention — 和 Encoder 类似,但加了下三角 Mask(只看已生成的词)。

子层 2:Cross-Attention — Q 来自本层输入,K 和 V 来自 Encoder 输出。Decoder 用自己当前的表示去"查"Encoder 对整个输入句子的理解。

子层 3:FFN — 和 Encoder 完全一样

省掉 Cross-Attention 行不行?不行:第 1 步生成时 Decoder 手里只有 [BOS] 一个符号,它从没见过「I love you」这 3 个源词,凭什么把首词定成「我」而不是「你」?所以必须保留一个专门回看源句的子层——这就是 Cross-Attention 存在的理由。

每个子层后面都跟着 Add & Norm。

🧮 翻译 "I love you" → "我 爱 你" 时,Decoder 第 1 步的 Cross-Attention
前提:Encoder 已处理完 "I love you",输出 encoder_output [3, 4]。
Encoder 位置编码后的向量
I[0.9, 0.5, 0.1, 1.1]
love[0.5, 1.0, 0.6, 0.4]
you[0.4, 0.4, 0.7, 1.2]
Decoder 第 1 步:当前已生成 [BOS](起始符),decoder_input = [0.2, 0.3, 0.6, 0.1]
子层 1 — Masked Self-Attention(只看 BOS) → 输出 [0.3, 0.4, 0.5, 0.2]。
Add & Norm:x + 子层输出 = [0.5, 0.7, 1.1, 0.3],LayerNorm 后 → x' = [−0.51, 0.17, 1.52, −1.18](由公式真实复算)
子层 2 — Cross-Attention:x' 作为 Q,encoder_output 作为 K 和 V。
Q = x' × W_Q = [−0.51, 0.17, 1.52, −1.18] × W_Q(W_Q / W_K / W_V 投影与下方得分均为示意,仅展示 Cross-Attention 流程)
K = encoder_output × W_K,V = encoder_output × W_V
Q·K 得分Softmax加权 V
Q·K_I = 0.42exp(0.42)/Σ = 0.3550.355 × V_I
Q·K_love = 0.35exp(0.35)/Σ = 0.3310.331 × V_love
Q·K_you = 0.30exp(0.30)/Σ = 0.3150.315 × V_you
Decoder 的 Q("下一步该生成什么词?")会更多关注 Encoder 中与当前生成最相关的源词。
Cross-Attention 输出 = 0.355×V_I + 0.331×V_love + 0.315×V_you → Add & Norm → FFN → Add & Norm
🎯 核心区别总结

Self-Attention 是"自己和自己聊天"——同一序列内部的信息融合。Cross-Attention 是"译者和原文对话"——Decoder 用自己的理解去原文中找相关线索。这是 Encoder-Decoder 架构的精髓:Encoder 负责把原文变成一个"信息库"(K 和 V),Decoder 用自己的"问题"(Q)去库中检索。

AI 助教
👋 对这张卡片有疑问?我会用具体数字和计算例子来回答。
4
残差连接和 LayerNorm——每个子层后面都跟着"Add & Norm",这俩到底解决了什么问题?
提示:想想"处理后的结果"和"原输入"相加这一步,对深层网络的数值尺度与梯度意味着什么。
▾
知识背景
残差连接(Residual Connection)由 He et al.(2016)在 ResNet 中提出用于图像识别,Vaswani et al.(2017)引入 Transformer。公式:output = LayerNorm(x + Sublayer(x))。两个作用:① 梯度高速通道(恒等映射 I 保证梯度至少为 1),② 让每层只需学习"残差"(输入和输出的差)而非完整变换。LayerNorm(Ba et al., 2016)对每个样本的特征维度做归一化(减均值/除标准差),稳定训练。

前面我们看了 Encoder 和 Decoder 各自的子层结构,每个子层后面都跟着"Add & Norm"。这俩到底为什么这么重要?残差连接:x + F(x)。如果这层学不到有用的东西(F(x)接近零),信息直接穿过。反向传播时(∂/∂x)至少为 1——不会指数衰减。

LayerNorm:归一化每层的输出,让数值范围稳定。没有它,深层网络的激活值会越来越大或越来越小。

就像给水流修一条旁通管:主管道再窄,水也能从旁通管直接流到下游(残差连接 提供这条直通路),而阀门把水压稳在同一刻度(LayerNorm 负责这一步)。

🧮 残差对梯度的数学影响
无残差时:x_l = F_l(x_{l-1}),梯度 ∂loss/∂x_{l-1} = ∂loss/∂x_l × ∂F_l/∂x_{l-1}
层数假设每层梯度乘子=0.85传到第1层的梯度
120.85¹²0.14(衰减 86%)
240.85²⁴0.02(衰减 98%)
480.85⁴⁸0.0004(几乎为零)
有残差时:x_l = x_{l-1} + F_l(x_{l-1}),梯度 ∂loss/∂x_{l-1} = ∂loss/∂x_l × (I + ∂F_l/∂x_{l-1})
层数I + 0.85×I = 1.85传到第1层的梯度
121.85¹²1607(不会消失!但太大了——需要 Norm)
241.85²⁴2.6e6(爆炸了!)
注:右表的放大是刻意构造的示意(假设每层乘子恒定且同向叠加);真实残差主要缓解梯度消失、不会自动爆炸。这里想说明的是:残差让梯度尺度随深度累积,仍需 LayerNorm / 归一化把尺度压回合理范围。
LayerNorm 两步:减均值 → 除标准差
步骤公式示例(向量 [2, 6, 4, 8])
减均值x_i - μμ=(2+6+4+8)/4=5 → [-3, 1, -1, 3]
除标准差(x_i-μ)/σσ=√((9+1+1+9)/4)=√5≈2.24 → [-1.34, 0.45, -0.45, 1.34]
缩放平移γ×norm + βγ 和 β 是可学习参数,恢复表达能力
🎯 残差 + LayerNorm = 深度训练的基石

没有残差:24 层梯度衰减 98%,浅层几乎学不到。没有 LayerNorm:24 层梯度放大 2.6e6 倍,数值爆炸。两者配合让 6 层、24 层甚至 96 层都能稳定训练——这是 Transformer 从 6 层扩展到千亿参数的前提。

AI 助教
👋 对这张卡片有疑问?我会用具体数字和计算例子来回答。
5
Self-Attention 本身没有位置概念——Transformer 怎么知道"我"在第 1 位、"你"在第 3 位?
提示:顺序信息必须能在不串行的前提下算出来,且不同位置的表示要互相区分得开。
▾
知识背景
Sinusoidal 位置编码出自 "Attention Is All You Need"(2017)。用不同频率的正弦/余弦函数为每个位置生成唯一编码:PE(pos, 2i) = sin(pos / 10000^(2i/d)),PE(pos, 2i+1) = cos(pos / 10000^(2i/d))。选择 sin/cos 的关键原因:PE(pos+k) 可以表示为 PE(pos) 的线性变换——这使得模型理论上能线性表示相对位置,但不保证超出训练长度仍可外推(实测仍会退化)。现代模型(Llama 等)已改用 RoPE(第 3 课详讲)。

前面分析了残差和 LayerNorm 如何稳定深层训练。现在看另一个必须的组件——位置编码。在词向量加上位置编码后,同样一个"打"字,位置 2 和位置 5 拿到的向量就不一样了。

就像给同一句话里的每个词发一张带座位号的票:词本身(词向量)不变,加上座位号后,"打"坐在第二排和第五排就是两个不同的输入向量。

这张"座位号"就是论文里的 Positional Encoding(位置编码)。

🧮 以 d_model=4 为例,计算前 3 个位置的编码
频率计算:ω_i = 1 / 10000^(2i/d)
维度 i2i/dω_i = 1/10000^(2i/d)
0(偶数维,用 sin)0/4 = 01/10000⁰ = 1.0
1(奇数维,用 cos)0/4 = 01/10000⁰ = 1.0
2(偶数维,用 sin)2/4 = 0.51/10000^0.5 = 1/100 = 0.01
3(奇数维,用 cos)2/4 = 0.51/10000^0.5 = 1/100 = 0.01
位置编码值 PE(pos, dim)
位置dim0 (sin(1.0×pos))dim1 (cos(1.0×pos))dim2 (sin(0.01×pos))dim3 (cos(0.01×pos))
pos=1sin(1)=0.84cos(1)=0.54sin(0.01)=0.01cos(0.01)=1.00
pos=2sin(2)=0.91cos(2)=-0.42sin(0.02)=0.02cos(0.02)=1.00
pos=3sin(3)=0.14cos(3)=-0.99sin(0.03)=0.03cos(0.03)=1.00
dim0-dim1 是高频(变化快,能区分相邻位置),dim2-dim3 是低频(变化慢,能覆盖长距离)。不同频率的组合让每个位置有唯一编码。
加到词向量上:"打"在位置 2 vs 位置 5
"打"的词向量+ 位置编码= 最终输入
位置2[0.2, 0.9, 0.4, 0.1]+[0.91, -0.42, 0.02, 1.00][1.11, 0.48, 0.42, 1.10]
位置5[0.2, 0.9, 0.4, 0.1]+[sin(5), cos(5), sin(0.05), cos(0.05)][不同的向量]
🎯 位置编码的本质

不是给位置"贴标签",而是用多频率 sin/cos 生成向量。高频维度捕获局部差异(相邻位置),低频维度覆盖全局距离。这比可学习位置嵌入更灵活——理论上能用线性变换表示相对位置,但超出训练长度仍会退化(需位置插值等外推技巧),并非可任意外推。

AI 助教
👋 对这张卡片有疑问?我会用具体数字和计算例子来回答。
6
输出端要把向量投影回整个词表,这张表能不能和输入端那张共用?
提示:数一数输出端要映射回多少个词、那张矩阵有多大,再看这两张表能不能合成一张。
▾
知识背景
Weight tying(权重共享) 出自 "Attention Is All You Need"(Vaswani et al., Google, 2017)第 3.4 节。原句是「we share the same weight matrix between the two embedding layers and the pre-softmax linear transformation」——意思是:输入端把词变成向量的那张表,和输出端把向量变回词的那张表,共用同一份权重;embedding 层还会把权重乘以 √d_model。当时词表有 37,000 个词、d_model=512(向量维度是 512),共用省下的正是这 37,000×512 个参数。

上一张卡片给输入端的每个词都配好了位置编码,把它们送进了 Encoder。现在把视线移到链条的另一端——Decoder 算完最后一层,手里是一个 d_model 维的向量,接下来的问题是:怎么把它变回一个词?

答案是拿一个输出矩阵把向量投影到整个词表上,得到每个词的得分,再取概率最大的那个。整个词表是关键:词表有 37,000 个词,这个矩阵就得有 37,000 行——它和输入端那张「词→向量」的表,其实一样大。

这就像一本双向词典:查词(词→向量)和造句(向量→词)用的是同一套词条,只是翻的方向相反。

🧮 一张矩阵要多大?共用了又省多少?
Step 1:输出端要映射回整个词表,矩阵就有多大
方向操作矩阵形状参数个数
读(词→向量)查表 embedding37,000 × 51237,000×512 = 18.94M
写(向量→词)线性投影 + softmax512 × 37,00037,000×512 = 18.94M
转置不影响参数个数:两张表各有 18.94M 个参数,形状正好互为转置。
Step 2:各学一遍 vs 共用一张——算原论文 base 的账
方案输入表输出表合计参数
各学一遍(不共享)18.94M18.94M2 × 18.94M = 37.89M
共用一张(weight tying)18.94M同一份18.94M
省下——18.94M
原论文 base 约 65M 参数;若输入、输出各养一张表,模型会膨胀到约 84M——多出来的 18.94M 已达原来的近三成(18.94 ÷ 65 ≈ 29%)。
Step 3:换成现代模型,同一张表又是多大
模型词表大小向量维度一张表的参数
原论文 base37,00051237,000×512 = 18.94M
Llama 2 7B32,0004,09632,000×4,096 = 131M
以 d_model=4096 为例(Llama 2 7B 的真实配置):一张表 131M,而它总参数约 6.74B,这张表只占 131M ÷ 6.74B ≈ 1.9%。
🎯 关键认知:这是一张「读」和「写」共用的表

输入端问的是「这个词该用哪个向量表示」,输出端问的是「这个向量最像哪个词」——两个问题的答案,都写在同一个「词 ↔ 向量」的对应关系里。共用这张表(weight tying)既省参数(原论文省 18.94M,Llama 2 7B 口径是 131M),又让同一组权重同时收到「读」和「写」两端的梯度信号——原论文与 GPT-2 等都采用了它(注意:Llama 2 等一批模型并未使用 weight tying)。

AI 助教
👋 对这张卡片有疑问?我会用具体数字和计算例子来回答。