← 学习库Transformer学习手册Attention Is All You Need · 2017

Transformer学习手册

《Attention Is All You Need》通俗解读

章节01 / 完整阅读

一个词的意思,需要向其他词借信息

01 / MOTIVATION

看句子“小王把书交给小李,因为他明天要用”。“他”指谁,要结合上下文判断。单独给“他”一个固定向量,无法表达这句话中的具体指代。我们希望每个位置都能参考其他位置,把相关信息融入自己的表示。

可以先把Attention想成一次可学习的信息检索:当前词提出查询,其他词提供匹配线索和可取回的信息;匹配程度决定混合比例。它不是检索某个外部数据库,而是对模型内部的向量做运算。输出还是向量,并不是一句“他指小李”的解释。

当前表示“他”的向量
还需要上下文
计算匹配分数参考每个位置
分数由学习参数决定
变成混合权重例如0.1、0.6、0.3
对一行求和为1
汇总其他表示加权组合信息
更新“他”的表示
图1 · 教学直觉。这里的比例不是实际模型对上面句子的注意力,也不能当作可靠的指代判定。

循环网络通常沿句子位置递推:后一个隐藏状态要等待前一个。Self-Attention可以让同一层的所有位置一起计算匹配,并让远处位置直接交换信息。但更短的计算路径不保证模型一定学对,也不代表整个训练没有顺序依赖。

原文定位:§1—2,第1—2页讨论顺序计算与长距离依赖。本文的中文指代例子是教学构造。

章节02 / 完整阅读

先把文字变成能计算的行向量

02 / REPRESENTATION

模型通常先将文本切成token。token可以是一个词、一个子词或其他片段,不能默认一个汉字或一个单词就是一个token。token编号只用于查表,本身不是语义坐标。

设词表大小为v,表示宽度为d,学习的嵌入表E有v行、d列。编号7取出E的第7行,得到长度d的向量。n个token组成X,形状为n×d;每行对应一个位置,每列是表示的一个分量。这些分量通常不能逐个命名成“人物”“时间”等人工标签。

教学简化:n=3,d=2,暂不加入位置编码
X = [[1, 0],       # 位置0
     [0, 1],       # 位置1
     [1, 1]]       # 位置2
形状:3×2;每行是一个位置的向量。

嵌入参数由训练更新。后面层的输入通常已经是带有上下文的隐藏表示,不再是最初的词表查表结果。“同一token在不同上下文有不同表示”,主要来自位置与逐层的信息交换。

原始论文§3.4还将嵌入乘以√d_model,并共享源/目标嵌入及词表输出线性变换的权重。按本文行向量记法,共享嵌入表E的形状为v×d,输出矩阵使用Eᵀ,形状为d×v。本文的小矩阵为便于手算省略嵌入缩放与权重共享,不是对完整2017配置的逐项复现;后续模型也未必沿用同一共享策略。

原文定位:§3.4,第5页。下文全部小矩阵独立于论文训练数据。

章节03 / 完整阅读

Q是查询,K用于匹配,V提供被汇总的内容

03 / LEARNED PROJECTIONS

检索比喻里,Q像“我现在需要什么信息”,K像“我能以什么特征被匹配”,V像“匹配后提供什么信息”。真正的实现是三个学习的线性投影:

Q = X WQ     K = X WK     V = X WV
X: n×d       WQ、WK: d×dk       WV: d×dv
Q、K: n×dk   V: n×dv

这里的“学习”表示WQ、WK、WV最初是参数,训练根据预测误差调整它们;不是程序员手写“Q代表主语、K代表宾语”。三个投影共享输入,却可以为匹配与传递信息保留不同特征。Q和K宽度相同才能点乘,V的宽度dv可以不同。

我们的教学例子取WQ和WK为2×2单位矩阵,WV为对角矩阵diag(2,1)。因此Q=K=X,V=[[2,0],[0,1],[2,1]]。例如第三行[1,1]乘WV得到[2,1]:第一分量乘2,第二分量保留。

Self-Attention中的Q、K、V来自同一组位置。Cross-Attention则让查询来自目标序列、K和V来自源序列;此时Q有m行,K和V有n行,两个序列长度可以不同。

原文定位:§3.2.1—3.2.3,第4—5页。用单位矩阵只是为了手算,训练中的参数不被限制为单位矩阵。

章节04 / 完整阅读

一次Attention:打分、归一化、取信息

04 / WORKED EXAMPLE

Attention(Q,K,V) = softmax(Q Kᵀ / √dk) V
一般形状:Q(m×dk) · Kᵀ(dk×n) → 分数(m×n)
逐行softmax后仍为m×n,再乘V(n×dv) → 输出(m×dv)。

