Files
simple-llm/doc/bpe_algorithm.md

9.7 KiB
Raw Permalink Blame History

Byte Pair Encoding (BPE) Algorithm

Документ актуален для Simple-LLM v1.0 (июль 2025)


Краткое summary: Этот документ подробно описывает алгоритм Byte Pair Encoding (BPE) — как он используется для токенизации текста, как устроен процесс обучения словаря и как происходит энкодинг/декодинг текста. Документ предназначен для пользователей Simple-LLM и всех, кто хочет понять внутреннюю механику BPE.


Структура документа:

  • Введение
  • Основные понятия
  • Алгоритм работы (обучение словаря)
  • Псевдокод
  • Пример работы
  • Алгоритм энкодинга (токенизации)
  • Алгоритм декодирования
  • Типовые ошибки и их решения

Введение

Byte Pair Encoding (BPE) - это алгоритм компрессии данных, адаптированный для токенизации текста в обработке естественного языка. В контексте языковых моделей BPE используется для создания эффективного словаря подстрок (токенов).

Основные понятия

  • Токен - элементарная единица текста (символ или последовательность символов)
  • Словарь - набор уникальных токенов, используемых для представления текста
  • Частота пары - количество раз, когда два токена встречаются вместе в тексте

Алгоритм работы

1. Инициализация

Исходный текст  Разбить на символы  Первоначальный словарь

Пример:

"мама" → ['м', 'а', 'м', 'а']

2. Основной цикл

graph TD
    A[Подсчет частот пар] --> B[Выбор наиболее частой пары]
    B --> C[Создание нового токена]
    C --> D[Обновление последовательности]
    D --> E{Достигнут лимит словаря?}
    E -->|Нет| A
    E -->|Да| F[Конец]

3. Детализация шагов

Шаг 1: Подсчет частот пар

Для текущей последовательности токенов подсчитываем все пары соседних токенов:

Текст: "мама мыла"
Токены: ['м', 'а', 'м', 'а', ' ', 'м', 'ы', 'л', 'а']
Пары: ('м','а'), ('а','м'), ('м','а'), ('а',' '), (' ','м'), ('м','ы'), ('ы','л'), ('л','а')

Шаг 2: Выбор пары для слияния

Находим пару с максимальной частотой. При равенстве частот выбираем пару, которая встречается раньше в тексте.

Шаг 3: Слияние

Объединяем выбранную пару в новый токен и заменяем все её вхождения в тексте:

Выбранная пара: ('м', 'а')
Новый токен: 'ма'
Обновленная последовательность: ['ма', 'ма', ' ', 'м', 'ы', 'л', 'а']

Шаг 4: Обновление словаря

Добавляем новый токен в словарь:

Словарь: ['м', 'а', ' ', 'ы', 'л', 'ма']

4. Критерии остановки

  1. Достижение заданного размера словаря
  2. Отсутствие пар для слияния (все возможные пары уже добавлены)
  3. Достижение максимального числа итераций

Псевдокод

def train_bpe(text, vocab_size):
    # Инициализация
    tokens = list(text)
    vocab = set(tokens)
    
    while len(vocab) < vocab_size:
        # Подсчет пар
        pairs = get_pairs(tokens)
        if not pairs:
            break
            
        # Выбор наиболее частой пары
        best_pair = max(pairs, key=pairs.get)
        
        # Слияние
        new_tokens = []
        i = 0
        while i < len(tokens):
            if i < len(tokens)-1 and (tokens[i], tokens[i+1]) == best_pair:
                new_tokens.append(best_pair[0] + best_pair[1])
                i += 2
            else:
                new_tokens.append(tokens[i])
                i += 1
        tokens = new_tokens
        
        # Обновление словаря
        vocab.add(best_pair[0] + best_pair[1])
    
    return vocab

Пример работы

Исходный текст: "мама мыла раму"

Итерация 1:

  • Пара ('м','а') встречается 2 раза
  • Новый токен: 'ма'
  • Текст: ['ма', 'ма', ' ', 'м', 'ы', 'л', 'а', ' ', 'р', 'а', 'м', 'у']

Итерация 2:

  • Пара ('ма',' ') встречается 1 раз
  • Новый токен: 'ма '
  • Текст: ['ма ', 'ма', 'мы', 'л', 'а', ' ', 'р', 'а', 'м', 'у']

Результирующий словарь (частично): ['м', 'а', ' ', 'ы', 'л', 'р', 'у', 'ма', 'ма ', 'мы']

Алгоритм энкодинга (токенизации)

После обучения BPE-модели (создания словаря), энкодинг текста происходит по следующему алгоритму:

graph TD
    A[Начало] --> B[Разбить текст на символы]
    B --> C[Инициализировать пустой список токенов]
    C --> D[Установить i=0 'начало последовательности']
    D --> E{i < длины текста?}
    E -->|Нет| F[Заменить токены на их ID]
    E -->|Да| G[Найти все токены в словаре, начинающиеся с text_i]
    G --> H[Выбрать самый длинный подходящий токен]
    H --> I[Добавить токен в результат]
    I --> J[Увеличить i на длину токена]
    J --> E
    F --> K[Конец]

Пошаговое описание:

  1. Инициализация:

    • Исходный текст разбивается на символы
    • Создается пустой список для результата
    • Указатель i устанавливается в 0
  2. Основной цикл:

    • Для текущей позиции i находим все токены в словаре, которые:
      • Начинаются с символа text[i]
      • Совпадают с подстрокой text[i:i+len(token)]
    • Из подходящих токенов выбираем самый длинный
    • Добавляем найденный токен в результат
    • Сдвигаем указатель i на длину добавленного токена
  3. Завершение:

    • Когда весь текст обработан, заменяем токены на их ID из словаря

Пример:

Словарь: ['ма', 'мама', ' ', 'мыл', 'а', 'раму']
Текст: "мама мыла раму"

Энкодинг:
1. Находим самый длинный токен, начинающийся с 'м' -> 'мама'
2. Добавляем 'мама', i += 4
3. Токен ' ' (пробел), i += 1
4. Токен 'мыл', i += 3
5. Токен 'а', i += 1
6. Токен ' ', i += 1
7. Токен 'раму', i += 4

Результат: ['мама', ' ', 'мыл', 'а', ' ', 'раму']

Алгоритм декодирования

Принцип работы

  1. Преобразование списка ID обратно в текст
  2. Замена каждого ID на соответствующий токен
  3. Обработка неизвестных ID ([UNK])
flowchart TD
    A[Список ID] --> B{ID ∈ словарь?}
    B -->|Да| C[Добавить токен]
    B -->|Нет| D[Добавить UNK]
    C --> E[Следующий ID]
    D --> E
    E --> F{Конец списка?}
    F -->|Нет| B
    F -->|Да| G[Объединить токены]

Пример:

decode([0,1,2])  "абра"  # Для словаря {0:"а", 1:"б", 2:"ра"}

Применение в языковых моделях

  1. Эффективное представление редких слов
  2. Снижение размерности входных данных
  3. Возможность обработки OOV (Out-of-Vocabulary) слов

Ограничения

  1. Чувствительность к регистру (можно решить предварительной нормализацией)
  2. Зависимость от обучающего корпуса
  3. Не всегда выделяет лингвистически осмысленные морфемы

Дополнительные материалы

  1. Original BPE paper
  2. BPE in HuggingFace
  3. Practical guide to BPE