Игорь Градов
Игорь Градов
6 мин
ai

Нейросеть GPT на русском с нуля: проект jarvis показывает каждый слой без готовых обёрток

Русскоязычную GPT можно собрать с нуля, без готовых обёрток и предобученных весов, и проект jarvis показывает каждый шаг: от собственного BPE-токенизатора (словарь для разбивки текста на части, понятные модели) до работающего Telegram-бота.

Нейросеть GPT на русском с нуля: проект jarvis показывает каждый слой без готовых обёрток
Почему это важно

Проект jarvis убирает «магию» из языковых моделей: вместо вызова чужого API вы видите каждый слой архитектуры, сами решаете, на каких текстах учить нейросеть, и получаете модель, заточенную под русский язык и диалоги.

Автор проекта объясняет мотивацию просто: пока вы пользуетесь API, нейросеть остаётся чёрным ящиком. Чтобы по-настоящему понять, как работает языковая модель, нужно построить свою, пусть компактную, но полностью рабочую. Готовый SFT-чекпойнт (контрольная точка модели после диалогового дообучения) и токенизатор уже опубликованы на Hugging Face.

Что понадобится?

  • Python 3.10+ и библиотека PyTorch
  • Доступ к Hugging Face для скачивания обучающих данных и публикации чекпойнтов
  • GPU для обучения (подойдёт одна карта, проект поддерживает распределённый запуск через DDP)
  • Telegram-аккаунт и токен бота, если хотите развернуть чат
  • Время: подготовка данных и обучение токенизатора занимают минуты, претрейн и дообучение (fine-tuning, обучение модели на ваших примерах под узкую задачу) зависят от объёма данных и мощности GPU

Как устроена архитектура jarvis?

Jarvis построен как decoder-only transformer (модель, которая генерирует текст слово за словом, опираясь на предыдущий контекст). Внутри нет стандартного nn.Transformer из PyTorch. Каждый блок собран вручную из двух веток с предварительной нормализацией:

class TransformerBlock(nn.Module):
    def forward(self, x, cache=None):
        attn_out, new_cache = self.attn(self.ln1(x), cache)
        x = x + attn_out
        x = x + self.ff(self.ln2(x))
        return x, new_cache

Вместо привычного LayerNorm используется RMSNorm, нормализация по среднему квадрату без центрирования. Слой MLP реализован через SwiGLU: один линейный слой формирует «вентиль», второй значения, результат перемножается после функции активации SiLU.

Ещё одно решение, которое экономит параметры: входные эмбеддинги (таблица, переводящая токены в числовые векторы) и выходная проекция делят одну матрицу весов. Для компактной модели это стандартный приём, но он заметно сокращает размер.

Пошаговая инструкция

  1. Подготовьте данные. Скрипт prepare_data.py собирает три типа текстов: веб-документы (до миллиона), тексты из корпуса gazeta (до 150 тысяч) и диалоги из набора russian_instructions_2 (до 120 тысяч примеров). Для веба и gazeta работают фильтры по длине и доле кириллицы, диалоги нормализуются, повторы отсеиваются.
python prepare_data.py --what all
  1. Обучите BPE-токенизатор. Скрипт train_tokenizer.py строит словарь на 16 384 токена (токен, минимальная единица текста для модели) на смеси обычных текстов (60%) и диалогов (40%). Byte-level подход не ломается на незнакомых символах: в худшем случае текст разбивается на отдельные байты.
python train_tokenizer.py

В словарь автоматически добавляются четыре служебных токена:

<|endoftext|>  <|user|>  <|assistant|>  <|pad|>

Системный промпт (system prompt, инструкция для модели, задающая роль и стиль ответа) отдельного токена не получает: системный текст присоединяется к первому сообщению пользователя. Это упрощает формат.

  1. Токенизируйте корпус. Скрипт tokenize_corpus.py превращает тексты в бинарные файлы с токенами и масками для дообучения.

  2. Запустите претрейн. Скрипт train.py обучает модель предсказывать следующий токен на всём корпусе.

  3. Проведите диалоговое дообучение (SFT). Здесь принципиальный момент: loss (функция ошибки, которую модель минимизирует) считается НЕ по всему диалогу. Токены пользователя получают вес 0, токены ассистента получают вес 1. Без этой маски нейросеть одинаково учится продолжать и вопрос, и ответ, а нам нужно только второе.

losses = F.cross_entropy(
    logits.view(-1, logits.shape[-1]),
    y.view(-1), reduction="none",
)
weights = mask.view(-1).float()
loss = (losses * weights).sum() / weights.sum().clamp_min(1.0)
  1. Проверьте результат. Локальный инференс (инференс, процесс генерации ответа обученной моделью) через chat.py или generate.py, бот через bot.py, бенчмарк через tools/bench_bpc.py.

Почему 60/40 для токенизатора?

Соотношение 60% литературных текстов и 40% диалогов при обучении токенизатора заслуживает отдельного внимания. Если обучить словарь только на книжном русском, диалоговые конструкции будут дробиться на мелкие фрагменты, и модель потратит больше токенов на каждый промпт. Если перекосить в сторону чатов, пострадает качество на длинных текстах. Автор проекта выбрал баланс, при котором нейросеть видит оба формата уже на уровне словаря.

