当前位置: 首页 > news >正文

14 BERT 的 Masked Language Modeling 详解

现在我们单独拿出 BERT 的核心预训练任务之一来详细讲解:

Masked Language Modeling

也就是:

掩码语言模型

它通常简称为:

MLM

MLM 是 BERT 区别于 GPT 的关键。GPT 使用的是 Causal Language Modeling,也就是:

给定前文,预测下一个 token

而 BERT 使用的是 Masked Language Modeling,也就是:

遮住句子中的一部分 token,让模型根据左右上下文预测被遮住的 token

例如原句是:

我 今天 去 学校 上课

BERT 会把其中一部分 token 遮住:

我 今天 去 [MASK] 上课

然后让模型预测:

学校

这个任务看起来很简单,但它背后非常关键。因为它让 BERT 能够学习双向上下文表示。也就是说,BERT 在预测[MASK]时,不仅能看左边:

我 今天 去

还能看右边:

上课

这正是 BERT 使用 Transformer Encoder 的原因。本文我们重点讲清楚:

1. MLM 要解决什么问题? 2. MLM 和 GPT 的 CLM 有什么不同? 3. BERT 为什么不能直接像 GPT 一样预测下一个词? 4. BERT 的 15% mask 策略是什么? 5. 80% / 10% / 10% 替换规则是什么意思? 6. MLM 的 loss 到底在哪些位置计算? 7. MLM 如何用代码实现? 8. MLM 有什么优势和局限?

一、为什么 BERT 需要 MLM?

BERT 的目标是学习一种适合理解任务的语言表示。什么叫理解任务?

例如:

情感分类:这句话是正面还是负面? 语义匹配:这两个句子意思是否相同? 自然语言推理:句子 B 是否可以由句子 A 推出? 命名实体识别:每个 token 是不是人名、地名、机构名? 阅读理解:答案在文章中的哪个位置?

这些任务通常需要模型理解完整输入。

例如句子:

这个苹果手机很好用。

如果模型只看左边:

这个苹果

它可能不知道“苹果”是水果还是公司。但如果模型能看到右边:

手机很好用

就能判断这里的“苹果”指的是 Apple 公司。所以,理解任务通常需要双向上下文。而 GPT 的训练方式是从左到右预测:

这个 苹果 手机 很 好用

预测“苹果”时只能看到:

这个

不能看到右边的“手机”。这对生成任务是合理的,因为生成时确实不能偷看未来。但对理解任务来说,右侧上下文非常重要。因此,BERT 没有使用 GPT 的 CLM,而是设计了 MLM。MLM 的核心目的就是:

让模型在训练时同时利用左右上下文,学习深层双向语言表示。


二、MLM 的基本思想

MLM 的基本流程很简单:

原始句子 ↓ 随机选择一部分 token ↓ 对这些 token 做遮挡或替换 ↓ 输入 BERT Encoder ↓ 只在被选中的位置预测原始 token

例如原始句子:

我 今天 去 学校 上课

随机选中:

学校

构造输入:

我 今天 去 [MASK] 上课

模型输入的是:

我 今天 去 [MASK] 上课

模型目标是:

学校

也就是说,模型不能直接看到“学校”这个 token,但可以通过上下文推断它。

因为左边有:

我 今天 去

右边有:

上课

所以模型可以学到:

去 ___ 上课

中间很可能是:

学校 / 教室 / 培训班

这就是 MLM 的训练信号。


三、MLM 的数学形式

假设输入序列是:

从中随机选择一部分位置作为 mask 集合:

例如:

M = {3, 7, 10}

表示第 3、7、10 个 token 被选中作为预测目标。

模型看到的是被处理后的输入:

也就是部分 token 被[MASK]、随机 token 或原 token 替换后的序列。

MLM 的训练目标是:

MLM 不是对所有 token 都算 loss,而是只对被选中的 token 位置算 loss。

例如:

输入:我 今天 去 [MASK] 上课 标签:-100 -100 -100 学校 -100

这里-100表示这个位置不参与 loss 计算。真正计算 loss 的只有[MASK]位置。


四、BERT 的 15% mask 策略

BERT 并不是把所有 token 都遮住。

如果把所有 token 都遮住,模型就看不到上下文了。

例如:

[MASK] [MASK] [MASK] [MASK] [MASK]

这显然没有意义。

BERT 的做法是:

随机选择输入中 15% 的 token 作为预测目标。

例如一句话有 20 个 token,那么大约选择:

20 × 15% = 3 个 token

作为 MLM 预测目标。

举个例子:

原句: 我 今天 去 学校 上课 , 老师 讲 了 Transformer 。

随机选中 15% token 后,可能选择:

学校 Transformer

然后构造 MLM 输入,让模型预测这两个原始 token。

为什么是 15%?

可以直观理解为一种折中。

如果 mask 比例太低,训练信号太少。

如果 mask 比例太高,上下文被破坏太严重。

15% 是 BERT 论文中采用的经验设置。


五、80% / 10% / 10% 替换规则

很多人以为:

BERT 选中的 token 全部替换成[MASK]

其实不是。

BERT 对被选中的 15% token 使用了三种处理方式:

80%:替换成 [MASK] 10%:替换成随机 token 10%:保持原 token 不变

也就是说,假设某个 token 被选中作为预测目标,它不一定会变成[MASK]

例如原句:

我 今天 去 学校 上课

如果选中“学校”,那么可能有三种情况。

1. 80% 情况:替换成[MASK]

我 今天 去 [MASK] 上课

模型需要预测:

学校

这是最典型的 MLM。

2. 10% 情况:替换成随机 token

我 今天 去 苹果 上课

这里“学校”被随机替换成“苹果”。

但模型的预测目标仍然是:

学校

这会迫使模型不能只依赖表面输入,而要根据上下文判断当前位置应该是什么词。

3. 10% 情况:保持原 token 不变

我 今天 去 学校 上课

输入中仍然是“学校”。

但这个位置仍然被选中参与 MLM loss。

模型目标仍然是预测:

学校

这看起来像是模型直接看到了答案。

但这样做有一个重要作用:减少预训练和下游任务之间的不一致。


六、为什么不全部替换成[MASK]

如果所有被选中的 token 都替换成[MASK],会有一个问题:

BERT 在预训练时经常看到[MASK],但下游任务中几乎看不到[MASK]

例如情感分类输入是:

[CLS] 这部电影很好看 [SEP]

命名实体识别输入是:

小明 在 北京 上学

这些下游任务不会出现[MASK]

如果预训练时模型过度依赖[MASK]这个特殊符号,那么预训练和微调之间就会产生差异。

所以 BERT 使用 80/10/10 策略:

80% 用 [MASK] 提供明确填空任务 10% 用随机 token 增强鲁棒性 10% 保持原 token 缓解 [MASK] 不一致问题

可以这样理解:

[MASK] 替换:让模型学会根据上下文填空 随机替换:让模型学会发现不合理 token 保持不变:让模型适应真实输入分布

这就是 BERT MLM 数据构造的关键细节。


七、MLM 的输入和标签是什么样?

假设原始 token 是:

[CLS] 我 今天 去 学校 上课 [SEP]

对应 token id:

[101, 2769, 791, 1343, 2110, 677, 102]

假设选中“学校”做 MLM。

经过替换后,输入变成:

[CLS] 我 今天 去 [MASK] 上课 [SEP]

对应 input_ids:

[101, 2769, 791, 1343, 103, 677, 102]

其中103可能是[MASK]的 id。

标签 labels 是:

[-100, -100, -100, -100, 2110, -100, -100]

这里:

2110 是原始 token “学校”的 id -100 表示忽略该位置,不计算 loss

所以训练时模型只在第 5 个位置计算损失。

这种设计和 PyTorch 中的CrossEntropyLoss(ignore_index=-100)很契合。


八、MLM 和 Attention Mask 是一回事吗?

不是。

这里非常容易混淆。

BERT 中经常有两种 mask:

1. MLM mask 2. Attention mask

它们完全不是一回事。

1. MLM mask

MLM mask 是训练任务的一部分。

它决定:

哪些 token 被选中做预测目标 哪些 token 被替换成 [MASK]、随机 token 或保持不变 哪些位置计算 loss

例如:

我 今天 去 [MASK] 上课

这里[MASK]就来自 MLM 数据构造。

2. Attention mask

Attention mask 是模型计算 attention 时使用的。

它通常用于屏蔽 padding token。

例如:

我 今天 去 学校 上课 [PAD] [PAD]

其中[PAD]不是真实文本。

Attention mask 会告诉模型:

真实 token 可以关注 [PAD] 位置不要关注

所以:

类型作用
MLM mask用于构造预训练任务,决定哪些 token 要预测
Attention mask用于 attention 计算,屏蔽 padding 等无效位置

BERT 是 Encoder-only 模型,不需要 GPT 那种 causal mask。

因为 BERT 可以双向看上下文。

但 BERT 仍然需要 attention mask 来屏蔽 padding。


