详细摘要 摘要

生成:2025-05-15 22:20

摘要详情

音频文件
Stanford CS224N NLP with Deep Learning | 2023 | Lecture 8 - Self-Attention and Transformers
摘要类型
详细摘要
LLM 提供商
openai
LLM 模型
gemini-2.5-pro-exp-03-25
已创建
2025-05-15 22:20:24

标题: Stanford CS224N NLP with Deep Learning | 2023 | Lecture 8 - Self-Attention and Transformers
描述: 90,539次观看 2023年9月20日 #deeplearning #naturallanguageprocessing
For more information about Stanford's Artificial Intelligence professional and graduate programs visit: https://stanford.io/ai

This lecture covers:
1. From recurrence (RNN) to attention-based NLP models
2. The Transformer model
3. Great results with Transformers
4. Drawbacks and variants of Transformers
副标题: 该讲座主要介绍了自然语言处理领域从循环神经网络(RNN)向基于自注意力机制和Transformer模型的转变。

概览/核心摘要 (Executive Summary)

本讲座阐述了自然语言处理从循环神经网络 (RNN) 向基于自注意力机制的 Transformer 模型的重大转变。核心内容包括:
1. RNN的局限性: 讨论了RNN在处理长距离依赖和并行计算方面的不足,如线性交互距离导致信息逐词传递困难、时序依赖性阻碍GPU并行处理,这些促使了新架构的探索。
2. 自注意力的突破: 引入自注意力机制,允许模型在处理单个序列时,让每个词直接关注序列中所有其他词,从而直接捕捉序列内任意词语间的关系,并实现高度并行化计算,有效克服RNN的瓶颈。
3. Transformer核心组件: 详细解析了Transformer模型的关键构成,如多头注意力(在不同表示子空间并行关注信息)、位置编码(解决自注意力缺乏顺序信息的问题)、逐位置前馈网络(引入非线性)、残差连接与层归一化(促进深度网络训练),以及掩码机制在特定任务(如解码)中的应用。
4. 架构与成就: 介绍了Transformer的编码器、解码器及完整的编码器-解码器架构,强调其在机器翻译等任务上的卓越表现和对大规模预训练模型(如BERT、GPT)发展的巨大推动作用。
5. 挑战与展望: 指出了Transformer面临的主要挑战,特别是随序列长度增长的二次方计算复杂度,并提及了相关的研究进展和模型变体。

课程管理与通知

  • 新的讲义已发布: 讲义内容与本次讲座内容基本一致,但包含更多细节。
  • 作业四 (Assignment 4): 将于一周后到期。
    • Azure 的问题仍在继续。
    • 助教已测试,作业可在 Colab 上完成训练,训练量在 Colab 会话允许范围内。建议没有 GPU 的学生使用 Colab。
    • 团队正在为作业五和最终项目争取更多 GPU 资源。
  • 最终项目提案 (Final Project Proposal):
    • 将于当晚发布,届时会有 Ed Announcement 通知。
    • 团队将对提案的可行性提供反馈,并建议修改方向,以确保项目在剩余学期内有较好的成功机会。
    • 反馈将尽快给出,因为学生将在作业五完成后主要投入到最终项目中。

从循环神经网络 (RNN) 到注意力机制

讲座回顾了课程早期处理自然语言处理问题的方法,通常采用双向长短期记忆网络 (BiLSTM) 对句子进行编码,并使用单向 LSTM 结合注意力机制逐个生成输出(如翻译或解析)。注意力机制被用于提供对记忆的灵活访问,例如在机器翻译中避免将整个源句信息压缩到单个向量中(即信息瓶颈问题)。

本次讲座的目标与之前类似,但将使用不同的构建模块。讲座指出,大约在 2014-2017 年间,RNN 是主流,而之后出现了新的构建模块(即 Transformer),它们可以直接替代 LSTM,并带来了更广泛和成功的应用。

RNN 的局限性

