大模型入门第一课: 理解Transformer

31 阅读2分钟

I: 注意力机制

注意力机制是理解Transform的基础。

一、先把「注意力机制」彻底理解

1️. 注意力机制到底在解决什么问题?

一句话:

如何让一个 token,按“相关程度”,从所有 token 那里取信息?

数学上:

注意力函数 A(q, K, V)

形式一:矩阵形式(论文 / 实现中使用)

Scaled Dot-Product Attention:

A(q,K,V)=softmax ⁣(qKTdk)VA(q, K, V) = \mathrm{softmax}\!\left( \frac{q K^{\mathsf T}}{\sqrt{d_k}} \right) V

其中:

  • qR1×dkq \in \mathbb{R}^{1 \times d_k}
  • KRn×dkK \in \mathbb{R}^{n \times d_k}
  • VRn×dvV \in \mathbb{R}^{n \times d_v}
  • 输出:A(q,K,V)R1×dvA(q,K,V) \in \mathbb{R}^{1 \times d_v}

形式二:标量展开形式(与矩阵形式完全等价)

先定义注意力权重:

αi=exp ⁣(qkidk)j=1nexp ⁣(qkjdk)\alpha_i = \frac{ \exp\!\left(\frac{q \cdot k_i}{\sqrt{d_k}}\right) }{ \sum_{j=1}^{n} \exp\!\left(\frac{q \cdot k_j}{\sqrt{d_k}}\right) }

再计算注意力输出:

A(q,K,V)=i=1nαiviA(q, K, V) = \sum_{i=1}^{n} \alpha_i \, v_i

等价关系说明

softmax ⁣(qKTdk)V        i=1nαivi\mathrm{softmax}\!\left(\frac{q K^{\mathsf T}}{\sqrt{d_k}}\right) V \;\;\Longleftrightarrow\;\; \sum_{i=1}^{n} \alpha_i v_i

两种形式在数学上完全等价,仅是表达层级不同:

  • 矩阵形式:适合论文与代码实现
  • 标量形式:适合理解与推导

这一步的本质是:

  • q:我想要什么信息
  • k:你能提供什么信息
  • v:你真正携带的内容
  • A(q,K,V) :我在当前上下文下得到的“信息总结”

到这里为止,注意力 = 一次全局加权信息聚合


二、从「注意力」到「自注意力」是第一步必然推广

问题来了:

如果我不是去查一个外部数据库,而是
一句话里的词,互相查询信息,行不行?

答案:必须行,否则没法做上下文建模。


2️. 什么是自注意力?

自注意力只做了一件事:

让每个 token,用“自己提出的问题”,
去查询“同一句话里的所有 token”。

数学上:

K=XWK,V=XWV,Q=XWQ\quad K = XW_K,\quad V = XW_V, \quad Q=XW_Q

然后对 每一个 token i

hi=A(qi,K,V)h_i=A(q_i,K,V)

这一步的结果是什么?

  • 输入:一句话的词嵌入
  • 输出:每个词一个「上下文相关」的向量

注意,这里每个词的意义以及发生变化:

一个词的表示,不再是“它是谁”,
而是“它在这句话里是什么意思”。


三、到这里,问题又来了(非常关键)

现在你已经有了 自注意力

那我们必须问一个非常硬的问题:

这样就够了吗?


四、单头自注意力的根本局限

假设只有一套 Q/K/V

也就是说:

  • 一个 token
  • 只能用 一种方式
  • 去衡量“相关性”

但一句话里,相关性不是只有一种

举个非常现实的例子:

“他告诉我,他要走了。”

“他”可能需要:

  • 最近的名词(语法关系)
  • 句首主语(指代关系)
  • 语义角色(谁是动作发起者)

❗这些关系:

  • 不是同一种相似度
  • 甚至在向量空间里是互相干扰的

五、关键转折点:为什么「一套 Q/K/V 不够」

这是从注意力 → 多头注意力的唯一逻辑跳板

一个注意力,只能学一种“相关性度量”。

即:

  • 一个内积空间
  • 一个相似度函数
  • 一个注意力分布

但语言需要的是:

多种、并行、彼此独立的相关性判断


六、于是,多头注意力不是“增强版”,而是「拆分版」

