具体模型方式 - 完形填空任务
1 课程概览
本课讲解 Transformers 的第三种方式:具体模型方式。具体模型方式与自动模型方式思路几乎一样,只是 API 不同。使用 BERT 系列的模型。会使用 BERT 做分词器的文本数值化,完成完形填空。只演示一个完形填空案例,因为其他五个任务思路一模一样。
2 核心概念与定义
- 具体模型方式:Transformers 的第三种方式,使用具体的模型类(如 BERT)。
- BertTokenizer:BERT 分词器。
- BertForMaskedLM:BERT 完形填空模型。
3 模型与算法详解
三种方式对比
| 方式 | API | 说明 |
|---|---|---|
| 管道 | pipeline | 最简单 |
| 自动 | Auto* | 中等,可 DIY |
| 具体模型 | Bert* | 最灵活,使用具体模型类 |
具体模型 vs 自动模型
思路几乎一样,只是 API 不同。
| 步骤 | 自动模型 | 具体模型 |
|---|---|---|
| 加载分词器 | AutoTokenizer.from_pretrained() | BertTokenizer.from_pretrained() |
| 加载模型 | AutoModel.from_pretrained() | BertForMaskedLM.from_pretrained() |
| 文本转张量 | encode_plus() | encode_plus() |
| 送给模型 | my_model(**inputs) | my_model(**inputs) |
完形填空流程
0. 定义变量记录模型名
1. 加载 Tokenizer(BertTokenizer)
2. 加载模型(BertForMaskedLM)
3. 文本转张量
4. 送给模型
5. 输出结果
模型选择
使用 Chinese BERT WWM 模型。
| 任务 | 模型 |
|---|---|
| 完形填空 | chinese-bert-wwm |
导包
使用具体的 BERT 类,而不是 Auto 类。
from transformers import BertTokenizer, BertForMaskedLM
4 数学原理与推导
完形填空
$$P(w_{\text{mask}}) = \text{BERT}(\text{input_ids}, \text{attention_mask})$$
其中:
- $\text{input_ids}$ 包含 <tool_call> 的 id
- $w_{\text{mask}}$ 是预测的词
文本转张量
$$\text{input} = \text{BertTokenizer}.\text{encode_plus}(\text{text}, \text{return_tensors}='pt')$$
5 代码示例
import torch
from transformers import BertForMaskedLM, BertTokenizer
def dm01_fill_mask():
"""具体模型方式:完形填空"""
# 0. 定义变量记录模型名
model_name = "C:/software/softwallg/pretrained_model/chinese-bert-wwm"
# 1. 加载 Tokenizer(使用 BertTokenizer)
my_tokenizer = BertTokenizer.from_pretrained(model_name)
# 2. 加载模型(使用 BertForMaskedLM)
my_model = BertForMaskedLM.from_pretrained(model_name)
# 3. 文本转张量
text = "我想明天去<tool_call>家吃饭"
inputs = my_tokenizer.encode_plus(
text,
return_tensors='pt'
)
print(f"输入文本: {text}")
print(f"输入张量: {inputs}")
# 4. 送给模型
my_model.eval()
with torch.no_grad():
output = my_model(**inputs)
# 5. 输出结果
logits = output.logits
# 找到 <tool_call> 的位置
mask_token_index = (inputs['input_ids'][0] == my_tokenizer.mask_token_id).nonzero(as_tuple=True)[0]
# 取概率最高的 5 个词
top_5 = torch.topk(logits[0, mask_token_index], 5)
print(f"\n预测结果:")
for score, token_id in zip(top_5.values[0], top_5.indices[0]):
token = my_tokenizer.convert_ids_to_tokens([token_id.item()])[0]
print(f" {token}: {score.item():.4f}")
return my_model
# 测试
if __name__ == "__main__":
print("=== 具体模型方式:完形填空 ===")
model = dm01_fill_mask()
代码说明
| 代码 | 说明 |
|---|---|
BertTokenizer.from_pretrained() | 加载 BERT 分词器 |
BertForMaskedLM.from_pretrained() | 加载 BERT 完形填空模型 |
my_tokenizer.mask_token_id | <tool_call> 的 id |
torch.topk(logits, 5) | 取概率最高的 5 个词 |
convert_ids_to_tokens() | 将 id 转成 token |
6 重难点与易错提醒
- ❗重点:具体模型方式与自动模型方式思路几乎一样,只是 API 不同。
- ❗重点:使用
BertTokenizer和BertForMaskedLM。 - ❗重点:除了第三方库和调用方式稍有不同,其他都一模一样。
- ⚠️易错:偷懒可以直接把 Auto 替换成 Bert。
- 💡技巧:只演示一个案例,因为其他五个任务思路一模一样。
7 课堂问答精选
Q1:具体模型方式和自动模型方式有什么区别?
A:思路几乎一样,只是 API 不同。具体模型使用具体的模型类(如 BertTokenizer、BertForMaskedLM),自动模型使用 Auto 类(如 AutoTokenizer、AutoModel)。
Q2:为什么只演示一个完形填空案例?
A:因为其他五个任务思路一模一样,只是 API 不同。掌握一个就能举一反三。
Q3:如何从自动模型代码改成具体模型代码?
A:偷懒可以直接把 Auto 替换成 Bert。如 AutoTokenizer → BertTokenizer,AutoModel → BertForMaskedLM。
Q4:具体模型方式使用什么类?
A:完形填空使用 BertTokenizer(分词器)和 BertForMaskedLM(模型)。
8 本课小结
- 具体模型方式:Transformers 的第三种方式,使用具体的模型类。
- 与自动模型方式思路几乎一样,只是 API 不同。
- 使用
BertTokenizer和BertForMaskedLM。 - 偷懒可以直接把 Auto 替换成 Bert。
- 只演示一个案例,因为其他五个任务思路一模一样。
9 延伸思考
- 迁移学习如何应用于中文分类案例?
- 数据加载和预处理如何进行?