讲座指出了 RNN 的两个主要问题:

  1. 线性交互距离 (Linear Interaction Distance):

    • RNN 按顺序(从左到右或从右到左)处理信息,这使得相邻词语易于交互。
    • 然而,对于长距离依赖关系(例如句子 "The chef who ... was..." 中 "chef" 和 "was" 的关系),信息需要在 RNN 中逐步传递。讲者指出:“非常长距离的依赖关系可能需要非常长的时间才能相互作用。”距离越远,学习这种依赖关系就越困难,梯度传播也更具挑战性。
    • 尽管 LSTM 比简单 RNN 在处理长距离梯度问题上有所改进,但并非完美。
    • 理想情况下,希望相关的词语能更容易地在神经网络的计算图中交互,而不受线性距离的限制。
  2. 缺乏并行性 (Lack of Parallelizability / Dependence on Time):

    • RNN 的前向和后向传播包含 O(序列长度) 数量的不可并行操作。
    • 要计算时间步 t 的隐藏状态,必须先计算时间步 t-1 的隐藏状态。讲者举例说明:“你无法在计算时间步四或时间步三的RNN隐藏状态之前,计算时间步五的RNN隐藏状态。”
    • 这限制了 GPU 等并行计算硬件的有效利用,因为序列越长,无法并行的操作链就越长,计算效率随序列长度增加而降低。

一位学生提问,注意力机制是否已经解决了线性交互问题。讲者回应,注意力确实有助于解决该问题,并且本讲座后续内容将更彻底地采用注意力,特别是自注意力,以完全取代循环结构。

深入理解注意力机制 (Attention)

讲座提出,如果 RNN 不是最佳选择,那么注意力机制是可行的替代方案。注意力机制的核心思想是:

  • 将每个词的表示视为一个查询 (Query)
  • 该查询用于访问并整合来自一组值 (Values) 的信息,这些值与相应的键 (Keys)相关联。
  • 注意力机制允许模型直接关注序列中任意远距离的词语,解决了线性交互问题。
  • 由于可以同时处理整个序列(或至少是序列的一部分,取决于注意力类型),它也解决了并行性问题。

注意力机制:类比于模糊查找

讲座将注意力机制比作在键值存储 (Key-Value Store) 中的一种“模糊查找”:

  • 标准查找表 (Lookup Table): 如 Python 字典,查询精确匹配一个键,然后返回对应的值。
  • 注意力机制:
    • 查询 (Query) 与所有键 (Keys) 进行“软性”匹配,计算相似度。
    • 通过 softmax 函数将相似度转换为权重 (0到1之间)。
    • 最终输出是所有值 (Values) 基于这些权重的加权平均。
    • 讲者将其描述为一种在“软性、模糊的向量空间”中进行的类似查找表的操作。

示例: 在句子 "I went to Stanford cs224n and learned" 中,为了构建 "learned" 的上下文感知表示,"learned" 作为查询,会与句子中所有词(作为键)计算相似度,并对这些词对应的值进行加权求和。

自注意力 (Self-Attention) 详解

自注意力是指在单个序列内部,元素之间相互关注,允许模型在处理单个句子时,让每个词直接关注到句子中的所有其他词。其计算步骤如下:

  1. 输入: 词序列 W_1, ..., W_n
  2. 词嵌入: 每个词 W_i 通过嵌入矩阵 E 转换为词向量 x_i (其维度为模型维度 d_model)。这些是无上下文的词嵌入。
  3. 生成查询 (Query)、键 (Key)、值 (Value) 向量:

    • 对每个词向量 x_i,使用三个不同的可学习权重矩阵 W_q, W_k, W_v (维度均为 d_model x d_model,将 d_model 维向量映射回 d_model 维向量) 进行线性变换,得到该词的查询向量 q_i、键向量 k_i 和值向量 v_i
      • q_i = W_q * x_i
      • k_i = W_k * x_i
      • v_i = W_v * x_i
    • 因此,序列中的每个词都同时扮演这三种角色。
  4. 计算注意力得分 (Attention Scores):

    • 对于任意一对词 ij (词 i 作为查询,词 j 作为键),计算它们之间的点积相似度 e_ij
      • e_ij = q_i^T * k_j
    • 这个得分表示词 i 应该多大程度上关注词 j
  5. 计算注意力权重 (Attention Weights):

    • 对每个词 i,将其与序列中所有其他词 j 的得分 e_ij 进行 softmax 归一化,得到注意力权重 alpha_ij
      • alpha_ij = softmax_j(e_ij) = exp(e_ij) / sum_k(exp(e_ik))
    • 权重 alpha_ij 表示词 i 的表示中,来自词 j 的信息的贡献程度。
  6. 计算输出向量 (Output Vectors):

    • i 的最终输出向量 o_i 是序列中所有词的值向量 v_j 的加权和,权重为 alpha_ij
      • o_i = sum_j (alpha_ij * v_j)