当前教学例子m=n=3,dk=dv=2。每个分数是一个查询与一个键的点积:第一行查询[1,0]对第三行键[1,1]的分数为1×1+0×1=1。把所有组合一起算:

QKᵀ = [[1, 0, 1],
        [0, 1, 1],
        [1, 1, 2]]
S = QKᵀ / √2
  ≈ [[0.707107, 0,        0.707107],
     [0,        0.707107, 0.707107],
     [0.707107, 0.707107, 1.414214]]
A = softmax(S),对每行分别算
  ≈ [[0.401112, 0.197776, 0.401112],
     [0.197776, 0.401112, 0.401112],
     [0.248255, 0.248255, 0.503490]]
O = AV
  ≈ [[1.604448, 0.598888],
     [1.197776, 0.802224],
     [1.503490, 0.751745]]

拆开第一行:输出第一分量=0.401112×2+0.197776×0+0.401112×2≈1.604448;第二分量=0.401112×0+0.197776×1+0.401112×1≈0.598888。匹配使用K,汇总使用V:输出不是“选中第三个词”,而是几行内容的加权组合。

如果三个V完全相同,改变权重也不改变这一层的加权输出。这已经说明不能只看权重就断言“哪个输入导致最终答案”。后面还有输出投影、其他头、残差和多层变换。

动手改变第一行查询

固定K和V,调整q两个分量,观察权重与输出。默认值对应上面的第一行;计算独立于任何已训练模型。

原公式定位:公式(1),第4页。数值可用本目录的verify.py重新计算。

章节05 / 完整阅读

为什么除以√dk,又为什么使用softmax

05 / SCALING AND SOFTMAX

点积把dk项相加。如果各分量近似独立、均值为0、方差为1,点积方差为dk,标准差随√dk增长。除以√dk使这一简化假设下的分数方差回到1。这不是强制向量长度为1,也不是余弦相似度;学习后的分量未必满足这些假设。

softmax把一行任意实数变成正权重,并令它们之和为1。令一行分数为s₀…sₙ₋₁,其第j个权重为exp(sⱼ)/Σexp(sₖ)。它比较的是同一查询面对所有键的相对分数,不是对每个分数独立求概率。

教学计算:s=[0.707107,0,0.707107]
exp(s)≈[2.028115,1,2.028115]
总和≈5.056230 → [0.401112,0.197776,0.401112]
稳定实现:exp(sⱼ-max(s)) / Σexp(sₖ-max(s))
一行全部加100后,权重不变;减最大值避免指数溢出。

分数过大时softmax可能极度尖锐。对两个分数[0,10],权重约[0.000045,0.999955];对[0,1]则约[0.268941,0.731059]。接近0或1时,对应的局部梯度可能很小。缩放缓和随维度增长的这一风险,并不保证所有训练都稳定。

原文定位:§3.2.1与脚注4,第4页;具体数字是教学计算。

章节06 / 完整阅读

Decoder训练时,不能提前看见答案

06 / CAUSALITY

预测第二个目标token时,只能用它之前的目标token。如果训练时让当前位置读取后面的正确答案,模型可以走捷径;真正生成时未来token尚不存在,这条路径无法使用。

M = [[0, -∞, -∞],
     [0,  0, -∞],
     [0,  0,  0]]          # 3×3
Acausal = softmax(S+M)
        ≈ [[1,        0,        0],
           [0.330238, 0.669762, 0],
           [0.248255, 0.248255, 0.503490]]

mask加在softmax之前,非法连接变成−∞,指数为0。第一行即使认为第三个键很匹配,也必须只看位置0。不能先softmax再直接清零而不重新归一化,否则合法权重的和可能小于1。

对角线允许读取当前位置,是因为Decoder输入已经右移一位:当前位置输入是上一个正确token,而不是当前要预测的答案。padding mask则屏蔽补齐的空白位置,用途与因果mask不同。若一行所有键都被屏蔽,直接计算softmax会出现未定义结果;实现需避免这种行或显式处理。

原文定位:§3.1,第3页及§3.2.3,第5页。

章节07 / 完整阅读

多头:保留多组不同的匹配与信息汇总

07 / MULTI-HEAD

只有一个头时,一次加权平均容易把不同来源的信息混成一份。多头先用不同投影分别计算,再把结果并排连接,最后学习如何组合。可以类比多组检索渠道,但不能保证某个头固定负责语法、另一个固定负责情绪。

headᵢ = Attention(X WQᵢ, X WKᵢ, X WVᵢ)
MultiHead(X) = Concat(head₁,…,headₕ) WO
每头投影:d×dk、d×dk、d×dv
每头输出:n×dv;拼接后:n×(h dv)
WO:(h dv)×d;最终:n×d。

