Transformer 大语言模型(LLM)基石 - Transformer架构详解 - 掩码机制(Masked)原理介绍以及算法实现

锋哥原创的Transformer 大语言模型(LLM)基石视频教程:

https://www.bilibili.com/video/BV1X92pBqEhV

课程介绍

本课程主要讲解Transformer简介,Transformer架构介绍,Transformer架构详解,包括输入层,位置编码,多头注意力机制,前馈神经网络,编码器层,解码器层,输出层,以及Transformer Pytorch2内置实现,Transformer基于PyTorch2手写实现等知识。

Transformer 大语言模型(LLM)基石 - Transformer架构详解 - 掩码机制(Masked)原理介绍以及算法实现

在解码器中,因为在翻译的过程中是顺序翻译的,即翻译完第 i 个单词,才可以翻译第 i+1 个单词。通过 Masked 操作可以防止泄露未来的信息 。

Transformer中的掩码机制主要有两种:一种是用于处理变长序列的填充掩码(Padding Mask),另一种是用于防止未来信息泄露的序列掩码(Sequence Mask,也称为因果掩码或Look-ahead Mask)。

1. 填充掩码(Padding Mask)

在自然语言处理中,为了将多个句子组成一个批次,通常会将句子填充到相同的长度。但在计算注意力时,我们不希望模型关注这些填充的位置。因此,我们需要一个掩码来告诉模型哪些位置是填充的,从而在计算注意力时忽略这些位置。

实现方式:对于填充的位置,将其对应的注意力分数设置为一个极小的值(如-1e9),这样在softmax之后,这些位置的权重就会接近于0。

2. 序列掩码(Sequence Mask / Causal Mask)

在Transformer的解码器中,为了确保在训练时不会使用未来的信息,我们需要使用序列掩码。具体来说,对于序列中的第i个位置,我们只能关注到1到i的位置,而不能关注i+1及之后的位置。这种掩码通常用于自回归模型,如GPT。

实现方式:生成一个上三角矩阵(对角线为0),将上三角部分(即未来位置)设置为一个极小的值,这样在计算softmax时,未来位置的权重就会接近于0。

代码实现:

复制代码
import numpy as np
import torch


def create_sequence_mask(seq_len):
    """
    创建序列掩码(下三角矩阵)
    """
    mask = np.triu(np.ones((1, seq_len, seq_len), dtype=np.uint8), k=1)
    return torch.from_numpy(1 - mask)


if __name__ == '__main__':
    scores = torch.tensor([[[1, 2, 3], [4, 5, 6], [7, 8, 9]]])
    print(scores)
    mask = create_sequence_mask(3)
    scores = scores.masked_fill(mask == 0, -1e9)
    print(scores)

运行输出:

复制代码
tensor([[[1, 2, 3],
         [4, 5, 6],
         [7, 8, 9]]])
tensor([[[          1, -1000000000, -1000000000],
         [          4,           5, -1000000000],
         [          7,           8,           9]]])

np.triu() 是 NumPy 中一个非常常用的函数,用于返回矩阵的上三角部分(upper triangular part),常在矩阵运算、线性代数、神经网络权重掩码等场景中使用

函数定义:

复制代码
numpy.triu(m, k=0)

参数说明:

  • m:array_like 输入矩阵(可以是二维数组或更高维张量)。

  • k

    :int,可选,默认 0

    控制"对角线的偏移量"。

    • k = 0 → 主对角线及其以上的元素保留;

    • k > 0 → 主对角线上方第 k 条对角线及其以上的元素保留;

    • k < 0 → 主对角线以下第 |k| 条对角线也会被保留下来。

具体示例:

复制代码
import numpy as np
​
if __name__ == '__main__':
    print('k=0\n', np.triu([
        [1, 1, 1, 1],
        [1, 1, 1, 1],
        [1, 1, 1, 1],
        [1, 1, 1, 1]
    ], k=0))
​
    print('\nk=1\n', np.triu([
        [1, 1, 1, 1],
        [1, 1, 1, 1],
        [1, 1, 1, 1],
        [1, 1, 1, 1]
    ], k=1))
​
    print('\nk=-1\n', np.triu([
        [1, 1, 1, 1],
        [1, 1, 1, 1],
        [1, 1, 1, 1],
        [1, 1, 1, 1]
    ], k=-1))

运行输出:

复制代码
k=0
 [[1 1 1 1]
 [0 1 1 1]
 [0 0 1 1]
 [0 0 0 1]]
​
k=1
 [[0 1 1 1]
 [0 0 1 1]
 [0 0 0 1]
 [0 0 0 0]]
​
k=-1
 [[1 1 1 1]
 [1 1 1 1]
 [0 1 1 1]
 [0 0 1 1]]

NumPy 广播机制(Broadcasting)

广播(Broadcasting)是NumPy中处理不同形状数组进行算术运算的核心机制。它允许NumPy在执行逐元素操作时自动扩展较小数组的形状,使其与较大数组的形状兼容,而无需实际复制数据。

一、广播的基本规则

NumPy广播遵循三个核心规则:

  1. 规则1:如果两个数组的维度数不同,将维度较小的数组形状前面补1

  2. 规则2:对于每个维度,大小必须相等,或其中一个为1

  3. 规则3:所有维度大小都兼容后,在大小为1的维度上进行数据"复制"

二、广播示例

示例1:标量与数组的运算

复制代码
import numpy as np
​
# 标量广播到整个数组
a = np.array([1, 2, 3])
b = 5
result = a + b  # b被广播为[5, 5, 5]
print(result)  # 输出: [6, 7, 8]
​
# 相当于
# a.shape = (3,)
# b.shape = () -> 补1 -> (1,) -> 扩展为(3,)

示例2:一维数组与二维数组

复制代码
# 一维数组在列方向广播
a = np.array([[1, 2, 3],  # shape: (2, 3)
              [4, 5, 6]])
b = np.array([10, 20, 30])  # shape: (3,)
​
result = a + b
# b广播为: [[10, 20, 30],
#          [10, 20, 30]]
print(result)
# 输出: [[11, 22, 33],
#       [14, 25, 36]]
相关推荐
李小星同志4 小时前
DPO,PPO,GRPO的学习
人工智能·深度学习·学习
范男4 小时前
Qwen3-VL + LLama-Factory进行针对Grounding任务LoRA微调
人工智能·深度学习·计算机视觉·transformer·llama
金融小师妹5 小时前
美联储议息夜:基于多智能体决策分歧模型的“鹰派降息”推演
人工智能·深度学习·1024程序员节
Study9967 小时前
科普专栏|大语言模型:理解与生成语言的人工智能
人工智能·深度学习·机器学习·大模型·agent·大模型微调·大模型应用开发
森诺Alyson7 小时前
前沿技术借鉴研讨-2025.12.9(胎儿面部异常检测/超声标准平面检测/宫内生长受限)
论文阅读·人工智能·经验分享·深度学习·论文笔记
Coding茶水间8 小时前
基于深度学习的遥感地面物体检测系统演示与介绍(YOLOv12/v11/v8/v5模型+Pyqt5界面+训练代码+数据集)
图像处理·人工智能·深度学习·yolo·目标检测·计算机视觉
金融小师妹8 小时前
基于NLP政策文本分析与多智能体博弈模拟的FOMC决策推演:“美联储传声筒”下的利率路径分歧
大数据·人工智能·深度学习·1024程序员节
TracyCoder1238 小时前
机器学习与深度学习基础(三):感知机、神经网络、前向传播、反向传播
深度学习·神经网络·机器学习