初中数学读懂 Attention Is All You Need:从加权平均到 Transformer

按论文原始顺序拆解 Transformer 涉及的数学:向量、矩阵乘、QKV、scaled dot-product attention、multi-head、位置编码、残差、LayerNorm、FFN、softmax、loss、学习率和复杂度,让初中数学背景也能啃读原文。

这篇是给“只有初中数学基础,但想硬啃《Attention Is All You Need》原论文”的读者写的。

先说结论:

这篇论文的数学主线,不是神秘公式,而是五个朴素动作:把词变成数字表格、用乘法加法算相似度、把分数变成比例、按比例加权平均、再把这套动作堆很多层。

如果你已经被这些词劝退:

  • vector
  • matrix
  • dot product
  • softmax
  • residual connection
  • layer normalization
  • positional encoding
  • multi-head attention
  • cross entropy
  • learning rate schedule

不要急。它们看着像一串大学数学黑话,但读这篇论文不需要先补完整线性代数。你只需要先会:

  • 加减乘除
  • 表格
  • 百分比
  • 平均数
  • 坐标点
  • 简单函数

我会按论文顺序拆。每遇到一个公式,先讲它在论文里解决什么问题,再用小数字手算,最后把小数字换回论文符号。

论文到底想解决什么

《Attention Is All You Need》是 2017 年 Vaswani 等人的论文。它提出 Transformer:一种不用 RNN、也不用卷积,主要靠 attention 做序列转换的架构。

当时论文主要任务是机器翻译:

输入:I love apples.
输出:我 爱 苹果 。

这类问题叫 sequence transduction,可以先理解成:

把一个序列变成另一个序列。

旧架构常用 RNN。RNN 像一个人从左到右读句子:

第 1 个词 -> 第 2 个词 -> 第 3 个词 -> ...

它的问题是慢,因为后一步依赖前一步。第 100 个词想知道第 1 个词的信息,要经过很长的传话链。

Transformer 的野心是:

让每个词直接看见其他词,不再一个一个排队传话。

这就是 attention 的核心价值。

读论文前的最小数学地基

1. 向量:一行数字

向量不要想复杂。先把它当成一行数字:

[2, 5, 1]

一个词进入模型后,会被表示成很多数字。论文里 base Transformer 的每个 token 向量长度是:

d_model = 512

这表示每个词不是一个数字,而是 512 个数字。

小白可以先想成:

"apple" -> [0.2, -1.1, 0.7, ... 共 512 个数]

这些数字不是人工写的,是训练学出来的。

2. 矩阵:很多行数字组成的表格

矩阵就是数字表格:

[
  [1, 2],
  [3, 4],
  [5, 6]
]

如果一句话有 3 个 token,每个 token 用 2 个数字表示,就能写成:

X =
[
  [1, 0],  # token 1
  [0, 1],  # token 2
  [1, 1]   # token 3
]

论文里常见的 QKV 都可以先看成这种表格。

3. 点积:对应相乘,再相加

点积是 attention 里最重要的小动作。

两个向量:

a = [1, 2]
b = [3, 4]

点积就是:

a · b = 1×3 + 2×4 = 11

它可以用来粗略衡量“两个方向像不像”。结果越大,通常表示越匹配。

attention 里会用:

Query · Key

来算“我想找的东西”和“你贴出来的标签”有多匹配。

4. 加权平均:按比例混合内容

普通平均是每个人权重一样:

(10 + 20 + 30) / 3 = 20

加权平均是每个人贡献不同:

0.6×10 + 0.3×20 + 0.1×30 = 15

attention 最后的输出,本质上就是:

根据相关程度,按比例混合一堆 Value。

5. softmax:把分数变成比例

attention 会先算出一串分数:

[2, 1, -1]

这些还不是比例。比例必须满足:

每个数 >= 0
加起来 = 1

softmax 就是把任意分数变成比例。大致三步:

  1. 先把每个分数变成正数。
  2. 全部加起来。
  3. 每个数除以总和。

论文里 attention 的“看哪里”,就是由 softmax 决定的。

如果你想单独补这一块,可以读本站这篇:《Masked Softmax 到底在 mask 什么》

论文第 3 节:Transformer 总架构

论文说,大多数序列转换模型都有 encoder-decoder 结构。

