ML Atlas

08 · LLM · 5 min czytania · Interaktywne · aktualizacja

Czym jest tokenizacja w LLM i jak działa algorytm BPE?

W skrócie

Tokenizacja dzieli tekst na tokeny, czyli kawałki słów, które model zamienia na liczby. BPE buduje słownik, łącząc najczęstsze pary symboli w dane.

Co to jest

Tokenizacja to zamiana tekstu na ciąg tokenów — jednostek ze stałego słownika, z których każda ma swój numer. Model językowy nie widzi liter ani słów, tylko te numery. Byte-Pair Encoding (BPE) to najpopularniejszy algorytm budowy takiego słownika: zaczyna od pojedynczych znaków (lub bajtów) i wielokrotnie skleja najczęściej sąsiadującą parę w nowy symbol.

Dlaczego nie słowa? Słownik całych słów musiałby być gigantyczny, a i tak nie pokryłby nowych nazw, literówek i form fleksyjnych — w polskim jedno słowo ma kilkanaście odmian. Dlaczego nie litery? Ciągi byłyby bardzo długie, a model musiałby od zera składać znaczenie z liter. Tokeny podsłowowe (subword) są kompromisem: częste słowa stają się jednym tokenem, rzadkie rozpadają się na kilka znanych kawałków.

Typowy słownik współczesnego LLM ma od kilkudziesięciu do kilkuset tysięcy tokenów. W tekście angielskim jeden token to średnio około trzech–czterech znaków; w polskim zwykle mniej, bo słownik budowany jest głównie na danych angielskich.

Mechanizm — dlaczego tak działa

Trening tokenizera. BPE w wersji Sennricha i in. (2016) działa na korpusie z policzonymi słowami. Każde słowo zapisuje się jako ciąg znaków z symbolem końca słowa. Następnie w pętli: (1) policz wszystkie pary sąsiednich symboli, ważąc liczbą wystąpień słowa; (2) najczęstszą parę zastąp nowym symbolem i dopisz regułę scalenia do listy; (3) powtarzaj, aż słownik osiągnie zadany rozmiar. Wynikiem jest uporządkowana lista scaleń.

Tokenizacja nowego tekstu. Tekst dzieli się na znaki i stosuje scalenia w tej samej kolejności, w jakiej je wyuczono. Ponieważ zawsze można zejść do pojedynczych znaków, każde słowo da się zapisać — nie ma problemu „nieznanego słowa”. Wersja bajtowa (GPT-2) zaczyna od 256 możliwych bajtów UTF-8, więc obsłuży dowolny tekst, także emoji i znaki z innych alfabetów.

Dlaczego częstość to dobra heurystyka. Scalanie najczęstszych par to zachłanna kompresja: każde scalenie najbardziej skraca zapis korpusu. Krótsze ciągi oznaczają, że w oknie kontekstu mieści się więcej treści, a model wykonuje mniej kroków na ten sam tekst. Przy okazji częste rdzenie i końcówki dostają własne tokeny, co ułatwia modelowi uczenie się morfologii — choć podział BPE nie pokrywa się z podziałem na morfemy.

Konsekwencje, które widać w zachowaniu modelu. Model „nie widzi” liter wewnątrz tokenu, dlatego zadania typu policzenie liter w słowie albo odwrócenie wyrazu wychodzą mu słabo. Liczby bywają dzielone na nieregularne kawałki, co utrudnia arytmetykę. Języki gorzej reprezentowane w danych tokenizera potrzebują więcej tokenów na to samo zdanie: płacą więcej, czekają dłużej i szybciej zapełniają kontekst (Petrov i in., 2023). Polskie litery z ogonkami zajmują w UTF-8 po dwa bajty, więc w tokenizerze bajtowym rzadziej łączą się w długie tokeny.

Warianty. WordPiece (BERT) wybiera scalenie, które najbardziej zwiększa wiarygodność danych, a nie samą częstość. Unigram LM (SentencePiece, Kudo i Richardson, 2018) robi odwrotnie: zaczyna od dużego słownika i usuwa najmniej przydatne tokeny. Zasada pozostaje ta sama: słownik podsłów dopasowany do statystyki korpusu.

