分词器文档
从内存中训练
并获得增强的文档体验
开始使用
从内存中训练
在快速入门中,我们看到了如何使用文本文件构建和训练一个分词器,但实际上我们可以使用任何 Python 迭代器。在本节中,我们将看到几种不同的训练分词器的方法。
对于下面列出的所有示例,我们将使用相同的 Tokenizer 和 Trainer
,构建方式如下:
from tokenizers import Tokenizer, decoders, models, normalizers, pre_tokenizers, trainers
tokenizer = Tokenizer(models.Unigram())
tokenizer.normalizer = normalizers.NFKC()
tokenizer.pre_tokenizer = pre_tokenizers.ByteLevel()
tokenizer.decoder = decoders.ByteLevel()
trainer = trainers.UnigramTrainer(
vocab_size=20000,
initial_alphabet=pre_tokenizers.ByteLevel.alphabet(),
special_tokens=["<PAD>", "<BOS>", "<EOS>"],
)
此分词器基于 Unigram 模型。它使用 NFKC Unicode 规范化方法对输入进行规范化处理,并使用 ByteLevel 预分词器以及相应的解码器。
有关此处使用的组件的更多信息,可以查看这里。
最基本的方法
你可能已经猜到了,训练分词器最简单的方法是使用 List
{.interpreted-text role=“obj”}:
# First few lines of the "Zen of Python" https://pythonlang.cn/dev/peps/pep-0020/
data = [
"Beautiful is better than ugly."
"Explicit is better than implicit."
"Simple is better than complex."
"Complex is better than complicated."
"Flat is better than nested."
"Sparse is better than dense."
"Readability counts."
]
tokenizer.train_from_iterator(data, trainer=trainer)
很简单,对吧?你可以在这里使用任何可作为迭代器的对象,无论是 List
{.interpreted-text role=“obj”}、Tuple
{.interpreted-text role=“obj”} 还是 np.Array
{.interpreted-text role=“obj”}。只要它能提供字符串,任何对象都可以。
使用 🤗 Datasets 库
使用 🤗 Datasets 库是访问众多可用数据集的绝佳方式。有关更多信息,请查看此处的官方文档。
我们先加载数据集:
import datasets
dataset = datasets.load_dataset("wikitext", "wikitext-103-raw-v1", split="train+test+validation")
下一步是为这个数据集构建一个迭代器。最简单的方法可能是使用生成器:
def batch_iterator(batch_size=1000):
# Only keep the text column to avoid decoding the rest of the columns unnecessarily
tok_dataset = dataset.select_columns("text")
for batch in tok_dataset.iter(batch_size):
yield batch["text"]
正如你在这里看到的,为了提高效率,我们实际上可以提供一批用于训练的样本,而不是逐个迭代。通过这样做,我们可以期望获得与直接从文件训练时非常相似的性能。
迭代器准备好后,我们只需启动训练。为了让进度条更好看,我们可以指定数据集的总长度:
tokenizer.train_from_iterator(batch_iterator(), trainer=trainer, length=len(dataset))
就这样!
使用 gzip 文件
由于 Python 中的 gzip 文件可以用作迭代器,因此在这类文件上进行训练非常简单:
import gzip
with gzip.open("data/my-file.0.gz", "rt") as f:
tokenizer.train_from_iterator(f, trainer=trainer)
现在,如果我们想从多个 gzip 文件进行训练,也不会难多少:
files = ["data/my-file.0.gz", "data/my-file.1.gz", "data/my-file.2.gz"]
def gzip_iterator():
for path in files:
with gzip.open(path, "rt") as f:
for line in f:
yield line
tokenizer.train_from_iterator(gzip_iterator(), trainer=trainer)
大功告成!
< > 在 GitHub 上更新