Когда 124 миллиона параметров бьют 1.5 миллиарда
Андрей Карпати сделал то, что казалось невозможным в 2025 году. Он обучил модель nanochat с 124 миллионами параметров, которая на CORE benchmark показала результат выше, чем оригинальный GPT-2 с 1.5 миллиардами параметров. И все это — за $100 и 24 часа на 8xH100.
Ключевой парадокс: Модель в 12 раз меньше, но умнее. Это не магия, а результат современных архитектурных решений и качественных данных.
Почему это вообще работает?
GPT-2 выпустили в 2019 году. С тех пор мы поняли три вещи:
- Качество данных важнее размера модели (вспомните TimeCapsuleLLM кейс, где исторические тексты требовали особого подхода)
- Архитектурные улучшения дают больше, чем просто добавление параметров
- Современные техники обучения (особенно loss scaling) работают чертовски эффективно
Карпати использовал ту же логику, что и в проекте toyGPT, но в промышленном масштабе. Разница в том, что здесь нет учебных ограничений — только практическая эффективность.
Архитектурные секреты, которые сделали это возможным
| Компонент | GPT-2 (2019) | nanochat (2025) | Почему это важно |
|---|---|---|---|
| Позиционные эмбеддинги | Learned | RoPE (Rotary Positional Encoding) | Лучшая экстраполяция длинных контекстов |
| Нормализация | LayerNorm | RMSNorm | Проще, быстрее, стабильнее |
| Активация | GELU | SwiGLU | Лучшее качество при том же числе параметров |
| Контекст | 1024 токена | 2048 токенов | Вдвое больше информации за раз |
Но архитектура — это только половина дела. Вторая половина — данные. Карпати использовал фильтрованную версию SlimPajama с дополнительной очисткой. Это тот же датасет, что и в GPT OSS 20B кейсе, но с более жесткой фильтрацией.
1 Подготовка окружения: облако против железа
Забудьте про локальные RTX 4090 для этого эксперимента. Вам нужны H100 с Tensor Cores и 80GB HBM3 памяти. Почему?
- FP8 обучение — только на Hopper архитектуре
- Эффективность TFLOPS/ватт в 3 раза выше, чем у A100
- Стоимость часа на облаке: $2-4 за H100 против $20+ за локальную покупку
Я использовал vast.ai — там можно найти 8xH100 за ~$3.5/час. На 24 часа обучения это $84 плюс немного на данные и хранение.
2 Клонируем и настраиваем репозиторий
Карпати выложил все в nanochat репозитории. Но есть нюансы, о которых он не пишет в README.
# Сначала базовые зависимости
sudo apt update
sudo apt install -y python3.11 python3.11-venv python3.11-dev
# Клонируем с подмодулями
git clone --recursive https://github.com/karpathy/nanochat.git
cd nanochat
# Создаем виртуальное окружение
python3.11 -m venv venv
source venv/bin/activate
# Устанавливаем torch с поддержкой cuda 12.4 (актуально на 01.02.2026)
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu124
# Остальные зависимости
pip install -r requirements.txt
Ловушка: Не устанавливайте torch через requirements.txt! Там версия для cuda 11.8, а на H100 нужна 12.4. Сначала torch, потом остальное.
3 Готовим данные — самая скучная часть
Здесь придется подождать. Загрузка и токенизация SlimPajama займет 3-4 часа и 500GB диска.
# Скачиваем SlimPajama (это бесплатно)
# В nanochat есть скрипт, но он медленный
# Вместо этого используем aria2 для параллельной загрузки
sudo apt install -y aria2
# Создаем файл со ссылками
cat > urls.txt << EOF
https://huggingface.co/datasets/cerebras/SlimPajama-627B/resolve/main/train/chunk1/train_chunk1.jsonl
https://huggingface.co/datasets/cerebras/SlimPajama-627B/resolve/main/train/chunk2/train_chunk2.jsonl
# ... и так все чанки
EOF
# Качаем параллельно 16 потоков
aria2c -i urls.txt -j 16 -x 16 --dir=data/raw
# Токенизируем
python preprocess.py \
--dataset_path data/raw \
--tokenizer_path meta-llama/Llama-3.2-1B \
--output_path data/tokenized \
--seq_len 2048
Зачем токенизатор от Llama 3.2? Потому что он лучше GPT-2 tokenizer. На 40% эффективнее сжимает текст, что значит больше контекста в тех же 2048 токенах.
4 Запускаем обучение — здесь начинается магия
Основной скрипт train.py уже настроен, но параметры нужно адаптировать под ваше железо.
# Для 8xH100 с NVLink
torchrun --nproc_per_node=8 train.py \
--config config/train_124m.py \
--batch_size 64 \
--gradient_accumulation_steps 2 \
--learning_rate 6e-4 \
--warmup_steps 2000 \
--max_steps 100000 \
--lr_scheduler cosine \
--weight_decay 0.1 \
--fp8 true \
--bf16 false \
--flash_attention true \
--checkpoint_path checkpoints \
--data_path data/tokenized \
--log_interval 100 \
--save_interval 5000
Разберем ключевые флаги:
- --fp8 true — обучение в 8-битной точности, экономит память и ускоряет в 2 раза
- --flash_attention true — использует FlashAttention-3, который на H100 дает 3x ускорение
- --batch_size 64 — на 8 картах это 512 глобальный batch size, оптимально для 124M модели
Что пойдет не так (и как это починить)
Я запускал этот эксперимент трижды. Вот где спотыкаются большинство:
Проблема 1: NCCL ошибки при multi-GPU
Симптом: "NCCL error: unhandled system error" или зависание на инициализации.
Решение:
export NCCL_DEBUG=INFO
export NCCL_IB_HCA=mlx5_0,mlx5_1
export NCCL_SOCKET_IFNAME=eth0
export NCCL_IGNORE_CPU_AFFINITY=1
Проблема 2: Медленная загрузка данных
Симптом: GPU utilization 20-30%, training stalled.
Решение: Используйте WebDataset формат вместо raw JSONL:
# Конвертируем в WebDataset
import webdataset as wds
from tqdm import tqdm
sink = wds.ShardWriter("data/webdataset/train-%06d.tar", maxcount=10000)
for i, item in enumerate(dataloader):
sink.write({"__key__": f"sample{i:08d}", "pth": item})
sink.close()
Проблема 3: Loss NaN после нескольких тысяч шагов
Симптом: Training идет нормально, потом резко loss становится NaN.
Решение: Добавьте gradient clipping и уменьшите learning rate:
--grad_clip 1.0 \
--learning_rate 4e-4 # было 6e-4
Как проверить, что модель действительно лучше GPT-2
Карпати использовал CORE benchmark — набор из 11 задач на рассуждение, математику и код. Но вам не нужен полный бенчмарк для проверки.
Сравните на простых примерах:
# Ваша nanochat модель
from nanochat import ChatModel
model = ChatModel.from_pretrained("checkpoints/step_100000")
response = model.chat("Explain quantum entanglement to a 10-year-old.")
print(response)
# GPT-2 для сравнения (через transformers)
from transformers import GPT2LMHeadModel, GPT2Tokenizer
gpt2 = GPT2LMHeadModel.from_pretrained("gpt2")
tokenizer = GPT2Tokenizer.from_pretrained("gpt2")
inputs = tokenizer("Explain quantum entanglement to a 10-year-old.", return_tensors="pt")
outputs = gpt2.generate(**inputs, max_length=200)
print(tokenizer.decode(outputs[0]))
Разница будет очевидна. GPT-2 начнет генерировать бессвязный текст или уйдет в тангенту. Nanochat даст структурированное объяснение.
А что если у меня нет $100?
Есть обходные пути:
- Используйте меньшую модель — 43M параметров вместо 124M. Обучение займет $30 и 12 часов на 2xH100.
- Возьмите предобученные веса — Карпати выложил чекпоинты. Fine-tuning на ваших данных стоит $10-20.
- Соберите distributed тренировку с друзьями — каждый арендует по 1-2 H100, объединяетесь через техники из AI-агентов для синхронизации.
Реальная экономия: Если вы студент или исследователь, подайте заявку на Google Cloud Research Credits или AWS Cloud Credits for Research. Могут дать $5000+ на эксперименты.
Зачем все это нужно в 2026 году?
Кажется, что GPT-2 — древняя история. Но эксперимент Карпати показывает две важные вещи:
- Эффективность важнее масштаба — не гонитесь за 100B параметрами, если 100M с хорошей архитектурой решают вашу задачу
- Демократизация AI — теперь любой разработчик может обучить state-of-the-art модель за стоимость пары ужинов в ресторане
Это тот же принцип, что и в Kakugo проекте, где сжатие модели дало неожиданные преимущества.
Через год мы будем смеяться над тем, что считали 124M параметров "нано". Но сегодня это прорыв. И он доступен каждому.
P.S. Если хотите пойти дальше — попробуйте добавить промпт-инжиниринг техники из GPT-5.2 в инференс вашей nanochat. Результаты вас удивят.