LLM Course documentation
Construirea unui tokenizer, bloc cu bloc
Construirea unui tokenizer, bloc cu bloc
După cum am văzut în secțiunile anterioare, tokenizarea cuprinde mai multe etape:
- Normalizare (orice curățare a textului care este considerată necesară, cum ar fi eliminarea spațiilor sau a accentelor, normalizarea Unicode etc.)
- Pre-tokenizarea (împărțirea inputului în cuvinte)
- Rularea inputului prin model (utilizarea cuvintelor pre-tokenizate pentru a produce o secvență de tokeni)
- Post-procesare (adăugarea tokenilor speciali ai tokenizerului, generarea attention maskului și a ID-urilor de tip token)
Ca un reminder, iată o altă perspectivă asupra procesului general:
Biblioteca 🤗 Tokenizers a fost construită pentru a oferi mai multe opțiuni pentru fiecare dintre acești pași, pe care le puteți amesteca și combina împreună. În această secțiune vom vedea cum putem construi un tokenizer de la zero, spre deosebire de antrenarea unui tokenizer nou dintr-unul vechi, așa cum am făcut în secțiunea 2. Veți putea apoi să construiți orice fel de tokenizer la care vă puteți gândi!
Mai exact, biblioteca este construită în jurul unei clase centrale Tokenizer
cu building grupate în submodule:
normalizers
conține toate tipurile posibile deNormalizer
pe care le puteți folosi (lista completă aici).pre_tokenizers
conține toate tipurile dePreTokenizer
pe care le poți folosi(lista completă aici).models
conține diferitele tipuri deModel
pe care le puteți folosi, precumBPE
,WordPiece
șiUnigram
(lista completă aici).trainers
conține toate tipurile diferite deTrainer
pe care le puteți folosi pentru a vă antrena modelul pe un corpus (unul pentru fiecare tip de model; lista completă aici).post_processors
conține diferitele tipuri dePostProcessor
pe care le puteți utiliza (lista completă aici).decoders
conține diferitele tipuri deDecoder
pe care le puteți utiliza pentru a decoda rezultatele tokenizării (lista completă aici).
Puteți găsi întreaga listă de blocuri aici.
Obținerea unui corpus
Pentru a antrena noul nostru tokenizer, vom utiliza un corpus mic de text (astfel încât exemplele să ruleze rapid). Pașii pentru obținerea corpusului sunt similari cu cei pe care i-am urmat la începutul acestui capitol, dar de data aceasta vom utiliza datasetul WikiText-2:
from datasets import load_dataset
dataset = load_dataset("wikitext", name="wikitext-2-raw-v1", split="train")
def get_training_corpus():
for i in range(0, len(dataset), 1000):
yield dataset[i : i + 1000]["text"]
Funcția get_training_corpus()
este un generator care va produce batch-uri de 1 000 de texte, pe care le vom utiliza pentru a antrena tokenizerul.
🤗 Tokenizers pot fi, de asemenea, antrenate direct pe fișiere text. Iată cum putem genera un fișier text care să conțină toate textele/inputurile din WikiText-2 pe care le putem utiliza local:
with open("wikitext-2.txt", "w", encoding="utf-8") as f:
for i in range(len(dataset)):
f.write(dataset[i]["text"] + "\n")
În continuare vă vom arăta cum să vă construiți propriile tokenizere BERT, GPT-2 și XLNet, bloc cu bloc. Acest lucru ne va oferi un exemplu pentru fiecare dintre cei trei algoritmi principali de tokenizare: WordPiece, BPE și Unigram. Să începem cu BERT!
Construirea unui tokenizator WordPiece de la zero
Pentru a construi un tokenizer cu biblioteca 🤗 Tokenizers, începem prin a inițializa un obiect Tokenizer
cu un model
, apoi îi setăm atributele normalizer
, pre_tokenizer
, post_processor
și decoder
la valorile dorite.
Pentru acest exemplu, vom crea un Tokenizer
cu un model WordPiece:
from tokenizers import (
decoders,
models,
normalizers,
pre_tokenizers,
processors,
trainers,
Tokenizer,
)
tokenizer = Tokenizer(models.WordPiece(unk_token="[UNK]"))
Trebuie să specificăm unk_token
astfel încât modelul să știe ce să returneze atunci când întâlnește caractere necunoscute. Alte argumente pe care le putem seta aici includ vocab
al modelului nostru (vom antrena modelul, deci nu este nevoie să setăm acest lucru) și max_input_chars_per_word
, care specifică o lungime maximă pentru fiecare cuvânt (cuvintele mai lungi decât valoarea trecută vor fi divizate).
Primul pas al tokenizării este normalizarea, așa că să începem cu aceasta. Deoarece BERT este utilizat pe scară largă, există un BertNormalizer
cu opțiunile clasice pe care le putem seta pentru BERT: lowercase
și strip_accents
, care se explică de la sine; clean_text
pentru a elimina toate caracterele de control și a înlocui spațiile repetate cu unul singur; și handle_chinese_chars
, care plasează spații în jurul caracterelor chinezești. Pentru a replica tokenizerul bert-base-uncased
, putem seta doar acest normalizator:
tokenizer.normalizer = normalizers.BertNormalizer(lowercase=True)
În general, atunci când construiți un nou tokenizer, nu veți avea acces la un normalizator atât de util, deja implementat în biblioteca 🤗 Tokenizers - așa că să vedem cum să creăm manual normalizatorul BERT. Biblioteca oferă un normalizator Lowercase
și un normalizator StripAccents
și puteți compune mai multe normalizatoare folosind un Sequence
:
tokenizer.normalizer = normalizers.Sequence(
[normalizers.NFD(), normalizers.Lowercase(), normalizers.StripAccents()]
)
De asemenea, folosim un normalizator Unicode NFD
, deoarece în caz contrar normalizatorul StripAccents
nu va recunoaște corect caracterele accentuate și astfel nu le va elimina.
După cum am mai văzut, putem folosi metoda normalize_str()
a normalizer
pentru a verifica efectele pe care le are asupra unui text dat:
print(tokenizer.normalizer.normalize_str("Héllò hôw are ü?"))
hello how are u?
Pentru a merge mai departe Dacă testați cele două versiuni ale normalizatorilor anteriori pe un șir care conține caracterul Unicode u"\u0085"
veți observa cu siguranță că acești doi normalizatori nu sunt exact echivalenți.
Pentru a nu complica prea mult versiunea cu normalizers.Sequence
, nu am inclus înlocuirile Regex pe care BertNormalizer
le cere atunci când argumentul clean_text
este setat la True
- care este comportamentul implicit. Dar nu vă faceți griji: este posibil să obțineți exact aceeași normalizare fără a utiliza utilul BertNormalizer
prin adăugarea a două normalizers.Replace
la secvența normalizers.
Urmează etapa de pre-tokenizare. Din nou, există un BertPreTokenizer
pre-construit pe care îl putem utiliza:
tokenizer.pre_tokenizer = pre_tokenizers.BertPreTokenizer()
Sau îl putem construi de la zero:
tokenizer.pre_tokenizer = pre_tokenizers.Whitespace()
Rețineți că pre-tokenizatorul Whitespace
separă spațiul și toate caracterele care nu sunt litere, cifre sau caracterul underscore, deci tehnic separă spațiul și punctuația:
tokenizer.pre_tokenizer.pre_tokenize_str("Let's test my pre-tokenizer.")
[('Let', (0, 3)), ("'", (3, 4)), ('s', (4, 5)), ('test', (6, 10)), ('my', (11, 13)), ('pre', (14, 17)),
('-', (17, 18)), ('tokenizer', (18, 27)), ('.', (27, 28))]
Dacă doriți să separați doar spațiile, ar trebui să utilizați în schimb pre-tokenizerul WhitespaceSplit
:
pre_tokenizer = pre_tokenizers.WhitespaceSplit()
pre_tokenizer.pre_tokenize_str("Let's test my pre-tokenizer.")
[("Let's", (0, 5)), ('test', (6, 10)), ('my', (11, 13)), ('pre-tokenizer.', (14, 28))]
Ca și în cazul normalizatorilor, puteți utiliza un Sequence
pentru a compune mai mulți pre-tokenizeri:
pre_tokenizer = pre_tokenizers.Sequence(
[pre_tokenizers.WhitespaceSplit(), pre_tokenizers.Punctuation()]
)
pre_tokenizer.pre_tokenize_str("Let's test my pre-tokenizer.")
[('Let', (0, 3)), ("'", (3, 4)), ('s', (4, 5)), ('test', (6, 10)), ('my', (11, 13)), ('pre', (14, 17)),
('-', (17, 18)), ('tokenizer', (18, 27)), ('.', (27, 28))]
Următorul pas în pipelineul de tokenizare este rularea inputurilor prin model. Am specificat deja modelul nostru în inițializare, dar mai trebuie să îl antrenăm, ceea ce va necesita un WordPieceTrainer
. Principalul lucru de reținut atunci când inițializați un trainer în 🤗 Tokenizers este că trebuie să îi transmiteți toți tokenii speciali pe care intenționați să îi utilizați - în caz contrar, acesta nu le va adăuga la vocabular, deoarece acestea nu se află în corpusul de antrenare:
special_tokens = ["[UNK]", "[PAD]", "[CLS]", "[SEP]", "[MASK]"]
trainer = trainers.WordPieceTrainer(vocab_size=25000, special_tokens=special_tokens)
Pe lângă specificarea vocab_size
și special_tokens
, putem seta min_frequency
(numărul de ori în care un simbol trebuie să apară pentru a fi inclus în vocabular) sau putem schimba continuing_subword_prefix
(dacă dorim să folosim ceva diferit de ##
).
Pentru a antrena modelul nostru folosind iteratorul pe care l-am definit anterior, trebuie doar să executăm această comandă:
tokenizer.train_from_iterator(get_training_corpus(), trainer=trainer)
De asemenea, putem utiliza fișiere text pentru a ne antrena tokenizerul, care ar arăta astfel (în prealabil, reinițializăm modelul cu un WordPiece
gol):
tokenizer.model = models.WordPiece(unk_token="[UNK]")
tokenizer.train(["wikitext-2.txt"], trainer=trainer)
În ambele cazuri, putem apoi testa tokenizerul pe un text prin apelarea metodei encode()
:
encoding = tokenizer.encode("Let's test this tokenizer.")
print(encoding.tokens)
['let', "'", 's', 'test', 'this', 'tok', '##eni', '##zer', '.']
encoding
-ul obținut este un Encoding
, care conține toate rezultatele necesare ale tokenizerului în diferitele sale atribute: ids
, type_ids
, tokens
, offsets
, attention_mask
, special_tokens_mask
, și overflowing
.
Ultimul pas în pipelineul de tokenizare este postprocesarea. Trebuie să adăugăm tokenul [CLS]
la început și tokenul [SEP]
la sfârșit (sau după fiecare propoziție, dacă avem o pereche de propoziții). Vom folosi un TemplateProcessor
pentru aceasta, dar mai întâi trebuie să cunoaștem ID-urile tokenilor [CLS]
și [SEP]
din vocabular:
cls_token_id = tokenizer.token_to_id("[CLS]")
sep_token_id = tokenizer.token_to_id("[SEP]")
print(cls_token_id, sep_token_id)
(2, 3)
Pentru a scrie templateul pentru TemplateProcessor
, trebuie să specificăm cum să tratăm o singură propoziție și o pereche de propoziții. Pentru ambele, scriem tokeni speciali pe care dorim să îi folosim; prima (sau singura) propoziție este reprezentată de $A
, în timp ce a doua propoziție (dacă facem encoding unei perechi) este reprezentată de $B
. Pentru fiecare dintre acestea (tokeni speciali și propoziții), specificăm și ID-ul tipului de token corespunzător după două puncte.
Modelul clasic BERT este astfel definit după cum urmează:
tokenizer.post_processor = processors.TemplateProcessing(
single=f"[CLS]:0 $A:0 [SEP]:0",
pair=f"[CLS]:0 $A:0 [SEP]:0 $B:1 [SEP]:1",
special_tokens=[("[CLS]", cls_token_id), ("[SEP]", sep_token_id)],
)
Rețineți că trebuie să transmitem ID-urile tokenilor speciali, astfel încât tokenizerul să le poată converti corect în ID-urile lor.
Odată ce acest lucru este adăugat, revenind la exemplul nostru anterior vom obține:
encoding = tokenizer.encode("Let's test this tokenizer.")
print(encoding.tokens)
['[CLS]', 'let', "'", 's', 'test', 'this', 'tok', '##eni', '##zer', '.', '[SEP]']
Și pe o pereche de propoziții, obținem rezultatul corect:
encoding = tokenizer.encode("Let's test this tokenizer...", "on a pair of sentences.")
print(encoding.tokens)
print(encoding.type_ids)
['[CLS]', 'let', "'", 's', 'test', 'this', 'tok', '##eni', '##zer', '...', '[SEP]', 'on', 'a', 'pair', 'of', 'sentences', '.', '[SEP]']
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1]
Aproape am terminat de construit acest tokenizer de la zero - ultimul pas este să includem un decodor:
tokenizer.decoder = decoders.WordPiece(prefix="##")
Haideți să-l testăm pe encoding
-ul nostru anterior:
tokenizer.decode(encoding.ids)
"let's test this tokenizer... on a pair of sentences."
Grozav! Putem salva tokenizatorul nostru într-un singur fișier JSON, astfel:
tokenizer.save("tokenizer.json")
Apoi putem reîncărca acel fișier într-un obiect Tokenizer
cu metoda from_file()
:
new_tokenizer = Tokenizer.from_file("tokenizer.json")
Pentru a utiliza acest tokenizer în 🤗 Transformers, trebuie să îl încorporăm în PreTrainedTokenizerFast
. Putem fie să folosim clasa generică, fie, dacă tokenizerul nostru corespunde unui model existent, să folosim clasa respectivă (aici, BertTokenizerFast
). Dacă aplicați această lecție pentru a construi un tokenizer nou, va trebui să utilizați prima opțiune.
Pentru a include tokenizatorul într-un PreTrainedTokenizerFast
, putem fie să transmitem tokenizerul construit ca tokenizer_object
, fie să transmitem fișierul tokenizerului salvat ca tokenizer_file
. Cel mai important lucru de reținut este că trebuie să setăm manual toți tokenii speciali, deoarece această clasă nu poate deduce din obiectul tokenizer
care token este tokenul mască, tokenul [CLS]
, etc.:
from transformers import PreTrainedTokenizerFast
wrapped_tokenizer = PreTrainedTokenizerFast(
tokenizer_object=tokenizer,
# tokenizer_file="tokenizer.json", # You can load from the tokenizer file, alternatively
unk_token="[UNK]",
pad_token="[PAD]",
cls_token="[CLS]",
sep_token="[SEP]",
mask_token="[MASK]",
)
Dacă utilizați o clasă specifică de tokenizer (cum ar fi BertTokenizerFast
), va trebui să specificați doar tokenii speciali care sunt diferiți de cei impliciți (aici, niciunul):
from transformers import BertTokenizerFast
wrapped_tokenizer = BertTokenizerFast(tokenizer_object=tokenizer)
Apoi puteți utiliza acest tokenizer ca orice alt tokenizer 🤗 Transformers. Îl puteți salva cu metoda save_pretrained()
sau îl puteți încărca în Hub cu metoda push_to_hub()
.
Acum că am văzut cum să construim un tokenizer WordPiece, hai să facem același lucru pentru un tokenizer BPE. Vom merge un pic mai repede, deoarece cunoașteți toți pașii, și vom evidenția doar diferențele.
Construirea unui tokenizer BPE de la zero
Să construim acum un tokenizer GPT-2. Ca și pentru tokenizer BERT, începem prin inițializarea unui Tokenizer
cu un model BPE:
tokenizer = Tokenizer(models.BPE())
De asemenea, la fel ca în cazul BERT, am putea inițializa acest model cu un vocabular, dacă am avea unul (în acest caz, ar trebui să oferim vocab
și merges
), dar din moment ce vom antrena de la zero, nu avem nevoie să facem acest lucru. De asemenea, nu trebuie să specificăm un unk_token
deoarece GPT-2 utilizează BPE la nivel de bytes, care nu necesită acest lucru.
GPT-2 nu utilizează un normalizator, deci sărim peste acest pas și trecem direct la pre-tokenizare:
tokenizer.pre_tokenizer = pre_tokenizers.ByteLevel(add_prefix_space=False)
Opțiunea pe care am adăugat-o aici la ByteLevel
nu este pentru a adăuga un spațiu unei propoziții (care este implicit în caz contrar). Putem arunca o privire la pre-tokenizarea unui text exemplu ca înainte:
tokenizer.pre_tokenizer.pre_tokenize_str("Let's test pre-tokenization!")
[('Let', (0, 3)), ("'s", (3, 5)), ('Ġtest', (5, 10)), ('Ġpre', (10, 14)), ('-', (14, 15)),
('tokenization', (15, 27)), ('!', (27, 28))]
Urmează modelul, care are nevoie de antrenare. Pentru GPT-2, singurul token special este tokenul de sfârșit de text:
trainer = trainers.BpeTrainer(vocab_size=25000, special_tokens=["<|endoftext|>"])
tokenizer.train_from_iterator(get_training_corpus(), trainer=trainer)
Ca și în cazul WordPieceTrainer
, precum și vocab_size
și special_tokens
, putem specifica min_frequency
dacă dorim, sau dacă avem un sufix de sfârșit de cuvânt (cum ar fi </w>
), îl putem seta cu end_of_word_suffix
.
Acest tokenizer poate fi antrenat și pe fișiere text:
tokenizer.model = models.BPE()
tokenizer.train(["wikitext-2.txt"], trainer=trainer)
Să aruncăm o privire la tokenizarea unui exemplu de text:
encoding = tokenizer.encode("Let's test this tokenizer.")
print(encoding.tokens)
['L', 'et', "'", 's', 'Ġtest', 'Ġthis', 'Ġto', 'ken', 'izer', '.']
Aplicăm postprocesarea la nivel de bytes pentru tokenizerul GPT-2 după cum urmează:
tokenizer.post_processor = processors.ByteLevel(trim_offsets=False)
Opțiunea trim_offsets = False
indică post-procesorului că ar trebui să lăsăm offseturile tokenilor care încep cu “Ġ” așa cum sunt: în acest fel, începutul offseturilor va indica spațiul dinaintea cuvântului, nu primul caracter al cuvântului (deoarece spațiul face parte din punct de vedere tehnic din token). Să aruncăm o privire asupra rezultatului cu textul pe căruia tocmai i-am făcut encoding, unde 'Ġtest'
este tokenul de la indexul 4:
sentence = "Let's test this tokenizer."
encoding = tokenizer.encode(sentence)
start, end = encoding.offsets[4]
sentence[start:end]
' test'
În cele din urmă, adăugăm un decoder la nivel de bytes:
tokenizer.decoder = decoders.ByteLevel()
și putem verifica de două ori dacă funcționează corect:
tokenizer.decode(encoding.ids)
"Let's test this tokenizer."
Grozav! Acum că am terminat, putem salva tokenizatorul ca înainte și îl putem încorpora într-un PreTrainedTokenizerFast
sau GPT2TokenizerFast
dacă dorim să îl folosim în 🤗 Transformers:
from transformers import PreTrainedTokenizerFast
wrapped_tokenizer = PreTrainedTokenizerFast(
tokenizer_object=tokenizer,
bos_token="<|endoftext|>",
eos_token="<|endoftext|>",
)
or:
from transformers import GPT2TokenizerFast
wrapped_tokenizer = GPT2TokenizerFast(tokenizer_object=tokenizer)
Ca un ultim exemplu, vă vom arăta cum să construiți un tokenizer Unigram de la zero.
Construirea unui tokenizer Unigram de la zero
Să construim acum un tokenizer XLNet. Ca și în cazul tokenizerelor anterioare, începem prin inițializarea unui Tokenizer
cu un model Unigram:
tokenizer = Tokenizer(models.Unigram())
Din nou, am putea inițializa acest model cu un vocabular, dacă am avea unul.
Pentru normalizare, XLNet utilizează câteva înlocuiri (care provin din SentencePiece):
from tokenizers import Regex
tokenizer.normalizer = normalizers.Sequence(
[
normalizers.Replace("``", '"'),
normalizers.Replace("''", '"'),
normalizers.NFKD(),
normalizers.StripAccents(),
normalizers.Replace(Regex(" {2,}"), " "),
]
)
Acest lucru înlocuitește “
și ”
cu ”
și orice secvență de două sau mai multe spații cu un singur spațiu, precum și ștergerea accentelor în textele ce trebuie tokenizate.
Pre-tokenizerul care trebuie utilizat pentru orice tokenizer SentencePiece este Metaspace
:
tokenizer.pre_tokenizer = pre_tokenizers.Metaspace()
Putem arunca o privire la pre-tokenizarea unui exemplu de text ca mai înainte:
tokenizer.pre_tokenizer.pre_tokenize_str("Let's test the pre-tokenizer!")
[("▁Let's", (0, 5)), ('▁test', (5, 10)), ('▁the', (10, 14)), ('▁pre-tokenizer!', (14, 29))]
Urmează modelul, care are nevoie de antrenare. XLNet are destul de mulți tokeni speciali:
special_tokens = ["<cls>", "<sep>", "<unk>", "<pad>", "<mask>", "<s>", "</s>"]
trainer = trainers.UnigramTrainer(
vocab_size=25000, special_tokens=special_tokens, unk_token="<unk>"
)
tokenizer.train_from_iterator(get_training_corpus(), trainer=trainer)
Un argument foarte important care nu trebuie uitat pentru UnigramTrainer
este unk_token
. Putem trece și alte argumente specifice algoritmului Unigram, cum ar fi shrinking_factor
pentru fiecare pas în care eliminăm tokeni (valoarea implicită este 0,75) sau max_piece_length
pentru a specifica lungimea maximă a unui token dat (valoarea implicită este 16).
Acest tokenizer poate fi antrenat și pe fișiere text:
tokenizer.model = models.Unigram()
tokenizer.train(["wikitext-2.txt"], trainer=trainer)
Să aruncăm o privire la tokenizarea unui exemplu de text:
encoding = tokenizer.encode("Let's test this tokenizer.")
print(encoding.tokens)
['▁Let', "'", 's', '▁test', '▁this', '▁to', 'ken', 'izer', '.']
O particularitate a XLNet este că pune tokenul <cls>
la sfârșitul propoziției, cu un ID de tip 2 (pentru a-l distinge de ceilalți tokeni). Ca urmare, este făcut padding la stânga. Putem trata toți tokenii speciali și ID-urile de tip ale tokenilor cu un template, ca în cazul BERT, dar mai întâi trebuie să obținem ID-urile tokenilor <cls>
și <sep>
:
cls_token_id = tokenizer.token_to_id("<cls>")
sep_token_id = tokenizer.token_to_id("<sep>")
print(cls_token_id, sep_token_id)
0 1
Templateul arată astfel:
tokenizer.post_processor = processors.TemplateProcessing(
single="$A:0 <sep>:0 <cls>:2",
pair="$A:0 <sep>:0 $B:1 <sep>:1 <cls>:2",
special_tokens=[("<sep>", sep_token_id), ("<cls>", cls_token_id)],
)
Și putem testa că funcționează prin codificarea unei perechi de propoziții:
encoding = tokenizer.encode("Let's test this tokenizer...", "on a pair of sentences!")
print(encoding.tokens)
print(encoding.type_ids)
['▁Let', "'", 's', '▁test', '▁this', '▁to', 'ken', 'izer', '.', '.', '.', '<sep>', '▁', 'on', '▁', 'a', '▁pair',
'▁of', '▁sentence', 's', '!', '<sep>', '<cls>']
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2]
În cele din urmă, adăugăm un decoder Metaspace
:
tokenizer.decoder = decoders.Metaspace()
și am terminat cu acest tokenizer! Putem salva tokenizerul ca înainte și îl putem încorpora într-un PreTrainedTokenizerFast
sau XLNetTokenizerFast
dacă dorim să îl folosim în 🤗 Transformers. Un lucru de reținut atunci când se utilizează PreTrainedTokenizerFast
este că, pe lângă tokenii speciali, trebuie să spunem bibliotecii 🤗 Transformers să facă padding la stânga:
from transformers import PreTrainedTokenizerFast
wrapped_tokenizer = PreTrainedTokenizerFast(
tokenizer_object=tokenizer,
bos_token="<s>",
eos_token="</s>",
unk_token="<unk>",
pad_token="<pad>",
cls_token="<cls>",
sep_token="<sep>",
mask_token="<mask>",
padding_side="left",
)
Sau alternativ:
from transformers import XLNetTokenizerFast
wrapped_tokenizer = XLNetTokenizerFast(tokenizer_object=tokenizer)
Acum că ați văzut cum sunt utilizate diferitele blocuri de construcție pentru a construi tokenizeri existenți, ar trebui să puteți scrie orice tokenizer doriți cu biblioteca 🤗 Tokenizers și să îl puteți utiliza în 🤗 Transformers.
< > Update on GitHub