看一个极小例子:X仍是三行二维向量,两个头各只有一维。头1的三个投影都取列向量[1,0],头2都取[0,1]。头1读取第一坐标,头2读取第二坐标,dk=dv=1。第一位置在头1中q=1,键和值都是[1,0,1];权重≈[0.422319,0.155362,0.422319],输出≈0.844638。头2中q=0,三分数都是0;权重各1/3,值为[0,1,1],输出2/3。

拼接得到[0.844638,0.666667]。若WO取[[1,1],[0,1]],最终第一行是[0.844638,1.511304]。这里拼接保留了两份结果,输出投影再组合它们;不是把两个头平均成一个。这个例子使用手设投影,只为看清运算。

原文定位:§3.2.2,第4—5页。头的实际作用需要检查具体模型,不能用此教学例子代替训练结果。

章节08 / 完整阅读

能相互参考,还要知道谁在前、谁在后

08 / ORDER

在没有位置编码、没有位置相关mask的纯Self-Attention中,如果重排输入行,输出也只是对应重排。这叫置换等变:它不会凭空产生原来的顺序信息。“小王喜欢小李”和“小李喜欢小王”拥有相同的token集合,却有不同关系,因此需要把位置信息注入表示。因果mask本身也带有方向约束,但不等于完整的距离表示。

PE(pos,2i)   = sin(pos / 10000^(2i/d))
PE(pos,2i+1) = cos(pos / 10000^(2i/d))
pos:位置编号;i:坐标对编号;PE整体形状n×d。
教学取d=4,i=0,1:
PE(0) = [0,1,0,1]
PE(1) ≈ [0.841471,0.540302,0.010000,0.999950]
PE(2) ≈ [0.909297,-0.416147,0.019999,0.999800]

同一位置用不同频率的正弦和余弦编码:有的变化快,有的变化慢。如果嵌入e=[1,0,1,0],在位置1相加得到[1.841471,0.540302,1.010000,0.999950]。不是追加两个新字段,宽度仍是4。

同一频率下,偏移一个固定距离相当于对sin/cos这一对分量作旋转,因此模型有机会利用相对位置的规律。这个代数性质不保证真实模型能处理任意长上下文。正弦编码可以计算到更大位置,但能算出不等于已经学会可靠外推。

原文定位:§3.5,第5—6页。位置编码公式和数字核验见verify.py。

章节09 / 完整阅读

Attention搬来信息,FFN继续加工每个位置

09 / COMPLETE BLOCK

Attention使不同位置交换信息。FFN对每个位置的向量分别做非线性变换,同一层各位置使用同一组参数,各层参数不同。只有线性变换连续相乘仍等效于一次线性变换;中间加入非线性,才扩展能表示的变换。

FFN(x) = ReLU(xW₁+b₁)W₂+b₂
x:1×d;W₁:d×f;b₁:f;W₂:f×d;b₂:d
教学:d=2,f=3,x=[1,-2],偏置为0
W₁=[[1,0,1],[0,1,1]];xW₁=[1,-2,-1]
ReLU → [1,0,0]
W₂=[[1,0],[0,1],[1,1]] → FFN(x)=[1,0]

残差把子层输出加回输入:y=x+F(x)。上述x与F(x)相加得到[2,−2]。它保留原信息的直接路径,也帮助梯度传播,不是保证无损保留每个细节。

原始块使用:LayerNorm(x + Sublayer(x)),即Post-LN。
对一个位置y的d个分量:
μ=(Σyⱼ)/d,σ²=(Σ(yⱼ-μ)²)/d
LN(y)ⱼ=γⱼ (yⱼ-μ)/√(σ²+ε)+βⱼ
μ、σ²为标量;γ、β有d个分量,均可学习。
教学y=[2,-2],γ=[1,1],β=[0,0],ε=10⁻⁶
μ=0,σ²=4 → LN(y)≈[1,-1]。

归一化在每个token的特征维上计算,不是把整句话的全部token混在一起求一个均值。训练时还有dropout;为了看清形状,上面省略它。现代模型可能改变归一化位置、激活函数与位置表示,不能直接套回原始图。

原文定位:§3.1,第3页和§3.3,第5页。LayerNorm展开与小矩阵为教学补充;定义可对照Layer Normalization原论文。

章节10 / 完整阅读

把这些步骤接成“读原文、生成译文”

10 / THE FULL MODEL

