Attention is all you need

鼎鼎大名的论文,每次理解后总以为很熟悉了,但是转头就忘。这次做一个整理,旨在常常回顾,减少遗忘。当然,和论文题目一样,注意力是学习的关键。

关系/演进路径

按输入来源分类

Attention(注意力机制)
核心:计算查询与键的相似度,加权聚合值

普通交叉 Attention
(两个序列间)
例:Decoder中的编码器-解码器注意力

Self-Attention(自注意力)
(单序列内部)
例:BERT、GPT中的基础模块

升级优化版:Multi-Head Attention
(多头注意力,Transformer 标配)

原理:
1. 将Q、K、V线性投影到h个不同的子空间
2. 在各子空间并行执行Attention
3. 拼接结果并再次线性变换

优势:
• 捕捉不同位置的多种关联模式
• 联合来自不同表征子空间的信息

Attention 注意力机制

动机/痛点

早期用 RNN/LSTM 处理长序列(长句子、大尺寸图片)时,有两个致命问题:
长序列遗忘:序列前面的信息会被逐步稀释,模型记不住长距离的关键内容;
无法精准匹配:模型不能针对性关注和当前任务相关的内容,只能按顺序硬编码所有信息。
注意力机制就是为了解决这两个问题,让模型像人一样 —— 看文章时重点看关键词,看 CT 片时重点看病灶区域。

核心定义

给输入的不同信息分配不同的权重,让模型重点关注和当前任务强相关的信息,自动弱化无关 / 噪声信息。

核心要素

  • Q(Query,查询):你当前要处理的「目标信息」(比如你查字典时,要搜的那个词);
  • K(Key,键):输入里的所有「候选信息」(比如字典里的所有词条目录);
  • V(Value,值):和 K 一一对应的「实际内容」(比如字典词条对应的详细解释)。

例子:把「我爱中国」翻译成「I love China」
当翻译到「China」这个词时,Q = 当前要翻译的目标词(China);
K = 原句的每个词(我、爱、中国),V = 每个词对应的语义特征;
模型计算 Q 和每个 K 的匹配度:Q 和「中国」的匹配度 90%,和「我」「爱」的匹配度各 5%;
用匹配度做权重,对 V 加权求和,最终输出的特征里,「中国」的语义占了 90%,完美匹配翻译需求。

核心公式

Attention(Q,K,V)=Softmax((Q⋅KT)/√dk)⋅VAttention(Q,K,V) = Softmax( (Q·K^T) / √d_k ) · VAttention(Q,K,V)=Softmax((QKT)/√dk)V

公式部分作用细节
Q·K^T计算 Q 和每个 K 的点积,代表两者的相似度点积越大,两个信息的关联越强
√d_k缩放因子,d_k 是 K 的维度防止点积数值太大,导致 Softmax 后梯度消失
Softmax把相似度归一化成 0-1 之间的权重,所有权重和为 1把匹配度转成可加权的权重
·V用权重对 V 加权求和,得到最终注意力输出相关信息权重高,主导输出;无关信息权重低,被弱化

Self-Attention 自注意力机制(Transformer 核心)

核心定义

Q、K、V 全部来自「同一个输入序列」,序列自己和自己计算注意力,专门挖掘序列内部「每个元素和其他所有元素」的关联关系。

类型Q/K/V 来源核心作用典型场景
普通 AttentionQ 来自一个序列,K/V 来自另一个序列两个不同序列之间的信息匹配机器翻译(目标句 Q vs 原句 K/V)、Transformer Decoder 的交叉注意力
Self-AttentionQ、K、V 全部来自同一个输入序列同一个序列内部的元素关联挖掘Transformer Encoder、ViT(视觉 Transformer)、医学图像 CT 特征提取

举例:

  • NLP 例子
    句子:「它是一只黑色的猫,它喜欢吃鱼」
    第二个「它」指代的是「猫」,Self-Attention 会自动给第二个「它」和「猫」分配极高的注意力权重,精准捕捉到这个长距离的指代关系,哪怕两个词隔了很远。
  • 医学 CV 例子(CT 分类场景)
    一张头部 CT 切片,我们把它分成 16×16 的图像块(Patch):
    Self-Attention 会计算「每个图像块」和「其他所有图像块」的关联;
    病灶区域的图像块,会和周围正常组织的图像块形成强关联,模型自动给病灶区域分配高权重,忽略无意义的背景区域,这就是 ViT 做医学图像分类的核心逻辑。