九、MLM 和 CLM 的区别

MLM 和 CLM 是两种不同的语言模型训练目标。

1. MLM:看左右上下文,预测被遮住 token

例如:

我 今天 去 [MASK] 上课

模型可以看到:

左边:我 今天 去 右边:上课

预测:

学校

这种方式适合 BERT,因为 BERT 使用 Encoder,可以双向建模。

2. CLM:只看左边,预测下一个 token

例如:

我 今天 去

模型只能看到左边上下文,预测:

学校

不能看到右边的:

上课

这种方式适合 GPT,因为 GPT 是自回归生成模型。

对比一下:

对比维度MLMCLM
代表模型BERTGPT
架构Encoder-onlyDecoder-only
可见上下文左右都能看只能看左边
是否使用[MASK]使用不使用
是否需要 causal mask不需要需要
适合任务理解、分类、抽取生成、对话、续写
loss 位置只在 mask 位置通常每个位置都预测下一个 token

一句话总结:

MLM 训练模型做双向理解,CLM 训练模型做自回归生成。


十、为什么 MLM 适合 Transformer Encoder?

Transformer Encoder 的 Self-Attention 是双向的。

在 Encoder 中,每个 token 都可以关注整个输入序列。

例如:

我 今天 去 [MASK] 上课

[MASK]位置可以关注:

我 今天 去 上课

因此它很适合根据完整上下文预测被遮住的 token。

如果使用 Decoder,就会有问题。

Decoder 的 causal self-attention 只能看左边。

那么[MASK]如果出现在中间,Decoder 不能自然利用右侧上下文。

所以 MLM 和 Encoder 是天然匹配的:

MLM 需要双向上下文 Encoder 提供双向 Self-Attention

这就是 BERT 使用 Encoder-only 架构的重要原因。


十一、MLM 的模型输出是什么?

BERT 输入经过多层 Transformer Encoder 后,会得到每个 token 的隐藏状态:

对于 MLM,被选中的位置会接一个预测头。这个预测头会把 hidden state 映射到词表大小:

如果词表大小是 30,000,那么每个被预测位置都会输出:

30000 个 logits

然后通过 softmax 得到每个 token 的概率。

最终模型希望真实 token 的概率尽可能高。


十二、MLM 的 loss 如何计算?

假设某个位置真实 token 是:

学校

它的 token id 是:

2110

模型在该位置输出 logits:

[词表中每个 token 的分数]

损失函数会计算:

模型给真实 token id 2110 的概率是否足够高。

如果模型认为:

学校

概率很高,loss 就小。

如果模型认为:

苹果

概率很高,loss 就大。

对于整个序列,MLM 只在被选中的位置计算 loss:

在代码中,通常使用:

CrossEntropyLoss(ignore_index=-100)

其中 labels 中不需要计算 loss 的位置设为:

-100

十三、MLM 数据构造代码示例

下面给出一个简化版 MLM 数据构造代码。

这个代码不依赖 Hugging Face,主要用于理解原理。

import random import torch def create_mlm_inputs( input_ids, vocab_size, mask_token_id, special_token_ids, mlm_probability=0.15 ): """ 构造 BERT MLM 训练样本。 参数: input_ids: List[int],原始 token ids vocab_size: 词表大小 mask_token_id: [MASK] 的 token id special_token_ids: 特殊 token 的 id 集合,例如 [CLS], [SEP], [PAD] mlm_probability: 选中 token 的比例,BERT 中通常是 15% 返回: masked_input_ids: 被处理后的输入 labels: MLM 标签,非预测位置为 -100 """ masked_input_ids = input_ids.copy() # labels 默认全是 -100,表示不计算 loss labels = [-100] * len(input_ids) for i, token_id in enumerate(input_ids): # 跳过特殊 token if token_id in special_token_ids: continue # 以 15% 概率选中该 token if random.random() < mlm_probability: # labels 记录原始 token labels[i] = token_id prob = random.random() # 80% 替换成 [MASK] if prob < 0.8: masked_input_ids[i] = mask_token_id # 10% 替换成随机 token elif prob < 0.9: masked_input_ids[i] = random.randint(0, vocab_size - 1) # 10% 保持原 token 不变 else: masked_input_ids[i] = token_id return masked_input_ids, labels # ====================== # 测试示例 # ====================== # 假设词表: # [PAD]=0, [CLS]=101, [SEP]=102, [MASK]=103 # 我=2001, 今天=2002, 去=2003, 学校=2004, 上课=2005 input_ids = [101, 2001, 2002, 2003, 2004, 2005, 102] vocab_size = 3000 mask_token_id = 103 special_token_ids = {0, 101, 102, 103} masked_input_ids, labels = create_mlm_inputs( input_ids=input_ids, vocab_size=vocab_size, mask_token_id=mask_token_id, special_token_ids=special_token_ids, mlm_probability=0.15 ) print("原始 input_ids:") print(input_ids) print("MLM 输入 masked_input_ids:") print(masked_input_ids) print("MLM 标签 labels:") print(labels)

