目 录CONTENT

文章目录

为 BERT 模型训练分词器

Administrator
2025-11-19 / 0 评论 / 0 点赞 / 0 阅读 / 0 字

📢 转载信息

原文链接:https://machinelearningmastery.com/training-a-tokenizer-for-bert-models/

原文作者:Jason Brownlee


我们经常使用像BERT这样的预训练模型来完成各种自然语言处理任务。这些模型是在大型文本语料库上训练的,并且它们使用一个分词器(tokenizer)将文本转换为模型可以理解的数字格式。

对于大多数任务,使用BERT模型原始训练时使用的分词器就足够了。然而,如果你正在使用一个在特定领域(例如医学、法律或金融)的文本上训练或微调BERT模型,那么使用一个专门针对该领域训练的分词器可能会带来性能提升。

本教程将向您展示如何使用Hugging Face tokenizers库训练一个WordPiece分词器,这是BERT模型使用的算法。

训练 BERT 分词器

WordPiece 分词器

WordPiece是一种基于子词(subword)的分词算法,由Google在其BERT模型中普及。它是一种基于频率的算法,用于构建词汇表,它从字符开始,迭代地合并最常见的相邻字符对,直到达到预定的词汇表大小。

这种方法允许模型表示词汇表中未见过的单词。它通过将未知单词分解为其已知的子词单元来实现这一点。例如,如果“tokenization”不在词汇表中,但“token”、“##iza”和“##tion”在词汇表中,则可以将该单词表示为这些子词单元的序列。

Hugging Face的tokenizers库提供了一个高效的Python实现,用于训练WordPiece分词器。

步骤 1: 安装依赖项

你需要安装tokenizers库。这是由Hugging Face维护的一个高性能库,用于训练和使用分词器。

pip install tokenizers

步骤 2: 准备训练数据

训练分词器需要一个包含您希望模型理解的文本的语料库。在真实场景中,您会有一个大型文本文件(例如,数百万行)。在本例中,我们将使用一个小的示例文本。

我们将把示例文本存储在一个列表中,并将其保存到文件中。

# 示例文本数据
training_corpus = [
    "The quick brown fox jumps over the lazy dog.",
    "A lazy dog is not good for any one.",
    "The fox is quick and the dog is lazy.",
    "Quick brown fox, quick.",
    "A lazy dog.",
    "The dog is quick.",
]

# 将数据保存到文件
corpus_file = "training_data.txt"
with open(corpus_file, "w", encoding="utf-8") as f:
    for sentence in training_corpus:
        f.write(sentence + "\n")

print(f"Training data saved to {corpus_file}")

步骤 3: 训练 WordPiece 分词器

使用tokenizers.train_from_iterator函数可以从文件中训练分词器。您需要提供几个参数:

  • files: 包含训练数据的文本文件路径列表。
  • vocab_size: 词汇表的目标大小。BERT模型通常使用30000或50000。
  • min_frequency: 仅包含出现频率高于此值的子词。
  • special_tokens: 要添加到词汇表中的特殊标记,如[UNK](未知)、[CLS](分类)、[SEP](分隔符)和[PAD](填充)。

以下是训练过程的代码:

from tokenizers import Tokenizer
from tokenizers.models import WordPiece
from tokenizers.trainers import WordPieceTrainer
from tokenizers.pre_tokenizers import Whitespace

# 1. 初始化 WordPiece 模型
# 我们将使用一个基本的 WordPiece 模型
tokenizer = Tokenizer(WordPiece(unk_token="[UNK]"))

# 2. 设置预分词器 (Pre-tokenizer)
# BERT通常使用基于空格的分词
tokenizer.pre_tokenizer = Whitespace()

# 3. 设置训练器
# 使用 BERT 常见的词汇表大小和特殊标记
special_tokens = ['[UNK]', '[CLS]', '[SEP]', '[PAD]', '[MASK]']
vocab_size = 30000
min_frequency = 2

trainer = WordPieceTrainer(
    vocab_size=vocab_size,
    min_frequency=min_frequency,
    special_tokens=special_tokens
)

# 4. 训练分词器
files = [corpus_file]
print("Starting tokenizer training...")
tokenizer.train(files, trainer=trainer)
print("Tokenizer training complete.")

训练结果检查

训练完成后,检查词汇表的大小和内容。

# 检查词汇表大小
print(f"Vocabulary size: {tokenizer.get_vocab_size()}")

