Bert Pytorch 源码分析:三、Transformer块

简介: Bert Pytorch 源码分析:三、Transformer块
# PFF 层,基本相当于两个全连接
# 每个 TF 块中位于注意力层之后
class PositionwiseFeedForward(nn.Module):
    "Implements FFN equation."
    def __init__(self, d_model, d_ff, dropout=0.1):
        super(PositionwiseFeedForward, self).__init__()
    # LL1,权重矩阵尺寸 ES * FF 
        self.w_1 = nn.Linear(d_model, d_ff)
    # LL2,权重矩阵尺寸 FF * ES
        self.w_2 = nn.Linear(d_ff, d_model)
    # Dropout
        self.dropout = nn.Dropout(dropout)
    # 激活函数是 GELU
        self.activation = GELU()
    def forward(self, x):
    # 输入 -> LL1 -> GELU -> Dropout -> LL2 -> 输出
        return self.w_2(self.dropout(self.activation(self.w_1(x))))
# 处理 TF 块内的残差
class SublayerConnection(nn.Module):
    """
    A residual connection followed by a layer norm.
    Note for code simplicity the norm is first as opposed to last.
    """
    def __init__(self, size, dropout):
        super(SublayerConnection, self).__init__()
    # 层级标准化
        self.norm = LayerNorm(size)
    # Dropout
        self.dropout = nn.Dropout(dropout)
    def forward(self, x, sublayer):
        # 输入 -> LN -> 自定义层 -> Dropout -> 残差连接 -> 输出
    #  |                                    ⬆
    #  +------------------------------------+
        return x + self.dropout(sublayer(self.norm(x)))
# GELU 是 RELU 的高斯平滑近似形式
class GELU(nn.Module):
    """
    Paper Section 3.4, last paragraph notice that BERT used the GELU instead of RELU
    """
    def forward(self, x):
        return 0.5 * x * (1 + torch.tanh(math.sqrt(2 / math.pi) * (x + 0.044715 * torch.pow(x, 3))))
# 层级标准化(原理见参考文献)
class LayerNorm(nn.Module):
    "Construct a layernorm module (See citation for details)."
    def __init__(self, features, eps=1e-6):
        super(LayerNorm, self).__init__()
    # 比例参数
        self.a_2 = nn.Parameter(torch.ones(features))
    # 偏移参数
        self.b_2 = nn.Parameter(torch.zeros(features))
    # 微小值防止除零错误
        self.eps = eps
    def forward(self, x):
    # 均值和方差都是对最后一维,也就是嵌入向量计算的
    # `keepdim=True`保持维数不变
    # 输入尺寸为 BS * ML * ES,计算之后是 BS * ML * 1
        mean = x.mean(-1, keepdim=True)
        std = x.std(-1, keepdim=True)
    # 将最后一维标准化,然后乘以比例加上偏移
        return self.a_2 * (x - mean) / (std + self.eps) + self.b_2
# Transformer 块是任何 Transformer 架构的基本结构,不仅限于 BERT,
# 不同模型只是层数、头数、嵌入维度、词表、训练数据以及解码器(具体任务)不同
class TransformerBlock(nn.Module):
    """
    Bidirectional Encoder = Transformer (self-attention)
    Transformer = MultiHead_Attention + Feed_Forward with sublayer connection
    """
    def __init__(self, hidden, attn_heads, feed_forward_hidden, dropout):
        """
        :param hidden: hidden size of transformer
        :param attn_heads: head sizes of multi-head attention
        :param feed_forward_hidden: feed_forward_hidden, usually 4*hidden_size
        :param dropout: dropout rate
        """
        super().__init__()
    # 第一部分:注意力层
        self.attention = MultiHeadedAttention(h=attn_heads, d_model=hidden)
    # 第二部分:PFF 层
        self.feed_forward = PositionwiseFeedForward(d_model=hidden, d_ff=feed_forward_hidden, dropout=dropout)
    # 注意力层残差模块
        self.input_sublayer = SublayerConnection(size=hidden, dropout=dropout)
    # PFF 层的残差模块
        self.output_sublayer = SublayerConnection(size=hidden, dropout=dropout)
    # 最后的 Dropout
        self.dropout = nn.Dropout(p=dropout)
    def forward(self, x, mask):
    # 输入 -> LN1 -> 注意力层 -> DropOut1 -> 残差连接 -> ...
    #  |                                      ↑
    #  +--------------------------------------+
    # 这里的注意力层的三个输入全是`x`,但是仍然命名为 QKV,容易引起混淆
        x = self.input_sublayer(x, lambda _x: self.attention.forward(_x, _x, _x, mask=mask))
    # ... -> LN2 -> FFN -> DropOut2 -> 残差连接 -> ...
    #  |                                  ↑
    #  +----------------------------------+
        x = self.output_sublayer(x, self.feed_forward)
    # ... -> DropOut3 -> 结果
        return self.dropout(x)
