mirror of
https://github.com/pese-git/simple-llm.git
synced 2026-01-23 21:14:17 +00:00
feat: implement bpe algorithm
This commit is contained in:
136
doc/bpe_algorithm.md
Normal file
136
doc/bpe_algorithm.md
Normal file
@@ -0,0 +1,136 @@
|
||||
# Byte Pair Encoding (BPE) Algorithm
|
||||
|
||||
## Введение
|
||||
|
||||
Byte Pair Encoding (BPE) - это алгоритм компрессии данных, адаптированный для токенизации текста в обработке естественного языка. В контексте языковых моделей BPE используется для создания эффективного словаря подстрок (токенов).
|
||||
|
||||
## Основные понятия
|
||||
|
||||
- **Токен** - элементарная единица текста (символ или последовательность символов)
|
||||
- **Словарь** - набор уникальных токенов, используемых для представления текста
|
||||
- **Частота пары** - количество раз, когда два токена встречаются вместе в тексте
|
||||
|
||||
## Алгоритм работы
|
||||
|
||||
### 1. Инициализация
|
||||
```python
|
||||
Исходный текст → Разбить на символы → Первоначальный словарь
|
||||
```
|
||||
Пример:
|
||||
```
|
||||
"мама" → ['м', 'а', 'м', 'а']
|
||||
```
|
||||
|
||||
### 2. Основной цикл
|
||||
```mermaid
|
||||
graph TD
|
||||
A[Подсчет частот пар] --> B[Выбор наиболее частой пары]
|
||||
B --> C[Создание нового токена]
|
||||
C --> D[Обновление последовательности]
|
||||
D --> E{Достигнут лимит словаря?}
|
||||
E -->|Нет| A
|
||||
E -->|Да| F[Конец]
|
||||
```
|
||||
|
||||
### 3. Детализация шагов
|
||||
|
||||
#### Шаг 1: Подсчет частот пар
|
||||
Для текущей последовательности токенов подсчитываем все пары соседних токенов:
|
||||
```
|
||||
Текст: "мама мыла"
|
||||
Токены: ['м', 'а', 'м', 'а', ' ', 'м', 'ы', 'л', 'а']
|
||||
Пары: ('м','а'), ('а','м'), ('м','а'), ('а',' '), (' ','м'), ('м','ы'), ('ы','л'), ('л','а')
|
||||
```
|
||||
|
||||
#### Шаг 2: Выбор пары для слияния
|
||||
Находим пару с максимальной частотой. При равенстве частот выбираем пару, которая встречается раньше в тексте.
|
||||
|
||||
#### Шаг 3: Слияние
|
||||
Объединяем выбранную пару в новый токен и заменяем все её вхождения в тексте:
|
||||
```
|
||||
Выбранная пара: ('м', 'а')
|
||||
Новый токен: 'ма'
|
||||
Обновленная последовательность: ['ма', 'ма', ' ', 'м', 'ы', 'л', 'а']
|
||||
```
|
||||
|
||||
#### Шаг 4: Обновление словаря
|
||||
Добавляем новый токен в словарь:
|
||||
```
|
||||
Словарь: ['м', 'а', ' ', 'ы', 'л', 'ма']
|
||||
```
|
||||
|
||||
### 4. Критерии остановки
|
||||
|
||||
1. Достижение заданного размера словаря
|
||||
2. Отсутствие пар для слияния (все возможные пары уже добавлены)
|
||||
3. Достижение максимального числа итераций
|
||||
|
||||
## Псевдокод
|
||||
|
||||
```python
|
||||
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 раз
|
||||
- Новый токен: 'ма '
|
||||
- Текст: ['ма ', 'ма', 'мы', 'л', 'а', ' ', 'р', 'а', 'м', 'у']
|
||||
|
||||
**Результирующий словарь** (частично):
|
||||
['м', 'а', ' ', 'ы', 'л', 'р', 'у', 'ма', 'ма ', 'мы']
|
||||
|
||||
## Применение в языковых моделях
|
||||
|
||||
1. Эффективное представление редких слов
|
||||
2. Снижение размерности входных данных
|
||||
3. Возможность обработки OOV (Out-of-Vocabulary) слов
|
||||
|
||||
## Ограничения
|
||||
|
||||
1. Чувствительность к регистру (можно решить предварительной нормализацией)
|
||||
2. Зависимость от обучающего корпуса
|
||||
3. Не всегда выделяет лингвистически осмысленные морфемы
|
||||
|
||||
## Дополнительные материалы
|
||||
|
||||
1. [Original BPE paper](https://arxiv.org/abs/1508.07909)
|
||||
2. [BPE in HuggingFace](https://huggingface.co/docs/transformers/tokenizer_summary)
|
||||
3. [Practical guide to BPE](https://towardsdatascience.com/byte-pair-encoding-subword-based-tokenization-algorithm-77828a70bee0)
|
||||
Reference in New Issue
Block a user