参考
零基础入门深度学习(8) - Transformer (1/3)
Transformer模型详解(图解) 还可以
Transformer 是视频
resnet中的残差连接,你确定真的看懂了
信息瓶颈Information Bottleneck及信息论相关概念梳理
一文读懂Transformer
Transformer 模型详解
自回归(Autoregressive)模型
RNN, Seq2Seq, Attention注意力机制
为什么Transformer的自注意力需要除以根号d?
transformer中的attention为什么scaled?
为什么Transformer 需要进行 Multi-head Attention?
Transformer通俗笔记:从Word2Vec、Seq2Seq逐步理解到GPT、BERT
The Illustrated Transformer
Transformer升级之路:2、博采众长的旋转式位置编码
一文通透位置编码:从标准位置编码、复数、欧拉公式到旋转位置编码RoPE
Self-Attention和Transformer
The Illustrated Transformer
Beam Search


Transformer的一些重要组成部分和特点:

  1. 自注意力机制(Self-Attention):Transformer的核心概念之一,它使模型能够同时考虑输入序列中的所有位置,而不是像循环神经网络(RNN)或卷积神经网络(CNN)一样逐步处理。自注意力机制允许模型根据输入序列中的不同部分来赋予不同的注意权重,从而更好地捕捉语义关系。
    RNN不能并行的问题在于后一个输入状态依赖于前一个状态的输出,只能一个节点一个节点的慢慢算,transformer能并行计算是因为他前后没有依赖,比如Attention第一个单词在计算的时候其他单词也可以同时在计算,最终算出来的注意力矩阵一起输出到后面层
  2. 多头注意力(Multi-Head Attention):Transformer中的自注意力机制被扩展为多个注意力头,每个头可以学习不同的注意权重,以更好地捕捉不同类型的关系。多头注意力允许模型并行处理不同的信息子空间。
  3. 堆叠层(Stacked Layers):Transformer通常由多个相同的编码器和解码器层堆叠而成。这些堆叠的层有助于模型学习复杂的特征表示和语义。
  4. 位置编码(Positional Encoding):由于Transformer没有内置的序列位置信息,它需要额外的位置编码来表达输入序列中单词的位置顺序。
  5. 残差连接和层归一化(Residual Connections and Layer Normalization):减轻训练过程中的梯度消失和爆炸问题,使模型更容易训练。
  6. 编码器和解码器:Transformer通常包括一个编码器用于处理输入序列和一个解码器用于生成输出序列,这使其适用于序列到序列的任务,如机器翻译。


嵌入层Embedding

一文读懂Embedding的概念,以及它和深度学习的关系 通俗易懂,推荐
position embedding为什么是加法 等效于增添位置维度,但是直接相加position embedding是否太粗暴了呢?原本认为相加后模型无法识别结果是什么,因为不清楚两者原有的大小,但是或许词向量趋于稳定可以视作常量?以此可以区分出距离,不过在学习中训练词向量也是会偏移的,只好认为小幅度移动并不会影响结果。
解码Transformer:深入理解输入、嵌入和位置编码 逻辑清晰
Transformer的位置编码 有点问题,但是也能看

每个 token 先被 embedding 成固定维度向量()。由于Transformer使用全局信息,且注意力本身不包含位置信息,因为在输入上拼接(concat)一个位置向量,然后做一次线性变换,等价于在输入的 embedding 上加一个位置向量。因此,Transformer 通常选择 逐元素相加 的方式。直接相加位置编码(positional encoding)与 token embedding 相当于隐含地为输入增加了一个“位置维度”,同时保证最终输入维度不变。

位置编码上采用固定的正弦/余弦形式,也可以使用可学习的位置向量。
满足了相同位置不因序列长度的不同而变化,不会过于受位置次序导致的影响不同,确保了序列中每个单词的位置嵌入保持唯一性。

嵌入层可以降维升维放大特征,区分笼统的特征,同时避免稀疏矩阵做计算时过度占用资源。


自注意力机制(Self-Attention)

核心是序列中任意两个Token之间都要计算注意力权重,即每个Token都会注意自身以及序列中的其它Token。i 对 j 的注意力和 j 对 i 注意力不一定相同。
注意力机制的本质是提升关键信息的权重,降低非关键信息的权重。

q, k, v分别是Query、Key、Value的缩写,它们是对注意力机制计算过程的抽象表达。三个权重矩阵都是模型训练过程中通过梯度下降自学习得到的参数。