# 打印词汇表中的前20个标记
vocab = tokenizer.get_vocab()
print("Top 20 tokens:")
# 按频率排序(如果tokenizers库没有内置频率排序,这里只是展示部分)
# 我们通过词典的键来展示
token_list = sorted(vocab, key=vocab.get, reverse=True)
print(token_list[:20])

在本例的小数据集上,您会看到词汇表大小远小于30000,因为频率要求和数据量有限。但在大型数据集上,它将接近目标大小。

步骤 4: 使用训练好的分词器

现在分词器已经训练好了,我们可以用它来编码和解码文本。

# 1. 编码示例文本
text_to_encode = "The quick brown fox jumps over the lazy dog."
encoding = tokenizer.encode(text_to_encode)

print(f"Original Text: {text_to_encode}")
print(f"Tokens: {encoding.tokens}")
print(f"IDs: {encoding.ids}")

# 2. 解码令牌序列
decoded_text = tokenizer.decode(encoding.ids)
print(f"Decoded Text: {decoded_text}")

# 3. 检查特殊标记
print(f"[UNK] token ID: {tokenizer.token_to_id('[UNK]')}")

你会注意到,WordPiece分词器将单词分解为子词单元,尤其是那些不常见的单词(尽管在这个小例子中可能不太明显)。它会自动添加BERT所需的分隔标记(如[CLS][SEP]),但请注意,为了完全模拟BERT的工作方式,您可能需要手动在编码后添加这些标记,或者使用BertWordPieceTokenizer

步骤 5: 保存和加载分词器

训练完成后,您需要将分词器保存到磁盘上,以便以后在模型推理或微调时使用。

# 保存分词器
save_path = "bert_wordpiece_tokenizer.json"
tokenizer.save(save_path)
print(f"Tokenizer saved to {save_path}")

# 加载分词器 (在新的会话或脚本中)
from tokenizers import Tokenizer

loaded_tokenizer = Tokenizer.from_file(save_path)

# 测试加载的分词器
loaded_encoding = loaded_tokenizer.encode("A lazy dog is quick.")
print(f"Loaded Tokenizer Tokens: {loaded_encoding.tokens}")

使用 BertWordPieceTokenizer

如果您希望直接使用Hugging Face提供的、更贴近BERT模型的完整实现(包括BERT特定的预处理步骤,例如添加[CLS][SEP]标记),您可以使用BertWordPieceTokenizer类。这个类封装了WordPiece模型和训练器,并自动处理BERT的特定需求。

以下是如何使用它训练的示例:

from tokenizers import BertWordPieceTokenizer

# 初始化新的 BERT 分词器
tokenizer = BertWordPieceTokenizer(
    clean_text=True,
    handle_chinese_chars=False,
    strip_accents=True,
    lowercase=True,
)

# 训练器参数(与之前类似)
special_tokens = ['[UNK]', '[CLS]', '[SEP]', '[PAD]', '[MASK]']

# 训练
tokenizer.train(
    files=[corpus_file],
    vocab_size=vocab_size,
    min_frequency=min_frequency,
    special_tokens=special_tokens
)

# 编码示例(它会自动添加 [CLS] 和 [SEP])
bert_encoding = tokenizer.encode("The quick brown fox.")

print("\n--- Using BertWordPieceTokenizer ---")
print(f"Tokens: {bert_encoding.tokens}")
print(f"IDs: {bert_encoding.ids}")

# 保存
bert_tokenizer_path = "bert_tokenizer.json"
tokenizer.save_model("bert_tokenizer_model", "bert_tokenizer")
print(f"BertTokenizer saved to bert_tokenizer_model directory.")

使用BertWordPieceTokenizer时,保存模型通常是将词汇表文件(vocab.txt)和分词器配置文件(tokenizer.json)保存在一个目录中。save_model方法更适合这种格式。

总结

本教程演示了如何使用Hugging Face tokenizers库为BERT模型从头训练一个WordPiece分词器。关键步骤包括:

  1. 准备一个包含领域特定文本的语料库。
  2. 使用WordPieceTrainer配置词汇表大小和特殊标记。
  3. 调用tokenizer.train()方法进行训练。
  4. 保存生成的词汇表文件供后续使用。

通过训练自定义分词器,您可以确保您的BERT模型能够有效地处理特定数据集的词汇和结构,从而优化下游NLP任务的性能。




🚀 想要体验更好更全面的AI调用?

欢迎使用青云聚合API,约为官网价格的十分之一,支持300+全球最新模型,以及全球各种生图生视频模型,无需翻墙高速稳定,文档丰富,小白也可以简单操作。

0

评论区