# Xenith [![Platform](https://img.shields.io/badge/platform-Linux-blue)]() [![C++](https://img.shields.io/badge/C++-20-blue)]() [![Лицензия](https://img.shields.io/badge/license-MIT-green)]() Трансформер на чистом C++: обучение и генерация текста на CPU, без внешних зависимостей. Всё в одном бинарнике. ## Что внутри Архитектура — как у LLaMA: pre-norm, RMSNorm, RoPE, SwiGLU, связанные эмбеддинги (tied weights), каузальное внимание. Обучение — вручную написанный обратный проход + AdamW. Никаких фреймворков. | файл | что делает | |---|---| | `xenith/core/tensor.hpp` | матрицы, три формы GEMM, RMSNorm, RNG, пул потоков | | `xenith/core/model.cpp` | конфигурация, инициализация, прямой проход, RoPE, Adam | | `xenith/core/backward.cpp` | обратный проход (ручной, без автомиффов) | | `xenith/core/trainer.cpp` | цикл обучения, расписание lr, чекпоинты, валидация | | `xenith/core/generate.cpp` | генерация с KV-кэшем, temperature / top-k / top-p | | `xenith/core/checkpoint.cpp` | формат `.xnh`, токенизатор, сохранение/загрузка | | `xenith/core/gradcheck.cpp` | численная проверка градиентов + бенчмарк | ## Быстрый старт ```bash # 1) активация окружения source activate.sh # 2) собрать модель из своего текста Xenith new models/my.xnh --corpus data.txt \ --vocab 512 --embd 128 --layers 6 --heads 8 --ctx 256 # 3) обучить Xenith train models/my.xnh --corpus data.txt \ --out models/my_trained.xnh --steps 5000 --batch 16 --lr 3e-4 # 4) сгенерировать Xenith gen models/my_trained.xnh --prompt "Привет" --n 200 --temp 0.8 ``` ## Перед использованием ***Xenith*** желательно активировать окружение ### Команда активации окружения ```bash # для bash source activate.sh # для zsh source activate.zsh # для fish source activate.fish ``` ## Команды ### new — создать модель Читает корпус, строит по нему словарь, инициализирует веса случайно. ``` --corpus PATH текст (обязательно) --out PATH файл модели (по умолчанию model.xnh) --vocab N размер словаря (512) --embd N ширина эмбеддинга (128) --layers N число слоёв (4) --heads N число голов (4). embd должен делиться на heads --ctx N максимальный контекст (128) --ffn N ширина FFN (0 = 4*embd) --rope N база RoPE (10000) --seed N зерно инициализации (1337) --untied отдельная матрица выхода вместо связанной с эмбеддингом --view-vocab вывести словарь нейросети ``` Словарь двухуровневый: частые слова берутся целиком, остальное режется на символы. Так словарь остаётся маленьким, а любой текст кодируется без потерь — модель может учить и слова, и буквы. ### train — обучить ``` --corpus PATH текст (обязательно) --out PATH куда сохранить (по умолчанию перезаписывает входной файл) --steps N шагов (1000) --batch N батч (8) --block N длина окна (64) --lr F скорость (3e-4) --wd F weight decay (0.01) --clip F клип нормы градиента (1.0) --warmup N прогрев (100) --seed N зерно (1337) --log-every N как часто печатать (50) --ckpt-every N промежуточный чекпоинт каждые N шагов (0 = нет) --val-every N валидация каждые N шагов (0 = нет) --val-tokens N размер валидации (20000) --threads N потоков (0 = все ядра) --resume продолжить с сохранённого step ``` Прогрев + косинусное затухание до `lr * 0.1`. Промежуточные чекпоинты пишутся как `models/my.xnh.step1500` — можно откатиться, если loss развалился. ### gen — сгенерировать ``` --prompt STR стартовый текст --n N сколько токенов (200) --temp F температура; 0 = жадный выбор (0.8) --top-k N top-k (40), 0 = выкл --top-p F top-p (0.95), 1.0 = выкл --seed N зерно --no-stream не печатать в процессе --batch "a;b;c" несколько промптов через ; --show-tokens показать id токенов ``` ### ollama — сгенерировать ``` --port PORT порт сервера (по умолчанию 11434) --conf NAME.conf конфиг с настройками и списком моделей ``` ### gradcheck - проверить градиенты численно ``` --fast эксперементаль флаг который ускоряет foreword примерно в x2-x5 ``` ### bench - замерить скорость форварда и шага обучения ``` --fast эксперементаль флаг который ускоряет foreword примерно в x2-x5 ``` ### info ```bash Xenith info models/my.xnh # конфигурация и словарь ``` ### update - проверка обновления `gradcheck` стоит запускать после любой правки в `model.cpp` / `backward.cpp` — он ловит ошибку в обратном проходе за секунды. ## Формат модели Один файл `.xnh` содержит и словарь, и веса, и состояние оптимизатора. При загрузке проверяется каждая размерность тензора, так что модель, собранная с другими настройками, отвергается с понятной ошибкой, а не молча портит вывод. Совместимость с `models/test_model.bfr` (старый формат) **не** поддерживается: там была другая раскладка весов. ## Что учесть - **Скорость.** ~7600 ток/с на 4 ядрах для 4 слоёв × 64 измерения. С ростом модели скорость падает квадратично по `embd` и линейно по слоям. Замеряйте своим `bench`. - **Форма входа.** `text`, `code`, `html` — чем однороднее корпус, тем меньше словарь и тем быстрее обучение. - **Количество данных.** Модель на 0.25 млн параметров хочет хотя бы несколько мегабайт текста, иначе будет только запоминать. - **Токенизатор** — слова + символы, не BPE. Для морфологически богатых языков это проще, но экономнее BPE приходится платить длиной последовательности.