Encoder:读源句源token → Embedding+位置
Self-Attention → Add & Norm
FFN → Add & Norm
重复多层 → 源表示Z
Decoder:生成译文目标前缀 → Embedding+位置
Masked Self-Attention → Add & Norm
Cross-Attention(Z) → Add & Norm
FFN → Add & Norm
重复多层 → 词表概率
图2 · 根据原图1重述的教学结构图。Cross-Attention每层读取最终Encoder输出;各层结构相同不代表参数共享。

Encoder的每个位置可以看源句的所有有效位置。因为翻译时整句源文本已经给定,这不算偷看目标答案。Decoder先参考已有目标前缀,再用自己的查询去读源表示:Q来自当前Decoder子层输入,K、V来自Encoder最终输出Z。

源长度n=4,目标长度m=3,d=8,单头dk=dv=2
Decoder输入D:3×8;Encoder输出Z:4×8
Q=D WQ:3×2;K=Z WK:4×2;V=Z WV:4×2
QKᵀ:3×4;Attention输出:3×2
多头拼接并投影回:3×8。

原文base配置的Encoder与Decoder各6层,d=512,8个头,每头dk=dv=64,FFN中间宽度2048。6层的结构相同,各层参数不同。它们是论文选定的配置,不是Transformer定义中不可变的常数。

最后一层Decoder隐藏状态H是m×d。乘词表输出矩阵Wo(d×v)得到m×v分数,逐行softmax给出每个位置的候选token分布。这里的softmax是在词表维上,前面的注意力softmax是在源位置或前缀位置维上;它们用途不同。

例如教学词表有3项,某位置分数为[2,1,0],概率约[0.665241,0.244728,0.090031]。选择第一项只是最简单的贪心解码;不同解码方法会改变最终序列,不改变这个概率向量的定义。

原文定位:图1与§3.1,第3页,§3.2.3—3.4,第5页。

章节11 / 完整阅读

训练可以一起算,生成仍要等上一个token

11 / TRAINING AND INFERENCE

设正确译文是“我 喜欢 学习”。训练时知道整段答案,把目标输入右移,并对齐标签:

位置Decoder输入可见目标前缀预测标签
0<BOS><BOS>我
1我<BOS> 我喜欢
2喜欢<BOS> 我 喜欢学习
3学习<BOS> 我 喜欢 学习<EOS>

这就是teacher forcing:用真实前缀训练下一token预测。整段右移输入已经给定,所以可以在一批矩阵运算中计算多个位置;因果mask仍阻止每个位置访问未来内容。并行的是位置的计算,不是取消层与层、训练步与训练步的依赖。

教学损失(不加label smoothing):
L = -(1/T) Σₜ log p(yₜ | y<ₜ, 源句)
T:有效目标位置数;L为标量。
若两个真实标签的预测概率为0.8、0.5:
L=-(log(0.8)+log(0.5))/2≈0.458145。
梯度通过词表输出、FFN、Attention传回投影与Embedding。

模型参数包含嵌入、Q/K/V投影、输出投影、FFN和归一化参数。某次运行的注意力权重A不是固定存储的模型参数,而是由本次输入和这些参数算出来的。训练不是给Q/K/V写人工语义,而是根据损失调整整个计算图。

训练已知真实译文 → 右移+mask
所有有效位置一起预测
计算误差 → 更新参数
推理<BOS> → 预测“我”
前缀+“我” → 预测“喜欢”
继续追加 → <EOS>或长度上限
图3 · 推理时下一步的前缀依赖实际生成结果,不能直接用不存在的未来token。

推理时模型可能选错一个token,后面的前缀就偏离训练时见到的真实前缀。这是理解teacher forcing局限的入口。缓存已经计算的K/V可以减少重复计算,但这是实现优化,不会把原始自回归生成变成一次直接输出整个未知序列。

原文定位:§3,第2页、§3.1,第3页及§6.1,第8页。训练损失和缓存说明是教学补充;原文还采用label smoothing。

章节12 / 完整阅读

创新在哪里:把Attention从辅助连接变成序列计算的主干

12 / WHAT CHANGED

先分清:它没有首次发明Attention

2014年提交、2015年发表于ICLR的Bahdanau等人的翻译论文,已经让Decoder在预测一个目标词时,动态读取不同源位置,而不是只依靠一个固定长度的源句摘要。此时Encoder与Decoder仍使用循环结构。Transformer进一步改变的是:源句内部、目标前缀内部,以及源句与目标句之间,都由注意力承担位置之间的信息交互,去掉序列主干的循环与卷积。

前史:Bahdanau等,Neural Machine Translation by Jointly Learning to Align and Translate;原论文§2,第2页也讨论此前的Self-Attention与卷积模型。不能把Q/K/V、残差、归一化等每个零件都说成2017年首次出现。