针对学生关于为何需要独立的 Q 和 K 矩阵的提问,讲者解释这与计算效率有关,最终会形成 QK^T 的低秩近似。关于词自身对其表示的注意力,讲者指出这取决于学习到的 W_qW_k 矩阵,模型可以通过学习决定一个词是否应该关注自身。

构建自注意力模块的关键组件

讲座指出,直接使用上述定义的自注意力机制替代 RNN 还存在一些问题,需要引入额外组件来构建一个“最小可行”的自注意力模块。

问题1:缺乏序列顺序信息 (No Notion of Sequence Order)

  • 问题描述: 自注意力机制本身是对集合的操作,它不关心词语在序列中的原始顺序。例如,"Zuko made his uncle" 和 "His uncle made Zuko" 在经过自注意力处理后可能会得到相同的表示,因为词的嵌入和注意力计算不依赖于词的位置索引。
  • 解决方案: 位置编码 (Positional Encoding)。将代表词语位置信息的向量 p_i 加到对应的词嵌入 x_i 上。
    • 正弦/余弦位置编码 (Sinusoidal Positional Encoding):
      • 使用不同频率的正弦和余弦函数为每个位置生成一个固定维度的向量。例如,P_i 的每个维度 k 的计算方式类似于 sin(pos / 10000^(2k/d_model))cos(pos / 10000^(2k/d_model))
      • 优点:理论上可以处理比训练时更长的序列,但实践中外推效果不佳。这是一种早期的、有时仍在使用的方法。
    • 可学习的位置编码 (Learned Positional Encoding):
      • 创建一个可学习的嵌入矩阵,维度为 (最大序列长度 N_max, 词嵌入维度 d_model)
      • 在输入时,将对应位置的向量加到词嵌入上。
      • 优点:模型可以学习到最适合数据的位置表示。
      • 缺点:无法处理超过 N_max 长度的序列。讲者提到,实践中,如果向模型输入超过预设最大长度 N_max 的序列,模型通常会出错或崩溃。
      • 目前大多数系统采用这种方式。实际中 N_max 可能为 4000 左右,对于小说或长篇维基百科页面仍显不足,这在实践中仍是一个问题,部分原因在于自注意力操作的二次方复杂度。
    • 其他方法:相对位置编码、依赖树结构感知的位置编码等(讲义中有更多细节)。

针对学生关于如何确保学习到的 P 矩阵代表位置信息的提问,讲者解释,因为 P 矩阵在每个位置上是固定的,而词是变化的,所以 P 矩阵唯一关联的就是位置信息,模型通过学习隐式地捕捉这种关联。

问题2:缺乏非线性 (No Non-linearities for Deep Learning Magic)

  • 问题描述: 如果仅仅堆叠自注意力层,本质上只是在反复对值向量进行加权平均,缺乏深度学习模型通常需要的非线性变换来增强表达能力。
  • 解决方案: 逐位置前馈神经网络 (Position-wise Feed-Forward Network, FFN)
    • 在自注意力层的输出之后,对每个位置的输出向量独立地应用一个小型的前馈网络(通常是一个两层的 MLP,包含一个非线性激活函数,如 ReLU)。
    • 例如,FFN(x) = max(0, xW_1 + b_1)W_2 + b_2
    • 这为模型引入了非线性,并且可以高效并行计算。

问题3:解码时“预知未来” (Looking at the Future)

  • 问题描述: 在某些任务中(如语言建模、机器翻译解码),模型在预测当前词时不应获取未来词的信息。标准的自注意力会允许一个词关注序列中所有其他词,包括未来的词。
  • 解决方案: 掩码 (Masking)
    • 在计算注意力权重之前,修改注意力得分矩阵 e_ij
    • 对于词 i,如果词 j 在其之后 (即 j > i),则将 e_ij 设置为一个非常小的负数 (如负无穷大)。
    • 这样,在 softmax 计算后,这些未来位置的注意力权重 alpha_ij 会趋近于零。讲者解释道:“当对包含负无穷的得分进行softmax时,负无穷会映射为零,因此未来词的注意力权重为零。”
    • 这使得模型在并行计算整个序列的注意力的同时,能够确保每个位置的表示仅依赖于当前和之前的位置。
    • 通常在解码器中使用,编码器中通常不需要(允许双向信息流)。

