惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Hacker News: Ask HN
Hacker News: Ask HN
H
Help Net Security
Microsoft Azure Blog
Microsoft Azure Blog
B
Blog RSS Feed
Jina AI
Jina AI
Stack Overflow Blog
Stack Overflow Blog
量子位
博客园_首页
Vercel News
Vercel News
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Forbes - Security
Forbes - Security
IT之家
IT之家
N
News and Events Feed by Topic
S
Security Affairs
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Webroot Blog
Webroot Blog
Recorded Future
Recorded Future
L
LangChain Blog
Y
Y Combinator Blog
AI
AI
MyScale Blog
MyScale Blog
大猫的无限游戏
大猫的无限游戏
小众软件
小众软件
Know Your Adversary
Know Your Adversary
AWS News Blog
AWS News Blog
Help Net Security
Help Net Security
Cyberwarzone
Cyberwarzone
L
Lohrmann on Cybersecurity
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Google Online Security Blog
Google Online Security Blog
V2EX - 技术
V2EX - 技术
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
PCI Perspectives
PCI Perspectives
I
Intezer
T
Tenable Blog
G
Google Developers Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
T
Troy Hunt's Blog
L
LINUX DO - 最新话题
云风的 BLOG
云风的 BLOG
C
CXSECURITY Database RSS Feed - CXSecurity.com
有赞技术团队
有赞技术团队
O
OpenAI News
P
Proofpoint News Feed
TaoSecurity Blog
TaoSecurity Blog
C
Check Point Blog
Last Week in AI
Last Week in AI
S
Schneier on Security
Simon Willison's Weblog
Simon Willison's Weblog
Blog — PlanetScale
Blog — PlanetScale

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания Автономность как точка невозврата: кто будет субъектом в цифровом будущем Обучение ИИ в «диких» условиях: как рутинные действия превращаются в датасеты Как измерить LLM для задач кибербеза: обзор открытых бенчмарков Где хранить код? Сравнение GitHub, GitLab и Bitbucket Математика объясняет, почему нормальное распределение встречается повсюду Почему ваш FinOps не работает: 12 тезисов от практиков Как подписать проектную документацию УКЭП с использованием бесплатных лицензий Pilot Адаптивное администрирование Sigla Vision Я грузил уран в бочки, а потом 20 лет строил ИТ в атомной отрасли Чем позвонить с Эвереста? История и обзор спутниковой связи. Часть 2 Как языковая модель помогает контролировать качество инструктажей по охране труда в металлургии Как не передать на desktop свой IP в РКН Анатомия SAP Privileges: как устроено управление правами в macOS MoneyDev: Сказка про три главных слова Обновлённый токенизатор видео K-VAE 2.0 от Сбера Как сделать диспетчеризацию дома на 1284 квартиры почти бесплатно Как мы разогнали железную дорогу Мы дали агентам рутину. Теперь надо решить — что делать с освободившимся временем Токсичный контент, промпт-хакинг и защита ИИ — всё о Guardrails для LLM Умный город начинается с точного взгляда: как «Фалькон Тех» меняет пространство к лучшему Навайбкодил приложение для анализа графов Почему Дюну так интересно читать? Упрощаем работу с рутиной или как стать Гендальфом Белым Деконструкция Go: CPU, RAM и что там происходит. Go Assembler база. Часть 1.1 Какие профессии исчезнут из-за ИИ, а какие появятся? И что с этим делать Как мы построили IT-отдел, где хочется расти: архитектурные встречи, прозрачные метрики и книжные подарки Rufler: Делаем из Claude Code автономный рой через один YAML-конфиг Sing-box и белый список приложений Как построить надёжный обмен сообщениями в микросервисах: лучшие практики для enterprise OpenAI строит MLM-пирамиду, а McKinsey и Accenture помогают ей в этом Дом, который не построил Фишер (Часть 2) «Сверхзвуковой математик» против «Вдумчивого логиста»: битва алгоритмов 3D-упаковки Мультимодальные модели – грубый и дорогой инструмент Разговоры ничего не стоят. Код тоже Проверки физических лиц: с кого начнет ФНС Топ-10 бесплатных нейросетей для создания видео в 2026 году Первые слои кода: как наши решения сегодня определяют архитектуру ИИ на десятилетия Разработка нового статического анализатора: PVS-Studio JavaScript Поиск уязвимостей ПО: базовый минимум или роскошный максимум Почему оценка персонала не работает как инструмент управления Как мы разработали ИИ-ассистента и сократили рутину продуктовой команды на 50% Как я ушел из найма, нажарил косточек и продал на маркетплейсах на 168 млн в год Когда 1С:ERP уже внедрена, а нормального производственного плана всё ещё нет Как я сделал Claude мультимодальным, подключив к нему Qwen Omni Как приглашение на вакансию мечты превращается в атаку Infrastructure as Code: философия и лучшие практики IaC Тестируем Yandex Code Assistant на задаче, в которой нужно хранить секреты nxs-universal-chart v3.0: новое поколение универсального Helm-чарта Callback Injection: Техника, которая отправила Microsoft Defender в глухой нокаут «Все идеи на стол»: митап как способ вывести проект из тупика Сегодня я узнал нечто новое о GPU благодаря багу в своей игре Как заставить LLM ̶ ̶г̶а̶л̶л̶ю̶ ̶ эволюционировать Карта событий как фундамент аналитики: практический кейс для E-commerce Что выбрать для AI: x86, ARM или RISC-V? Дайджест железа за март Роль соматических мутаций в развитии аутоиммунных заболеваний: путь к избирательной терапии Mythos от Anthropic — тревожный сигнал для всех, а не только для банков Guardrails для LLM на Java: как приручить промпт‑инъекции и токсичные ответы Green-VLA: как мы собрали VLA-модель для реального антропоморфного робота и не потеряли обобщение Финансовая гонка вооружений: почему умные люди добровольно в ней участвуют Эра ИИ-агентов наступила: выбираем лучшего цифрового сотрудника # Практический опыт внедрения WinCC Redundancy на производственном предприятии Сделал MVP за 3 дня, а потом неделю прикручивал оплату. Оно того стоило? Физика против Маска: почему Starship V3 может оказаться ещё одной катастрофой Нефть Венесуэлы: крупнейшие запасы в мире, но не крупнейшая нефтяная держава JPA 4. Переосмысление Hibernate Почему зеркальная фотокамера Nikon D5 десятилетней давности идеально подошла для миссии «Артемида-2» Проект «Уровень-Спутник» или как мы сделали платформу для гидрологов «Замедлиться, чтобы ускориться»: почему ИИ повышает цену ошибок в требованиях и архитектуре Как с нуля поднять трафик IT-компании на 1657% при бюджете 55 тыс. и выжить Pixel-perfect Downsampling — идеальная отрисовка 50 миллионов точек без потерь
Токенизация: почему ИИ сложно считать буквы «r» в «strawberry»?
maxim_tsar ( · 2026-05-07 · via Все публикации подряд на Хабре

Пока мы воспринимаем свои промпты как обычный текст из символов, для LLM они в виде токенов «выглядят» совсем иначе. И если не осознавать этого, порой можно наткнуться на проблемы. Поэтому полезно (и интересно) понимать: что вообще представляют собой токены? По какому алгоритму текст преобразуют в них и обратно? Какие важные нюансы при этом возникают?

Возможно, подробнее и понятнее всех объяснил пару лет назад ИИ-рисерчер Андрей Карпатый, записав двухчасовое видео на английском. А теперь мы решили сделать хабрапост, который и пересказывает на русском главное из этого видео, и делает поправку на прошедшее время, и учитывает другие источники (вроде книги «Build a Large Language Models from Scratch»). Описанное применимо к мейнстримовым LLM вроде GPT, в других моделях возможны отличия.

Токенизация дает немало возможностей «пострелять себе в ногу». Она усложняет для LLM целый ряд задач:

  • разбор слов по буквам;

  • обработку строк вроде «перевернуть текст задом наперед»;

  • работу с различными языками вроде японского;

  • арифметические операции;

  • для некоторых (обычно старых) LLM — работу с Python или JSON;

  • некоторые LLM могли останавливаться при виде слова «<|endoftext|>»;

  • некоторые LLM могли «сходить с ума» при виде слова «SolidGoldMagikarp».

Поэтому многие проблемы, которые выглядят для людей как «недостатки LLM», на самом деле связаны не с самими LLM, а с тем, как токенизатор предоставляет им информацию. 

С этим можно частично справляться: например, современная LLM может не заниматься арифметикой сама, а сразу использовать калькулятор. Но проблемы остаются. Скажем, если попросить перевернуть слово, у части моделей «Хабрахабр» все еще может превратиться в какой-то «Хахабрабр»:

Почему так? И как это все работает? Начнем рассматривать с наглядного примера.

Tiktokenizer

Сайт tiktokenizer.vercel.app позволяет ввести любой текст и наглядно увидеть, на какие токены он окажется разделен. Рекомендуем немного побаловаться, это позволяет многое ощутить живее, чем по теоретическим текстам.

Например, там можно переключаться между разными токенизаторами, выбирая из списка справа вверху. И благодаря этому заметно, насколько они порой различаются. Варианты «gpt-2» и «gpt-4» могут делить один и тот же текст на совершенно разное количество токенов. Так что разные модели «увидят» один и тот же промпт по-разному.

А еще наглядно, если при выбранном варианте «cl100k_base» ввести простое слово «egg» в трех вариантах: целиком строчными буквами, начать с заглавной, целиком с заглавными. Получается так:

Получившиеся токены различаются: это регистрозависимая система. Но еще любопытнее, как все оказалось поделено на части. Простое «egg» — это целиком один токен. В «Egg» отдельным токеном стал первый символ. А в «EGG» — последний.

Если в промпте дважды встречается слово «egg» и один раз оно оказалось в начале предложения, то для нас это ощущается как «одно и то же слово». А для машины тут это даже не «два разных токена», а «один токен против двух». Совершенно неконсистентная система, в которой нет строгого правила, как именно делить.

С числами не проще. Есть блог-пост «Integer tokenization is insane», который прямо кричит: это же безумие. Если бы все поделили по принципу «одна цифра — один токен», было бы консистентно. А тут числа одной длины могут в совсем разных местах делиться на части. 

Неудивительно, что у LLM могут быть проблемы с переворачиванием слов или арифметикой. Когда смотришь на такое, наивный внутренний голос перестает спрашивать: «Ну, этим LLM чо, сложно правильно посчитать, что ли?» И начинает спрашивать противоположное: «Блин, как тогда все вообще хоть как-то работает? И почему все так сделали?» 

Почему все сложно

Казалось бы, человечеству привычно обрабатывать строки посимвольно. Напрашивается вопрос: почему тут было не сделать так же, разве всем не было бы проще? Потому что тут пытаемся работать со «смысловыми единицами»? Так, может, просто регуляркой порезать на отдельные слова, как в некоторых других случаях делают? Откуда вообще взялись эти обрубки по несколько символов?

Тут любопытно заглянуть в публикацию «Language Models are Unsupervised Multitask Learners», которая представляла всем модель GPT-2. Там авторы объясняют свой подход. Вот, пишут они, одни модели оперируют на уровне байтов, а другие — на уровне слов. И те, что со словами, получаются настолько производительнее, что игнорировать это нельзя.

Но есть и проблема: если у тебя слова и какой-то «словарь» из них, то что делать с тем, что в словарь не попадает? Универсальная языковая модель должна допускать возможность абсолютно любой строки. С набором слов это затруднительно, тут лучше подходят байты UTF-8: из них что хочешь собирай.

И с этими двумя вводными, пишут они, хорошим компромиссом оказывается подход byte-pair encoding. С ним, когда какие-то сочетания символов часто встречаются, они сами смогут схлопываться в единый токен. А редкие символы останутся одиночными. Так и производительность вырастет, и нужной гибкости не потеряем.

Карпатый объясняет логику схожим образом. Мол, он сам и рад бы просто символами все машине скармливать. Но у нас в LLM ведь всегда «ограниченный бюджет» контекста и внимания. Если каждый символ отдельным токеном делать, и из промпта будет получаться длиннющая цепочка токенов, то бюджет начнет быстро расходоваться. А когда тот же промпт в меньшее число символов упакован, куда лучше получается.

Впрочем, это не значит «надо как можно больше в один токен запихнуть». Имеющиеся варианты токенов хранятся в «словаре», и растить его безразмерно тоже плохо. Поэтому насколько большой будет словарь и насколько агрессивно текст будет «схлопываться» — это настраиваемый гиперпараметр. Нет единственно верного значения, надо нащупывать точку баланса.

А как именно это схлопывание происходит?

Byte-pair encoding

Идея в следующем. Вот есть у нас, например, такая строка:

хабрахабр

В ней четыре разных символа: «х», «а», «б», «р». Можем записать их в словарь, присвоить каждому свой номер. Получится словарь из четырех разных токенов, и дальше мы можем модели передавать эти токены, составляя из них «хабрахабр» или еще что-то. 

Но теперь попробуем сокращать. Для этого пройдемся по всей строке и посмотрим: какая пара символов там встречается чаще всего?

Для начала — «ха». Запишем в словаре, что кроме «х», «а», «б», «р», есть еще и новый токен со своим номером. И он означает «ха» вместе.  

Представим тут для условного отображения этот токен как J, с ним строка получается такой:

JбраJбр

Смотрим дальше и видим, что «бр» тоже встречается дважды. Сделаем тоже единым токеном, заменим на K:

JKаJK

И теперь самое интересное: можно и рекурсивно. Вот у нас теперь дважды JK повторяются. Заменим на L, запишем в словаре, что это пара JK. А про сами J и K в нем уже записано, что они сами за пары.

LaL

Дальше сокращать некуда, повторяющихся пар нет. Но строка в токенах сократилась с девяти символов до всего лишь трех. И теперь у нас есть словарь из семи вариантов «х», «а», «б», «р», «J», «K», «L». Этот словарь позволяет восстановить ее из токенов (декодировать).

В общем-то, главная идея уже объяснена. Сначала мы с помощью какого-то текста, находя в нем частые сочетания, создаем словарь токенов. В данном случае мы быстро уперлись в «пар больше нет». Но при реальном использовании подали бы куда больше текста и поставили бы ограничение: например, «нам нужен словарь примерно на 50 000 токенов, так что как сократишь 50 000 пар — остановись».

А затем, когда словарь уже есть, можно его использовать в обе стороны. Когда пользователь задает любой промпт строкой, по имеющемуся словарю можно закодировать ее токенами и отправить в языковую модель. А она отвечает токенами, и дальше их, опять же с помощью словаря, можно декодировать в текст, чтобы показать пользователю понятным ему образом. Вроде бы все просто?

Нюансы

При кажущейся простоте здесь хватает своих тонкостей. Начиная с того, что алгоритм называется «byte-pair», но выше мы объединяли символы. А они ведь в UTF-8 могут и больше одного байта занимать. И чем мы тогда оперируем-то, символами или байтами?

Вообще говоря, возможны оба подхода. Библиотека SentencePiece от Google подходит на уровне Unicode Code Points. А Tiktoken от OpenAI — на уровне байтов.

И авторы публикации GPT-2, и Карпатый в своем видео ратуют за второй подход. Причина в следующем. Словарь у модели должен быть такой, чтобы из него можно было сложить любую строку. Значит, исходный набор токенов (до того, как начнем объединять в пары) должен покрывать все варианты. Вот мы выше начинали с «х», «а», «б», «р», но из этого мало что можно собрать, кроме «Хабра». А с чего надо начинать, чтобы складывалось вообще все?

Для Unicode Code Points «все варианты» — это весь текущий юникод, в районе 150 000 вариантов. Всю эту прорву надо просто с ходу добавить в словарь, еще до byte-pair encoding. А ведь там еще и добавляют со временем эмодзи всякие, с этим что делать, когда ваша модель уже выпущена?

А вот если оперировать на уровне байтов, то вариантов-то, в общем-то, всего 256. Добавил их в начале словаря — и свободен. 

Но при переходе к байтам возникают свои нюансы. Например, если символ редкий и занимает больше одного байта, то при объединении пар его байты могут так и не «склеиться» вместе. И если потом набрать текст из таких редких символов, может получиться, что в нем токенов еще больше, чем символов. А мы тут вроде бы сокращать пытаемся.

Кстати, а редкий — это вообще по какому принципу? Редкий среди чего именно? И вот тут вылезает еще один интересный нюанс: по сути, у токенизаторов есть свой процесс обучения на датасете. Слово «обучение» тут может звучать слишком громко, поскольку в целом это просто применение byte-pair encoding для обнаружения частых пар, а не градиентный спуск. Но и здесь есть о чем подумать.

Датасет

Выше мы считали пары в строке «хабрахабр». И словарь возникал на основе этой строки: какие пары встречались часто, те попали в него и стали объединяться в цельный токен. А подали бы мы вместо этого строку «гоголь-моголь» — в словаре были бы совсем другие пары, и все объединялось бы иначе. 

И от этого, что было выбрано, зависит вся дальнейшая работа. Сначала словарь токенов формируется на основе того, что изначально было подано на вход. А затем, когда этот словарь уже создан и используется, приходят пользователи со своими промптами, где может быть нечто совсем другое. 

Скажем, выше мы оперировали строкой «хабрахабр» на привычном нам языке. И благодаря этому некоторые русскоязычные сочетания букв стали объединяться. Но если мы сделаем LLM с таким токенизатором, а ею попробуют воспользоваться китаец или бразилец, они будут вводить промпты на своих языках.

И если мы не показывали токенизатору заранее тексты на этих языках, то он не будет ничего знать о частых сочетаниях в них и не сможет ничего эффективно соединять в токены. Получается, токенов там будет получаться много, и качество работы нашей LLM будет хуже. Значит, если модель создается для всего мира, то и при обучении датасета надо думать о самых разных языках. 

Если на tiktokenizer.vercel.app сравнить варианты «gpt-2» и «gpt-4» с текстами на русском, выглядит так, будто при создании первой модели еще особо не задумывались об отличных от английского языках, а вот при разработке второй уже начали это делать.   

Но языки — это еще не все. Люди ведь сейчас обращаются к LLM еще и, скажем, за кодом. А там свои типичные сочетания. Для Python, например, важны многочисленные пробелы. А еще можно вспомнить, что для LLM строчные и прописные буквы различаются, при этом частые сочетания значимы в обоих случаях, так что и в датасете нужны оба…

И получается вот что. Мы давно привыкли слышать, что при обучении LLM важен хороший датасет. Но гораздо реже говорят о том, что он нужен и при создании токенизатора. Датасет может быть как тем же, что у самой LLM, так и другим. И от него тоже отчасти зависит, каких результатов можно будет от добиться от языковой модели. 

Но и это еще не все…

Предобработка

Выше сказано, что в токенизации LLM ушли от подхода «поделить на слова». На самом деле — не совсем.

Если просто объединять все буквы по частотности с помощью byte-pair encoding, может оказаться так, что захватишь «конец одного слова, пробел и начало другого». Скажем, «he is» и «she is» слипнется вместе общее «e i». 

Обычно это не то, чего хотелось бы. Поэтому возник гибридный подход: давайте сначала разрежем все регулярным выражением на отдельные слова и другие сущности, а затем уже в этих разрезанных фрагментах будем соединять частые пары. Чтобы символы «слипались» только в пределах одного слова или числа, а не соединяли разные.

Сама модель GPT-2 закрытая, но на GitHub выложено немного связанного с ней кода, в том числе и файл, касающийся токенизации. Он включает в себя строку с угрожающего вида регуляркой:

```python
self.pat = re.compile(r"""'s|'t|'re|'ve|'m|'ll|'d| ?\p{L}+| ?\p{N}+| ?[^\s\p{L}\p{N}]+|\s+(?!\S)|\s+""")
```

Что тут происходит? То самое «разрезание на части». Сначала в тексте ищут типичные сокращения с апострофами (вроде «you're» или «I've»), чтобы сразу отделить часть с апострофом. Затем ищут сочетания из нескольких букв подряд (то есть слова), из цифр, отдельно разбираются со знаками препинания… 

В целом понятно, но есть любопытные моменты. Во-первых, захардкожены типичные сокращения из английского языка, но не из каких-либо других. То есть и здесь получается, что в LLM разные языки могут обрабатываться с разным качеством еще на стадии токенизации, когда до самой LLM дело даже не дошло. 

А во-вторых, над этой строкой на GitHub есть трогательный комментарий:

# Should haved added re.IGNORECASE so BPE merges can happen for capitalized versions of contractions

То есть сообщается примерно следующее: «Блин, мы забыли сделать это регистронезависимым, чтобы сокращения парсились, даже когда они капслоком». Если пользователь напишет «you've», то «'ve» будет в токенах учитываться отдельно от «you», но вот если «YOU'VE», там регулярка ничего не отделит.

Как видим, задача токенизации не такая уж примитивная, если даже ведущие мировые компании могут в ней сами сокрушаться об ошибках. Но позже, в библиотеке Tiktoken, это все-таки поправили.

Специальные токены

Выше мы писали об «обычных» токенах, в которые превращаются сообщения пользователя и модели. Но все несколько хитрее. Есть еще и «служебные».

Самое простое — токен «окончание сообщения», бывают и другие. Благодаря этому, например, когда в датасете сконкатенированы разные тексты подряд, модель может понять, где заканчивается один и начинается другой.

Карпатый рассказывает, как с ранними моделями GPT это могло приводить к забавным сложностям: если сказать модели «напиши мне <|endottext|>», она не понимала, что именно ее просят повторить. Похоже, такой токен сразу обрабатывался отдельно, а на вход модели даже не подавался.

Сейчас ранние проблемы обычно уже не встречаются. Но для специальных токенов развилось другое направление: теперь агентские системы используют их, чтобы модель могла обращаться к инструментам. И в агентских системах порой возникают свои сложности, достойные отдельного хабрапоста.

SolidGoldMagikarp

Напоследок можно добавить забавную историю. В видео рассказано, как в 2023-м в ChatGPT была обнаружена странность. Если пользователь включал в сообщения некоторые «странные» слова вроде «SolidGoldMagikarp», модель словно сходила с ума: могла переключиться на другую тему или даже начать материть пользователя, хотя это ей совершенно не свойственно.

Почему так? Похоже, дело в следующем. Изначально SolidGoldMagikarp — юзернейм пользователя на Reddit. Сейчас этот профиль уже удален, но до того информация о нем, вероятно, уже попала в датасет для токенизатора. А вот в датасет для обучения самой модели — не попала.

И получилось вот что. Токенизатор при обучении много раз встречал «SolidGoldMagikarp» и объединил это. Если пользователь пишет что-то такое, то оно не делится на символы, а единым токеном отправляется в LLM.

Но поскольку в датасете обучения LLM такой токен не встречался, модель понятия не имеет, что с ним делать. Она на нем не обучена, каждый раз видит его словно впервые, и ничего из данных для обучения не подсказывает ей, что с ним делать, — статистических связей нет.

А в итоге получается «undefined behavior». Может произойти что угодно.

Конкретно случай с «SolidGoldMagikarp» заметили, поэтому теперь, в новых моделях, вряд ли можно натолкнуться на проблемы именно с этим словом. Но возможны какие-то новые «glitch tokens», о которых мы еще не знаем.

Что дальше

Если хочется залезть в тему глубже, то можно посмотреть двухчасовое англоязычное видео целиком или отдельно открыть код из него. Там можно увидеть конкретную простую имплементацию токенизатора на Python. Только учитывайте, что это не единственно верный способ написать токенизатор, а лишь один из. 

Это видео Карпатый снял еще в мире, где LLM воспринимались лишь как чат-боты. А с тех пор пришли агенты с использованием «инструментов» (tools). И теперь, когда модели сталкиваются со сложными для них задачами (например, арифметическими), во многих случаях они пользуются инструментом (например, калькулятором), который даст точный результат.

Поэтому сейчас сложности токенизации уже не делают так больно, как в 2024-м. Но это не значит, что надо махать рукой, мол, теперь можно не разбираться. Тут проблемы не решили магически целиком, а в основном обошли стороной. Так что на грабли все еще можно наступить, и где они разложены — полезно понимать.

При этом токенизация — только начало сложного процесса. Если пользователь вводит текстовый промпт, этот текст разбивается на токены… и дальше от токенов происходит переход к эмбеддингам. А если все это работает т в агентской системе, то еще и у агента запускается цикл выполнения. Во всем этом тоже интересно разбираться.