先翻译成人话:

  • encoder:读懂输入句子。
  • decoder:根据读懂的内容,一个词一个词生成输出句子。

论文符号写成:

(x1, ..., xn) -> z = (z1, ..., zn)

意思是:

输入 token 序列 x
经过 encoder
变成一串连续向量 z

然后 decoder 根据 z 生成:

(y1, ..., ym)

也就是输出 token。

这就是机器翻译:

英文 token -> encoder -> 理解后的向量序列 -> decoder -> 中文 token

自回归:一次只生成下一个词

论文说 decoder 是 auto-regressive。

人话:

生成第 i 个词时,只能看已经生成出来的前面词,不能偷看未来答案。

比如要生成:

我 爱 苹果

生成“爱”时,decoder 可以看“我”,但不能提前看“苹果”。

这就是后面 masked attention 的原因。

Encoder layer:两块积木

论文里的 encoder 由 N = 6 个相同层堆起来。每层有两块:

1. multi-head self-attention
2. position-wise feed-forward network

可以画成:

flowchart LR
  X["输入 hidden states"] --> A["Multi-Head Self-Attention"]
  A --> B["Add & LayerNorm"]
  B --> C["Feed-Forward Network"]
  C --> D["Add & LayerNorm"]
  D --> Y["输出 hidden states"]

这里还有两个辅助动作:

  • residual connection
  • layer normalization

论文公式是:

LayerNorm(x+Sublayer(x))\mathrm{LayerNorm}(x + \mathrm{Sublayer}(x))

拆开看:

x                 原来的输入
Sublayer(x)        经过 attention 或 FFN 算出来的新信息
x + Sublayer(x)    原信息 + 新信息
LayerNorm(...)     把数值整理到更稳定的范围

residual connection:别把旧信息丢掉

x + Sublayer(x) 就是 residual connection。

人话:

每一层不要从零重写 token,而是在原来的表示上加一段改动。

这像改作文:不是把整篇删掉重写,而是在原稿上修改。

为什么有用?因为深层网络很容易训练困难。残差连接给信息留了一条直路,让模型更容易把前面层的信息传到后面。

LayerNorm:把每个 token 的数字整理一下

LayerNorm 可以先理解成:

把一行数字拉回比较稳定的范围。

比如某个 token 的向量是:

[100, 102, 98]

数值整体太大。另一个 token 是:

[0.01, 0.02, -0.01]

数值整体很小。网络层层相乘相加时,如果数值忽大忽小,训练会不稳定。

LayerNorm 做的事是:对每个 token 自己那一行数字,减去均值、除以波动大小,再学一个缩放和平移。你先不用会公式,只要知道它在维持数值稳定。

Decoder layer:三块积木

decoder 每层比 encoder 多一块。

1. masked multi-head self-attention
2. encoder-decoder attention
3. position-wise feed-forward network

画成:

flowchart LR
  Y0["已生成的输出 token"] --> M["Masked Self-Attention"]
  M --> E["Encoder-Decoder Attention"]
  Z["encoder 输出 z"] --> E
  E --> F["Feed-Forward Network"]
  F --> Y1["下一层 decoder 表示"]

第一块 masked self-attention 只看已经生成的输出。

第二块 encoder-decoder attention 会看 encoder 输出,也就是输入句子的理解结果。

这两种 attention 的数学形式一样,差别在 Q/K/V 来自哪里。后面会讲。

论文第 3.2 节:Attention 是什么

论文对 attention 的定义很漂亮:

一个 attention 函数把 query 和一组 key-value pairs 映射到一个 output。

翻译成图书馆:

Query:我想找什么
Key:每本书贴出来的标签
Value:书里的真正内容
Output:我按相关程度读完几本书后得到的新理解

对应到 Transformer:

  • Query:当前 token 想找什么信息。
  • Key:其他 token 暴露给别人匹配的标签。
  • Value:其他 token 真正能贡献的内容。

如果想更细补 QKV,可以读本站这篇:《QKV 投影到底在投什么》

Scaled Dot-Product Attention:论文最核心公式

论文公式是:

