Decoder-only Transformer языковая модель, построенная полностью с нуля — BPE-токенизатор, архитектура модели, цикл обучения и генерация — на Python + PyTorch (~2500 строк кода).
Архитектура
Компонент
Решение
Обоснование
Нормализация
RMSNorm (pre-norm)
Стандарт LLaMA/Mistral, ~10-15% быстрее LayerNorm
Позиции
RoPE (split + cat, без complex)
Лучшая экстраполяция длины, совместимость с MPS/AMP
FFN
SwiGLU (3 проекции)
Выше качество при том же вычислительном бюджете
Attention
F.scaled_dot_product_attention
Flash Attention на CUDA, math fallback на MPS
Генерация
KV cache (prefill + decode)
O(S) на новый токен вместо O(S²)
Веса
Weight tying (embed ↔ lm_head)
Экономия ~24.6M параметров
AMP
autocast + GradScaler
CUDA и MPS (PyTorch 2.2+)
Конфигурации модели
Вариант
d_model
heads
layers
ff_dim
Параметры
Full
768
12
12
2048
~110M
Установка
bash
1# Клонировать репозиторий и перейти в корень проекта (имя папки может отличаться)2cd llm
34# Создать виртуальное окружение5python3 -m venv .venv
6source .venv/bin/activate
78# Установить зависимости9pip install -r requirements.txt
Чекпоинты весов (models/*.pt) не коммитятся (см. .gitignore). Для примеров ниже положите файлы base_step_15000.pt и chat_step_500.pt в каталог models/ или передайте свой путь в --checkpoint. Для BPE нужен data/vocab.json из того же обучения (или --vocab), если путь из чекпоинта на этой машине не существует.
Зависимости
Пакет
Обязательный
Назначение
torch>=2.2.0
да
PyTorch (CUDA / MPS / CPU)
numpy>=1.20
да
Memmap для pretokenized-корпусов
regex>=2023.0
да
Unicode-aware pre-tokenization (GPT-2 паттерн)
transformers>=4.20
нет
Адаптер HuggingFace-токенизатора (--tokenizer)
tokenizers>=0.15
нет
Быстрое BPE-обучение через Rust (train_bpe_hf.py)
gensim>=4.0
нет
Парсинг дампа Wikipedia (data/wiki_download.py)
Быстрый старт
Полный пайплайн одной командой
bash run_train.sh
Скрипт выполнит: обучение BPE-токенизатора → pre-training на Wikipedia → fine-tuning на чат-корпусе.
Пошаговый запуск
1. Обучение BPE-токенизатора
bash
1# Собственная реализация (чистый Python, ~20-50x быстрее наивного алгоритма)2python train_bpe.py --corpus data/wiki_text/corpus.txt --vocab-size 3200034# Или через HuggingFace tokenizers (Rust, ~100-1000x быстрее на больших корпусах)5python train_bpe_hf.py --corpus data/wiki_text/corpus.txt --vocab-size 32000
2. Pretokenization корпуса (для больших датасетов)
Для корпусов >1 GB рекомендуется pretokenization — после неё обучение стартует мгновенно:
Параметры подобраны тестированием на base_step_15000 (pre-trained) и chat_step_500 (chat fine-tuned)
на 8 различных промптах по 9 конфигурациям каждый. Значения по умолчанию в коде (GenerateConfig)
установлены как универсальный компромисс: temperature=0.5, repetition_penalty=1.15.
1# Базовый режим (каждый вопрос независимый)2python generate.py --checkpoint models/chat_step_500.pt \3 --chat --temperature 0.5 --repetition-penalty 1.145# С сохранением контекста (sliding window по границам реплик)6python generate.py --checkpoint models/chat_step_500.pt \7 --chat --keep-history
Пример сессии:
=== Chat Mode (type 'quit' to exit) ===
You: Что такое машинное обучение?
Assistant: Машинное обучение — раздел ИИ: алгоритмы, которые улучшают своё поведение
на основе данных без явного программирования каждого шага.
You: Что такое фотосинтез?
Assistant: Фотосинтез — процесс образования органических веществ из CO₂ и воды
на свету при участии хлорофилла. Выделяется кислород.
You: quit
Параметры генерации
Параметр
По умолчанию
Описание
--temperature
0.5
Температура сэмплирования (ниже = детерминированнее)
--top-k
—
Ограничение по top-k токенам
--top-p
—
Nucleus sampling (top-p)
--max-tokens
256
Максимум новых токенов
--repetition-penalty
1.15
Штраф за повторения (1.0 = выкл, рекомендуется 1.1-1.2)
--stream
off
Потоковый вывод токенов
--chat
off
Интерактивный чат-режим
--keep-history
off
Сохранение контекста диалога между репликами
--vocab
auto
Путь к vocab.json (если чекпоинт обучен на другой машине)
Параметры обучения
Параметр CLI
Конфиг
По умолчанию
Описание
--max-steps
max_steps
23000
Максимум шагов
--batch-size
batch_size
32
Размер батча
--lr
learning_rate
6e-4
Learning rate
--grad-accum
grad_accum_steps
4
Gradient accumulation
--warmup
warmup_steps
2000
Шаги warmup
--save-every
save_every_steps
2000
Частота сохранения
--seq-len
max_seq_len
1024
Длина контекста
--no-amp
use_amp
True
Отключить AMP
--stop-at-loss
stop_at_loss
—
Ранняя остановка по loss
--stop-at-perplexity
stop_at_perplexity
—
Ранняя остановка по val perplexity
LR scheduler: linear warmup → cosine annealing (single cycle).