方案位置如何交互主要代价或限制
RNN/LSTM主干hₜ=F(hₜ₋₁,xₜ),沿位置递推;带Attention时可再读取源状态。同一层的hₜ要等hₜ₋₁;纯循环路径上的远距离信息需穿过多个状态。
局部CNN主干每层读取固定邻域;多层扩大感受野。位置可并行,但远距离联系要经过多层;膨胀卷积可缩短路径。
Transformer主干当前层直接计算允许位置间的匹配,再汇总内容。同层可批量计算,连接随输入变化;全连接分数矩阵随n²增长。

创新一:把位置递推变成矩阵运算

“我今天在图书馆借了一本关于……”的第8个位置若使用循环状态,必须先得到前7个状态。Transformer在一层的输入X已经给定后,可以同时生成全部Q、K、V,再用矩阵乘法计算QKᵀ。这让GPU有机会通过大块矩阵计算处理多个位置,不必为每个位置启动一段依赖前一个位置的递推。

这里消除的是同层沿序列位置的状态递推。第2层仍要等待第1层,下一次参数更新仍要等待本次损失,生成第8个token仍要等前面生成的token。它改变训练计算的组织方式,而不是把所有依赖都取消。

创新二:让远处信息有更短的传递路径

假设位置0的信息影响位置99。在纯循环路径里,它需沿许多状态传播;宽度3、步长1、无膨胀的局部卷积每层只能扩大有限范围。全局Self-Attention允许位置99在一层里直接读取位置0的V。反向传播时,沿这条连接更新相关投影也不必逐个穿过中间位置。

短路径提供了学习长距离关系的条件,却没有保证学到正确关系。点积仍可能分配错误权重,位置表示仍可能失效,有限宽度仍会限制信息容量。因果Decoder还只能向过去读取,不能因为“全局”二字就读未来。

创新三:多头保留多份内容相关的交互结果

单头的一次加权平均容易把几种关系压在同一份结果里。多头用不同学习投影,形成多份权重与汇总向量,再拼接。这为不同关系并存提供了表示空间。第7节的小矩阵已显示:两个头保留的两份结果,与先平均成一份不同。

按原文base配置d=512、h=8、每头64维,全部头的Q投影总参数数目是8×512×64=262144,恰好等于一个512×512投影;K、V同理。这说明拆成8头不等于把每个头都做成512维并把计算放大8倍。头数改变表示的分组方式,收益仍需消融实验验证。

创新四:把这些机制组成可训练的完整替代方案

缩放点积使匹配适合矩阵计算,位置编码补上顺序信息,逐位置FFN提供非线性加工,残差和归一化帮助深层训练。这些构件各有前史;论文贡献在于用它们构成完整Encoder—Decoder,并通过实验说明:去掉循环与序列卷积后,翻译质量和训练效率仍有竞争力。论文不是只给出一个Attention公式。

为什么更容易扩展,但不是所有长度都更省

表1关注位置交互层,n为长度,d为表示宽度:
循环层:约O(nd²),沿位置有O(n)次顺序操作。
全局Self-Attention核心:约O(n²d),位置顺序操作O(1)。
完整Transformer还包括Q/K/V与输出投影、FFN:约O(nd²)。
一个常见块的计算量因此包含O(n²d + nd²)。

并行性、计算量、显存是三个不同维度。教学取n=128、d=512,n²d为8388608,而nd²为33554432;这只是无常数项的数量级比较,不能据此宣称整块快4倍。若n增到8192,n²d变成34359738368,长序列Attention核心就很昂贵。

再看显式分数矩阵:n=8192时,一个头有67108864个元素,用FP16每元素2字节,单头128MiB,8头共1GiB;这里仅计一层、一个样本的一份分数,尚未计其他激活、梯度、参数或工作区。现代实现可以避免完整存下这份矩阵;这个例子解释原始显式算法的压力,不是实际训练显存测量。

依据:§3.2多头与缩放、§4与表1、表3消融。复杂度代入、参数量与显存为本文教学计算。

章节13 / 完整阅读

架构给出计算方法,训练才决定它会什么

13 / WHERE ABILITY COMES FROM

为什么能算Attention,不等于已经会翻译

前面手设的单位矩阵可以算出合法权重,却没有从任何语料学到语言。初始参数不同,同一句话的结果就不同。真正模型需要反复比较预测与真实文本,沿计算图更新参数,才能让投影、FFN、嵌入协作产生有用表示。

以单个位置为例,输出logits为z,词表softmax为p,真实标签的one-hot向量为y。普通交叉熵L=−Σyⱼlog(pⱼ)对logits的导数是∂L/∂zⱼ=pⱼ−yⱼ。这给出了明确的更新信号:真实token的概率太低,就推动它对应的logit上升;其他token则相应调整。这个信号继续传回隐藏表示、FFN、Attention投影与词嵌入。