Attention(Q,K,V)=softmax(QKTdk)V\mathrm{Attention}(Q,K,V)=\mathrm{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V

这是整篇论文最关键的公式。先不要怕,我们按四步拆:

1. QK^T
   用 Query 和 Key 算匹配分数

2. 除以 sqrt(d_k)
   把分数缩小一点,避免太大

3. softmax
   把分数变成权重比例

4. 乘 V
   按权重混合真正内容

用小数字手算一遍

假设当前 token 的 Query 是:

q = [1, 2]

有三个历史 token 的 Key:

k1 = [1, 0]
k2 = [0, 1]
k3 = [1, 1]

先算点积:

q · k1 = 1×1 + 2×0 = 1
q · k2 = 1×0 + 2×1 = 2
q · k3 = 1×1 + 2×1 = 3

得到分数:

[1, 2, 3]

因为向量长度 d_k = 2,论文会除以:

21.414\sqrt{2} \approx 1.414

缩放后约等于:

[0.71, 1.41, 2.12]

再 softmax,得到一组大致权重:

[0.14, 0.28, 0.58]

意思是:

第 1 个 token 看 14%
第 2 个 token 看 28%
第 3 个 token 看 58%

现在假设三个 token 的 Value 是:

v1 = [10, 0]
v2 = [0, 20]
v3 = [10, 10]

按权重加权平均:

output
= 0.14×[10, 0] + 0.28×[0, 20] + 0.58×[10, 10]
= [1.4, 0] + [0, 5.6] + [5.8, 5.8]
= [7.2, 11.4]

这就是 attention 输出。

一句话:

attention 不是复制某一个词,而是按相关程度混合一堆词的信息。

QK^T 到底是什么

如果一共有很多 Query 和很多 Key,论文不会一个一个写点积,而是把它们打包成矩阵。

假设:

Q =
[
  q1,
  q2,
  q3
]

K =
[
  k1,
  k2,
  k3
]

那么:

QK^T

就是一张分数表:

k1k2k3
q1q1·k1q1·k2q1·k3
q2q2·k1q2·k2q2·k3
q3q3·k1q3·k2q3·k3

每一行表示:

某个 token 在看所有 token 时,给每个 token 打多少分。

softmax 通常对每一行做。于是每一行都变成一组加起来等于 1 的注意力权重。

为什么要除以 sqrt(d_k)

论文说,如果 d_k 很大,点积会变大,把 softmax 推到梯度很小的区域。所以要除以:

dk\sqrt{d_k}

小白先用这个直觉理解:

点积是很多个“小乘法结果”的总和。维度越多,加起来越容易变大。

比如 2 维点积:

1×1 + 1×1 = 2

8 维点积:

1×1 + 1×1 + ... 共 8 项 = 8

项数越多,分数越容易变大。softmax 遇到很大的分数,会变得特别偏心:

softmax([20, 1, 0]) ≈ [几乎 1, 几乎 0, 几乎 0]

这样模型早早只盯一个位置,训练时也不容易调整。

除以 sqrt(d_k) 就像给分数降温,让 softmax 不要太尖。

在论文 base 模型里:

d_model = 512
h = 8
d_k = 64
sqrt(d_k) = 8

所以每个 head 的 QK 点积会除以 8。

Multi-Head Attention:为什么要多头

论文公式是:

MultiHead(Q,K,V)=Concat(head1,,headh)WO\mathrm{MultiHead}(Q,K,V)=\mathrm{Concat}(\mathrm{head}_1,\ldots,\mathrm{head}_h)W^O

其中:

headi=Attention(QWiQ,KWiK,VWiV)\mathrm{head}_i=\mathrm{Attention}(QW_i^Q,KW_i^K,VW_i^V)

翻译成人话:

不要只用一个角度看句子。先把 Q/K/V 投影成多个小空间,每个空间各算一次 attention,再把结果拼起来混合。

论文 base 模型数字是:

d_model = 512
h = 8
d_k = d_v = 512 / 8 = 64

也就是:

原来每个 token 512 个数字
分成 8 个 head
每个 head 看 64 个数字

为什么这有用?

一个 head 可能更擅长看附近词。另一个 head 可能更擅长看主谓关系。另一个 head 可能更擅长看指代关系。当然,真实 head 不一定能被人类干净命名,但多头至少给模型提供了多个并行观察角度。

如果只有一个 head,attention 输出是一次加权平均,很多信息会被混在一起。multi-head 让模型可以同时做多种加权平均。

最后的 Concat(... )W^O 做两件事:

  1. Concat:把 8 个 head 的结果拼回 512 维。
  2. W^O:再用一个矩阵重新混合,让多头结果回到通用 hidden 空间。

这一块可以接着读本站:《Out 投影到底在输出什么》

Transformer 里三种 attention

论文第 3.2.3 说 Transformer 用了三种 multi-head attention。

1. Encoder self-attention

encoder 里,Q/K/V 都来自输入句子上一层的表示。

英文句子内部互相看

比如翻译这句:

The animal didn't cross the street because it was tired.

it 要看前面的词,判断指的是 animal 还是 street。encoder self-attention 就负责这种输入内部的信息交互。

2. Decoder masked self-attention

decoder 里,生成中文时,已经生成的中文 token 之间互相看。

但它不能看未来。

比如正在生成第 3 个词:

我 爱 ?

它可以看“我”“爱”,不能偷看后面的标准答案。

论文做法是:在 softmax 前,把非法位置设成 -∞

为什么 -∞ 有用?因为 softmax 后它的权重会变成 0。

未来 token 的分数 = -∞
softmax 后权重 = 0

这就是 mask。

3. Encoder-decoder attention

decoder 生成中文时,还要看英文输入。

这时:

  • Query 来自 decoder。
  • Key 和 Value 来自 encoder 输出。

人话:

我现在要生成一个中文词。
我拿当前中文上下文当问题 Q。
去英文句子理解结果里找相关信息 K/V。

这就是翻译里的“对齐”直觉:生成某个中文词时,去看输入英文里相关的位置。

Position-wise FFN:每个位置单独过两层小网络

论文公式:

FFN(x)=max(0,xW1+b1)W2+b2\mathrm{FFN}(x)=\max(0,xW_1+b_1)W_2+b_2

拆成四步:

1. xW1 + b1
   先做一次线性变换

2. max(0, ...)
   ReLU:负数变 0,正数保留

3. 再乘 W2
   再做一次线性变换

4. + b2
   加偏置

ReLU 是什么

ReLU 就是:

max(0, x)

例子:

输入ReLU 输出
-30
-10
00
22
55

它给网络加入非线性。没有 ReLU,很多层线性变换叠起来,本质上仍然像一层线性变换,表达力会弱。

为什么叫 position-wise

因为 FFN 对每个位置单独做同一套计算。

attention 负责:

token 之间互相交流

FFN 负责:

每个 token 自己内部的 512 个特征再加工

论文里的维度:

d_model = 512
d_ff = 2048

也就是:

512 -> 2048 -> 512

先把表示放大到 2048 维加工,再压回 512 维。

Embedding 和最后的 softmax

论文第 3.4 讲 embeddings and softmax。

embedding:把 token 编号变成向量

模型不能直接读文字。它先把文字切成 token,再把 token 变成向量。

"apple" -> token id 3912 -> embedding 向量 [0.2, -1.1, ...]

论文里输入 token 和输出 token 都映射到:

d_model = 512

最后的 softmax:把 decoder 输出变成下一个词概率

decoder 最后一层输出的仍然是向量,不是词。

要预测下一个 token,需要:

decoder hidden
-> 线性变换
-> 每个词表 token 一个分数 logits
-> softmax
-> 概率分布

比如词表只有 5 个词:

tokenlogitsoftmax 后概率
1.20.18
0.30.07
苹果3.00.68
电脑0.50.09
-1.00.01

模型会根据这个分布生成下一个 token。

论文还提到 embedding 权重和 pre-softmax 线性变换共享权重,并在 embedding 层乘以:

dmodel\sqrt{d_{model}}

小白先记成:

输入查词表和输出猜词表,用的是同一张词向量表的两种方向;乘以根号维度是为了让数值尺度更合适。

Positional Encoding:没有 RNN 后,顺序从哪里来

RNN 天然知道顺序,因为它从左到右读。

Transformer 一次让所有 token 互相看。这样很并行,但问题来了:

如果不额外告诉它位置,它怎么知道哪个词在第 1 个,哪个词在第 10 个?

论文解决方法:给每个 token 的 embedding 加上 positional encoding。

token embedding + position encoding

embedding 表示“这个词是什么”。position encoding 表示“这个词在哪个位置”。

论文的 sin/cos 公式

论文使用:

PE(pos,2i)=sin(pos/100002i/dmodel)PE(pos,2i)=\sin(pos/10000^{2i/d_{model}}) PE(pos,2i+1)=cos(pos/100002i/dmodel)PE(pos,2i+1)=\cos(pos/10000^{2i/d_{model}})

看不懂没关系。先拆符号:

  • pos:token 在句子里的位置。
  • i:向量里的第几个维度。
  • sincos:可以理解成周期性波浪。
  • 10000^{...}:让不同维度的波浪频率不同。

为什么要很多频率?

因为只用一种波浪,很快会重复。不同频率叠在一起,就像给每个位置发一个复杂的座位编号。

位置 1 有一串波纹数字。位置 2 有另一串。位置 100 也有一串。

论文选择 sin/cos 的一个原因是:模型可能更容易学到相对位置。

人话:

如果两个词相隔 3 个位置,不管它们出现在句首还是句尾,这个“相隔 3”的关系都应该容易被模型识别。

论文也实验了 learned positional embedding,效果几乎一样;最后选择 sinusoidal,是因为它可能更容易外推到训练时没见过的更长序列。

如果你想补 sin/cos 和位置编码的直觉,可以读本站:《欧拉公式:旋转如何藏进 LLM 的 RoPE 位置编码》

论文第 4 节:为什么 self-attention

论文比较了 self-attention、RNN、卷积。这里数学重点是复杂度和路径长度。

n 和 d 是什么

论文表格里:

  • n:序列长度,也就是 token 数。
  • d:每个 token 的向量维度。

比如:

n = 100   句子有 100 个 token
d = 512   每个 token 有 512 个数字

Self-attention 的复杂度

self-attention 要让每个 token 看每个 token。

如果有 n 个 token,就有大约:

n × n

对关系。

所以论文写:

O(n2d)O(n^2 \cdot d)

小白读法:

序列越长,attention 的关系表按平方增长。

100 个 token 是 10,000 对关系。1000 个 token 是 1,000,000 对关系。

这就是后来长上下文模型很贵的根本原因之一。

但 self-attention 很并行

RNN 必须从左到右一步步走:

第 1 步 -> 第 2 步 -> 第 3 步 -> ...

论文说 RNN 的 sequential operations 是:

O(n)O(n)

self-attention 一层里,所有 token 的关系可以同时算,所以 sequential operations 是:

O(1)O(1)

小白读法:

attention 计算总量不一定最小,但它非常适合 GPU 一起算。

path length:远距离信息要传几手

论文还比较 maximum path length。

这个词很关键。

假设第 1 个词的信息要影响第 100 个词。

在 RNN 里,它要一站一站传:

1 -> 2 -> 3 -> ... -> 100

路径长度大约是 n

在 self-attention 里,第 100 个词可以直接看第 1 个词:

1 -> 100

路径长度是常数。

这就是论文为什么强调 self-attention 擅长 long-range dependencies。

人话:

长距离关系在 Transformer 里不需要层层传话,可以直接连线。

论文第 5 节:训练里的数学

BPE:把词切成更小单位

论文使用 byte-pair encoding 或 word-piece vocabulary。

小白理解:

模型不是直接用完整单词,而是把文字切成更小的 token。

好处是词表不会无限大,罕见词也能由小片段拼出来。

Adam:自动调参数的优化器

训练就是不断调整权重,让模型更会预测下一个 token。

普通梯度下降像这样:

参数 = 参数 - 学习率 × 梯度

Adam 是更聪明的版本。它会参考:

  • 梯度最近的平均方向。
  • 梯度波动大小。
  • 一个很小的 epsilon 防止除零。

论文参数:

β1 = 0.9
β2 = 0.98
ε = 10^-9

不用背。知道它们是 Adam 的控制旋钮就够。

学习率 schedule:先热身,再慢慢降

论文学习率公式:

lrate=dmodel0.5min(step_num0.5,step_numwarmup_steps1.5)lrate=d_{model}^{-0.5}\cdot \min(step\_num^{-0.5}, step\_num \cdot warmup\_steps^{-1.5})

看着吓人,其实是两段策略:

前 4000 步:学习率逐渐升高
4000 步之后:学习率慢慢降低

为什么要 warmup?

训练刚开始,参数还很乱。如果学习率一上来太大,模型可能乱跳。先小步热身,等模型进入状态后再放大步子。

为什么后面降低?

后期接近好区域,步子太大容易错过细节,所以慢慢减小。

论文用:

warmup_steps = 4000

Dropout:训练时故意随机关掉一点

dropout 是防过拟合的方法。

人话:

训练时随机让一部分通道暂时失效,逼模型不要太依赖某几个特征。

论文在多个地方使用 dropout:

  • sub-layer 输出加回 residual 前。
  • embedding 和 positional encoding 相加后。

base model 使用:

Pdrop = 0.1

也就是大约 10% 随机关掉。

Label smoothing:别让模型太自信

普通训练会告诉模型:

正确词概率应该是 1
其他词概率应该是 0

label smoothing 会把它软化一点。

比如词表只有 5 个词,正确答案是“苹果”。

硬标签:

[0, 0, 1, 0, 0]

软一点:

[0.025, 0.025, 0.9, 0.025, 0.025]

论文使用:

ε_ls = 0.1

这会让模型别把全部概率压到一个词上。论文说它会伤害 perplexity,因为模型被训练得更不绝对自信,但能改善 accuracy 和 BLEU。

如果你想补交叉熵、PPL,可以读本站:《困惑度 PPL 到底是什么》

论文第 6 节:结果里的数学

BLEU:翻译质量分数

BLEU 是机器翻译常用指标。粗略理解:

模型翻译和参考翻译有多少 n-gram 重合,同时惩罚太短的翻译。

论文报告:

  • English-to-German:Transformer big 达到 28.4 BLEU。
  • English-to-French:Transformer big 达到 41.8 BLEU。

这里不要把 BLEU 理解成“百分制理解能力”。它只是翻译任务上的一种自动评价指标。

FLOPs:训练花了多少计算

FLOPs 表示浮点运算次数。

论文比较了模型质量和训练成本。核心想表达:

Transformer 不只是效果好,还能更并行、更快训练。

base model 训练 100,000 steps,大约 12 小时。big model 训练 300,000 steps,大约 3.5 天,硬件是 8 张 NVIDIA P100。

PPL:模型有多意外

Table 3 里还有 PPL,也就是 perplexity。

直觉:

PPL 越低,模型对正确 token 越不意外。

但论文也提醒 label smoothing 会让模型更不自信,所以 PPL 可能变差,而 BLEU 反而变好。

这说明:

一个数学指标不等于全部能力。

Table 3:模型变体给我们的数学启发

论文做了 ablation,也就是改某个部件,看效果怎么变。

head 数不是越多越好

论文试了不同 head 数。单 head 比较差,但 head 太多也会下降。

原因可以这样理解:

d_model 固定时,head 越多,每个 head 分到的维度越少。

如果每个 head 太窄,它单独判断相似度的能力会变弱。

所以多头 attention 是平衡:

观察角度要多,但每个角度也要有足够表达空间。

d_k 太小会伤质量

论文观察到 reducing attention key size d_k hurts model quality。

人话:

Key 空间太小,模型就不容易判断“谁和谁匹配”。

这说明 compatibility function 不是简单小技巧,而是 attention 的核心。

大模型更好,但 dropout 很重要

论文里更大的 d_modeld_ff 通常效果更好。

但如果没有合适 dropout,容易过拟合。

这给小白一个朴素判断:

容量、数据、正则化要一起看。模型变大不是单独发生的好事。

sinusoidal 和 learned position 差不多

论文把 sin/cos position encoding 换成 learned positional embedding,结果接近。

这说明:

当时 Transformer 成功的核心,不是某一个位置编码公式,而是 attention-only 架构整体。

不过 sin/cos 位置编码有外推长度的潜在优势,所以论文采用了它。

从头到尾看,论文涉及哪些数学

现在把论文里的数学按模块收拢成清单。

论文位置数学概念小白读法
encoder-decoder序列到序列函数输入一串 token,输出另一串 token
embedding查表、向量token id 变成一行数字
Q/K/V projection矩阵乘法把同一份 hidden 变成三种角色
dot product乘法再相加算 Query 和 Key 有多匹配
scaling除以根号维度防止分数太大
softmax分数转比例决定看各个 token 的权重
weighted sum加权平均按权重混合 Value
multi-head多组投影并行多个角度同时看句子
concat + output projection拼接和再混合把多头结果混回 hidden
mask禁止未来信息生成时不能偷看答案
residual原输入加新变化保留旧信息,方便训练深层网络
LayerNorm标准化控制数值范围
FFN两层线性 + ReLU每个 token 内部再加工
positional encodingsin/cos 波纹编号告诉模型 token 位置
Big-O粗略成本attention 长度平方增长,但并行好
Adam优化器自动调权重
warmup schedule学习率变化先热身,再减速
dropout随机失活防止死记硬背
label smoothing软标签别让模型过度自信
BLEU/PPL/FLOPs指标质量、困惑度、计算成本

真正啃论文时怎么读

建议按这个顺序读原文。

第一次读:只抓结构

先跳过公式细节,只看:

encoder
decoder
self-attention
encoder-decoder attention
FFN
positional encoding
training
results

目标是知道论文在搭一台什么机器。

第二次读:只攻公式 1

公式 1:

Attention(Q,K,V)=softmax(QKTdk)V\mathrm{Attention}(Q,K,V)=\mathrm{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V

必须啃下来。

如果这行懂了,论文一半就通了。

第三次读:攻 multi-head

公式:

headi=Attention(QWiQ,KWiK,VWiV)\mathrm{head}_i=\mathrm{Attention}(QW_i^Q,KW_i^K,VW_i^V)

要能说出:

W_i^Q / W_i^K / W_i^V 是第 i 个 head 的投影矩阵
每个 head 先变换 Q/K/V
再单独算 attention
最后拼起来

第四次读:攻位置编码和复杂度表

位置编码不用背公式推导。你要懂:

没有 RNN/卷积,就必须额外注入顺序
sin/cos 给每个位置一串可外推的波纹编号

复杂度表要懂:

self-attention: token 两两连接,所以 n²
RNN: 一步步传,所以顺序长度 n
self-attention path length 短,长距离依赖更容易

第五次读:看实验,不神化指标

Table 2 看效果和成本。

Table 3 看组件变化。

记住:

论文不是只说“attention 好”,而是说 attention-only 架构在翻译任务上效果好、并行性强、训练快,而且 ablation 支持多头、key 维度、dropout、模型规模这些设计选择。

这篇论文和现在大模型的关系

今天很多大语言模型是 decoder-only Transformer,而原论文是 encoder-decoder Transformer,用于翻译。

所以不要把原论文里的每个结构直接等同于现代 LLM。

但核心数学仍然是同一套:

token -> embedding
hidden -> Q/K/V
QK^T -> softmax -> V
multi-head
residual
norm
FFN
logits -> softmax
cross entropy training

现代模型会改很多细节:

  • 用 decoder-only。
  • 用 causal mask。
  • 用 RMSNorm 或 pre-norm。
  • 用 RoPE 替代原始 sin/cos 加法位置编码。
  • 用 SwiGLU 等 FFN 变体。
  • 用 GQA/MQA 改 KV head。
  • 用 FlashAttention 优化计算。

但如果你读懂这篇论文的数学主线,后面看这些变体就不是从零开始。

读完要能回答的 12 个问题

  1. token 为什么要先变成 embedding 向量?
  2. Q、K、V 分别是什么角色?
  3. 点积为什么能当相似度分数?
  4. QK^T 为什么是一张分数表?
  5. attention 为什么要 softmax?
  6. softmax 后为什么要乘 V?
  7. 为什么要除以 sqrt(d_k)
  8. multi-head 比 single-head 多了什么?
  9. decoder 为什么需要 mask?
  10. residual connection 为什么是 x + Sublayer(x)
  11. positional encoding 解决什么问题?
  12. self-attention 的 成本和 O(1) 路径长度分别是什么意思?

这 12 个问题能答出来,就可以回去读原论文。读不懂的部分,不再是“完全陌生”,而是某个局部概念还要补。

最后一句

《Attention Is All You Need》的数学,不是为了把人挡在门外。

它真正说的是:

把每个词变成向量,让词和词之间直接打分,再按分数混合信息;把这件事并行做很多次、堆很多层,就能替代过去一步步传话的序列模型。

这就是 Transformer 的第一性原理。

你不需要一开始就懂所有证明和工程优化。先把这条链背后的加减乘除吃透:

向量
-> 点积
-> softmax
-> 加权平均
-> 多头
-> 残差和归一化
-> 逐 token FFN
-> 下一词概率

再回头看论文,公式就不再是一堵墙,而是一张机器说明书。

本站延伸阅读

参考入口