Scaled Dot-Product Attention(核心运算)

指数函数会极度放大差异,导致softmax 输出接近 one-hot(极端化),反向传播时,非最大值位置的梯度几乎为 0,训练不稳定、收敛慢、存在梯度消失问题。缩放可以防止点积数值过大,避免 softmax 梯度消失。

控制方差为 1 的本质就是控制尺度,尺度过小会注意力权重差异不明显,模型无法有效区分重点;尺度过大则 softmax 会输出接近 0 或 1 的极端概率,梯度接近 0 导致训练停滞。

可参考
为什么Attention计算公式中,QK的点积要除以根号d

用 Q K V 三组向量计算注意力权重:先计算 Q 与 K 的点积、再按 sqrt(d_k) 缩放,然后 softmax 得到权重,最后加权 V。每个 query 向量在所有 key 上打分,得到的权重决定从所有 value 中聚合哪些信息。注意力最终通过对所有位置的信息进行加权求和来实现信息整合。

随着模型处理输入序列的每个单词,自注意力会关注整个输入序列的所有单词,帮助模型对本单词更好地进行编码。

输入序列长度 = ,每个 token 的投影维度 =

softmax 不是对整个 矩阵一次做,而是对每一行单独做,保证每个 query 都有一套自己的注意力分布。

softmax 得到的权重矩阵形状是 , 乘上 → 得到输出

1
2
3
4
5
6
7
8
9
Q = X @ Wq   
K = X @ Wk
V = X @ Wv

A = Q @ K.T # 相关性,即重视程度
A /= math.sqrt(Dk)

AA = softmax(A, axis=1)
O = AA @ V

每个 token 是独立判断的,每个 token 的注意力分布是独立生成的,虽然每个 token 分别得到自己的注意力分布,但它的权重分布是基于“全序列”的信息(Q 对所有 K)。因此每个 token 的新表示其实是“全局上下文”的结果,而不是只看自己。所有 token 的结果再合在一起,就是新的序列表示。

逻辑会不会乱?不会。

残差连接(Residual Connection):Transformer 在注意力层之后会把原始 token 表示加回去,不会丢掉本身的信息。
多头机制(Multi-Head Attention):不是只学一套注意力,而是并行学多套,每一头可能关注不同的逻辑关系(比如语法依赖、长距离信息、局部搭配等)。
后续层的堆叠:多层注意力不断迭代,全局依赖关系会逐渐清晰。

因此,虽然每个 token 独立计算权重,但最终组合在一起的表示能够保持句子逻辑,甚至更好地建模复杂依赖。

Multi-Head Attention(多头注意力)

为了让模型在不同的子空间并行学习不同的关联,Transformer 把 Q/K/V 线性投影成多个头(head),每个头单独做 attention,最后把各头的输出串接并再线性变换回原维度。多头能让模型同时关注不同类型的关系。
1

Encoder 结构

Add & Norm层

由 Add 和 Norm 两部分组成
其中 X表示 Multi-Head Attention 或者 Feed Forward 的输入,MultiHeadAttention(X) 和 FeedForward(X) 表示输出 (输出与输入 X 维度是一样的,所以可以相加)。

Add指 X+MultiHeadAttention(X),是一种残差连接,通常用于解决多层网络训练的问题,可以让网络只关注当前差异的部分。

Norm指 Layer Normalization,通常用于 RNN 结构,Layer Normalization 会将每一层神经元的输入都转成均值方差都一样的,这样可以加快收敛。

前馈网络(Feed-Forward Network, FFN)

扩大维度 + 非线性激活
是一个两层的全连接层,第一层的激活函数为 Relu,第二层不使用激活函数

FFN 对序列中每个位置独立地做“通道间”的非线性变换:把一个位置的向量投影到更高维度做非线性激活、再投回原位置。所以它增强每个位置内部的特征组合能力,补充了 attention 跨位置的信息聚合。

把维度升高有两层好处:

  1. 在高维空间里,线性分割面/非线性组合有更多自由度,能组合出更丰富的特征(类似把数据映射到高维后更容易线性可分)。
  2. 实际上把原始通道做出许多“基方向”或“特征检测器”,激活后重新混合这些检测到的特征,产生更表达力强的输出。

Encoder