教学词表:“我”“你”“他”;真实标签为“你”。
p=[0.6,0.3,0.1],y=[0,1,0]
∂L/∂z=[0.6,-0.7,0.1]
一次对logits的梯度下降示意:z新=z旧−η(p−y)
“你”的logit提高0.7η;“我”“他”分别降低0.6η、0.1η。
实际训练更新的是共享模型参数,不是为每个句子单独保存一组logits。

注意力权重也能收到梯度。Oᵢ=ΣⱼAᵢⱼVⱼ,假设下游传来向量gᵢ=∂L/∂Oᵢ,则∂L/∂Aᵢⱼ=gᵢ·Vⱼ。不同V与下游误差的关系,决定怎样调整混合权重;再通过softmax、点积传回Q和K。这比“模型自己知道该关注谁”更准确。若所有V相同,单靠重分配这一行的权重就无法改善其加权输出。

从翻译监督到文本自监督,数据来源发生了改变

原始翻译模型学习p(译文|源文),需要成对源文与译文。GPT路线则让一个因果语言模型学习p(xₜ|x₍ₜ之前₎):从连续文本取前缀,把下一个token作为标签。文本本身就能提供大量训练目标,无须为每个位置人工写答案。这叫自监督,仍有明确的预测标签和损失。

例如训练片段“水在标准大气压下达到100摄氏度时沸腾”,前缀与下一个token反复形成样本。跨许多文本,模型有机会学到语言结构和常见事实关系。但低预测损失不保证事实正确;语料错误、模式偏差、训练中罕见的问题都可能导致错误回答。

“知识在哪里”的教学解释:训练把能降低损失的规律编码到大量共享参数中;推理时上下文又通过注意力改变本次隐藏表示。模型并非把每句训练文本都变成一条可准确检索的数据库记录,也不是每次作答都重新学习并永久写入参数。

上下文学习与参数学习要分开

在提示中写“猫→cat,狗→dog,鸟→”,模型可能接着生成“bird”。示例作为输入改变本次计算,称为上下文学习;通常没有反向传播,也没有修改权重。2018年GPT论文主要使用预训练后针对任务微调,2020年GPT-3则系统研究不更新参数的zero-shot、one-shot与few-shot任务表现。两种路径不能混为一谈。

训练导数是普通交叉熵的教学推导,未包含原论文label smoothing。后续路线:2018年GPT论文§3—4;2020年GPT-3论文。

章节14 / 完整阅读

为什么2017年已有Transformer,2022年才出现ChatGPT

14 / 2017 → 2022

Transformer解决了“怎样组织序列模型的计算”;ChatGPT还需要“从大量文本学到通用能力”“把能力用于用户指令”“在多轮对话里可用”。2017年论文的主要实验是翻译,并没有同时交付一个通用对话助手。中间五年有连续的模型和训练方法演进,而不是等待同一篇论文突然生效。

时间与证据这一步增加了什么还缺什么
2017:Transformer,首次提交6月12日。以注意力构成序列主干,提供更适合并行训练的架构。主要验证翻译;架构本身没有大规模通用知识与聊天行为。
2018:GPT论文。12层decoder-only模型先做语言预训练,再用监督数据微调下游任务。任务能力仍主要经单独微调验证,尚非大众多轮助手。
2019:GPT-2论文。研究更大语料与模型,以及用文本上下文表达任务的零样本迁移。流畅续写不保证按指令回答,更不保证事实正确。
2020:GPT-3论文,首次提交5月28日。最大模型1750亿参数;系统检验不更新参数的few-shot任务表现。不同任务表现不均;基础训练目标仍是续写文本。
2022:InstructGPT论文。示范答案、偏好排序、强化学习把输出朝用户意图调整。偏好优化不能保证真实,也不等于完整聊天产品。
2022年11月30日:ChatGPT研究预览。在GPT-3.5系列基础上做对话训练与人类反馈优化,并开放交互界面。发布时仍明确存在错误答案与其他限制。

第一道差距:翻译器变成通用语言模型

原始模型分别处理源句与目标句。GPT路线把文本组织为一个序列,保留因果Self-Attention,通常去掉独立Encoder及读取其输出的Cross-Attention。配合下一token预训练,任务不再局限于一组翻译句对。它继承Transformer的计算思想,但训练目标、数据、网络配置都已变化。

第二道差距:有架构,还要有足够的数据和训练预算

2020年的Scaling Laws研究表明,在其实验范围内,语言预测损失与参数量、数据量、训练计算量呈可建模的幂律关系;研究者由此能更系统地规划扩大训练。2022年的Chinchilla研究又强调,固定计算预算下,参数量与训练token数要平衡,单纯增大参数并不充分。这些研究解释了“扩大什么、如何花预算”的问题。