对比RNN的优势

  1. 长距离依赖捕捉能力碾压:RNN 处理长序列时会出现梯度消失 / 信息遗忘,而 Self-Attention 可以直接计算序列中任意两个位置的关联,不管两个元素隔了多远,都能精准捕捉;
  2. 支持并行计算,训练速度大幅提升:RNN 是串行结构,必须等前一个 token 计算完,才能算下一个;而 Self-Attention 所有位置的计算可以同时进行,完美适配 GPU 并行加速;
  3. 可解释性极强:注意力权重可以直接可视化,能清晰看到模型到底关注了输入的哪个区域 / 哪个词,这在医疗、金融等对可解释性要求高的场景至关重要。

Multi-Head Attention 多头注意力机制(Transformer 标配)

核心定义

把 Q、K、V 分别通过多个独立的线性层,拆分成 h 个「头」,每个头独立做一次 Self-Attention 计算,最后把所有头的结果拼接起来,通过一个线性层融合,得到最终输出。
不同的头提取不同空间的特征,举例:
单头注意力 = 1 个医生看病,只能从一个角度判断病情;
多头注意力 = 多个不同科室的医生会诊,每个医生(每个头)关注不同维度的特征,最后汇总所有医生的结论,得到更全面、更准确的结果。

对比单头注意力的优势

  1. 特征表达能力指数级提升:单头注意力只能学到一种类型的特征关联,而多头可以同时捕捉不同维度、不同类型的特征(语法 / 语义、局部 / 长距离、纹理 / 位置等),让模型学到更丰富的信息;
  2. 计算量几乎不变,性价比极高:多头拆分后,每个头的特征维度会等比例缩小(比如原维度 512,8 头的话每个头维度 64),总计算量和单头注意力几乎一致,却能带来巨大的效果提升;
  3. 泛化能力更强:不同头学到的特征模式不同,模型能适配更多样的输入场景,不容易过拟合,这在医疗小样本场景里尤为重要。

提问:头数越多越好?
不是。
头数太多:每个头的特征维度会变得极小,学不到有效的特征,反而会导致效果下降,还会增加计算和显存开销;
头数太少:无法捕捉足够多的特征模式,达不到多头的效果;
工业界最优实践:Transformer-Base 用 8 头,Transformer-Large 用 16 头,ViT 基础版也是 8/16 头,这个区间是经过大量实验验证的。

Transformer里注意力的应用

设计初衷

RNN 的痛点:

  • 串行依赖:rnn处理长序列,必须等到前面的词计算完成,也就是必须串行计算,计算效率低,而transformer支持并行计算。矩阵并行化计算大大提升计算效率。
  • 长距离记忆衰减: RNN存在梯度消失的问题,距离一长就对句首遗忘。transformer每次计算都在考虑全局。

transformer的encoder的input和decoder的output到底是啥

  • Encoder 的 Input:源语言序列
    Encoder 的输入是你想要模型理解的原始信息。
    例子(中译英):
    如果你想把“我爱中国”翻译成英文。
    Encoder Input = [我, 爱, 中, 国](加上起始和结束符)。
    提取语义特征。Encoder 的任务是把这些词变成一个个包含上下文信息的“深层特征向量”,供后续 Decoder 查阅。(Decoder的query)
  • Decoder 的 input
    • 训练时:Decoder 的 Input 是“正确答案”(但向右平移一位,加上 [SOS])。
    • 推理/生成时:Decoder 的 Input 是历史的生成数据
  • Decoder 的 output
    • 训练时:output是对下一个词的预测结果的概率分布,拿这个 Output 去和真正的正确答案做对比(计算 Cross Entropy Loss),从而优化模型。
    • 推理时:Output 就是模型真正“写”出来的词

