#
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 de `Normalizer` pe care le puteți folosi (lista completă aici).
- `pre_tokenizers` conține toate tipurile de `PreTokenizer` pe care le poți folosi(lista completă aici).
- `models` conține diferitele tipuri de `Model` pe care le puteți folosi, precum `BPE`, `WordPiece` și `Unigram` (lista completă aici).
- `trainers` conține toate tipurile diferite de `Trainer` 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 de `PostProcessor` pe care le puteți utiliza (lista completă aici).
- `decoders` conține diferitele tipuri de `Decoder` 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