依据:Scaling Laws for Neural Language Models;Training Compute-Optimal Large Language Models。它们提供实验规律,不是智能必然出现的数学定理,也不是本文对ChatGPT内部训练预算的披露。

工程上还要让大训练持续运行:数据筛选与去重、分词、分布式计算、显存与数值精度管理、检查点恢复、评估与服务部署都影响能否交付。这里是通用工程分析;公开资料不足以把2017—2022的时间精确分摊到每项工程,不能断言某一种硬件或技术单独造成了五年间隔。

第三道差距:“继续写”与“帮用户完成请求”目标不同

教学例子:输入“帮我写一封请假邮件”。以网络文本续写为目标的基础模型,可能生成文章标题、问题列表或别人的回复;这些续写可以符合语料分布,却没有完成请求。用户希望的是一封可用邮件。需要额外训练把“按要求提供帮助”的行为变得稳定。

预训练大量文本 → 下一token标签
学习广泛语言与模式
优化文本预测损失
监督微调(SFT)请求 → 人写的理想回答
继续训练模型参数
示范应如何响应
奖励模型同一请求的多个回答 → 人类排序
学习偏好分数r(x,y)
分数表示偏好,不是真值
反馈优化与对话应用依据奖励调整回答策略
约束偏离参考模型的程度
再接入多轮交互与服务
图4 · 根据InstructGPT训练流程作教学拆解;最后一格加入产品层说明。它不是2017年Transformer论文内容,也不是所有现代模型必用的唯一流程。

监督微调仍使用预测损失,只是数据变成“请求—期望回答”。奖励模型读取请求和回答,根据人类排序学习评分。随后通过强化学习优化生成模型,使它更倾向于高评分回答;InstructGPT使用PPO,并通过相对参考策略的KL惩罚控制偏移。奖励模型与生成模型承担不同角色,不是让人对每个token在线打分。

教学示意(省略InstructGPT的额外预训练项):
最大化 E[ r(x,y) − β log(πθ(y|x) / πref(y|x)) ]
x:请求;y:生成回答;r:学习的偏好奖励。
πθ:正在优化的生成策略;πref:参考策略;β:偏移约束强度。
这是目标的直觉形式,不是完整PPO更新公式或ChatGPT训练复现。

同一个基础模型经不同后训练,行为可以明显不同。但奖励高并不意味着事实真:排序者可能偏好流畅、详细但错误的回答,模型也可能学会迎合偏好。这一步主要改变能力的调用方式与行为倾向,不能解释成“RLHF把全部知识装进去”。

方法依据:InstructGPT论文;2022年1月27日官方介绍。数学式与请假邮件场景为教学构造。

第四道差距:把模型做成多轮对话产品

ChatGPT最初发布资料说明,它从GPT-3.5系列模型微调,使用人工编写的对话与回答排序,沿用与InstructGPT相近的人类反馈训练方法。聊天界面又把历史消息组织成上下文,方便用户追问与修正。这使已有模型能力更容易被普通用户调用;界面不是知识来源,但改变了使用门槛。

历史依据:2022年11月30日ChatGPT发布说明。本文讨论首次发布,不据此推断今天ChatGPT使用的模型或训练细节;未披露的GPT-3.5参数量不填入猜测值。

这五年的合理解释:Transformer提供架构,后续工作扩大预训练、探索任务迁移,再加入指令和对话训练,最后完成面向公众的交付。这是基于公开里程碑的分析,不能证明ChatGPT“必须等到2022年才能出现”,也不能把成功归因于参数规模、RLHF或界面中的单一因素。

章节15 / 完整阅读

它是一篇架构与实验论文,结论要放回任务中

15 / EVIDENCE AND LIMITS

论文提出用注意力代替循环与卷积来承担序列交互,并在翻译与句法分析上检验。它提供实验支持,不是不可能性证明;标题也不表示整个网络只有Attention。

原文证据报告的结果能支持的结论与限制
表2,PDF第8页英德BLEU:base27.3、big28.4;英法:base38.1、big41.8。对应WMT2014测试与论文配置;不是所有任务的质量排名。
§5.2,第7页8块P100 GPU;base约12小时,big约3.5天。是该硬件与训练设置的报告,不能当作今天复现的时间承诺。
表3,第9页单头开发集BLEU24.9;8头25.8;32头25.4。这组控制计算量的变体支持多头有帮助;不支持“头越多越好”。
表3(E),第9页学习位置嵌入25.7,正弦编码base25.8。该实验接近;没有证明正弦必然优于所有位置编码。
表4,第9页句法分析还比较不同数据规模。为迁移到另一任务提供证据,没有检验现代聊天模型的全部能力。
版本内部差异。固定v5的摘要与表2报告英法41.8,但§6.1正文写41.0。上表明确使用表2数字;这一差异应保留给读者核验,不能把两个数字混成同一条无条件结论。