Transformer 分为编码器 Encoder和解码器 Decoder,里面一共 3 种注意力:

  1. Encoder 层:多头自注意力(Multi-Head Self-Attention)
    作用:对输入序列做全局编码,捕捉序列内部所有元素的关联,无掩码,能看到输入的所有位置;
  2. Decoder 第一层:掩码多头自注意力(Masked Multi-Head Self-Attention)
    作用:防止模型 “剧透”,生成当前词的时候,只能看到前面已经生成的词,看不到后面的词(用掩码把后面位置的权重置 0);
  3. Decoder 第二层:交叉注意力(Cross-Attention,也就是普通 Attention)
    作用:把 Encoder 的编码结果和 Decoder 的生成结果结合,Q 来自 Decoder 的自注意力输出,K/V 来自 Encoder 的输出,让生成内容能精准关注输入的关键信息。
    transformer架构

左侧Encoder,负责理解输入;右侧Decoder,负责生成输出
左侧:

  1. Input Embedding(输入嵌入):将输入序列的每个词(token)映射成固定维度的向量;目的是把离散的词变成模型能计算的连续向量
  2. Positional Encoding(位置编码):Transformer 没有 RNN 或 CNN 的序列顺序感,所以必须显式注入位置信息;位置编码和输入向量相加,让模型知道词的顺序
  3. Multi-Head Attention(多头自注意力):Q、K、V 都来自同一个输入序列(即 Encoder 的输入);作用:让每个词看到句子里的其他词,捕捉上下文依赖;多头:多个不同的注意力头并行,捕捉不同维度的关系(比如语法关系、语义关系)
  4. Add & Norm(残差连接 + 层归一化):Add:把输入加到输出上(残差连接),防止梯度消失;Norm:对输出做层归一化,稳定训练
  5. Feed Forward(前馈神经网络):每个位置独立经过一个全连接层(MLP);作用:引入非线性变换,增强模型的表达能力
  6. 重复 N 次

右侧:

  1. Output Embedding + Positional Encoding:目标语言的输入(训练时是真实输出 shifted right,推理时是已生成的部分)被嵌入 + 加位置编码
  2. Masked Multi-Head Attention(带掩码的多头自注意力):mask 的作用:不让当前位置看到未来的词(防止信息泄露)
  3. Multi-Head Attention(交叉注意力):Q 来自 Decoder 上一层的输出;K、V 来自 Encoder 的最终输出;作用:让 Decoder 在生成每个词时,能“看”到 Encoder 理解的整个输入句子的信息;这是普通 Attention 的典型应用(Q 来自一个序列,K/V 来自另一个序列)

一句话总结:交叉注意力 = Decoder 拿着“当前想找什么(Q)”,去 Encoder 的信息库里“检索(匹配 K)”,然后把最相关的内容(V)加权取出来,帮助自己决定下一个词该说什么。

输出层:

  1. Linear:把 Decoder 最后一层的输出向量映射到词汇表大小的维度
  2. Softmax:把线性层的输出转成概率分布;每个位置对应词汇表里每个词的概率
  3. Output Probabilities:选择概率最高的词作为当前步的输出

部分细节

Output Embedding 在训练时的特殊处理:

Shifted Right(右移一位)

时间步Decoder 输入(Output Embedding 的输入)要预测的词
t=1<start>
t=2
t=3中国
t=4中国<end>

因为 Decoder 的任务是根据已知的词预测下一个词,所以第 1 步不能直接给 ,否则就泄露答案了
<start>,让模型预测

Output Embedding 和最后的 Linear 层的关系

Linear层(顶部)

输入: 向量(d_model维)

矩阵W2: [d_model, vocab_size]

输出: logits(vocab_size维)

Output Embedding层

输入: 词(one-hot)

矩阵W1: [vocab_size, d_model]

输出: 词向量(d_model维)

权重共享
(可选: W2 = W1.T)

很多 Transformer 模型(如 GPT)会共享这两个矩阵的权重,因为:

  • 把词变成向量(Embedding)和把向量变回词(Linear)是互逆的过程
  • 共享权重可以减少参数量
transfomer的并行化
  • 所有token输入可以同时进行训练(矩阵运算)
  • 训练时,decoder通过mask的方法可以实现并行训练
训练中的梯度流传过程简述

具体例子:源句(Encoder输入) 是“我爱中国”,目标句(Decoder输入) 是“I love China”。


1. 数据的前向传播(Forward Pass)