最小自注意力构建模块总结:
1. 输入嵌入 + 位置编码
2. 自注意力机制 (计算 Q, K, V, 得分, 权重, 输出)
3. (可选) 掩码机制 (用于解码等任务)
4. 逐位置前馈神经网络

这个模块可以堆叠多次,形成深度网络。

Transformer 模型详解

讲座指出,之前介绍的“最小自注意力模块”并非实际中性能最佳的方案。Transformer 模型在此基础上引入了更多关键细节。

Transformer 解码器 (Decoder)

Transformer 解码器用于语言模型等任务,其核心组件包括:

  1. 掩码多头自注意力 (Masked Multi-Head Self-Attention):

    • 动机: 单个自注意力机制可能难以同时捕捉多种不同类型的依赖关系。例如,一个词可能需要基于语义相似性关注某些词,同时基于句法结构关注另一些词。
    • 多头机制:
      • 将原始的查询、键、值向量分别投影到 H 个不同的、更低维度的子空间中(每个子空间的维度是 d_model / H)。
      • 在每个子空间(即每个“头”)内独立地执行自注意力计算(带掩码)。
      • H 个头的输出拼接起来。
      • 通过一个最终的线性变换层 (W_o) 将拼接后的结果融合。
    • 讲者强调:“每个头可以关注不同的事物,并以不同的方式构建其值向量。”
    • 实现: 通过对 Q, K, V 矩阵进行变形 (reshape) 来高效实现,计算成本并不会显著高于单头注意力。
    • 效果: 允许模型从不同角度、不同表示子空间关注信息。实践中,不同的头倾向于学习关注不同的模式。尽管没有显式保证,但它们倾向于自发地专业化。
  2. 缩放点积注意力 (Scaled Dot-Product Attention):

    • 问题: 当键向量的维度 d_k (即 d_model / H) 较大时,点积 q^T * k 的结果可能会变得很大,导致 softmax 函数进入梯度饱和区,使得梯度非常小,不利于学习。
    • 解决方案: 在计算 softmax 之前,将点积结果除以 sqrt(d_k)
      • Attention(Q, K, V) = softmax( (QK^T) / sqrt(d_k) ) * V
    • 这有助于在初始化时保持注意力权重的平滑分布。
  3. 残差连接 (Residual Connections) 与层归一化 (Layer Normalization) (合称 "Add & Norm"):

    • 在每个子层(如多头注意力层、前馈网络层)的输出端应用。
    • 残差连接: 将子层的输入 x 加到其输出 SubLayer(x) 上,即 x + SubLayer(x)
      • 极大地帮助了深度网络的训练,缓解梯度消失问题,使网络更容易学习恒等映射。讲者解释说,通过残差连接,梯度可以直接传播,“因为它是恒等映射,所以梯度为1”,这非常有利于训练。
    • 层归一化: 对每个样本的每个词的表示向量(在 d_model 维度上)进行归一化,使其均值为0,标准差为1。然后通过可学习的缩放参数 gamma 和偏移参数 beta 进行调整。
      • LayerNorm(x) = gamma * ( (x - mean(x)) / sqrt(std(x)^2 + epsilon) ) + beta
      • 有助于稳定训练过程,减少层间协方差偏移。
      • 注意: 层归一化是针对单个词向量的维度进行的,不跨序列中的词,也不跨批次中的样本。

Transformer 解码器模块 (Block) 结构:
一个解码器模块通常包含以下顺序操作:
1. 掩码多头自注意力 (Masked Multi-Head Self-Attention)
2. Add & Norm (残差连接 + 层归一化)
3. 逐位置前馈神经网络 (FFN)
4. Add & Norm (残差连接 + 层归一化)
这样的模块会重复堆叠 N 次。

