Transformers documentation
Personalizando tokenizers
Personalizando tokenizers
Os tokenizers são desacoplados de seus vocabulários aprendidos. Isso permite que você inicialize um tokenizer vazio para treinamento ou crie um diretamente com seu próprio vocabulário. O pipeline de tokenização subjacente permanece o mesmo (normalizador, pré-tokenizador, algoritmo de tokenização), então você não precisa recriá-lo do zero.
Este guia mostra como treinar e criar um tokenizador personalizado.
Treinando um tokenizador
Um tokenizer treinável vazio substitui o vocabulário por um novo vocabulário de destino. Isso é útil para se adaptar a um novo domínio, como finanças, um idioma com poucos recursos ou código.
Crie um tokenizador vazio e carregue um conjunto de dados.
from datasets import load_dataset
from transformers import GemmaTokenizer
tokenizer = GemmaTokenizer()
dataset = load_dataset("Josephgflowers/Finance-Instruct-500k", split="train")Use o método TokenizersBackend.train_new_from_iterator() para treinar o tokenizador. Este método aceita uma função geradora para retornar blocos de texto do conjunto de dados, em vez de carregar tudo na memória de uma só vez. O argumento vocab_size define o tamanho do vocabulário dos tokenizadores.
def batch_iterator(batch_size=1000):
for i in range(0, len(dataset), batch_size):
yield dataset[i : i + batch_size]["assistant"]
trained_tokenizer = tokenizer.train_new_from_iterator(
batch_iterator(),
vocab_size=32000,
)
encoded = trained_tokenizer("The stock market rallied today.")
print(encoded["input_ids"])
[5866, 11503, 98, 5885, 8617, 13381, 30]Adicione novos tokens especiais com o argumento new_special_tokens ou use special_tokens_map para renomear os tokens especiais antigos para os novos tokens especiais.
Salve o novo tokenizer de finanças com save_pretrained() ou salve e envie para o Hub com push_to_hub(). Isso cria um arquivo tokenizer.json que captura o vocabulário recém-treinado, as regras de mesclagem e a configuração completa do pipeline.
trained_tokenizer.save_pretrained("./finance-gemma-tokenizer")
trained_tokenizer.push_to_hub("finance-gemma-tokenizer")Vocabulário personalizado
Um tokenizer vazio suporta vocabulário personalizado com os argumentos vocab e merges.
vocabé o conjunto completo de tokens que um tokenizer conhece e cada entrada mapeia um token para seu id de entrada.mergesdefine como o algoritmo BPE deve combinar tokens adjacentes.
from transformers import GemmaTokenizer
vocab={
"<pad>": 0,
"</s>": 1,
"<s>": 2,
"<unk>": 3,
"<mask>": 4,
"▁the": 5,
"▁stock": 6,
"▁market": 7,
"▁": 8,
"r": 9,
"a": 10,
"l": 11,
"i": 12,
"e": 13,
"d": 14,
"ra": 15,
"li": 16,
"lie": 17,
"lied": 18,
"ral": 19,
"ralli": 20,
"rallie": 21,
"rallied": 22,
}
merges=[
("r", "a"), # r + a → ra
("l", "i"), # l + i → li
("li", "e"), # li + e → lie
("lie", "d"), # lie + d → lied
("ra", "l"), # ra + l → ral
("ral", "li"), # ral + li → ralli
("ralli", "e"), # ralli + e → rallie
("rallie", "d"), # rallie + d → rallied
]
tokenizer = GemmaTokenizer(vocab=vocab, merges=merges)
encoded = tokenizer("the stock market rallied")
print(encoded["input_ids"])Subclassing de TokenizersBackend
Tokenizers suporta quatro backends diferentes. Em geral, você deve usar o TokenizersBackend para definir um novo tokenizer, pois ele é mais rápido.
O PythonBackend é um tokenizador em Python puro que não depende de backends como Rust, SentencePiece ou mistral-common. Você deve usar o PythonBackend apenas se estiver construindo um tokenizador muito especializado que não possa ser expresso pelo backend Rust.
- Subclasse o TokenizersBackend com atributos de classe, como o lado do padding e o algoritmo de tokenização a ser usado.
- Defina o pipeline de tokenização no
__init__. Isso inclui o algoritmo de tokenização a ser usado, como dividir o texto bruto antes do algoritmo e como decodificar os tokens de volta para texto.
from tokenizers import Tokenizer, decoders, pre_tokenizers
from tokenizers.models import BPE
from transformers import TokenizersBackend
class NewTokenizer(TokenizersBackend):
padding_side = "left"
model = BPE
def __init__(
self,
vocab=None,
merges=None,
unk_token="<unk>",
bos_token="<s>",
eos_token="</s>",
pad_token="<pad>",
):
self._vocab = vocab or {
str(unk_token): 0,
str(bos_token): 1,
str(eos_token): 2,
str(pad_token): 3,
}
self._merges = merges or []
self._tokenizer = Tokenizer(
BPE(vocab=self._vocab, merges=self._merges, fuse_unk=True)
)
self._tokenizer.pre_tokenizer = pre_tokenizers.ByteLevel(add_prefix_space=False)
self._tokenizer.decoder = decoders.ByteLevel()
super().__init__(
unk_token=unk_token,
bos_token=bos_token,
eos_token=eos_token,
pad_token=pad_token,
)Treine ou salve o novo tokenizer vazio.
tokenizer = NewTokenizer()
# train on new corpus
corpus = ["The stock market rallied today.", "Bond yields fell sharply."]
trained_tokenizer = tokenizer.train_new_from_iterator(corpus, vocab_size=32000)
# save tokenizer
trained_tokenizer.save_pretrained("./new-tokenizer")