训练时的核心特点是:上帝视角,全量并行。

第一步:输入嵌入 (Input Embedding)

  • Encoder 端:将 [我, 爱, 中, 国] 转化为向量,加上位置编码。
  • Decoder 端:将正确答案右移后的序列 [SOS, I, love, China] 转化为向量,加上位置编码。

第二步:Encoder 提取语义

  • 数据进入 Encoder。通过多层 Self-Attention,每个汉字都融合了周围词的信息。
  • 输出:一组语义向量 MemoryMemoryMemory。这组向量描述了“我爱中国”的深层含义。

第三步:Decoder 并行预测

  • 掩码自注意力 (Masked Self-Attention):Decoder 同时处理 [SOS, I, love, China]

  • 在算 SOS 时,Mask 挡住后面的 I, love, China

  • 在算 I 时,Mask 挡住后面的 love, China

  • 交叉注意力 (Cross-Attention):Decoder 的每一层都会去翻看 Encoder 输出的 MemoryMemoryMemory

  • SOS 向量去询问 MemoryMemoryMemory,发现最该对应 I

  • I 向量去询问 MemoryMemoryMemory,发现后面接 love 最合理。

  • 输出:经过最后的 Linear 和 Softmax,模型输出一个维度为 [4, 词表大小] 的矩阵,每一行代表对下一个词的概率分布预测


2. 损失计算(Loss Calculation)

模型生成的“预测结果”要和“真实标签”对质。

  • 预测值 (y^\hat{y}y^):模型在四个位置给出的概率分布。
  • 真实标签 (yyy):没有位移的正确答案 [I, love, China, EOS]
  • 计算 Loss:使用 交叉熵损失 (Cross Entropy Loss)
  • 计算第一个位置预测出 I 的概率偏差。
  • 计算第二个位置预测出 love 的概率偏差。
  • 将所有位置的误差求平均,得到总 Loss。

3. 梯度的反向传播(Backward Pass)

一旦有了 Loss,工厂就要开始“追责”并改进参数。

第一步:计算梯度

  • 利用链式法则,从 Loss 开始往回推。
  • 首先计算输出层权重对误差的影响,然后跨越残差连接和 LayerNorm。

第二步:跨越 Decoder 和 Encoder

  • 在 Decoder 中:梯度流经 FFN、Cross-Attention 和 Masked Attention。
  • 跨越桥梁:由于 Cross-Attention 连接了两者,梯度会从 Decoder 流向 Encoder 的输出端。
  • 在 Encoder 中:梯度继续回传,直到最初的词嵌入层。

第三步:参数更新 (Optimizer)

  • 优化器(如 Adam)拿到所有权重矩阵(WQ,WK,WVW_Q, W_K, W_VWQ,WK,WV 等)的梯度。
  • 更新公式Wnew=Wold−η⋅GradientW_{new} = W_{old} - \eta \cdot \text{Gradient}Wnew=WoldηGradient(其中 η\etaη 是学习率)。
  • 结果:权重微调后,下次再遇到“我爱中国”,模型输出 I love China 的概率会更高一点。

4. 总结:训练全流程清单

  1. 准备:源序列 →\rightarrow Encoder;目标序列(Shifted Right) →\rightarrow Decoder。
  2. 并行计算:利用 Mask 保证 Decoder 在并行计算时不“偷看”未来。
  3. 对齐:Decoder 输出层产生 NNN 个位置的概率预测。
  4. 惩罚:计算预测概率与真实单词 ID 之间的 Cross Entropy。
  5. 回传:梯度通过注意力机制的路径,从输出端一路流回输入端。
  6. 进化:更新权重,完成一个 Step 的训练。

一个容易被忽略的细节

为什么推理(Inference)比训练(Training)慢得多?

  • 训练时:因为有 Mask 和正确答案,我们可以像看照片一样,一眼看完(并行)并计算 Loss。
  • 推理时:因为没有正确答案,我们像拍视频,必须拍完第一帧(生成第一个词),才能根据第一帧拍第二帧(串行)。

你现在对这套“并行训练、串行推理”的逻辑有更清晰的画面感了吗?如果需要,我们可以深入讨论梯度在 Cross-Attention 那里是如何“跨行”流动的。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