BLEU衡量与参考译文的匹配,不是“人类理解能力”的统一刻度。测试集表2与开发集变体表3也不能直接比较成同一个排行榜。训练成本是作者估算的浮点运算量,并非对每个基线在同一台机器上重新计时。

Attention核心的n×n分数矩阵使序列变长时成本增长很快:n从100到1000,矩阵元素从1万到100万。这只比较显式分数矩阵,不是整模型耗时恰好增加100倍。投影和FFN也有成本:标准宽度d下,完整块还包含约O(nd²)的计算。不能把表1的Attention项直接当作整个Transformer复杂度。

原始模型是Encoder—Decoder:Encoder读源句,Decoder既有因果自注意力又有Cross-Attention。后来的decoder-only语言模型沿用因果注意力来处理一个token序列,并不是把原图右半边原封不动复制过去;通常没有独立源Encoder和读取它的Cross-Attention。GPT的发展是后续论文的主题,原论文没有提出今天的聊天对齐流程。可对照2018年GPT原论文§3.1与§4查看decoder-only架构的后续使用。

论文附录给出注意力可视化。它们能帮助观察信息混合,但注意力权重本身不构成对最终预测的可靠因果解释。本文对此采用谨慎的教学边界:读懂运算与读懂模型真正为何作答,是两个不同问题。后续研究Attention is not Explanation(2019)给出相关实验警示;其结论应按各自任务与模型范围理解。

原文定位:表1与§4,第6—7页、§6、表2—4,第8—10页及附录图3—5,第13—15页。架构边界与成本补充为本文分析。

章节16 / 完整阅读

用自己的话串起模型,再回到原文

16 / EXPLAIN IT BACK

Transformer先把token映射成向量并加入位置表示。每个注意力头通过学习的Q、K投影计算匹配,缩放并逐行softmax,再按权重汇总V。多头结果拼接并投影,接上残差、归一化和逐位置FFN。Encoder读取整个源句;Decoder对右移的目标前缀使用因果mask,再读取Encoder表示。训练时真实前缀已经给定,可以并行计算各位置;推理时继续使用刚生成的token,仍然逐步输出。原论文的贡献是架构和任务实验,不能直接扩展成对所有AI能力的保证。
Q、K、V是人工指定的语义字段吗?

不是。它们由输入表示乘不同的学习矩阵得到。检索类比解释计算角色,不能给向量坐标赋予固定可读语义。

为什么softmax按行,而不是整个矩阵一起?

每行代表一个查询对所有键的选择。每个查询各自需要一组总和为1的权重;整个矩阵一起归一化会让不同查询互相争抢同一个总和。

为什么mask允许对角线,却没有答案泄漏?

目标输入已右移:当前输入是前一个正确token,当前位置预测下一个。只有右移与因果mask一起才完整说明可见范围。

Attention与FFN各做什么?

Attention在不同位置之间混合信息;FFN对每个位置分别非线性加工。同一层FFN参数跨位置共享,多层间不共享。

并行训练是否意味着一次生成完整答案?

训练输入含整段真实前缀,可以一次计算各位置;推理没有未来token,下一步依赖已生成前缀,仍然自回归。

注意力权重0.9是否说明某个词对答案贡献90%?

不是。它只描述一个头、一个层、一次运行的V混合系数,不是最终输出的因果贡献比例。

Transformer首次发明了Attention吗?

没有。此前翻译模型已经使用Attention。关键改变是用注意力承担序列主干的位置交互,并组成无需循环与序列卷积的完整架构。

为什么把2017年的模型直接做成网页,还不是ChatGPT?

原模型主要用于翻译。通用助手还需要语言预训练及其数据与计算规模、指令和对话后训练,以及服务交付。架构、学到的能力与响应行为是不同层面。

原文阅读顺序

先读第3页图1,再对照第4页公式(1)做手算;第5页看三种Attention路径与FFN,第6页看位置编码和复杂度;最后读第7—10页实验设置与结果,再审视第13—15页可视化能说明多少。

本地核验:python3 docs/transformer/verify.py重新计算全部教学数字并检查网页锚点。无需安装数值库,不需要下载模型。

主要资料:固定版本记录;完整PDF;作者公布的实现仓库。本文没有宣称核验该仓库全部源码或复现完整模型。

全文搜索

输入关键词,搜索完整正文。