В рамках выпуска 🤗 Tokenizers 0.9 еще никогда не было так просто создавать чрезвычайно быстрые и универсальные токенизаторы для вашей следующей задачи NLP.

Нет лучшего способа продемонстрировать новые возможности токенизаторов, чем создать токенизатор Bert с нуля.

Токенизатор

Во-первых, давайте установим последнюю версию пакета на момент написания этой статьи:

pip install tokenizers===0.9

BERT использует WordPiece, поэтому мы создаем новый экземпляр Tokenizer с помощью этой модели:

from tokenizers import Tokenizer
from tokenizers.models import WordPiece

bert_tokenizer = Tokenizer(WordPiece())

Затем мы знаем, что BERT предварительно обрабатывает тексты, удаляя диакритические знаки и строчные буквы. Мы также используем нормализатор юникода:

from tokenizers import normalizers
from tokenizers.normalizers import Lowercase, NFD, StripAccents

bert_tokenizer.normalizer = normalizers.Sequence([NFD(), Lowercase(), StripAccents()])

Пре-токенизатор просто разделяет пробелы и знаки препинания:

from tokenizers.pre_tokenizers import Whitespace

bert_tokenizer.pre_tokenizer = Whitespace()

А постобработка использует шаблон, который мы видели в предыдущем разделе:

from tokenizers.processors import TemplateProcessing

bert_tokenizer.post_processor = TemplateProcessing(
    single="[CLS] $A [SEP]",
    pair="[CLS] $A [SEP] $B:1 [SEP]:1",
    special_tokens=[
        ("[CLS]", 1),
        ("[SEP]", 2),
    ],
)

Мы можем использовать этот токенизатор и тренироваться на нем на викитексте, как в Кратком туре:

from tokenizers.trainers import WordPieceTrainer

trainer = WordPieceTrainer(
    vocab_size=30522, special_tokens=["[UNK]", "[CLS]", "[SEP]", "[PAD]", "[MASK]"]
)
files = [f"data/wikitext-103-raw/wiki.{split}.raw" for split in ["test", "train", "valid"]]
bert_tokenizer.train(trainer, files)

model_files = bert_tokenizer.model.save("data", "bert-wiki")
bert_tokenizer.model = WordPiece.from_file(*model_files, unk_token="[UNK]")

bert_tokenizer.save("data/bert-wiki.json")

Теперь, когда токенизатор BERT настроен и обучен токенизатору BERT, мы можем загрузить его с помощью:

from tokenizers import Tokenizer

bert_tokenizer = Tokenizer.from_file("data/tokenizer-wiki.json")

Расшифровка

Помимо кодирования входных текстов, Tokenizer также имеет API для декодирования, который преобразует идентификаторы, сгенерированные вашей моделью, обратно в текст. Это делается методами decode() (для одного прогнозируемого текста) и decode_batch() (для пакета прогнозов).

Декодер сначала преобразует идентификаторы обратно в токены (используя словарь токенизатора) и удалит все специальные токены, а затем соединит эти токены пробелами.

Если вы использовали модель, которая добавляла специальные символы для представления подэлементов заданного «слова» (например, "##" в WordPiece), вам потребуется настроить декодер для правильной их обработки. Если мы возьмем, например, наш предыдущий bert_tokenizer, декодирование по умолчанию даст:

output = bert_tokenizer.encode("Welcome to the 🤗 Tokenizers library.")
print(output.tokens)
# ["[CLS]", "welcome", "to", "the", "[UNK]", "tok", "##eni", "##zer", "##s", "library", ".", "[SEP]"]

bert_tokenizer.decode(output.ids)
# "welcome to the tok ##eni ##zer ##s library ."

Но, изменив его на правильный декодер, мы получим:

from tokenizers import decoders

bert_tokenizer.decoder = decoders.WordPiece()
bert_tokenizer.decode(output.ids)
# "welcome to the tokenizers library."

Ресурсы

Все заслуги принадлежат документации Hugging Face Tokenizers — для получения более подробной информации перейдите по ссылкам ниже.

Документация: https://huggingface.co/docs/tokenizers/python/latest/pipeline.html#all-together-a-bert-tokenizer-from-scratch

Colab: https://colab.research.google.com/github/tenexcoder/huggingface-tutorials/blob/main/BERT_tokenizer_from_scratch.ipynb

Суть: https://gist.github.com/tenexcoder/85b38e17a5557f0bb7c44bda4a08271d