diff --git a/README.md b/README.md index bae8cae..092f20d 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,45 @@ [![Python Version](https://img.shields.io/badge/python-3.8%2B-blue)]() [![PyTorch Version](https://img.shields.io/badge/pytorch-1.10%2B-orange)]() +> **Актуально для Simple-LLM v1.0 (июль 2025)** + +--- + +## 🚀 Установка + +### Через pip (локально) +```bash +pip install . +``` + +### Через pip (с PyPI) +```bash +pip install simple-llm +``` + +После установки вы сможете запускать примеры и использовать модули из любого места. + +**Краткая инструкция по обучению на своих данных:** +1. Обучите BPE-токенизатор на тексте (см. `simple_llm.tokenizer.bpe.BPE`). +2. Токенизируйте корпус и создайте датасет через `GetData`. +3. Инициализируйте модель `GPT` с нужными параметрами. +4. Обучите модель одной строкой: `model.fit(train_loader, num_epoch=10)`. +5. Для подробной инструкции и примеров см. [документацию](doc/train_on_custom_data_ru.md). + +--- + +**Структура README:** +- Обзор +- Быстрый старт +- Основные компоненты +- Документация +- Тестирование +- Как внести вклад +- Лицензия +- [FAQ](#faq) + +--- + Простая и понятная реализация языковой модели GPT-стиля с нуля на PyTorch ## 🔍 Обзор @@ -114,5 +153,29 @@ pytest tests/ 4. Запушьте ветку (`git push origin feature/AmazingFeature`) 5. Откройте Pull Request +--- + +## ❓ FAQ + +**Q: Как установить Simple-LLM, чтобы работали все импорты?** +A: Рекомендуется установить через pip (локально: `pip install .` или с PyPI: `pip install simple-llm`). Тогда все примеры и импорты будут работать из любой директории. + +**Q: Как запустить Simple-LLM на CPU?** +A: Передайте параметр `device="cpu"` при инициализации модели или обработке данных. + +**Q: Как использовать свой датасет?** +A: Используйте класс `GetData` из `simple_llm.data.get_data` для подготовки своих последовательностей. Следуйте формату `(input_ids, targets)`. + +**Q: Где посмотреть примеры?** +A: В папке [`example/`](./example/) есть скрипты генерации и обучения. + +**Q: Ошибка CUDA out of memory!** +A: Уменьшите размер batch_size или размерность модели, либо используйте CPU. + +**Q: Как добавить новый модуль или улучшение?** +A: Ознакомьтесь с документацией, следуйте рекомендациям по вкладу и открывайте Pull Request. + +--- + ## 📜 Лицензия Распространяется под лицензией MIT. См. [LICENSE](./LICENSE) diff --git a/data/corpus/corpus.txt b/data/corpus/corpus.txt new file mode 100644 index 0000000..abae4d7 --- /dev/null +++ b/data/corpus/corpus.txt @@ -0,0 +1,30 @@ +Наука — это организованное стремление к познанию окружающего мира. Современные технологии позволяют анализировать большие объёмы данных и делать открытия в различных областях. Искусственный интеллект и машинное обучение становятся неотъемлемой частью нашей жизни, помогая автоматизировать рутинные задачи и открывать новые горизонты для исследований. + +Образование играет ключевую роль в развитии общества. Благодаря доступу к информации, люди могут обучаться дистанционно, осваивать новые профессии и совершенствовать навыки. + +Культура и искусство вдохновляют на творчество, объединяют людей и способствуют развитию критического мышления. Чтение книг, посещение театров и музеев обогащают внутренний мир каждого человека. + +Здоровый образ жизни включает в себя правильное питание, физическую активность и заботу о психоэмоциональном состоянии. Регулярные занятия спортом укрепляют организм и повышают работоспособность. + +Экология — важная сфера, требующая внимания каждого. Сохранение природы, рациональное использование ресурсов и снижение загрязнения окружающей среды — задачи, которые стоят перед современным обществом. + +Азбука: А а Б б В в Г г Д д Е е Ё ё Ж ж З з И и Й й К к Л л М м Н н О о П п Р р С с Т т У у Ф ф Х х Ц ц Ч ч Ш ш Щ щ Ъ ъ Ы ы Ь ь Э э Ю ю Я я. + +Латиница: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z. + +Цифры: 0 1 2 3 4 5 6 7 8 9. Пример: В 2025 году 13 студентов успешно сдали экзамен по информатике. + +Знаки препинания: . , ! ? : ; " ' ( ) [ ] { } < > — - _ / \ | @ # $ % ^ & * + = ~ ` + +Пример e-mail: test.user@example.com + +Дата и время: 23 июля 2025 года, 14:30. + +Математические выражения: x = y^2 + 3*z - (a/2). + +Вопрос: Какой сегодня день недели? Ответ: Среда! + +Спецсимволы в тексте: @home #важно $100 %успеха &друзья *звезда +плюс =равно ~волна `обратная кавычка` + +"Каждый охотник желает знать, где сидит фазан" — известная фраза для проверки всех цветов радуги. + diff --git a/data/model/simple_llm_gpt.pth b/data/model/simple_llm_gpt.pth new file mode 100644 index 0000000..8e909a7 Binary files /dev/null and b/data/model/simple_llm_gpt.pth differ diff --git a/data/tokenizer/bpe_tokenizer.json b/data/tokenizer/bpe_tokenizer.json new file mode 100644 index 0000000..e5884c8 Binary files /dev/null and b/data/tokenizer/bpe_tokenizer.json differ diff --git a/data/tokens/corpus_tokens.pkl b/data/tokens/corpus_tokens.pkl new file mode 100644 index 0000000..5eef224 Binary files /dev/null and b/data/tokens/corpus_tokens.pkl differ diff --git a/doc/bpe_algorithm.drawio b/doc/bpe_algorithm.drawio deleted file mode 100644 index 01fb2c7..0000000 --- a/doc/bpe_algorithm.drawio +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/doc/bpe_algorithm.md b/doc/bpe_algorithm.md index 2be0046..050ade0 100644 --- a/doc/bpe_algorithm.md +++ b/doc/bpe_algorithm.md @@ -1,5 +1,26 @@ # Byte Pair Encoding (BPE) Algorithm +> **Документ актуален для Simple-LLM v1.0 (июль 2025)** + +--- + +**Краткое summary:** +Этот документ подробно описывает алгоритм Byte Pair Encoding (BPE) — как он используется для токенизации текста, как устроен процесс обучения словаря и как происходит энкодинг/декодинг текста. Документ предназначен для пользователей Simple-LLM и всех, кто хочет понять внутреннюю механику BPE. + +--- + +**Структура документа:** +- Введение +- Основные понятия +- Алгоритм работы (обучение словаря) +- Псевдокод +- Пример работы +- Алгоритм энкодинга (токенизации) +- Алгоритм декодирования +- Типовые ошибки и их решения + +--- + ## Введение Byte Pair Encoding (BPE) - это алгоритм компрессии данных, адаптированный для токенизации текста в обработке естественного языка. В контексте языковых моделей BPE используется для создания эффективного словаря подстрок (токенов). diff --git a/doc/decoder_ru.md b/doc/decoder_ru.md index 32327c3..2957511 100644 --- a/doc/decoder_ru.md +++ b/doc/decoder_ru.md @@ -1,5 +1,24 @@ # Декодер Transformer +> **Документ актуален для Simple-LLM v1.0 (июль 2025)** + +--- + +**Краткое summary:** +Документ описывает работу декодера Transformer: архитектуру, алгоритм, пример использования, параметры и типовые ошибки. + +--- + +**Структура документа:** +- Назначение +- Алгоритм работы +- Использование +- Параметры +- Особенности +- Типовые ошибки и их решения + +--- + ## Назначение Декодер - ключевой компонент архитектуры Transformer, предназначенный для: - Генерации последовательностей (текст, код и др.) @@ -75,15 +94,40 @@ masked_output = decoder(x, mask) - Генерация текста - Кодогенерация -## Особенности реализации +## Рекомендации +- Используйте корректные маски для автопрегрессивного декодирования +- Следите за размерностью входа и маски +- Для сложных случаев используйте teacher forcing -1. **Масштабирование**: - - Поддержка длинных последовательностей - - Оптимизированные вычисления внимания +--- -2. **Обучение**: - - Поддержка teacher forcing - - Автопрегрессивное декодирование +## Типовые ошибки и их решения + +### Ошибка: Размерности не совпадают при подаче входа или маски +**Возможные причины:** +- Размерность входного тензора не совпадает с emb_size +- Форма маски не совпадает с [seq_len, seq_len] + +**Решение:** +- Проверьте, что размерность входа и маски соответствует требованиям + +### Ошибка: Модель не обучается (loss не уменьшается) +**Возможные причины:** +- Ошибка в подключении слоя к модели +- Ошибка в маскировании (утечка будущего) + +**Решение:** +- Проверьте корректность маски +- Проверьте, что параметры декодера передаются в оптимизатор + +### Ошибка: CUDA out of memory +**Возможные причины:** +- Слишком большой batch_size, seq_len или emb_size + +**Решение:** +- Уменьшите batch_size, seq_len или emb_size + +--- 3. **Оптимизации**: - Кэширование ключей/значений diff --git a/doc/feed_forward_ru.md b/doc/feed_forward_ru.md index 3d7c87c..76aa712 100644 --- a/doc/feed_forward_ru.md +++ b/doc/feed_forward_ru.md @@ -1,5 +1,24 @@ # FeedForward - Прямая полносвязная сеть трансформера +> **Документ актуален для Simple-LLM v1.0 (июль 2025)** + +--- + +**Краткое summary:** +Документ описывает модуль двухслойной прямой полносвязной сети (Feed Forward) в трансформерах. Включает алгоритм, пример использования, параметры и типовые ошибки. + +--- + +**Структура документа:** +- Назначение +- Алгоритм работы +- Пример использования +- Параметры +- Особенности +- Типовые ошибки и их решения + +--- + ## Назначение Модуль реализует двухслойную нейронную сеть, которая: - Добавляет нелинейность в трансформер @@ -55,9 +74,40 @@ output = ff(x) # [1, 10, 512] | `emb_size` | int | Размерность входных/выходных векторов | | `dropout` | float | Вероятность dropout (0.0-1.0)| -## Особенности -- Сохраняет размерность входа/выхода -- Автоматически обрабатывает batch и последовательности +## Рекомендации +- Dropout обычно выбирают 0.1–0.3 +- Следите, чтобы emb_size совпадал с размерностью входа/выхода +- Используйте режимы train/eval корректно +- Для визуализации используйте [пример](/example/feed_forward_example.py) + +--- + +## Типовые ошибки и их решения + +### Ошибка: Размерности не совпадают при прямом проходе +**Возможные причины:** +- emb_size не совпадает с размерностью входных данных + +**Решение:** +- Проверьте, что emb_size слоя FeedForward совпадает с размерностью последнего слоя перед ним + +### Ошибка: Модель не обучается (loss не уменьшается) +**Возможные причины:** +- Dropout слишком высокий +- Ошибка в подключении слоя к модели + +**Решение:** +- Попробуйте уменьшить dropout +- Проверьте, что слой FeedForward включён в модель и его параметры передаются в оптимизатор + +### Ошибка: CUDA out of memory +**Возможные причины:** +- Слишком большой batch_size или размерность emb_size + +**Решение:** +- Уменьшите batch_size или emb_size + +--- - Поддерживает режимы train/eval [Пример визуализации](/example/feed_forward_example.py) diff --git a/doc/gpt_documentation_ru.md b/doc/gpt_documentation_ru.md index 6ccadca..083138a 100644 --- a/doc/gpt_documentation_ru.md +++ b/doc/gpt_documentation_ru.md @@ -1,5 +1,24 @@ # Документация по GPT модели +> **Документ актуален для Simple-LLM v1.0 (июль 2025)** + +--- + +**Краткое summary:** +Этот документ подробно описывает архитектуру и практическое применение GPT (Generative Pre-trained Transformer) — авторегрессивной языковой модели, реализованной в Simple-LLM. Документ предназначен для разработчиков и исследователей, желающих понять детали реализации и настройки GPT-модели. + +--- + +**Структура документа:** +- Общее описание +- Архитектура и алгоритм +- Практическое использование +- Особенности генерации +- Обучение модели +- Типовые ошибки и их решения + +--- + ## 1. Общее описание GPT (Generative Pre-trained Transformer) - это авторегрессивная модель генерации текста на основе архитектуры трансформера. diff --git a/doc/head_attention_ru.md b/doc/head_attention_ru.md index 4d3ffdf..a7616fa 100644 --- a/doc/head_attention_ru.md +++ b/doc/head_attention_ru.md @@ -1,5 +1,22 @@ # HeadAttention - Механизм самовнимания одной головы +> **Документ актуален для Simple-LLM v1.0 (июль 2025)** + +--- + +**Краткое summary:** +Данный файл описывает реализацию механизма внимания одной головы (Single Head Attention) в трансформерах. Охватывает основные этапы вычислений, пример использования и типовые ошибки. + +--- + +**Структура документа:** +- Назначение +- Алгоритм работы +- Пример использования +- Типовые ошибки и их решения + +--- + ## Назначение Модуль реализует механизм внимания одной головы из архитектуры Transformer. Основные применения: - Моделирование зависимостей в последовательностях @@ -58,6 +75,42 @@ x = torch.randn(2, 10, emb_size) output = attn_head(x) # [2, 10, head_size] ``` +--- + +## Типовые ошибки и их решения + +### Ошибка: Размерности не совпадают при умножении матриц +**Возможные причины:** +- Несовпадение emb_size и head_size при инициализации +- Некорректная форма входного тензора + +**Решение:** +- Проверьте, что emb_size делится на head_size без остатка +- Убедитесь, что вход имеет форму [batch_size, seq_len, emb_size] + +### Ошибка: CUDA out of memory +**Возможные причины:** +- Слишком большой batch_size или seq_len + +**Решение:** +- Уменьшите batch_size или seq_len + +### Ошибка: Не работает маскирование +**Возможные причины:** +- Неправильная форма или тип маски + +**Решение:** +- Проверьте, что mask совпадает по размерности с attention scores + +## Рекомендации по использованию +- Следите, чтобы emb_size делился на head_size без остатка +- Для визуализации весов используйте специализированные инструменты +- Для сложных задач используйте MultiHeadAttention +- Размер головы (`head_size`) обычно выбирают 64-128 +- Для длинных последовательностей (>512) используйте оптимизации: + - Локальное внимание + - Разреженные паттерны + ## Особенности реализации ### Ключевые компоненты @@ -73,11 +126,6 @@ output = attn_head(x) # [2, 10, head_size] - Поддерживает только causal-режим - Фиксированный максимальный размер последовательности -## Рекомендации по использованию -1. Размер головы (`head_size`) обычно выбирают 64-128 -2. Для длинных последовательностей (>512) используйте оптимизации: - - Локальное внимание - - Разреженные паттерны 3. Сочетайте с MultiHeadAttention для лучшего качества [Дополнительные примеры](/example/attention_examples.py) diff --git a/doc/index.md b/doc/index.md new file mode 100644 index 0000000..86d0cb5 --- /dev/null +++ b/doc/index.md @@ -0,0 +1,42 @@ +# Навигация по документации Simple-LLM + +> **Документация актуальна для Simple-LLM v1.0 (июль 2025)** + +--- + +## Содержание + +- [Архитектура GPT](./gpt_documentation_ru.md) + - Описание, блок-схемы, режимы генерации, обучение, типовые ошибки +- [Алгоритм BPE](./bpe_algorithm.md) + - Теория, примеры, псевдокод, FAQ +- [Обработка данных](./get_data_documentation_ru.md) + - Форматы, примеры, рекомендации +- [Обучение на своих данных](./train_on_custom_data_ru.md) + - Подробная инструкция по обучению токенизатора и модели +- [Внимание (Attention)](./head_attention_ru.md) + - Описание механизма, формулы +- [Мультиголовное внимание](./multi_head_attention_ru.md) + - Теория, схемы +- [Позиционные эмбеддинги](./positional_embeddings_ru.md) + - Теория, примеры +- [Токен-эмбеддинги](./token_embeddings_ru.md) + - Описание, схемы, примеры +- [Feed Forward слой](./feed_forward_ru.md) + - Теория, формулы +- [Декодер](./decoder_ru.md) + - Архитектура, схема + +--- + +## Как пользоваться документацией + +- Для быстрого старта изучите [README.md](../README.md) +- Для понимания архитектуры — [GPT](./gpt_documentation_ru.md) и [BPE](./bpe_algorithm.md) +- Для деталей по каждому модулю — соответствующий файл из списка выше +- Для практики — смотрите примеры в папке `example/` +- Для тестирования — используйте тесты из папки `tests/` + +--- + +**Если вы нашли ошибку или хотите предложить улучшение — создайте issue или pull request на GitHub!** diff --git a/doc/multi_head_attention_ru.md b/doc/multi_head_attention_ru.md index e38eba2..483f892 100644 --- a/doc/multi_head_attention_ru.md +++ b/doc/multi_head_attention_ru.md @@ -1,5 +1,23 @@ # MultiHeadAttention - Многоголовый механизм внимания +> **Документ актуален для Simple-LLM v1.0 (июль 2025)** + +--- + +**Краткое summary:** +Документ описывает реализацию многоголового механизма внимания (Multi-Head Attention) в трансформерах. Включает описание алгоритма, пример использования и типовые ошибки. + +--- + +**Структура документа:** +- Назначение +- Алгоритм работы +- Пример использования +- Параметры +- Типовые ошибки и их решения + +--- + ## Назначение Модуль реализует ключевой компонент архитектуры Transformer, который: - Параллельно вычисляет несколько типов внимания @@ -58,6 +76,40 @@ output = mha(x) # [1, 50, 512] ## Параметры | Параметр | Тип | Описание | |---------------|------|------------------------------| + +## Рекомендации +- Размерность emb_size должна делиться на num_heads * head_size +- Для визуализации весов используйте специализированные инструменты + +--- + +## Типовые ошибки и их решения + +### Ошибка: Размерности не совпадают при разделении на головы +**Возможные причины:** +- emb_size не делится на num_heads * head_size +- Некорректная форма входного тензора + +**Решение:** +- Проверьте, что emb_size = num_heads * head_size +- Убедитесь, что вход имеет форму [batch_size, seq_len, emb_size] + +### Ошибка: CUDA out of memory +**Возможные причины:** +- Слишком большой batch_size, seq_len или число голов + +**Решение:** +- Уменьшите batch_size, seq_len или num_heads + +### Ошибка: Не работает маскирование +**Возможные причины:** +- Неправильная форма или тип маски + +**Решение:** +- Проверьте, что mask совпадает по размерности с attention scores + +--- + | `num_heads` | int | Количество голов внимания | | `emb_size` | int | Размерность входных эмбеддингов| | `head_size` | int | Размерность каждой головы | diff --git a/doc/positional_embeddings_ru.md b/doc/positional_embeddings_ru.md index 34d0787..11539f7 100644 --- a/doc/positional_embeddings_ru.md +++ b/doc/positional_embeddings_ru.md @@ -1,5 +1,24 @@ # PositionalEmbeddings - Позиционные эмбеддинги +> **Документ актуален для Simple-LLM v1.0 (июль 2025)** + +--- + +**Краткое summary:** +Документ описывает работу слоя позиционных эмбеддингов в трансформерах. Включает алгоритм, пример использования, сравнение подходов и типовые ошибки. + +--- + +**Структура документа:** +- Назначение +- Алгоритм работы +- Пример использования +- Сравнение подходов +- Оптимальные практики +- Типовые ошибки и их решения + +--- + ## Назначение Позиционные эмбеддинги добавляют информацию о порядке элементов в последовательности. Критически важны для: - Transformer-архитектур @@ -50,7 +69,35 @@ class TransformerBlock(nn.Module): | Обучаемые | Да | Гибкость | Требует данных | | Синусоидальные | Нет | Хорошая обобщающая способность | Фиксированный паттерн | -## Оптимальные практики +## Рекомендации - Для `max_seq_len` берите с запасом (+20%) - Размерность делайте равной размерности токенных эмбеддингов - Для длинных последовательностей комбинируйте с синусоидальными + +--- + +## Типовые ошибки и их решения + +### Ошибка: IndexError при запросе эмбеддингов +**Возможные причины:** +- seq_len превышает max_seq_len, заданный при инициализации слоя + +**Решение:** +- Увеличьте max_seq_len при создании слоя +- Проверяйте длину входных данных заранее + +### Ошибка: Размерности не совпадают при сложении с токенными эмбеддингами +**Возможные причины:** +- Размерность позиционных и токенных эмбеддингов не совпадает + +**Решение:** +- Убедитесь, что emb_size одинаков для обоих слоев + +### Ошибка: Модель не обучается (позиционные эмбеддинги не обновляются) +**Возможные причины:** +- Параметры слоя не добавлены в оптимизатор + +**Решение:** +- Проверьте, что слой PositionalEmbeddings включён в модель и его параметры передаются в оптимизатор + +--- diff --git a/doc/token_embeddings.md b/doc/token_embeddings.md deleted file mode 100644 index e69de29..0000000 diff --git a/doc/token_embeddings_flow.drawio b/doc/token_embeddings_flow.drawio deleted file mode 100644 index 2f6e600..0000000 --- a/doc/token_embeddings_flow.drawio +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/doc/token_embeddings_ru.md b/doc/token_embeddings_ru.md index a14af8d..b35cbd5 100644 --- a/doc/token_embeddings_ru.md +++ b/doc/token_embeddings_ru.md @@ -1,5 +1,24 @@ # TokenEmbeddings - Векторные представления токенов +> **Документ актуален для Simple-LLM v1.0 (июль 2025)** + +--- + +**Краткое summary:** +Документ описывает слой преобразования индексов токенов в плотные векторные представления (эмбеддинги). Включает алгоритм, пример использования, параметры и типовые ошибки. + +--- + +**Структура документа:** +- Назначение +- Алгоритм работы +- Использование +- Параметры +- Особенности +- Типовые ошибки и их решения + +--- + ## Назначение Модуль `TokenEmbeddings` преобразует дискретные индексы токенов в плотные векторные представления (эмбеддинги). Это фундаментальный компонент большинства нейросетевых моделей для обработки естественного языка (NLP). @@ -53,10 +72,38 @@ embeddings = embedding_layer(tokens) # векторные представле | vocab_size | int | Размер словаря (количество уникальных токенов) | | emb_size | int | Размерность векторных представлений | -## Особенности -- **Автоматическое обучение**: Векторы адаптируются в процессе тренировки модели -- **Эффективность**: Быстрое преобразование индексов в векторы -- **Гибкость**: Может использоваться как самостоятельный слой или часть более сложной архитектуры +## Рекомендации +- Для больших словарей используйте размерность 256-1024 +- При использовании предобученных эмбеддингов можно заморозить слой (embedding_layer.requires_grad_(False)) +- Для обработки неизвестных токенов (OOV) резервируйте нулевой индекс + +--- + +## Типовые ошибки и их решения + +### Ошибка: Индекс токена вне диапазона словаря +**Возможные причины:** +- Входные индексы превышают vocab_size + +**Решение:** +- Проверьте, что все индексы < vocab_size +- Добавьте обработку [UNK] токенов при необходимости + +### Ошибка: Размерности не совпадают при сложении эмбеддингов с другими слоями +**Возможные причины:** +- emb_size не совпадает с размерностью других эмбеддингов + +**Решение:** +- Приведите размерности к одному значению во всех слоях + +### Ошибка: Эмбеддинги не обучаются +**Возможные причины:** +- Параметры слоя не добавлены в оптимизатор + +**Решение:** +- Проверьте, что слой TokenEmbeddings включён в модель и его параметры передаются в оптимизатор + +--- ## Типичные сценарии использования 1. Первый слой в нейросетевых моделях NLP diff --git a/doc/train_on_custom_data_ru.md b/doc/train_on_custom_data_ru.md new file mode 100644 index 0000000..db08b33 --- /dev/null +++ b/doc/train_on_custom_data_ru.md @@ -0,0 +1,137 @@ +# Обучение токенизатора и модели Simple-LLM на своих данных + +> **Инструкция актуальна для Simple-LLM v1.0 (июль 2025)** + +--- + +## Оглавление +- [1. Подготовка корпуса](#1-подготовка-корпуса) +- [2. Обучение BPE-токенизатора](#2-обучение-bpe-токенизатора) +- [3. Токенизация корпуса](#3-токенизация-корпуса) +- [4. Создание датасета](#4-создание-датасета) +- [5. Обучение модели с помощью fit()](#5-обучение-модели-с-помощью-fit) +- [6. Сохранение и генерация](#6-сохранение-и-генерация) +- [7. Советы и FAQ](#7-советы-и-faq) + +--- + +## 1. Подготовка корпуса +- Соберите тексты в один или несколько `.txt` файлов. +- Очистите данные при необходимости. + +## 2. Обучение BPE-токенизатора +```python +import torch +# Автоматический выбор устройства +if torch.cuda.is_available(): + device = 'cuda' +elif getattr(torch.backends, 'mps', None) and torch.backends.mps.is_available(): + device = 'mps' # Apple Silicon +else: + device = 'cpu' +print(f"Используется устройство: {device}") + +from simple_llm.tokenizer.bpe import BPE + +with open('corpus.txt', 'r', encoding='utf-8') as f: + texts = f.readlines() + +tokenizer = BPE(vocab_size=5000) +tokenizer.train(texts, vocab_size=5000, min_freq=2) +tokenizer.save('bpe_tokenizer.json') +``` + +## 3. Токенизация корпуса +```python +from simple_llm.tokenizer.bpe import BPE +import pickle + +tokenizer = BPE.load('bpe_tokenizer.json') +with open('corpus.txt', 'r', encoding='utf-8') as f: + lines = f.readlines() +tokenized = [tokenizer.encode(line) for line in lines] + +with open('corpus_tokens.pkl', 'wb') as f: + pickle.dump(tokenized, f) +``` + +## 4. Создание датасета +```python +from simple_llm.data.get_data import GetData +import pickle + +with open('corpus_tokens.pkl', 'rb') as f: + tokenized = pickle.load(f) +all_tokens = [token for line in tokenized for token in line] +seq_len = 64 +dataset = GetData(data=all_tokens, seq_len=seq_len, device='cuda') +``` + +## 5. Обучение модели с помощью fit() +```python +from torch.utils.data import DataLoader +from simple_llm.transformer.gpt import GPT + +loader = DataLoader(dataset, batch_size=32, shuffle=True) +model = GPT( + vocab_size=tokenizer.vocab_size, + max_seq_len=seq_len, + emb_size=256, + num_heads=4, + head_size=64, + num_layers=4, + device='cuda' +) + +# Обучение одной строкой! +model.fit( + train_loader=loader, + valid_loader=None, # можно передать DataLoader для валидации + num_epoch=10, + learning_rate=1e-4 +) + +print('Train loss:', model.train_loss) +``` + +## 6. Сохранение и генерация +```python +import torch +# Сохранить веса +torch.save(model.state_dict(), 'simple_llm_gpt.pth') + +# Генерация текста после обучения +from simple_llm.tokenizer.bpe import BPE + +# Загрузим токенизатор и модель (если нужно) +tokenizer = BPE.load('bpe_tokenizer.json') +# model.load_state_dict(torch.load('simple_llm_gpt.pth')) # если требуется загрузка +model.eval() + +# Пример: сгенерировать продолжение для строки prompt +prompt = "Привет, мир! " +input_ids = torch.tensor([tokenizer.encode(prompt)], device=model._device) +output = model.generate( + x=input_ids, + max_new_tokens=30, + do_sample=True, + temperature=1.0 +) +# Декодируем результат +result = tokenizer.decode(output[0].tolist()) +print("Сгенерированный текст:", result) +``` + +## 7. Советы и FAQ +- Используйте GPU для ускорения обучения. +- Размер словаря токенизатора должен совпадать с vocab_size модели. +- Для генерации текста используйте метод `generate` и декодируйте результат. +- Для валидации можно передать valid_loader в fit(). +- Ошибки по размерностям чаще всего связаны с некорректными параметрами seq_len, batch_size или vocab_size. + +--- + +**Полезные ссылки:** +- [Документация по классу GetData](./get_data_documentation_ru.md) +- [Документация по GPT](./gpt_documentation_ru.md) +- [README.md](../README.md) diff --git a/example/generate_text.py b/example/generate_text.py new file mode 100644 index 0000000..224edc3 --- /dev/null +++ b/example/generate_text.py @@ -0,0 +1,50 @@ +""" +Генерация текста с помощью обученной GPT-модели и токенизатора +""" +import torch +from simple_llm.transformer.gpt import GPT +from simple_llm.tokenizer.bpe import BPE + +if __name__ == "__main__": + import torch + # Определяем устройство + #if torch.cuda.is_available(): + # device = 'cuda' + #elif getattr(torch.backends, 'mps', None) and torch.backends.mps.is_available(): + # device = 'mps' # Apple Silicon + #else: + # device = 'cpu' + device = 'cpu' + print(f"Используется устройство: {device}") + + # Загрузим токенизатор и модель + tokenizer = BPE.load('data/tokenizer/bpe_tokenizer.json') + model = GPT( + vocab_size=tokenizer.vocab_size, + max_seq_len=64, + emb_size=256, + num_heads=4, + head_size=64, + num_layers=4, + device=device + ) + model.load_state_dict(torch.load('data/model/simple_llm_gpt.pth', map_location=device)) + model.eval() + + # Введите начальный текст + prompt = "Привет, мир! " + prompt_tokens = tokenizer.encode(prompt) + print(f"Токены prompt: {prompt_tokens}") + print(f"Размер словаря токенизатора: {tokenizer.vocab_size}") + if any(idx >= tokenizer.vocab_size or idx < 0 for idx in prompt_tokens): + print("ВНИМАНИЕ: В prompt есть токены с индексом вне диапазона словаря! Генерация невозможна.") + exit(1) + input_ids = torch.tensor([prompt_tokens], device=device) + output = model.generate( + x=input_ids, + max_new_tokens=30, + do_sample=True, + temperature=1.0 + ) + result = tokenizer.decode(output[0].tolist()) + print("Сгенерированный текст:", result) diff --git a/example/tokenize_corpus.py b/example/tokenize_corpus.py new file mode 100644 index 0000000..a248578 --- /dev/null +++ b/example/tokenize_corpus.py @@ -0,0 +1,25 @@ +""" +Токенизация текстового корпуса с помощью обученного BPE-токенизатора +""" +from simple_llm.tokenizer.bpe import BPE +import pickle + +if __name__ == "__main__": + import torch + # Определяем устройство + #if torch.cuda.is_available(): + # device = 'cuda' + #elif getattr(torch.backends, 'mps', None) and torch.backends.mps.is_available(): + # device = 'mps' # Apple Silicon + #else: + # device = 'cpu' + device = 'cpu' + print(f"Используется устройство: {device}") + + tokenizer = BPE.load('data/tokenizer/bpe_tokenizer.json') + with open('data/corpus/corpus.txt', 'r', encoding='utf-8') as f: + lines = f.readlines() + tokenized = [tokenizer.encode(line) for line in lines] + with open('data/tokens/corpus_tokens.pkl', 'wb') as f: + pickle.dump(tokenized, f) + print("Корпус токенизирован и сохранён в data/corpus_tokens.pkl") diff --git a/example/train_gpt_model.py b/example/train_gpt_model.py new file mode 100644 index 0000000..8a6fe67 --- /dev/null +++ b/example/train_gpt_model.py @@ -0,0 +1,50 @@ +""" +Обучение GPT-модели на токенизированном корпусе +""" +import pickle +from torch.utils.data import DataLoader +from simple_llm.data.get_data import GetData +from simple_llm.transformer.gpt import GPT + +if __name__ == "__main__": + import torch + # Определяем устройство + #if torch.cuda.is_available(): + # device = 'cuda' + #elif getattr(torch.backends, 'mps', None) and torch.backends.mps.is_available(): + # device = 'mps' # Apple Silicon + #else: + # device = 'cpu' + device = 'cpu' + print(f"Используется устройство: {device}") + + with open('data/tokens/corpus_tokens.pkl', 'rb') as f: + tokenized = pickle.load(f) + all_tokens = [token for line in tokenized for token in line] + seq_len = 64 + dataset = GetData(data=all_tokens, seq_len=seq_len, device=device) + loader = DataLoader(dataset, batch_size=32, shuffle=True) + + # Загрузите токенизатор для определения размера словаря + from simple_llm.tokenizer.bpe import BPE + tokenizer = BPE.load('data/tokenizer/bpe_tokenizer.json') + + model = GPT( + vocab_size=tokenizer.vocab_size, + max_seq_len=seq_len, + emb_size=256, + num_heads=4, + head_size=64, + num_layers=4, + device='cpu' + ) + + model.fit( + train_loader=loader, + valid_loader=None, + num_epoch=10, + learning_rate=1e-4 + ) + print('Train loss:', model.train_loss) + torch.save(model.state_dict(), 'data/model/simple_llm_gpt.pth') + print("Модель обучена и сохранена в data/model/simple_llm_gpt.pth") diff --git a/example/train_tokenizer.py b/example/train_tokenizer.py new file mode 100644 index 0000000..82fab83 --- /dev/null +++ b/example/train_tokenizer.py @@ -0,0 +1,23 @@ +""" +Обучение BPE-токенизатора на текстовом корпусе +""" +from simple_llm.tokenizer.bpe import BPE + +if __name__ == "__main__": + import torch + # Определяем устройство + #if torch.cuda.is_available(): + # device = 'cuda' + #elif getattr(torch.backends, 'mps', None) and torch.backends.mps.is_available(): + # device = 'mps' # Apple Silicon + #else: + # device = 'cpu' + device = 'cpu' + print(f"Используется устройство: {device}") + + with open('data/corpus/corpus.txt', 'r', encoding='utf-8') as f: + texts = f.readlines() + tokenizer = BPE(vocab_size=5000) + tokenizer.fit(" ".join(texts)) + tokenizer.save('data/tokenizer/bpe_tokenizer.json') + print("Токенизатор обучен и сохранён в data/tokenizer/bpe_tokenizer.json")