输出可能是:

原始 input_ids: [101, 2001, 2002, 2003, 2004, 2005, 102] MLM 输入 masked_input_ids: [101, 2001, 2002, 2003, 103, 2005, 102] MLM 标签 labels: [-100, -100, -100, -100, 2004, -100, -100]

这里说明:

学校 被替换成了 [MASK] 模型输入看到的是 [MASK] 模型目标是预测原始 token 2004

也就是“学校”。


十四、MLM 模型训练代码示意

假设我们已经有一个 BERT 模型,它输出每个位置的 logits:

logits: [batch_size, seq_len, vocab_size]

labels 是:

labels: [batch_size, seq_len]

其中不需要计算 loss 的位置是-100

训练代码通常类似:

import torch import torch.nn as nn criterion = nn.CrossEntropyLoss(ignore_index=-100) # logits: [batch_size, seq_len, vocab_size] # labels: [batch_size, seq_len] loss = criterion( logits.view(-1, logits.size(-1)), labels.view(-1) )

为什么要 reshape?

因为CrossEntropyLoss需要输入形状:

[N, C]

其中:

  • (N):样本数量;

  • (C):类别数量,也就是 vocab_size。

而原始 logits 是:

[batch_size, seq_len, vocab_size]

所以要变成:

[batch_size * seq_len, vocab_size]

labels 也要从:

[batch_size, seq_len]

变成:

[batch_size * seq_len]

这样每个 token 位置就变成一个分类任务。

但是因为大多数位置 label 是-100,所以它们不会参与 loss。


十五、MLM 为什么能学习上下文表示?

MLM 强迫模型根据上下文恢复被遮住的词。

例如:

医生 给 病人 开 了 [MASK]

可能预测:

再比如:

他 把 钱 存进 了 [MASK]

可能预测:

银行

模型要完成这个任务,必须学会很多语言规律:

词和词之间的搭配关系 句法结构 语义关系 实体类型 上下文约束 常识知识

比如预测“银行”,模型要理解:

钱 存进

这些词和“银行”高度相关。

所以 MLM 不是简单填空,而是在训练模型建立上下文语义表示。

这也是为什么经过 MLM 预训练后,BERT 可以迁移到很多理解任务上。


十六、MLM 的优势

MLM 的优势主要有三点。

1. 可以利用双向上下文

这是 MLM 最大的优势。

模型预测某个位置时,可以同时使用左边和右边信息。

这非常适合语言理解。

2. 适合 Encoder-only 架构

Transformer Encoder 本身就是双向 Self-Attention。

MLM 和 Encoder 的结构天然匹配。

这使得 BERT 可以学习每个 token 的深层上下文表示。

3. 下游任务迁移效果好

BERT 经过 MLM 预训练后,可以通过微调适配很多任务。

例如:

文本分类 自然语言推理 语义匹配 命名实体识别 阅读理解

这是因为这些任务都依赖文本理解,而 MLM 正是在训练模型理解上下文。


十七、MLM 的局限

MLM 也有一些明显局限。

1. 预训练和下游任务存在[MASK]不一致

预训练时会出现[MASK]

但下游微调和真实推理时通常没有[MASK]

虽然 BERT 用 80/10/10 策略缓解了这个问题,但它仍然存在。

2. 训练效率不如 CLM

BERT 通常只选择 15% token 做预测。

也就是说,一句话中大部分 token 不参与 loss。

而 GPT 的 CLM 通常每个位置都预测下一个 token,训练信号更密集。

所以从训练效率角度看,MLM 有一定劣势。

3. 不适合直接生成长文本

BERT 学的是填空式理解,不是从左到右生成。

因此它不适合像 GPT 那样自然生成长文本。

虽然可以设计特殊方法让 BERT 做生成,但这不是它的强项。

4. 独立预测多个 mask 位置

如果一句话中有多个[MASK],BERT 通常是并行预测这些位置。

这意味着它不一定像自回归模型那样显式建模被 mask token 之间的生成依赖。

例如:

我 喜欢 [MASK] [MASK]

两个 mask 位置之间的依赖不如 CLM 那样自然逐步建模。