相关文章
|
PyTorch 算法框架/工具
Bert Pytorch 源码分析:五、模型架构简图 REV1
Bert Pytorch 源码分析:五、模型架构简图 REV1
307 0
|
PyTorch 算法框架/工具
Bert Pytorch 源码分析:四、编解码器
Bert Pytorch 源码分析:四、编解码器
203 0
|
PyTorch 算法框架/工具
Bert Pytorch 源码分析:五、模型架构简图
Bert Pytorch 源码分析:五、模型架构简图
245 0
|
4月前
|
机器学习/深度学习 自然语言处理 PyTorch
Transformer自回归关键技术:掩码注意力原理与PyTorch完整实现
掩码注意力是生成模型的核心,通过上三角掩码限制模型仅关注当前及之前token,确保自回归因果性。相比BERT的双向注意力,它实现单向生成,是GPT等模型逐词预测的关键机制,核心仅需一步`masked_fill_`操作。
433 0
Transformer自回归关键技术:掩码注意力原理与PyTorch完整实现
|
4月前
|
机器学习/深度学习 人工智能 自然语言处理
编码器-解码器架构详解:Transformer如何在PyTorch中工作
本文深入解析Transformer架构,结合论文与PyTorch源码,详解编码器、解码器、位置编码及多头注意力机制的设计原理与实现细节,助你掌握大模型核心基础。建议点赞收藏,干货满满。
1225 3
|
3月前
|
机器学习/深度学习 自然语言处理 监控
23_Transformer架构详解:从原理到PyTorch实现
Transformer架构自2017年Google发表的论文《Attention Is All You Need》中提出以来,彻底改变了深度学习特别是自然语言处理领域的格局。在短短几年内,Transformer已成为几乎所有现代大型语言模型(LLM)的基础架构,包括BERT、GPT系列、T5等革命性模型。与传统的RNN和LSTM相比,Transformer通过自注意力机制实现了并行化训练,极大提高了模型的训练效率和性能。
|
8月前
|
PyTorch 调度 算法框架/工具
阿里云PAI-DLC任务Pytorch launch_agent Socket Timeout问题源码分析
DLC任务Pytorch launch_agent Socket Timeout问题源码分析与解决方案
435 18
阿里云PAI-DLC任务Pytorch launch_agent Socket Timeout问题源码分析
|
机器学习/深度学习 人工智能 PyTorch
Transformer模型变长序列优化:解析PyTorch上的FlashAttention2与xFormers
本文探讨了Transformer模型中变长输入序列的优化策略,旨在解决深度学习中常见的计算效率问题。文章首先介绍了批处理变长输入的技术挑战,特别是填充方法导致的资源浪费。随后,提出了多种优化技术,包括动态填充、PyTorch NestedTensors、FlashAttention2和XFormers的memory_efficient_attention。这些技术通过减少冗余计算、优化内存管理和改进计算模式,显著提升了模型的性能。实验结果显示,使用FlashAttention2和无填充策略的组合可以将步骤时间减少至323毫秒,相比未优化版本提升了约2.5倍。
680 3
Transformer模型变长序列优化:解析PyTorch上的FlashAttention2与xFormers
|
机器学习/深度学习 自然语言处理 数据建模
三种Transformer模型中的注意力机制介绍及Pytorch实现:从自注意力到因果自注意力
本文深入探讨了Transformer模型中的三种关键注意力机制:自注意力、交叉注意力和因果自注意力,这些机制是GPT-4、Llama等大型语言模型的核心。文章不仅讲解了理论概念,还通过Python和PyTorch从零开始实现这些机制,帮助读者深入理解其内部工作原理。自注意力机制通过整合上下文信息增强了输入嵌入,多头注意力则通过多个并行的注意力头捕捉不同类型的依赖关系。交叉注意力则允许模型在两个不同输入序列间传递信息,适用于机器翻译和图像描述等任务。因果自注意力确保模型在生成文本时仅考虑先前的上下文,适用于解码器风格的模型。通过本文的详细解析和代码实现,读者可以全面掌握这些机制的应用潜力。
1105 3
三种Transformer模型中的注意力机制介绍及Pytorch实现:从自注意力到因果自注意力
|
机器学习/深度学习 人工智能 自然语言处理
算法金 | 秒懂 AI - 深度学习五大模型:RNN、CNN、Transformer、BERT、GPT 简介
**RNN**,1986年提出,用于序列数据,如语言模型和语音识别,但原始模型有梯度消失问题。**LSTM**和**GRU**通过门控解决了此问题。 **CNN**,1989年引入,擅长图像处理,卷积层和池化层提取特征,经典应用包括图像分类和物体检测,如LeNet-5。 **Transformer**,2017年由Google推出,自注意力机制实现并行计算,优化了NLP效率,如机器翻译。 **BERT**,2018年Google的双向预训练模型,通过掩码语言模型改进上下文理解,适用于问答和文本分类。
926 9

热门文章

最新文章

推荐镜像

更多