Alterna · учебный материал
12.1 Буква, байты и токен — не одно и то же
Внешне один знак может быть записан несколькими кодовыми единицами. Сначала разделим способы хранения строки и правила её разбиения моделью.
Что в этом материале
- Четыре способа посчитать текст
Содержание и основные понятия
Компьютер хранит строки через кодовые единицы и байты.
Внешне один знак может быть записан несколькими кодовыми единицами. Сначала разделим способы хранения строки и правила её разбиения моделью.
Разбиение задаётся конкретным словарём и правилами. Байт, символ, слово и токен не обязаны совпадать. Полученный номер — адрес, а не числовой смысл слова.
Для изменения рисунка включитеJavaScript; расчёт и теория доступны далее.
Четыре способа посчитать текст
Число видимых знаков, 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
Академическая база →