这也是 MLM 的一个限制。


十八、MLM 和 RoBERTa、ALBERT、ELECTRA 的关系

BERT 之后,很多模型都围绕 MLM 或其缺点做改进。

1. RoBERTa

RoBERTa 认为 BERT 训练还不够充分。

它主要改进了训练策略,例如:

更大数据 更大 batch 训练更久 去掉 NSP 动态 mask

RoBERTa 仍然使用 MLM,但对训练方式进行了优化。

2. ALBERT

ALBERT 主要解决 BERT 参数量大的问题。

它仍然使用 MLM,但通过参数共享、embedding factorization 等方式减少参数。

3. ELECTRA

ELECTRA 则对 MLM 的训练效率提出了更强的改进。

它不再只是让模型预测被 mask 的 token,而是让模型判断每个 token 是否被替换。

这个任务叫:

Replaced Token Detection

相比 MLM 只在 15% 位置计算 loss,ELECTRA 可以在所有 token 位置获得训练信号。

所以 ELECTRA 在训练效率上很有优势。

这说明:

MLM 是 BERT 的关键起点,但后续很多工作都在改进它的效率和训练方式。


十九、MLM 的直观总结

可以用一个简单例子总结 MLM。

原始文本:

我 今天 去 学校 上课

随机选中:

学校

输入模型:

我 今天 去 [MASK] 上课

目标标签:

学校

模型通过 Encoder 看完整上下文:

我 今天 去 + 上课

然后预测[MASK]位置最可能是什么词。

训练完成后,模型学到的是:

每个 token 在上下文中的语义表示

所以 BERT 可以很好地用于理解任务。

http://www.jsqmd.com/news/943625/

相关文章:

  • 5分钟快速上手:DeepL Chrome翻译插件终极指南,免费享受专业级网页翻译体验
  • Arduino超声波水位监测系统:从传感器到彩色显示的完整实现
  • OBS背景移除插件:AI虚拟绿幕技术全解析
  • Python 爬虫实战:IT之家科技资讯爬取与热点追踪分析
  • 2026年防水透气膜焊接设备与超声波焊接机采购决策全景图 - 企业名录优选推荐
  • 微软推出 Intelligent Terminal 0.1 版本:集成原生 Agent 功能,带来全新终端体验
  • 5分钟搞定Windows流媒体服务器:Nginx-RTMP-Win32终极指南 [特殊字符]
  • 基于Arduino Uno的互动解谜游戏:从硬件连接到状态机编程实践
  • 别再手动录入了!用Java+Spire.OCR 1.9.0批量提取身份证信息,附正则表达式模板
  • Joy-Con Toolkit专业配置指南:深度解析任天堂Switch手柄高级调校技术
  • 3分钟搞定B站缓存视频转换:m4s-converter让你的离线视频重获新生
  • 科技企业如何避免在研发投入中押错方向?
  • 3步完成Evernote数据永久备份:evernote-backup工具完全指南
  • 2026年上海报考健身教练指南:正规靠谱院校甄选推荐 - 品牌2026
  • 基于MPU-6050与Arduino Leonardo的DIY飞行摇杆制作指南
  • Windows风扇控制终极指南:5分钟掌握Fan Control解决散热噪音与温度问题
  • 3个实战案例带你掌握Elsa Workflows:.NET工作流引擎的终极指南
  • 微服务调用
  • 【Excel报表工程化手册】从 #N/A 到透视表失真:一套可复用的排查与提效流程 - PC修复电脑医生
  • 宇树科技冲刺A股,王兴兴十年创业路,具身智能短板待补能否突围?
  • 电动汽车充电功率跟踪精度提升:前馈与反馈控制方案对比与实践
  • 3步实现专业MDX词典制作:揭秘AutoMdxBuilder的自动化效率革命
  • KeymouseGo:终极鼠标键盘自动化工具完全指南 - 快速解放双手的智能助手
  • 如何快速实现Joy-Con手柄转换:XJoy开源方案终极指南
  • 当所有GPU都“说同一种语言”,AI会迎来怎样的爆发?
  • DIY低成本PCB蚀刻摇床:从原理到制作全解析
  • AMD MI300X部署大模型:虽遇软件困境,仍有8.6%性能提升,AI硬件格局渐趋多元
  • Pearcleaner:macOS应用彻底卸载的终极解决方案,3步告别残留文件困扰
  • 树莓派魔法相框:从硬件改造到自动化播放的完整DIY指南
  • XAutoDaily:重新定义QQ自动化签到的智能解决方案