Model językowy nie czyta liter ani słów. Dostaje ciąg tokenów, czyli kawałków tekstu wyciętych według reguł tokenizera. Ten etap, zwykle pomijany w dyskusjach o jakości modeli, tłumaczy kilka codziennych zjawisk: kłopoty z liczeniem liter, szybsze zapełnianie okna kontekstu przy polskim tekście i rachunek za API wyższy, niż sugerowałaby liczba znaków.
Czym właściwie jest token
Token to jednostka, na którą tokenizer dzieli tekst przed przekazaniem go modelowi. Nie jest to ani litera, ani słowo. W najczęściej stosowanym podejściu, byte pair encoding (BPE), algorytm zaczyna od pojedynczych bajtów i wielokrotnie łączy najczęściej występujące pary w dłuższe fragmenty. Po treningu na dużym korpusie powstaje słownik złożony z kilkudziesięciu tysięcy elementów: częste słowa i ich formy trafiają do niego w całości, rzadkie rozpadają się na kawałki.
Sam pomysł pochodzi z kompresji danych, ale do uczenia maszynowego wprowadził go w 2015 roku zespół Rico Sennricha z Uniwersytetu w Edynburgu, zastępując awaryjne słowniki dla słów spoza słownika segmentacją podwyrazową (arXiv:1508.07909). [1] Współczesne modele OpenAI korzystają z byte-level BPE, gdzie alfabetem są bajty, a nie znaki. Dzięki temu żaden tekst nie jest dla modelu nieznany, ale ceną bywa dłuższa reprezentacja.
Konsekwencja jest prosta: granice tokenów nie pokrywają się z jednostkami, o których myślimy. Spacja często przykleja się do następnego słowa, interpunkcja bywa osobnym tokenem, a długi wyraz może zająć kilka. Model widzi wtedy coś w rodzaju nie, prawdo, podobnie i nie ma w tym nic dziwnego, dopóki nie poprosimy go o operację na literach albo o porównanie końcówek.
Warto dodać, że tokenizacja nie jest uniwersalna. Każda rodzina modeli ma własny słownik i własne reguły, a liczba tokenów wyliczona dla jednego modelu nie przenosi się na inny. To jedna z przyczyn, dla których porównywanie cen API przez liczbę znaków bywa mylące.
Dlaczego polski tekst zajmuje więcej tokenów
Polski ma dwa utrudnienia, które nakładają się na siebie. Pierwsze jest techniczne: w kodowaniu UTF-8 znaki diakrytyczne zajmują dwa bajty. Każde ą, ć, ę, ł, ń, ó, ś, ź, ż to dwa bajty zamiast jednego. W byte-level BPE taki znak musi zostać złożony z jednego lub kilku tokenów bajtowych, zależnie od tego, czy autorzy słownika uwzględnili go jako całość, czy tylko jako kombinację bajtów.
Drugie utrudnienie jest statystyczne. Słowniki tokenizerów powstają na korpusach zdominowanych przez angielski, więc polskie słowa, zwłaszcza w formach fleksyjnych, są w nich rzadsze i częściej rozpadają się na fragmenty. Tekst o identycznej treści może mieć inną długość w tokenach, zależnie od języka. Widać to szczególnie przy odmianie: jedna końcówka potrafi zmienić podział wyrazu na kawałki, mimo że znaczenie pozostaje zbliżone.
Skala bywa duża. W pracy opublikowanej na konferencji NeurIPS 2023 Aleksandar Petrov, Emanuele La Malfa, Philip Torr i Adel Bibi porównali tokenizację tych samych treści w różnych językach i znaleźli różnice sięgające 15 razy. Nawet modele pracujące na bajtach, teoretycznie odporne na brakujące znaki, wykazywały ponad czterokrotne różnice w długości kodowania dla niektórych par języków (arXiv:2305.15425). [2] To wartości skrajne, nie średnia dla polskiego, ale kierunek jest jasny: im mniejszy udział języka w korpusie treningowym, tym dłuższa reprezentacja.
Co dokładnie widzi model
Z punktu widzenia modelu nie ma znaczenia, czy token to całe słowo, czy jego fragment. Sieć neuronowa nauczyła się pracować na takich jednostkach i radzi sobie z nimi dobrze. Problem pojawia się na granicach zadań: gdy trzeba odwrócić wyraz, policzyć samogłoski, porównać długość napisów albo odtworzyć dokładny ciąg znaków. Wtedy model musi niejako złożyć wynik z kawałków, których nie widzi jako całości.
To samo dotyczy liczb. Cyfry bywają dzielone na grupy, co utrudnia operowanie pozycją dziesiątkową. Nie jest to jedyne wyjaśnienie słabszej arytmetyki modeli, ale jeden z powodów, dla których warto prosić o obliczenia w osobnym narzędziu, a nie tylko w rozmowie.
Praktyczne skutki: koszt, czas i okno kontekstu
Po pierwsze, pieniądze. Rozliczenie API idzie za tokeny wejścia i wyjścia, nie za znaki. Dłuższa reprezentacja tej samej treści oznacza wyższy rachunek, a przy dużych wolumenach różnica bywa odczuwalna bardziej niż zmiana cennika. Dotyczy to zwłaszcza systemów, które wysyłają ten sam długi kontekst przy każdym zapytaniu.
Po drugie, czas. Model generuje odpowiedź token po tokenie, więc dłuższy tekst to także dłuższe oczekiwanie. W aplikacjach interaktywnych opóźnienie bywa ważniejsze niż koszt, a polski tekst ma tu pod górkę z przyczyn opisanych wyżej.
Po trzecie, okno kontekstu. Jeśli model przyjmuje określoną liczbę tokenów, polski dokument zmieści się w nim w mniejszej całości niż angielski o tej samej objętości. Przy długich umowach, transkrypcjach czy kodzie warto liczyć tokeny, a nie znaki. Biblioteka tiktoken OpenAI robi to lokalnie dla konkretnego kodowania, na przykład o200k_base używanego przez GPT-4o, i pozwala sprawdzić długość tekstu przed wysłaniem go do modelu (github.com/openai/tiktoken). [4] [5]
Po czwarte, dzielenie dokumentów. Przy fragmentowaniu długiego tekstu warto ciąć po granicach zdań i zostawiać zapas na odpowiedź oraz na instrukcję systemową. Tokenizer SentencePiece, opisany przez Takua Kudo i Johna Richardsona w 2018 roku, powstał właśnie po to, by segmentacja nie zależała od języka i nie wymagała wstępnego dzielenia na słowa (arXiv:1808.06226). [3] To wygodne, ale nie usuwa różnic w gęstości informacji między językami.
Czego tokenizacja nie wyjaśnia
Łatwo przecenić ten mechanizm. Zły podział na tokeny nie jest główną przyczyną halucynacji modeli ani słabego rozumowania. To raczej jeden z kosztów, obok danych treningowych, sposobu uczenia i samej architektury. Nie każda pomyłka w liczeniu liter wynika z tokenizacji, choć właśnie tam trzeba szukać pierwszego wyjaśnienia.
Trzeba też uważać na liczby z badań. Wspomniane 15 razy dotyczy konkretnych par języków i konkretnych tokenizerów, a nie uniwersalnej reguły. Kolejne generacje słowników są trenowane na bardziej zróżnicowanych korpusach, więc różnice maleją, ale nie znikają, dopóki optymalizacja idzie pod dominujący język. Wniosek jest skromny: jeśli coś dzieli się dziwnie, sprawdź tokenizer i policz tokeny, zamiast zgadywać na podstawie liczby znaków.
Źródła
- Sennrich, R., Haddow, B., Birch, A., Neural Machine Translation of Rare Words with Subword Units, arXiv:1508.07909, wersja 5 z 10 czerwca 2016, arxiv.org/abs/1508.07909.
- Petrov, A., La Malfa, E., Torr, P. H. S., Bibi, A., Language Model Tokenizers Introduce Unfairness Between Languages, NeurIPS 2023, arXiv:2305.15425, wersja 2 z 20 października 2023, arxiv.org/abs/2305.15425.
- Kudo, T., Richardson, J., SentencePiece: A simple and language independent subword tokenizer and detokenizer for Neural Text Processing, arXiv:1808.06226, 19 sierpnia 2018, arxiv.org/abs/1808.06226.
- OpenAI, tiktoken (repozytorium i dokumentacja), github.com/openai/tiktoken, dostęp 20 października 2026.
- OpenAI Cookbook, How to count tokens with tiktoken, github.com/openai/openai-cookbook, dostęp 20 października 2026.


