DataWhale 11月 Happy-LLM T3:Transformer 架构

在自然语言处理领域,Transformer架构的出现无疑是一次里程碑式的革命。作为一名NLP技术研究者,我在学习Transformer的过程中深刻体会到,理解其核心机制——注意力机制,是掌握现代大语言模型的关键。本文将带你深入理解Transformer的注意力机制,并结合代码实现,分享我的学习心得。

一、从传统神经网络到注意力机制

在深入注意力机制之前,我们先回顾深度学习的三大基础架构:

1. 全连接神经网络(FNN)

  1. 每层神经元完全连接上下层
  2. 参数量大,适合小规模数据

个人体会:就像认识新朋友时,试图记住每个人的所有细节

2. 卷积神经网络(CNN)

  1. 局部连接,参数共享
  2. 擅长捕捉局部特征

学习心得:如同先认识局部特征,再组合成整体认知

3. 循环神经网络(RNN)

  1. 专为序列数据设计
  2. 能捕捉时序信息

核心问题:无法并行计算,难以捕捉长距离依赖

二、注意力机制:Transformer

2.1 注意力机制的核心思想

我的理解:当我们阅读文章时,不会平等关注每个词,而是聚焦于关键信息

技术定义:通过计算Query与Key的相关性,为Value加权求和

三个核心变量

  • Query(查询):我们要寻找什么

  • Key(键):我们能提供什么

  • Value(值):实际返回的内容

2.2 从字典查询到注意力计算

通过一个例子理解注意力机制:

# 传统字典查询(精确匹配)
dictionary = {"apple": 10, "banana": 5, "chair": 2}
query = "apple"
result = dictionary[query]  # 返回10

# 但如果我们查询"fruit"呢?
# 注意力机制给出了解决方案:
attention_weights = {"apple": 0.6, "banana": 0.4, "chair": 0}
result = 0.6*10 + 0.4*5 + 0*2  # 返回8

从直观上讲,我们可以认为 Key 与 Query 相关性越高,则其所应该赋予的注意力权重就越大。

2.3 注意力计算公式推导

基础公式

Attention(Q, K, V) = softmax(QKᵀ/√dₖ)V
  1. 相似度计算QKᵀ 计算Query和Key的相似度

  2. 缩放处理:除以√dₖ防止梯度消失

  3. 归一化softmax转换为概率分布

  4. 加权求和:与Value相乘得到最终结果

代码实现

def attention(query, key, value, dropout=None):
    d_k = query.size(-1)
    # 计算相似度得分
    scores = torch.matmul(query, key.transpose(-2, -1)) / math.sqrt(d_k)
    # Softmax归一化
    p_attn = scores.softmax(dim=-1)
    if dropout is not None:
        p_attn = dropout(p_attn)
    # 加权求和
    return torch.matmul(p_attn, value), p_attn

心得:在实现时要注意矩阵维度的匹配,特别是转置操作的位置。

三、自注意力

3.1 自注意力 vs 普通注意力

普通注意力

  • Q来自一个序列,K、V来自另一个序列

  • 用于机器翻译等跨序列任务

自注意力

  • Q、K、V都来自同一个序列

  • 用于理解序列内部关系

# 自注意力计算
self_attention_output = attention(x, x, x)

3.2 自注意力的价值

实际案例:分析句子"I like programming because it is challenging"

通过自注意力,模型可以学习到:

  • "programming"与"challenging"的强关联

  • "it"指代"programming"

  • "because"表达的因果关系

个人体会:自注意力让模型能够建立词与词之间的关系图谱,而不仅仅是序列关系。

四、掩码自注意力

4.1 为什么需要掩码?

语言模型任务:根据历史词预测下一个词

问题:如果模型能看到未来信息,就失去了学习意义

解决方案:使用掩码遮蔽未来信息

4.2 掩码实现原理

掩码矩阵生成

# 创建上三角掩码矩阵
mask = torch.full((1, seq_len, seq_len), float("-inf"))
mask = torch.triu(mask, diagonal=1)  # 上三角部分为-inf

掩码应用

scores = scores + mask  # 未来位置分数变为-inf
scores = softmax(scores)  # -inf经过softmax变为0

可视化理解

输入序列: [A, B, C, D]
掩码矩阵:
[0, -inf, -inf, -inf]
[0,   0, -inf, -inf]  
[0,   0,    0, -inf]
[0,   0,    0,    0]

心得:掩码机制是Transformer能够并行训练的关键,也是理解GPT等自回归模型的基础。

五、多头注意力

5.1 多头注意力的动机

核心思想:单一注意力头可能只捕捉一种关系,多个头可以捕捉多种关系

类比理解:就像多人阅读同一篇文章,每个人关注的重点不同,综合起来得到更全面的理解

5. 多头注意力实现

公式表达

MultiHead(Q,K,V) = Concat(head₁,...,headₕ)Wᵒ
where headᵢ = Attention(QWᵢᵩ, KWᵢᴷ, VWᵢⱽ)

代码实现:

class MultiHeadAttention(nn.Module):
    def __init__(self, args):
        super().__init__()
        self.n_heads = args.n_heads
        self.head_dim = args.dim // args.n_heads
        
        # 参数矩阵
        self.wq = nn.Linear(args.n_embd, self.n_heads * self.head_dim)
        self.wk = nn.Linear(args.n_embd, self.n_heads * self.head_dim)  
        self.wv = nn.Linear(args.n_embd, self.n_heads * self.head_dim)
        self.wo = nn.Linear(self.n_heads * self.head_dim, args.dim)
    
    def forward(self, q, k, v):
        # 拆分多头
        xq = xq.view(bsz, seqlen, self.n_heads, self.head_dim)
        xq = xq.transpose(1, 2)  # (B, n_heads, T, head_dim)
        
        # 各头分别计算注意力
        scores = torch.matmul(xq, xk.transpose(2, 3)) / math.sqrt(self.head_dim)
        # ... 后续计算

5.3 多头注意力的优势

  1. 不同注意力头确实学习到不同模式

  2. 有的头关注语法结构,有的头关注语义关系

  3. 有的头捕捉局部依赖,有的头捕捉长距离依赖

心得:在文本分类任务中,通过可视化注意力权重,发现不同头确实关注文本的不同方面,这验证了多头设计的有效性。

六、学习心得

通过系统学习Transformer的注意力机制,我深刻认识到:注意力机制的本质是对信息的选择性聚焦,这模仿了人类的认知过程。自注意力让模型能够建立词与词之间的直接连接,突破了RNN的序列限制。掩码机制解决了训练并行性与因果关系的矛盾。多头设计提供了多角度理解文本的能力,增强了模型的表达能力。

个人感悟:学习注意力机制就像学习一种新的思维方式——不再局限于线性的、顺序的思考,而是能够建立全局的、网络化的认知。这种思维方式的转变。

 资料来源:Happy-LLM


希望这份结合理论知识与个人心得的指南,能帮助你在NLP的学习道路上少走弯路。欢迎在评论区交流你的学习体会和遇到的问题!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值