通过上面描述的 Multi-Head Attention, Feed Forward, Add & Norm 就可以构造出一个 Encoder block,Encoder block 接收输入矩阵,并输出一个矩阵。通过多个 Encoder block 叠加就可以组成 Encoder。
第一个 Encoder block 的输入为句子单词的表示向量矩阵,后续 Encoder block 的输入是前一个 Encoder block 的输出,最后一个 Encoder block 输出的矩阵就是编码信息矩阵 C,这一矩阵后续会用到 Decoder 中。

Decoder 结构

第一个 Multi-Head Attention

Decoder block 的第一个 Multi-Head Attention 采用了 Masked 操作,避免获取后面信息。 Mask 操作是在 Self-Attention 的 Softmax 之前使用的。

第二个 Multi-Head Attention

主要的区别在于其中 Self-Attention 的 K, V矩阵不是使用 上一个 Decoder block 的输出计算的,而是使用 Encoder 的编码信息矩阵 C 计算的。
这样做的好处是在 Decoder 的时候,每一位单词都可以利用到 Encoder 所有单词的信息 (这些信息无需 Mask)。

编码器 / 解码器的结构差异


Encoder(N 层堆叠):每层包含 Multi-Head Self-Attention → Add&Norm → FFN → Add&Norm。

Decoder(N 层堆叠):每层包含 Masked Multi-Head Self-Attention(防止看到未来信息)→ Add&Norm → Encoder-Decoder Attention(把 encoder 输出作为 K,V)→ Add&Norm → FFN → Add&Norm。

在 Encoder 里,输入的所有 token 可以同时互相注意(全连接注意力),因为它是“已知完整序列”的任务(比如翻译源句)。
但在 Decoder 做语言生成时(比如生成目标句),它不能“偷看”未来的词,只能依赖之前已生成的词。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def causal_attention(query, key, value):
"""
因果注意力机制
query: [S, dq] key: [S, dk] value: [S, dv]
返回:output: [S, dv] attention_weights: [S, S]
"""
d_k = query.shape[1]
seq_len = query.shape[0]

# 注意力分数 (scaled dot-product)
attn_scores = np.dot(query, key.T) / np.sqrt(d_k)

# 构造 causal mask(True 表示未来位置)
mask = np.triu(np.ones((seq_len, seq_len)), k=1).astype(bool)
attn_scores = np.where(mask, -np.inf, attn_scores)

# 数值稳定的 softmax
exp_scores = np.exp(attn_scores - np.max(attn_scores, axis=1, keepdims=True))
attention_weights = exp_scores / np.sum(exp_scores, axis=1, keepdims=True)

# 注意力加权求和
output = np.dot(attention_weights, value)
return output, attention_weights

训练

训练/前向(Encoder-Decoder,逐步)
Tokenize + Embedding:输入文本分词 → 每个 token 映射为向量(embedding)。

加位置编码:embedding + positional encoding。

送入 Encoder 堆叠:经过 L 个 encoder 层(self-attention + FFN + 残差 + LayerNorm),得到 encoder 输出序列(每个位置的上下文化向量)。
NeurIPS Papers

准备 Decoder 输入:训练时 decoder 可见目标序列(右移),推理时采用已生成的 token(自回归)。

Decoder 的 Masked Self-Attention:保证每个位置只看到当前及之前的输出(因果掩码)。
Stanford University

Encoder-Decoder Attention:decoder 的 queries 与 encoder 的 K,V 做 attention,从输入序列中检索相关信息。
NeurIPS Papers

最终线性 + softmax:decoder 最上层输出经过线性变换到词表维度并 softmax 得到下一个 token 的概率分布。

计算损失 & 反向传播(训练):用目标序列计算交叉熵,反向传播更新参数。

训练时:decoder 的输入是目标序列的右移(shifted)embedding(通常称为 teacher forcing),decoder 的 masked self-attention 只看到已生成/左侧的目标 tokens;同时 decoder 在 encoder-decoder attention 层中把 encoder 的输出作为 K、V 来查询。
推理时:decoder 使用已生成的 token(自回归)作为输入,逐步生成下一个 token,直到结束符。
训练时因为知道ground truth embeding,相当于知道正确答案,网络可以一次训练完成。
预测时,首先输入start,输出预测的第一个单词 然后start和新单词组成新的query,再输入decoder来预测下一个单词,循环往复 直至end

Mask 在 Decoder Self-Attention 里完成,对应的是 序列内部的未来信息遮挡。

Encoder-Decoder Attention 不需要 Mask,因为 Encoder 输出是完整上下文,Decoder 可以自由查询。