针对模型如何处理可变长度输入的问题,讲座解释,输入通常会被填充 (pad) 到一个固定的最大长度。在注意力计算中,可以通过掩码机制忽略这些填充标记的贡献,将对应位置的注意力得分设为负无穷大。

Transformer 编码器 (Encoder)

  • 结构与解码器模块非常相似。
  • 主要区别: 编码器中的多头自注意力层是非掩码的 (unmasked),允许每个位置关注序列中的所有其他位置(双向上下文)。

Transformer 编码器-解码器 (Encoder-Decoder) 架构

这是原始 "Attention Is All You Need" 论文中提出的完整 Transformer 架构,常用于机器翻译等序列到序列任务。

  • 编码器 (Encoder):

    • N 个编码器模块堆叠而成。
    • 处理输入源序列(例如,待翻译的句子)。
    • 其最终输出是一系列上下文感知的词表示。
  • 解码器 (Decoder):

    • N 个解码器模块堆叠而成。
    • 生成目标序列(例如,翻译后的句子)。
    • 解码器模块与之前描述的略有不同,它包含两个多头注意力子层:
      1. 掩码多头自注意力层 (Masked Multi-Head Self-Attention): 对解码器自身已生成的部分序列进行自注意力计算(与独立解码器中的一样)。
      2. 编码器-解码器注意力层 (Encoder-Decoder Attention / Cross-Attention):
        • 查询 (Queries) 来自前一个解码器子层(即掩码自注意力层)的输出。
        • 键 (Keys) 和 值 (Values) 来自编码器的最终输出
        • 这一层允许解码器在生成每个目标词时,关注源序列中的相关部分。
        • 这一层是非掩码的,因为解码器可以关注源序列的任何部分。
      3. 逐位置前馈神经网络 (FFN)。
    • 每个子层(两个注意力层和 FFN)之后都跟着一个 "Add & Norm" 操作。

Transformer 的卓越成果

  • 机器翻译: 原始 Transformer 论文在机器翻译任务上取得了优异成绩。虽然不一定比当时最好的系统有惊人的提升,但其训练效率显著更高,因为它能更好地利用并行计算,处理更多数据,并充分利用GPU。
  • 预训练模型的基石: Transformer 的并行性和效率使其能够处理海量数据进行预训练,催生了 BERT、GPT 等一系列强大的预训练语言模型。
  • 广泛应用: 在各种自然语言处理基准测试中,基于 Transformer 的模型迅速成为主流,并在文档生成、摘要、问答等多种任务上取得了顶尖 (State-of-the-Art) 结果。讲者总结道:“这种利用海量数据和计算资源的能力,使得Transformer在几乎所有现代自然语言处理的进展中都遥遥领先于LSTM。”

Transformer 的不足与变体

  1. 二次方计算复杂度 (Quadratic Compute Problem):

    • 自注意力机制需要计算序列中所有词对之间的交互,导致计算量和内存消耗随序列长度 NO(N^2 * d_model) 增长(d_model为模型维度)。
    • 这限制了 Transformer 处理非常长序列(如整本书或长篇文档)的能力。讲者举例说明,如果序列长度达到如50000,N平方项将变得巨大,使得计算完全不可行。相比之下,RNN 的复杂度通常认为是 O(N * d_model^2)
    • 许多研究工作致力于降低这种复杂度(例如,稀疏注意力、线性化注意力),但讲座提到,对于像 GPT-3 这样的大模型,自注意力部分可能已不是主要的计算瓶颈,这是否仍是必要的研究方向是一个开放问题。
  2. 位置表示: 绝对位置编码可能不是最优的,相对位置编码等变体被提出。

  3. 模型变体: 过去几年中出现了大量 Transformer 的变体,但讲座认为,原始 Transformer 加上一些小的修改(如改变 FFN 中的非线性激活函数)仍然非常强大且具有持久力。

结论与展望

  • Transformer 架构,特别是其自注意力机制,已经成为现代自然语言处理领域的基础。
  • 尽管存在计算复杂度等问题,但其并行性和强大的表示能力使其在各种任务中取得了巨大成功。
  • 未来的讲座将讨论预训练技术。
  • 提醒学生关注作业四的截止日期和最终项目提案的发布。