1. Tokenizacja

Reading time: 3 minutes

Tokenizacja

Tokenizacja to proces dzielenia danych, takich jak tekst, na mniejsze, łatwiejsze do zarządzania fragmenty zwane tokenami. Każdemu tokenowi przypisywany jest unikalny identyfikator numeryczny (ID). To fundamentalny krok w przygotowywaniu tekstu do przetwarzania przez modele uczenia maszynowego, szczególnie w przetwarzaniu języka naturalnego (NLP).

tip

Celem tej początkowej fazy jest bardzo prosty: Podzielić dane wejściowe na tokeny (id) w sposób, który ma sens.

Jak działa tokenizacja

  1. Podział tekstu:
  • Podstawowy tokenizator: Prosty tokenizator może dzielić tekst na pojedyncze słowa i znaki interpunkcyjne, usuwając spacje.
  • Przykład:
    Tekst: "Hello, world!"
    Tokeny: ["Hello", ",", "world", "!"]
  1. Tworzenie słownika:
  • Aby przekształcić tokeny w numeryczne ID, tworzony jest słownik. Ten słownik zawiera wszystkie unikalne tokeny (słowa i symbole) i przypisuje każdemu z nich konkretny ID.
  • Tokeny specjalne: To specjalne symbole dodawane do słownika, aby obsługiwać różne scenariusze:
  • [BOS] (Początek sekwencji): Wskazuje początek tekstu.
  • [EOS] (Koniec sekwencji): Wskazuje koniec tekstu.
  • [PAD] (Wypełnienie): Używane do wyrównania długości wszystkich sekwencji w partii.
  • [UNK] (Nieznany): Reprezentuje tokeny, które nie znajdują się w słowniku.
  • Przykład:
    Jeśli "Hello" ma ID 64, "," to 455, "world" to 78, a "!" to 467, to:
    "Hello, world!"[64, 455, 78, 467]
  • Obsługa nieznanych słów:
    Jeśli słowo takie jak "Bye" nie znajduje się w słowniku, jest zastępowane przez [UNK].
    "Bye, world!"["[UNK]", ",", "world", "!"][987, 455, 78, 467]
    (Zakładając, że [UNK] ma ID 987)

Zaawansowane metody tokenizacji

Podczas gdy podstawowy tokenizator dobrze działa w przypadku prostych tekstów, ma ograniczenia, szczególnie w przypadku dużych słowników i obsługi nowych lub rzadkich słów. Zaawansowane metody tokenizacji rozwiązują te problemy, dzieląc tekst na mniejsze podjednostki lub optymalizując proces tokenizacji.

  1. Kodowanie par bajtów (BPE):
  • Cel: Zmniejsza rozmiar słownika i obsługuje rzadkie lub nieznane słowa, dzieląc je na często występujące pary bajtów.
  • Jak to działa:
  • Zaczyna od pojedynczych znaków jako tokenów.
  • Iteracyjnie łączy najczęściej występujące pary tokenów w jeden token.
  • Kontynuuje, aż nie będzie można połączyć więcej częstych par.
  • Korzyści:
  • Eliminuje potrzebę tokena [UNK], ponieważ wszystkie słowa mogą być reprezentowane przez łączenie istniejących tokenów subword.
  • Bardziej efektywny i elastyczny słownik.
  • Przykład:
    "playing" może być tokenizowane jako ["play", "ing"], jeśli "play" i "ing" są częstymi subwordami.
  1. WordPiece:
  • Używane przez: Modele takie jak BERT.
  • Cel: Podobnie jak BPE, dzieli słowa na jednostki subword, aby obsługiwać nieznane słowa i zmniejszać rozmiar słownika.
  • Jak to działa:
  • Zaczyna od podstawowego słownika pojedynczych znaków.
  • Iteracyjnie dodaje najczęściej występujący subword, który maksymalizuje prawdopodobieństwo danych treningowych.
  • Używa modelu probabilistycznego do decyzji, które subwordy połączyć.
  • Korzyści:
  • Równoważy między posiadaniem zarządzalnego rozmiaru słownika a efektywnym reprezentowaniem słów.
  • Efektywnie obsługuje rzadkie i złożone słowa.
  • Przykład:
    "unhappiness" może być tokenizowane jako ["un", "happiness"] lub ["un", "happy", "ness"] w zależności od słownika.
  1. Model językowy Unigram:
  • Używane przez: Modele takie jak SentencePiece.
  • Cel: Używa modelu probabilistycznego do określenia najbardziej prawdopodobnego zestawu tokenów subword.
  • Jak to działa:
  • Zaczyna od dużego zestawu potencjalnych tokenów.
  • Iteracyjnie usuwa tokeny, które najmniej poprawiają prawdopodobieństwo modelu dla danych treningowych.
  • Finalizuje słownik, w którym każde słowo jest reprezentowane przez najbardziej prawdopodobne jednostki subword.
  • Korzyści:
  • Elastyczny i może modelować język w sposób bardziej naturalny.
  • Często prowadzi do bardziej efektywnych i kompaktowych tokenizacji.
  • Przykład:
    "internationalization" może być tokenizowane na mniejsze, znaczące subwordy, takie jak ["international", "ization"].

Przykład kodu

Zrozummy to lepiej na przykładzie kodu z https://github.com/rasbt/LLMs-from-scratch/blob/main/ch02/01_main-chapter-code/ch02.ipynb:

python
# Download a text to pre-train the model
import urllib.request
url = ("https://raw.githubusercontent.com/rasbt/LLMs-from-scratch/main/ch02/01_main-chapter-code/the-verdict.txt")
file_path = "the-verdict.txt"
urllib.request.urlretrieve(url, file_path)

with open("the-verdict.txt", "r", encoding="utf-8") as f:
raw_text = f.read()

# Tokenize the code using GPT2 tokenizer version
import tiktoken
token_ids = tiktoken.get_encoding("gpt2").encode(txt, allowed_special={"[EOS]"}) # Allow the user of the tag "[EOS]"

# Print first 50 tokens
print(token_ids[:50])
#[40, 367, 2885, 1464, 1807, 3619, 402, 271, 10899, 2138, 257, 7026, 15632, 438, 2016, 257, 922, 5891, 1576, 438, 568, 340, 373, 645, 1049, 5975, 284, 502, 284, 3285, 326, 11, 287, 262, 6001, 286, 465, 13476, 11, 339, 550, 5710, 465, 12036, 11, 6405, 257, 5527, 27075, 11]

Odniesienia