2、Transformer核心原理回顾:从Attention到Self-Attention,多头注意力机制详解
好,咱们开始第二讲。在动手部署之前,我习惯先把核心原理捋一遍。尤其是Transformer,很多人把它当黑盒用,但部署的时候一遇到性能瓶颈,就抓瞎了。今天咱们就把它的心脏——注意力机制,彻底拆开看看。
2.1 从最朴素的Attention说起
Attention机制,说白了就是「加权求和」。你想想看,人类看东西的时候,不会把画面里每个像素都同等对待。你会聚焦在关键区域,忽略背景。Attention做的就是这件事。
在NLP里,最早期的Attention是用于机器翻译的。比如翻译"I love you"到中文,模型在生成「爱」这个字的时候,应该更关注英文里的"love",而不是"I"或"you"。这就是一个典型的Encoder-Decoder Attention。
它的数学形式很简单:
Attention(Q, K, V) = softmax(Q * K^T / sqrt(d_k)) * V
这里Q是查询(Query),K是键(Key),V是值(Value)。你可以把Q想象成「我想找什么」,K是「我有什么标签」,V是「我实际的内容」。通过计算Q和K的相似度,得到权重,再用这个权重去加权V。
2.2 Self-Attention:自己跟自己玩
那Self-Attention又是什么?其实就是Q、K、V都来自同一个输入序列。模型在理解一个词的时候,要看看它周围的词是什么。
举个例子,句子「我吃了一个苹果,它很甜」。模型要理解「它」指的是什么,就得看看「它」前面的词。Self-Attention就是干这个的——让每个词都能「关注」到序列里的其他词。
计算步骤我拆解一下:
- 生成Q、K、V:输入向量分别乘以三个权重矩阵Wq、Wk、Wv,得到Q、K、V。
- 计算相似度:Q乘以K的转置,得到注意力分数矩阵。
- 缩放:除以sqrt(d_k),防止内积过大导致softmax梯度消失。
- Softmax归一化:得到0到1之间的注意力权重。
- 加权求和:权重乘以V,得到最终的输出。
2.3 多头注意力机制:让模型「多角度」看问题
单头注意力有个问题——它只能从一个角度去理解关系。比如在句子「他打碎了花瓶,然后把它粘好了」里,「它」既可能指「花瓶」,也可能指「碎片」。单头注意力只能关注到一种可能性。
多头注意力机制(Multi-Head Attention)就是解决这个问题的。它把Q、K、V拆成多个「头」,每个头独立计算注意力,最后再拼起来。
具体做法:
- 把Q、K、V分别拆成h份(h是头的数量,比如8个)。
- 每个头独立做一次Self-Attention。
- 把h个头的输出拼接起来。
- 再经过一个线性变换,得到最终输出。
数学上可以写成:
MultiHead(Q, K, V) = Concat(head_1, ..., head_h) * Wo
其中 head_i = Attention(Q * Wq_i, K * Wk_i, V * Wv_i)
每个头可以学到不同的关系模式。有的头关注语法关系,有的头关注语义相似度,有的头关注位置距离。
| 头编号 | 关注模式 | 实际例子 |
|---|---|---|
| 头1 | 相邻词关系 | 「红色」→「苹果」 |
| 头2 | 远距离依赖 | 「他」→「打碎」 |
| 头3 | 语法结构 | 主语→谓语→宾语 |
| 头4 | 指代消解 | 「它」→「花瓶」 |
2.4 位置编码:给模型「空间感」
Self-Attention本身是「无序」的。你想想看,如果把句子里的词打乱顺序,Self-Attention计算出来的结果是一样的。这显然不合理,因为「我打你」和「你打我」意思完全不同。
所以Transformer引入了位置编码(Positional Encoding),给每个词加上位置信息。原始论文用的是正弦和余弦函数:
PE(pos, 2i) = sin(pos / 10000^(2i/d_model))
PE(pos, 2i+1) = cos(pos / 10000^(2i/d_model))
为什么用这个?因为正弦和余弦函数有周期性,模型可以学到相对位置关系。比如位置3和位置5的关系,跟位置103和位置105的关系,在数学上是相似的。
2.5 总结:部署时你需要记住的
好了,原理讲完了。在部署到边缘设备之前,我建议你记住这几点:
- 计算瓶颈:Self-Attention的计算复杂度是O(n²),n是序列长度。部署时一定要控制n。
- 内存占用:多头注意力的每个头都需要存储中间结果,头数越多,内存越大。
- 量化友好性:Softmax这一步对量化不太友好,部署时可以考虑用ReLU或者分段线性函数替代。
- 剪枝机会:有些注意力头其实是冗余的,可以剪掉。我在一个项目里剪掉了30%的头,精度几乎没掉。
下一讲,咱们会深入Transformer的整体架构,看看Encoder和Decoder是怎么配合的。到时候我会结合一个实际的部署案例,让你看看这些原理在硬件上是怎么落地的。