🧩 Что такое BPE = умный конструктор для слов
BPE (Byte Pair Encoding) — это алгоритм, который учит компьютер разбивать слова на осмысленные части.
Простой пример:
Слово: "investment"
Этап 1: i-n-v-e-s-t-m-e-n-t (отдельные буквы)
Этап 2: in-v-e-st-m-e-n-t (нашли частые пары)
Этап 3: in-vest-ment (объединили еще больше)
Результат: 3 токена вместо 10 букв!
🗺️ План нашего обучения BPE:
Этап 1: Подготовка → Разбиваем слова на символы + маркеры
Этап 2: Анализ → Считаем частоту отдельных символов
Этап 3: Биграммы → Ищем самые частые пары символов
Этап 4: Слияние → Объединяем одну пару в новый токен
Этап 5: Автоматизация → Повторяем 1000 раз подряд
Этап 6: Результат → Словарь из символов + подслов
🎯 Зачем это нужно в реальной жизни?
ChatGPT, BERT, и другие LLM используют BPE, чтобы:
- ✅ Понимать новые слова через части: crypto+currency
- ✅ Экономить память: "ing" вместо "i+n+g"
- ✅ Работать с разными языками одинаково
- ✅ Обрабатывать опечатки и сленг
🚀 Практика: строим BPE токенизатор
✅ Инструкция по запуску:
- 📱 Откройте Google Colab >>>>>ссылка на блокнот
- ▶️ Запускайте ячейки по порядку
- 🔄 Можете менять текст, смотреть, как меняются токены
- 🧠 Учитесь, как работают GPT, BERT и другие модели — изнутри
🚀 Ячейка 1: Установка и импорт (выполнить первой)
🎯 Что делаем: Устанавливаем самую свежую версию библиотеки для работы с датасетами.
⚠️ Если спросит: "Вы хотите перезапустить среду выполнения?" — нажмите "Перезапустить сеанс"
🔄 Ячейка 2: Импорт модулей
🎯 Что получили: Все необходимые инструменты для анализа текста и работы с данными.
📂 Ячейка 3: Загрузка данных
📊 Что происходит в этом коде:
- Загрузка датасета:Используем библиотеку datasets от Hugging Face.
Датасет ashraq/financial-news содержит заголовки финансовых новостей.
Это реальные данные из различных источников. - Выбор подмножества:Перемешиваем с фиксированным seed=1234 (для воспроизводимости).
Берем первые 1000 записей.
Извлекаем только поле "headline".
🎯 Почему финансовые новости?
- 💼 Много сложных составных слов (blockchain, cryptocurrency).
- 📈 Частые аббревиатуры (CEO, IPO, GDP).
- 🌍 Хорошо показывает, как BPE справляется с реальным языком.
Пример возможного вывода:
🧩 Ячейка 4: Подготовка к обучению BPE-токенизатора
Эта ячейка реализует первый этап обучения алгоритма BPE (Byte Pair Encoding) — подготовку начального словаря в виде последовательностей символов.
🎯 Главная идея: превратить текст в формат для BPE
ДО: "The price rises!"
ПОСЛЕ: "t h e ▁" "p r i c e ▁" "r i s e s ▁"
💡 Пример трансформации:
"blockchain"
↓ format_word()
"b l o c k c h a i n ▁"
↓ почему так?
- Каждая буква = отдельный токен
- ▁ = "здесь кончается слово"
- BPE будет искать: какие буквы часто рядом?
🔧 Код реализации:
🔧 Реализация: пошаговый разбор
1. Функция format_word
Что делает:
- Преобразует слово в строку, где каждый символ отделён пробелом, и в конце добавляется специальный маркер (по умолчанию ▁ ).
💡 Символ ▁ — стандартный маркер в токенизации, обозначающий начало нового слова (или что за ним следует пробел). Часто используется в BPE/WordPiece.
Зачем это нужно:
- BPE работает с последовательностями токенов и ищет самые часто встречающиеся пары соседних элементов.
- В начале все "токены" — это отдельные символы + маркер слова.
- Алгоритм будет постепенно "учиться", что b + l часто идут вместе → можно создать новый токен bl, и т.д.
2. Функция initialize_vocab(texts, lowercase=True)
✅ Шаг 1: Приведение к нижнему регистру
- Например: "Stock Market Rises!" → "stock market rises!"
- Это нормализация, которая уменьшает размер словаря и помогает модели лучше обобщать.
- Apple и apple будут считаться одним словом.
✅ Шаг 2: Нормализация пробелов
- \s+ — любые пробельные символы (пробелы, табуляции, переносы строк).
- Заменяются на один пробел.
- text.strip() убирает пробелы в начале и конце.
Пример:
" Fed announces rate hike " → "Fed announces rate hike"
👉 Это важно, чтобы не создавать "виртуальные" слова из-за лишних пробелов.
✅ Шаг 3: Разделение на слова
words = text.split()
- Разделяет текст по пробелам.
- Получаем список слов: ["fed", "announces", "rate", "hike"]
✅ Шаг 4: Очистка слов от конечной пунктуации
- Очищает слова от пунктуации на конце — корректно обрабатывает word!!! → word.
- Не затрагивает символ $ в начале — экономические обозначения сохраняются.
- Готовит данные к BPE, убирая "артефакты разметки", которые искажают частоты и мешают токенизации.
Примеры:
- "hike!" → "hike"
- "NASDAQ," → "NASDAQ"
- "non-profit" → "non-profit" ✅
- "10%?" → "10%"
📌 Это умная очистка: сохраняет внутреннюю структуру (например, e-commerce, cost-to-income), но убирает шум в виде пунктуации.
✅ Шаг 5: Форматирование и подсчёт частот
- Каждое очищенное слово преобразуется в формат BPE.
- В словаре vocab подсчитывается, сколько раз встречается каждый форматированный вариант слова.
Пример:
"blockchain" → "b l o c k c h a i n ▁"
"AI" → "A I ▁"
Если слово встречается несколько раз — его счётчик увеличивается.
✅ Результат выполнения ячейки
В результате предварительной обработки текстовых данных был сформирован начальный словарь для алгоритма BPE. Он включает 3424 уникальных отформатированных слова в виде последовательностей символов, разделённых пробелами, с добавлением специального маркера ▁, обозначающего конец слова.
Например, слово "blockchain" преобразуется в "b l o c k c h a i n ▁".
Словарь построен на основе следующих шагов:
- приведение текста к нижнему регистру,
- нормализация пробелов,
- удаление знаков препинания в конце слов (например, !!!, .),
- разделение на токены.
Анализ частотности выявил ожидаемую доминацию служебных слов английского языка:
- the (159 раз),
- to (151 раз),
- in, on, of — также входят в топ.
На фоне них особенно выделяются тематически значимые термины:
- earnings — 134 вхождения,
- analyst — 85,
- blog — 83.
Наличие earnings и analyst в топ-10 подтверждает тематическую фокусировку корпуса на финансовых и аналитических новостях, где ценность информации о прибылях компаний и оценках аналитиков особенно высока. Упоминание blog как частотного слова может указывать на активное цитирование мнений из блогов и медиа-платформ в новостных заголовках.
🧩 Ячейка 5: Анализ токенов
На этом этапе мы проводим глубинный анализ базовых элементов, из которых будет строиться языковая модель. Поскольку алгоритм BPE (Byte Pair Encoding) обучается, начиная с символов, крайне важно понимать:
- Какие символы (токены) присутствуют в корпусе,
- С какой частотой они встречаются,
- Какие из них могут стать основой для первых слияний.
Функция get_tokens_from_vocab выполняет разложение всех отформатированных слов на отдельные символы и суммирует их взвешенную частоту с учётом количества вхождений каждого слова.
🔹 Шаг 1: Инициализация счётчика — подробное объяснение
🧠 Что делает эта строка?
Она создаёт словарь нового типа — defaultdict, который автоматически присваивает значение по умолчанию каждому новому ключу, как только вы к нему обращаетесь.
В данном случае:
- int — это функция-конструктор, которая возвращает 0, когда вызывается без аргументов.
- То есть: int() → 0
- Значит, всякий раз, когда мы пытаемся обратиться к ещё не существующему ключу, он будет автоматически создан и присвоен ему ноль.
🔹 Шаг 2: Перебор всех слов словаря
- word — это отформатированное слово, например: 'e a r n i n g s ▁',
- freq — сколько раз это слово встречается в корпусе (например, earnings — 134 раза).
🔹 Шаг 3: Разбиение слова на токены
Получаем список отдельных символов (включая маркер ▁).
🔹 Шаг 4: Накопление частоты для каждого символа
- Каждый символ в слове учитывается столько раз, сколько само слово встречается в тексте.
- Пример:
Слово 'e a r n i n g s ▁' встречается 134 раза → каждый из 9 символов добавляет +134 к своему счётчику.
✅ Таким образом, функция учитывает не просто "сколько раз символ встретился в тексте",
а "вклад символа в общую статистику" на основе частотности слов.
🔹 Шаг 5: Возврат результата
Преобразуем defaultdict обратно в обычный словарь для удобства использования.
📊 Полученные результаты
✅ Итог и вывод
Ячейка 5 выполняет критически важный диагностический этап подготовки к обучению BPE. Она декомпозирует отформатированные слова на атомарные компоненты — символы и маркеры — и вычисляет их взвешенную частоту с учётом популярности слов. Полученные данные показали, что начальный словарь состоит из 48 уникальных токенов, доминируемых типичными для английского языка буквами (e, a, t, n, s) и маркером границы слова ▁. Высокая частота ▁ (8996 раз) подтверждает корректность разметки. Эти результаты служат основой для последующей итеративной агрегации — первого шага алгоритма BPE.
🔗 Ячейка 6: Поиск биграмм (пар символов)
На данном этапе мы переходим от частотности отдельных токенов к анализу их соседских отношений — то есть биграмм, или пар подряд идущих символов. Это ключевой шаг в алгоритме Byte Pair Encoding (BPE): его суть — повторяющиеся паттерны сливаются в новые, более крупные единицы, начиная с самых частотных.
✅ Задача:
Найти все смежные пары символов во всём словаре, посчитать, сколько раз они встречаются в совокупности всех слов с учётом их частот, и выделить топ-кандидатов на первое слияние.
🔍 Что делает код?
Функция:
Проходит по каждому отформатированному слову (например, "e a r n i n g s ▁"),
Разбивает его на символы,
Собирает все пары соседей:
('e','a'), ('a','r'), ('r','n'), ..., ('s','▁'),
Прибавляет к счётчику этой пары частоту всего слова — то есть одна пара в слове, которое встречается 150 раз, даёт вклад +150.
📊 Полученные результаты
1. 🥇 Лидер — ('s', '▁') — 1764 раза!
- Это конец слова с окончанием -s, например:earnings, analysts, reports, markets, blogs, prices.
- Вклад усилен как высокой частотой самих слов (например, earnings — 134 раза), так и их множественными формами.
- Появление s▁ как токена позволит BPE:Эффективно сжимать окончания,
Распознавать множественное число и притяжательный падеж (company's → company 's, но reports → reports → s▁).
🔥 Это очень полезное слияние — экономит много токенов.
2. 🥈 ('i', 'n') — 1092 раза
- Комбинация из: Стоп-слова in (110 раз),
Суффиксов: earnings, senior, analyst, currency,
Приставок: in- (в income, inflation, insights).
Укажет BPE на морфемную важность этой пары — уже на первом шаге будет выучена не просто буква, а значимая языковая единица.
3. 🥉 ('e', '▁') — 950 раз
- Слова, заканчивающиеся на e:
- the (159 раз)
- to, of, and, are, company
- .e — может быть в артефактах (u.k.'s → k . ' s — но если e в конце — это чисто).
- Покажет BPE, что некоторые символы часто "дышат" перед пробелом — пажилая основа для формирования границ.
⚙️ Ячейка 7: Функция слияния — сердце BPE
На этом этапе алгоритм BPE переходит от анализа к трансформации. Мы реализуем ключевую операцию — слияние двух наиболее частотных подряд идущих токенов в один новый токен, что является основным механизмом обучения модели.
🔁 Эта операция повторяется тысячи раз, создавая из отдельных символов устойчивые единицы: окончания, корни, артикли, вспомогательные глаголы — всё, что часто встречается в данном языковом корпусе.
🧰 Цель ячейки
- Реализовать корректную функцию слияния: merge_vocab.
- Проверить её на простом примере.
- Продемонстрировать работу на реальных данных из текущего словаря.
- Увидеть, как паттерн (s, ▁) превращается в токен s▁.
✅ 1. Реализация функции merge_vocab
Функция merge_vocab — это движущая сила BPE. Она находит указанную пару токенов и везде, где она встречается как отдельные соседние токены, заменяет её на новый составной токен.
🧠 Пояснение регулярного выражения:
- (?<!\S) — перед парой не должно быть не-пробела (начало или после пробела).
- (?!\S) — после пары тоже не должно быть не--пробела (конец или перед пробелом).
- Это гарантирует, что замена происходит только когда токены стоят отдельно, а не как часть других фрагментов.
🔬 2. Проверка на простом примере
Прежде чем применять к реальному корпусу, проверим логику на искусственном случае.
Результат исполнения:
🌍 3. Применение к реальным данным
Теперь — главный шаг: применение к настоящим данным.
Предыдущий анализ (Ячейка 6) показал, что наиболее частая биграмма — ('s', '▁'), встречается 1764 раза.
Почему она так часто появляется?
Потому что:
- В корпусе много слов во множественном числе: earnings, stocks, results, blogs.
- Много предложений начинаются с is: «Is inflation rising?», «Is the market stable?».
- В этих случаях s и ▁ часто стоят рядом как отдельные токены.
Значит, логично объединить их в один блок.
Выполняем слияние
🚀 Применяем слияние к реальному словарю из 3424 слов:
Слияние: ('s', '▁') → 's▁'
📌 Примеры слов до слияния:
'e a r n i n g s ▁' → 134
'r e s u l t s ▁' → 56
'i s ▁' → 52
's t o c k s ▁' → 82
✅ Результаты слияния:
'e a r n i n g s ▁' → 'e a r n i n g s▁' → 134
'r e s u l t s ▁' → 'r e s u l t s▁' → 56
'i s ▁' → 'i s▁' → 52
'b l o g s ▁' → 'b l o g s▁' → —
's t o c k s ▁' → 's t o c k s▁' → 82
🎉 Слияние завершено. Размер словаря: 3424 слов.
Новый токен 's▁' теперь часть BPE-лексикона и будет использоваться как единое целое.
Что меняется?
- Количество уникальных строк в словаре — остаётся прежним (3424).
Мы не добавляем и не удаляем слова, только переформатируем их. - Структура токенов — меняется: теперь s▁ — один токен вместо двух.
- Этот блок будет участвовать в следующих шагах как атомарная единица.
Зачем это нужно?
После объединения:
- Модель будет распознавать s▁ как паттерн границы слова.
- Это помогает при токенизации составных слов: например, earningsreport легче разбить на earnings + report, если модель знает, что s▁ — возможная граница.
- Уменьшается число шагов при разборе текста — обработка становится короче и эффективнее.
Итог
Мы:
- Реализовали функцию слияния merge_vocab.
- Проверили её на тестовом примере.
- Применили к частотной паре ('s', '▁').
- Обновили словарь: теперь s▁ — единый токен.
Это первый шаг в автоматическом создании словаря.
Далее процесс будет повторяться много раз — BPE сам будет строить представление текста, двигаясь от символов к подсловам.
🧩 Ячейка 8: Реализация основного цикла BPE
Цель этого этапа — научить модель автоматически строить словарь подслов из текстового корпуса.
Алгоритм называется Byte Pair Encoding (BPE).
Он используется в современных языковых моделях — таких как BERT, GPT и других.
Мы уже подготовили словарь: каждое слово разбито на символы, разделённые пробелами, с добавлением маркера начала слова ▁.
Например:
inflation → i n f l a t i o n ▁
growth → g r o w t h ▁
Теперь начинается обучение: модель будет последовательно объединять самые частые пары символов или фрагментов в единые токены.
Как работает алгоритм BPE
BPE — это жадный итеративный алгоритм.
Он не видит весь текст за раз и не предсказывает структуру.
Он просто:
- Ищет в текущем словаре самую частую пару соседних токенов.
- Объединяет эту пару в один новый токен.
- Заменяет все её вхождения.
- Повторяет.
Со временем из i n → in, из in fl → inf → infl, и так далее, пока не начнут образовываться осмысленные морфемы.
Код функции train_bpe
Шаг 1: Вход и инициализация
Функция получает:
- Словарь vocab, где каждое слово — строка из символов и ▁, разделённых пробелами.
- Количество итераций num_merges.
- Точки вывода для контроля обучения.
Она создаёт копию словаря и начинает цикл.
Основной цикл по шагам
На каждом шаге функция get_bigram_counts проходит по каждому слову и считает, сколько раз встречаются пары вроде:
- ('i', 'n')
- ('n', ' ') — нет, токены разделены, это ('n', 'f')
- ('e', '▁')
- ('s', 't')
Каждая такая пара — кандидат на слияние. Частота складывается по всем словам.
Если пар больше нет — алгоритм завершается досрочно.
Из всех пар выбирается та, которая встречается чаще всего.
Например, если ('i', 'n') встречается 1092 раза — она будет выбрана первой.
Функция merge_vocab проходит по всем словам и заменяет каждое вхождение i n на in.
При этом:
- Замена происходит только если i и n стоят отдельно.
- Используется регулярное выражение, чтобы не затронуть m i n e → mine случайно, если не нужно.
Правило ('i', 'n') добавляется в merge_rules — это история, по которой можно восстановить работу модели позже.
На указанных шагах выводится:
- Номер шага
- Какие два токена объединяются
- Какой новый токен получается
- Сколько раз эта пара встречалась
- Сколько токенов сейчас в словаре (общий размер)
Каждые 100 шагов — общий прогресс.
Это помогает оценить, как растёт словарь и не застрял ли алгоритм.
После 1000 шагов функция:
- Собирает все токены, оставшиеся в словаре.
- Выводит итоговое количество.
- Возвращает три объекта, необходимых для следующих шагов.
Что происходит при запуске
Пример вывода:
Что означают эти данные
- Шаг 0: модель сразу находит частый фрагмент in — он есть во многих словах: inflation, income, increase, interest.
- Шаг 1: e+▁ — означает, что за словом на e часто идёт конец — например, rate▁, price▁, economy▁. Модель начинает замечать паттерны окончания.
- Шаг 2: e+r → er — consumer, market, revenue — важная морфема.
- Шаг 50: d+e → de — из debt, deflation, decrease.
- К 1000 шагу — в словаре уже 1030 уникальных токенов.
Почему увеличилось число токенов?
Потому что добавляются новые составные фрагменты (in, er, st, de), но старые символы (i, n, e) ещё остаются в других контекстах.
Это нормально на промежуточной стадии.
🎉 Что мы получили в итоге?
Мы начали с 3424 уникальных слов, разбитых на 62 примитивных символа. После 1000 слияний у нас появился словарь из 1030 умных токенов. Этот словарь теперь состоит не только из букв, но и из осмысленных частей слов:
- Суффиксы: ing, er, es, ment
- Приставки: re, in, un
- Корни и целые слова: market, stock, price, an, the
Мы с нуля создали токенизатор, который научился видеть внутреннюю структуру языка на основе статистики. Теперь вы знаете, что именно происходит под капотом у больших языковых моделей, когда вы отправляете им свой запрос.
Теперь ваша очередь экспериментировать! Попробуйте запустить код на других текстах (например, на стихах или новостях из другой сферы) и посмотрите, какие "умные токены" выучит ваш собственный BPE. Удачи