从内存中训练
在快速入门中,我们看到了如何使用文本文件构建和训练分词器,但实际上我们可以使用任何 Python 迭代器。在本节中,我们将看到几种不同的分词器训练方法。
对于下面列出的所有示例,我们将使用相同的分词器和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://www.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”}。只要它提供字符串,任何东西都可以工作。
使用 🤗 数据集库
访问众多现有数据集的一种很棒的方法是使用 🤗 数据集库。有关它的更多信息,你应该查看此处的官方文档。
让我们从加载数据集开始
import datasets
dataset = datasets.load_dataset("wikitext", "wikitext-103-raw-v1", split="train+test+validation")
下一步是构建此数据集的迭代器。最简单的方法可能是使用生成器
def batch_iterator(batch_size=1000):
for i in range(0, len(dataset), batch_size):
yield dataset[i : i + batch_size]["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)
就是这样!