Как это применить

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

python chat.py

Вводите:

<|user|>Привет!<|assistant|>

Модель генерирует продолжение только после токена <|assistant|>, потому что именно на этом участке она училась отвечать. Результат: связный ответ на русском языке, сгенерированный моделью, которую вы собрали сами.

Частые ошибки
  • Считать loss по всему диалогу. Без маски модель учится «продолжать» реплики пользователя, а не отвечать на них. Качество ответов падает.
  • Обучать токенизатор только на литературном корпусе. Диалоги дробятся на мелкие куски, контекстное окно расходуется впустую, нейросеть хуже справляется с живыми вопросами.
  • Писать attention вручную через матрицу QK и softmax. Код получается нагляднее, но работает медленнее. В jarvis используется оптимизированное ядро torch.nn.functional.scaled_dot_product_attention, при этом QKV-проекции, RoPE и логика кэша остаются авторскими.
  • Игнорировать фильтрацию данных. Скрипт prepare_data.py отсеивает тексты с низкой долей кириллицы и короткие документы. Без этого в обучающие данные попадает мусор, и модель выдаёт бессвязные ответы.

Что делать с этим прямо сейчас, по ролям

Автору на Дзене. Проект jarvis не заменит нейросеть Яндекса или ChatGPT для ежедневной работы с текстом. Но если вы хотите понять, как именно нейросеть «думает» и почему она иногда выдумывает факты (галлюцинация, когда модель уверенно генерирует то, чего не было), jarvis даёт возможность увидеть каждый слой изнутри. Это меняет подход к промптам (промпт, текстовая инструкция для нейросети): вы начинаете формулировать запросы точнее, когда понимаете механику.

Маркетологу. Собственная компактная модель полезна для экспериментов с тоном и стилем ответов, которые нельзя доверить стороннему API из-за конфиденциальности. Данные не уходят наружу, модель работает локально.

Разработчику и предпринимателю в РФ. Проект целиком на русском языке, код открыт (открытая модель, код доступен для изучения и модификации), чекпойнт лежит на Hugging Face. Если вы строите продукт и нужна базовая русскоязычная модель под свои задачи, jarvis показывает рабочий путь без зависимости от зарубежных API, доступ к которым может быть ограничен. Из доступных в РФ готовых решений для повседневных задач: нейросеть Яндекса (YandexGPT) и GigaChat от Сбера.

Мнение редакции dzen.guru

Jarvis не конкурент большим моделям и не претендует на это. Словарь в 16 384 токена и компактная архитектура дают модель, которая отвечает на простые вопросы, но не потянет сложную аналитику. Ценность в другом: это, пожалуй, самый прозрачный русскоязычный проект, где можно пройти весь путь от сырого текста до работающего чат-бота и понять каждый шаг. Я рекомендую пройти хотя бы этапы токенизации и дообучения, даже если вы не собираетесь разворачивать свою модель в продакшене. После этого промпты для любой нейросети, хоть YandexGPT, хоть ChatGPT, начинаешь писать иначе. Честная оговорка: для запуска обучения нужна GPU, и на слабом железе процесс может занять часы.

Попробуйте генерацию контента с ИИ на dzen.guru

Если вы пока не готовы строить нейросеть с нуля, протестируйте готовые инструменты для авторов Дзена.

Попробовать

Проект jarvis доказывает простую вещь: чтобы разобраться в нейросетях, не нужен бюджет OpenAI. Нужны открытый код, русскоязычные данные и готовность прочитать каждый слой, а не просто вызвать API.

Поделиться:TelegramVK
Игорь Градов
Игорь Градов

Основатель dzen.guru. Эксперт по монетизации и продвижению на Дзен. Автор курса «Старт на Дзен 2026».

Комментарии

Читайте также

ИИ нашёл две уязвимости в PHP с оценкой 9.2 из 10: кибербезопасность миллионов сайтов под угрозой
ai

ИИ нашёл две уязвимости в PHP с оценкой 9.2 из 10: кибербезопасность миллионов сайтов под угрозой

Компания Cloudflare и специалисты Amazon зафиксировали массовые попытки эксплуатации двух критических уязвимостей в PHP, обнаруженных 21 октября и позволяющих…

5 мин
Что такое ИИ-агент без технических ограничений: 11 запретов не спасли базу на 1 206 записей
ai

Что такое ИИ-агент без технических ограничений: 11 запретов не спасли базу на 1 206 записей

Джейсон Лемкин, основатель SaaStr, в июле 2025 года девять дней строил приложение с помощью ИИ-агента на платформе Replit и потерял рабочую базу данных, хотя…

5 мин
Две уязвимости в PHP угрожают 70% сайтов: Cloudflare насчитала миллионы атак за сутки
ai

Две уязвимости в PHP угрожают 70% сайтов: Cloudflare насчитала миллионы атак за сутки

PHP оказался под ударом: две уязвимости, найденные с помощью ИИ, угрожают миллионам сайтов по всему миру, и российские проекты на 1С-Битрикс и WordPress не…

6 мин