alterna ai
ALTERNA AI / ГЛАВА 12 · 01

12.1 Буква, байты и токен — не одно и то же

Компьютер хранит строки через кодовые единицы и байты.

Внешне один знак может быть записан несколькими кодовыми единицами. Сначала разделим способы хранения строки и правила её разбиения моделью.

Разбиение задаётся конкретным словарём и правилами. Байт, символ, слово и токен не обязаны совпадать. Полученный номер — адрес, а не числовой смысл слова.

Четыре способа посчитать текст

Число видимых знаков, Unicode code points, UTF-16 code units и UTF-8 bytes может различаться. В JavaScript .length считает UTF-16 units. Итератор строки проходит code points; Intl.Segmenter умеет выделять grapheme clusters, приблизительно соответствующие воспринимаемым символам. Это ещё не токены языковой модели. L01.

У строки «Я🙂» два code points, три UTF-16 units и шесть UTF-8 bytes. Буква занимает два байта, emoji четыре. Знак «é» можно записать одним U+00E9 или двумя code points: e и combining acute accent. Внешне строки похожи, байты различны.

Эксперимент. Вставьте кириллицу, emoji, пробел, перевод строки и составной знак. Сопоставьте code point U+…, UTF-8 bytes и grapheme count. Нельзя подменять отсутствие Intl.Segmenter приблизительным числом и объявлять его точным.

Нормализация NFC может сделать эквивалентные записи одинаковыми, но это изменение представления. В нашем обратимом byte-tokenizer она не выполняется, регистр и пробелы сохраняются. Изолированные UTF-16 surrogates отклоняются: стандартное UTF-8 кодирование заменило бы их U+FFFD, нарушив обещание восстановления исходной строки.

Связь с LLM. Контекстное окно обычно измеряется токенами, не буквами или байтами. Для одной фразы разные tokenizers могут выдавать разное число IDs. До сравнения размеров контекста нужно знать именно tokenizer модели.

text='Я🙂'
assert len(text)==2
assert len(text.encode('utf-16-le'))//2==3
assert len(text.encode('utf-8'))==6
assert 'é'.encode('utf-8') != 'e\u0301'.encode('utf-8')

Код повторяет только что разобранные операции. Полный проверяемыйPython-пример главы доступен отдельным файлом; показанный короткий фрагмент не заменяет его реализацию.

Emoji может занимать две UTF-16 units и один code point.

Словарь задаёт значение номера. Как этот вопрос продолжает полученный результат?

Python-примеры главы 12 Академическая база →