当前位置: 首页 > 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.cnnetsun.cn/news/2732523.html

相关文章:

  • 今天不部署AI举报联动,明天就进网信办整改清单:2024Q3智能举报接入倒计时启动
  • OpenAI时隔六年重返机器人赛道,以大模型优势重塑行业研发模式?
  • 3种高效日志分析方法:开源工具glogg实战指南
  • XAutoDaily:重新定义QQ自动化签到的智能解决方案
  • 手把手教你用Wireshark配合CANoe做车载以太网诊断(当TCP/IP Stack选‘用系统网卡’时)
  • 从考研真题看差异:数学专业‘数分’ vs 工科‘高数’,备考重点和刷题策略全解析
  • FunASR不只是ASR:手把手教你用它的VAD和标点恢复,让语音转文字结果更专业
  • 基于ESP32与Node.js的物联网远程控制系统:从HTTP轮询到家居自动化
  • KMS智能激活脚本:5分钟解决Windows和Office激活难题
  • Crystal项目:基于推测性分析的代码冲突早期预警系统解析
  • 如何用5个步骤彻底解决AMD Ryzen性能瓶颈问题?SMUDebugTool完整指南
  • 终极歌词同步体验:LyricsX macOS歌词工具完整配置指南
  • 终极指南:如何使用Ludusavi免费备份你的PC游戏存档,彻底告别进度丢失!
  • 保姆级教程:用Docker Compose一键部署WVP-Pro+ZLMediaKit+Assist监控平台(附配置文件)
  • 2026 郑州高性价比化妆品柜推荐:5 家主流服务商解析
  • 使用 hionic 将 Web 应用部署到鸿蒙PC平台
  • 告别Vitis Classic!在Windows 10上从零配置Vitis HLS 2023.2新IDE(含OpenCV 4.4.0与Vitis Vision库避坑指南)
  • FastAPI 分层架构深度解析:从 Controller 到 Service 与 CRUD 层
  • 数智化浪潮下,国产 PLM 的突围之路 —— 璞华易研 PLM 的行业地位与价值实践
  • Luyten深度解析:基于Procyon的Java反编译GUI实战指南
  • 告别纸上谈兵:用Python模拟Torus与Mesh网络,直观对比延迟与负载平衡
  • DRIFT Search:动态推理检索技术,让RAG应用既见树木又见森林
  • 错过这轮整合,你的AI投入将归零:2024Q3前必须完成的6个智能成就校准动作
  • 基于ESP8266与MAX7219的物联网LED点阵屏远程控制系统
  • DIY门铃辅助开关:用低成本工程实践实现包容性设计
  • 【2026最新】Adobe Animate动画神器:2D动画轻松拿捏!
  • 虚幻引擎是什么?用来做什么?
  • 避坑指南:EISeg安装时遇到的cv2.dnn报错和模型闪退,我是这样解决的
  • 如何用Mousecape在5分钟内彻底改变你的macOS鼠标指针
  • 摩托罗拉GP300/GP88等老款对讲机写频工具包,含亚音、功率、信道等完整参数设置功能