1. 理解Padding Mask的核心作用
在Transformer架构中,处理变长输入序列是个常见需求。想象你正在批处理10个句子,最长的有50个词,最短的只有12个词。为了能并行计算,我们需要将所有句子填充(padding)到相同长度——这就是Padding的由来。但填充的token(通常是0)不应该参与注意力计算,否则会影响模型对真实语义的理解。
Padding Mask的本质是一个二进制张量,形状与输入序列相同。真实token位置为0,填充位置为1。在计算注意力权重时,这些mask位置会被加上一个极大的负值(如-1e9),使得经过softmax后的注意力权重趋近于0。这种操作确保了:
- 计算效率:避免了为每个样本单独处理的开销
- 数学正确性:防止填充位置影响梯度计算
- 语义完整性:确保模型只关注真实有效的token
关键细节:在多头注意力中,mask需要广播到所有注意力头。PyTorch中的实现通常用
masked_fill方法:
python复制attention_scores = attention_scores.masked_fill(mask == 1, -1e9)
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 实现Padding Mask的三种典型场景
2.1 序列建模中的静态Mask
处理NLP任务时,通常在数据预处理阶段就确定mask。假设我们有以下两个句子:
code复制["Hello", "world", "<pad>", "<pad>"]
["I", "love", "deep", "learning"]
对应的mask矩阵为:
python复制[[0, 0, 1, 1],
[0, 0, 0, 0]]
这种静态mask适用于大多数文本分类、序列标注任务。实现要点:
- 需要预先知道最大序列长度
- 通常在DataLoader中完成mask生成
- 对于超过最大长度的序列需要截断
2.2 动态长度输入的实时Mask
在对话系统等场景中,输入长度可能实时变化。这时需要:
- 记录每个样本的实际长度
- 在模型前向传播时动态生成mask
python复制def create_mask(seq_len, max_len):
mask = torch.ones(max_len)