核心思想(非常重要):

不要让一个注意力承担所有语义关系。
把它拆成多个低维注意力,各管一类关系。


多头注意力是怎么“拆”的?

不再是一套投影,而是 h 套

Qi=XWQ(i),  Ki=XWK(i),  Vi=XWV(i)Qi=XWQ(i),  Ki=XWK(i),  Vi=XWV(i)

对每一套:

headi=A(Qi,Ki,Vi)\text{head}_i = A(Q_i, K_i, V_i)

每个 head:

  • 看到的是同一句话
  • 但在不同的表示子空间
  • 不同的“相关性标准”

最后一步:为什么要 concat + WOW_O

多个 head 得到的是:

  • 不同角度
  • 不同子空间
  • 不同关系下的理解结果

但下一层 Transformer 只接受一个统一表示

所以必须:

  1. Concat:保留所有角度的信息
  2. WOW_O:重新融合,回到统一语义空间

这一步相当于:

“把多个专家的结论,整理成一份报告。”


从注意力 → 多头注意力,一条完整因果链

你可以把整条逻辑记成下面 6 步:

  1. 注意力:按相关性做全局信息聚合
  2. 自注意力:token 之间互相查询
  3. Q/K/V:把“查询 / 匹配 / 内容”解耦
  4. 单头限制:只能学一种相关性
  5. 多头动机:语言需要多种关系并行建模
  6. 多头实现:多个低维注意力子空间 + 融合

II: 架构分析:

下面将从Transform架构分析各个模块的作用。

Encoder 架构

输入
 ↓
多头自注意力(Self-Attention)
 ↓
Add & Norm
 ↓
前馈网络(FFN)
 ↓
Add & Norm
 ↓
输出

1. 输入:词嵌入 + 位置编码

注意力不关心顺序,所以 Transformer 必须补一件事:

显式告诉模型“第几个词”

所以输入是:

X=Embedding+Positional EncodingX = \text{Embedding} + \text{Positional Encoding}

这一步只是“准备材料”,不做理解。

2. 多头自注意力

多头注意力不是让注意力更大,而是让注意力“更有结构、更有分工”,
可以同时从多个子空间捕获不同的依赖关系,再把它们综合起来。

3️. Add & Norm(残差 + LayerNorm)

这一步非常工程,但非常重要

为什么要加残差?

output=X+Attention(X)output=X + \text{Attention}(X)

因为:

  • 防止信息被注意力“洗掉”
  • 让模型可以选择“改 or 不改”
为什么要 LayerNorm?
  • 稳定数值分布
  • 防止深层堆叠训练崩掉

可以理解为:

允许网络“保守更新”

4️. 前馈网络(FFN):逐 token 的非线性变换

公式很简单:

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

但语义非常重要:

FFN 不看别的 token,
只负责“把当前 token 想深一点”。

对比一下:

模块作用
自注意力和别人交流
FFN自己消化

Decoder 架构:在 Encoder 基础上多两件事

Decoder Block 长这样:

Masked Self-Attention
↓
Add & Norm
↓
Encoder–Decoder Attention
↓
Add & Norm
↓
FFN
↓
Add & Norm

我们只讲和 Encoder 不同的地方


1️. Masked Self-Attention(不能偷看未来)

在生成第 t 个词时:

只能看 1~t-1,不能看 t+1

所以用 mask 把未来位置的注意力权重设为 −∞。

这是 自回归生成的根本约束


2️. Encoder–Decoder Attention(跨序列查询)

这是 Transformer 最“聪明”的地方之一。

  • Query:来自 Decoder(我现在想生成什么)
  • Key / Value:来自 Encoder(输入句子的理解)

作用一句话:

生成时,随时对齐输入内容

比如翻译时:

  • Decoder 在问:“我现在这个词,对应原句哪一部分?”

最后输出:线性层 + Softmax

Decoder 最后一层输出的是向量:

→ Linear → Softmax → 下一个 token 概率

模型就是这样一步步生成序列的。


总结:把整个 Transformer 压成一段话

Transformer 用多头自注意力让 token 彼此交流,
用前馈网络深化单点理解,
用残差和归一化稳定堆叠,
通过 Encoder 理解输入,
通过 Decoder 受控生成输出。