Na przykładzie

Weźmy mini-korpus: „dom” ×6, „domu” ×3, „domy” ×2, „kot” ×4, „kota” ×1, „kotu” ×2 (symbol _ oznacza koniec słowa). Na starcie zapis zajmuje 80 symboli. Pary „d o” i „o m” występują po 11 razy — remis rozstrzygamy na rzecz pierwszej. Kolejne scalenia: (1) d+o → „do” (11), (2) do+m → „dom” (11), (3) k+o → „ko” (7, remis z „o t”), (4) ko+t → „kot” (7), (5) dom+_ → „dom_” (6), (6) u+_ → „u_” (5, bo „domu” i „kotu” dają razem 3 + 2), (7) kot+_ → „kot_” (4).

Po siedmiu scaleniach „dom” to jeden token, „domu” to dom·u_, „kotu” to kot·u_, a cały korpus zajmuje 29 symboli zamiast 80. Algorytm sam wydzielił rdzenie i końcówkę „-u”, choć nic nie wie o gramatyce. Nowe słowo „domek”, którego w korpusie nie było, zostanie zapisane jako dom·e·k·_ — z rdzenia i liter. Tak samo działa to w skali: GPT-2 ma słownik 50 257 tokenów, czyli 256 bajtów bazowych, 50 000 wyuczonych scaleń i jeden token specjalny (Radford i in., 2019).

Ta ilustracja działa w przeglądarce z włączonym JavaScriptem: tokenizator BPE uczony na kilkudziesięciu zdaniach: im więcej scaleń, tym mniej tokenów, a nieznane słowa rozpadają się na litery.

W praktyce

  • Do liczenia tokenów używaj tokenizera konkretnego modelu: AutoTokenizer.from_pretrained(...) w transformers, tiktoken lub sentencepiece. Różne modele dzielą ten sam tekst inaczej.
  • Własny tokenizer trenuje się np. biblioteką tokenizers (BPE, BpeTrainer) — opłaca się tylko przy trenowaniu modelu od zera.
  • Limity kontekstu i cenniki są podawane w tokenach. Polski tekst zużywa ich zwykle wyraźnie więcej niż angielski o tej samej treści — zmierz to na własnych danych.
  • Spacja jest zwykle częścią tokenu („ dom” i „dom” to różne tokeny), co ma znaczenie przy budowie promptów i parsowaniu wyjścia.
  • Typowy błąd: dodanie do słownika nowych tokenów bez douczenia ich embeddingów — model traktuje je jak szum.

Najczęstsze pytania

Ile słów to jeden token?
Zależy od języka i tokenizera. Dla angielskiego popularna reguła mówi o około 0,75 słowa na token; dla polskiego tokenów na słowo jest więcej. Jedyny pewny sposób to policzyć tokenizerem danego modelu.
Dlaczego LLM myli się przy liczeniu liter?
Bo dostaje tokeny, a nie litery. Słowo „truskawka” może być dwoma–trzema tokenami i model musiałby z pamięci wiedzieć, z jakich liter składa się każdy z nich. Pomaga rozpisanie słowa litera po literze w poleceniu.
Czy tokenizer można zmienić w gotowym modelu?
Nie bez kosztów. Embeddingi i warstwa wyjściowa są przypisane do konkretnych numerów tokenów, więc zmiana słownika wymaga dalszego treningu. Częściej dodaje się kilka tokenów specjalnych i douczaje model.

Źródła

  • Sennrich R., Haddow B., Birch A., 2016, „Neural Machine Translation of Rare Words with Subword Units”, ACL 2016.
  • Radford A. i in., 2019, „Language Models are Unsupervised Multitask Learners”, raport techniczny OpenAI.
  • Kudo T., Richardson J., 2018, „SentencePiece: A simple and language independent subword tokenizer and detokenizer for Neural Text Processing”, EMNLP 2018 (System Demonstrations).
  • Petrov A. i in., 2023, „Language Model Tokenizers Introduce Unfairness Between Languages”, NeurIPS 2023.
  • Jurafsky D., Martin J. H., „Speech and Language Processing”, 3rd ed. (wersja robocza online), rozdz. 2 (słowa i tokeny).

Zobacz też