共计 1686 个字符,预计需要花费 5 分钟才能阅读完成。
语言模型基础与 MLM 的革新
传统语言模型(如 n -gram 或 RNN)通过预测下一个词来学习语言规律,这种单向建模限制了上下文信息的利用。BERT 提出的掩码语言模型 (MLM) 则采用双向训练方式:随机遮盖输入文本中的部分词汇(称为 ” 掩码 ”),让模型通过上下文预测被遮盖的词。这种创新使模型能同时学习前后文信息,显著提升了语义理解能力。

15% 掩码策略的技术内幕
BERT 选择 15% 的词进行掩码处理,这个比例经过严格实验验证:
- 比例选择依据:过低会导致训练效率低下,过高则破坏句子结构。15% 在英语和中文语料中均表现稳定
- 80-10-10 策略:
- 80% 概率替换为特殊标记
[MASK] - 10% 概率随机替换为词典中其他词
- 10% 概率保留原词不变
这种设计巧妙解决了预训练 - 微调时的数据分布差异问题(微调时没有 [MASK] 标记)。随机替换帮助模型增强抗噪声能力,保留原词则维持部分原始分布。
PyTorch 实现核心代码
import torch
import random
# 假设 vocab_size=30522,特殊标记定义
MASK_ID = 103
RANDOM_WORD_PROB = 0.1
KEEP_WORD_PROB = 0.1
def create_masked_input(input_ids, mask_prob=0.15):
"""
实现 BERT 的 15% 掩码策略
:param input_ids: 原始 token id 序列 [batch_size, seq_len]
:return: (掩码后的输入, 真实标签)
"""
labels = input_ids.clone()
# 生成掩码位置矩阵(15% 概率)
prob_matrix = torch.full(labels.shape, mask_prob)
masked_indices = torch.bernoulli(prob_matrix).bool()
# 80% 替换为[MASK]
mask_token_prob = torch.full(labels.shape, 0.8)
mask_tokens = masked_indices & (torch.bernoulli(mask_token_prob).bool())
input_ids[mask_tokens] = MASK_ID
# 10% 随机替换
random_token_prob = torch.full(labels.shape, RANDOM_WORD_PROB/0.15)
random_tokens = masked_indices & (torch.bernoulli(random_token_prob).bool())
random_words = torch.randint(0, vocab_size, labels.shape)
input_ids[random_tokens] = random_words[random_tokens]
# 剩余 10% 保持原词(无需操作)
return input_ids, labels
策略优势与局限分析
核心优势
- 上下文双向建模:相比 GPT 等自回归模型,MLM 能同时利用左右上下文
- 鲁棒性增强:随机替换使模型对输入噪声更健壮
- 迁移学习友好:预训练目标与下游任务(如文本分类)高度兼容
潜在局限
- 训练效率:每批次只有 15% 的 token 产生有效梯度
- 长文本处理:对超过 512token 的文档需要特殊处理
- 低频词挑战:罕见词可能因随机替换被错误强化
最佳实践指南
- 比例调整建议:
- 专业领域文本可降低至 10%
- 社交媒体等噪声数据可提升至 20%
- 低频词处理:
- 对稀有词采用动态掩码概率
- 添加子词 (subword) 级别的掩码
- 多语言适配:
- 黏着语 (如日语) 需调整 n -gram 掩码
- 形态丰富语言 (如俄语) 建议结合词干分析
延伸思考
- 如果提高到 30% 掩码比例,模型会如何表现?为什么?
- 如何处理中文中常见的未登录词 (OOV) 问题?
- 对比 MLM 和 ELECTRA 的替换 token 检测 (RTD) 目标,各有什么优劣?
通过本文的代码示例和技术解析,相信您已经掌握 BERT 预训练的核心机制。建议在实践中尝试调整掩码策略,观察对不同类型 NLP 任务的影响。记住,没有放之四海皆准的超参数,关键是根据数据特性找到最佳平衡点。
正文完
发表至: 未分类
近两天内
