Andrej Karpathy только что создал полноценный GPT в 243 строках Python
Аннотация: В феврале 2026 года известный исследователь ИИ Андрей Карпати опубликовал проект
microGPT— минималистичную реализацию трансформера, обучающуюся и выполняющую инференс всего в 243 строках чистого Python без внешних зависимостей. Этот «арт-проект» демонстрирует фундаментальные математические принципы работы больших языковых моделей, делая архитектуру GPT прозрачной и доступной для изучения. [[5]]
📋 Краткое содержание
Аспект | Описание |
|---|---|
Автор проекта | Andrej Karpathy (бывший директор по ИИ в Tesla, сооснователь OpenAI) |
Дата публикации | 11 февраля 2026 года |
Объём кода | 243 строки чистого Python |
Зависимости | Только стандартная библиотека: |
Цель | Образовательная: показать «атомарное ядро» алгоритма GPT [[9]] |
Данные для обучения | Список детских имён (names.txt) |
Результат | Модель генерирует новые, правдоподобные имена |
🔍 Что такое microGPT и зачем он нужен?
«Это самый атомарный способ обучить и запустить инференс GPT на чистом Python без зависимостей. Этот файл содержит полный алгоритм. Всё остальное — лишь вопрос эффективности.» — Andrej Karpathy [[9]]
Ключевая идея
Большинство современных реализаций трансформеров (PyTorch, TensorFlow, JAX) скрывают математическую суть за слоями абстракций. microGPT делает обратное: всё построено «с нуля» на базовых операциях Python, чтобы любой мог прочитать код и понять:
Как работает автоматическое дифференцирование (autograd)
Как устроено многоголовое внимание (multi-head attention)
Как происходит обучение через обратное распространение ошибки
Как работает оптимизатор Adam
Аналогия
🚗 Игрушечная машинка и Tesla: у обеих есть двигатель, колёса, руль и тормоза. Игрушка не выиграет гонку, но если вы хотите понять, как работает автомобиль — она идеальна.
🧩 Архитектура microGPT: разбор по компонентам
1️⃣ Токенизатор (строки 15–20)
uchars = sorted(set(''.join(docs))) # Уникальные символы в датасете BOS = len(uchars) # Токен начала последовательности vocab_size = len(uchars) + 1 # Размер словаря
Аннотация: Компьютеры не понимают буквы — только числа. Токенизатор сопоставляет каждый символ уникальному целочисленному ID. Специальный токен <BOS> (Beginning of Sequence) обрамляет каждую последовательность, помогая модели понимать границы.
2️⃣ Autograd Engine: обратное распространение «с нуля» (строки 23–60)
class Value: __slots__ = ('data', 'grad', '_children', '_local_grads') def __init__(self, data, children=(), local_grads=()): self.data = data # Значение узла self.grad = 0 # Градиент функции потерь по этому узлу self._children = children # Дочерние узлы в графе вычислений self._local_grads = local_grads # Локальные производные def __add__(self, other): other = other if isinstance(other, Value) else Value(other) return Value(self.data + other.data, (self, other), (1, 1)) def backward(self): # Топологическая сортировка + применение цепного правила ...
Аннотация: Класс Value — это «атом» вычислительного графа. Каждый объект хранит:
data— скалярное значениеgrad— градиент функции потерь по этому значению_children— ссылки на операнды_local_grads— локальные производные для обратного прохода
Метод backward() выполняет топологическую сортировку графа и рекурсивно применяет цепное правило для вычисления градиентов — точная копия механизма autograd в PyTorch, но в 40 строках кода. [[5]]
3️⃣ Архитектура GPT: трансформер «в лоб» (строки 95–150)
def gpt(token_id, pos_id, keys, values): # 1. Эмбеддинги токена и позиции tok_emb = state_dict['wte'][token_id] pos_emb = state_dict['wpe'][pos_id] x = [t + p for t, p in zip(tok_emb, pos_emb)] x = rmsnorm(x) for li in range(n_layer): # 2. Multi-head Self-Attention q = linear(x, state_dict[f'layer{li}.attn_wq']) k = linear(x, state_dict[f'layer{li}.attn_wk']) v = linear(x, state_dict[f'layer{li}.attn_wv']) # ... вычисление attention-весов и контекста ... # 3. Feed-Forward Network (MLP) x = linear(x, state_dict[f'layer{li}.mlp_fc1']) x = [xi.relu() for xi in x] # ReLU² активация x = linear(x, state_dict[f'layer{li}.mlp_fc2']) # 4. Логиты для предсказания следующего токена logits = linear(x, state_dict['lm_head']) return logits
Аннотация: Реализация следует архитектуре GPT-2 с минимальными упрощениями:
✅ RMSNorm вместо LayerNorm (проще, стабильнее)
✅ ReLU² вместо GeLU (квадрат ReLU:
x.relu() ** 2)✅ Без bias-параметров в линейных слоях
✅ Кэширование ключей/значений (KV-cache) для инференса
⚠️ Это не «упрощённая» модель — это та же математика, что в GPT-4, просто в миниатюре. [[1]]
4️⃣ Оптимизатор Adam: «с нуля» (строки 155–175)
# Параметры Adam learning_rate, beta1, beta2, eps_adam = 0.01, 0.85, 0.99, 1e-8 m = [0.0] * len(params) # Первый момент (среднее градиентов) v = [0.0] * len(params) # Второй момент (среднее квадратов) # Обновление параметров for i, p in enumerate(params): m[i] = beta1 * m[i] + (1 - beta1) * p.grad v[i] = beta2 * v[i] + (1 - beta2) * p.grad ** 2 m_hat = m[i] / (1 - beta1 ** (step + 1)) # Bias correction v_hat = v[i] / (1 - beta2 ** (step + 1)) p.data -= learning_rate * m_hat / (v_hat ** 0.5 + eps_adam)
Аннотация: Adam — самый популярный оптимизатор в глубоком обучении. Здесь он реализован полностью прозрачно:
Коррекция смещения (bias correction) для первых шагов
Адаптивный learning rate на основе истории градиентов
Численная стабильность через
eps_adam
5️⃣ Цикл обучения и инференс (строки 180–220)
# Обучение for step in range(num_steps): doc = docs[step % len(docs)] tokens = [BOS] + [uchars.index(ch) for ch in doc] + [BOS] # Forward pass + вычисление loss losses = [] for pos_id in range(n): logits = gpt(tokens[pos_id], pos_id, keys, values) probs = softmax(logits) losses.append(-probs[tokens[pos_id + 1]].log()) loss = sum(losses) / n loss.backward() # Backward pass # Обновление параметров через Adam ... # Инференс: генерация новых имён for sample_idx in range(20): token_id = BOS for pos_id in range(block_size): logits = gpt(token_id, pos_id, keys, values) probs = softmax([l / temperature for l in logits]) # Temperature sampling token_id = random.choices(range(vocab_size), weights=[p.data for p in probs])[0] if token_id == BOS: break sample.append(uchars[token_id])
Аннотация:
Обучение: Модель учится предсказывать следующий символ в имени, минимизируя кросс-энтропийный loss.
Инференс: Генерация через temperature sampling — чем ниже температура, тем более «консервативны» предсказания.
🎓 Почему microGPT — прорыв в обучении?
Преимущество | Объяснение |
|---|---|
Полная прозрачность | Нет «чёрных ящиков»: каждый градиент, каждое умножение видно в коде [[5]] |
Нулевые зависимости | Не нужно устанавливать PyTorch, CUDA, conda — достаточно Python 3 |
Отладка в реальном времени | Можно добавить |
Модифицируемость | Хотите заменить ReLU на Swish? Изменить число heads? Правьте код напрямую |
Реальные результаты | Модель действительно обучается и генерирует осмысленные имена после ~1000 шагов |
💡 «Всё, что выходит за рамки этих 243 строк — это оптимизация, а не интеллект.»
⚙️ Как запустить microGPT
# 1. Скачайте код curl -O https://gist.githubusercontent.com/karpathy/8627fe009c40f57531cb18360106ce95/raw/microgpt.py # 2. Запустите python microgpt.py
Что произойдёт:
Автоматически скачается
names.txt(список имён)Модель обучится 1000 шагов (~3 часа на CPU)
Сгенерирует 20 новых «имён»
🐌 Да, это медленно. Но цель — не скорость, а понимание.
📊 Ограничения и практические замечания
Ограничение | Причина | Решение для продакшена |
|---|---|---|
Медленная скорость | Чистый Python, скалярные операции, нет GPU | Использовать PyTorch/TensorFlow с векторизацией |
Малый масштаб | 1 слой, 16 эмбеддингов, 4 heads | Увеличить |
Простой датасет | Только имена (~10K символов) | Заменить |
Нет батчинга | Обработка одного примера за шаг | Добавить мини-батчи для ускорения сходимости |
🔬 Идеи для экспериментов
# 🧪 1. Измените архитектуру n_layer = 2 # Добавьте второй слой трансформера n_embd = 32 # Увеличьте размер эмбеддингов n_head = 8 # Больше голов внимания # 🧪 2. Попробуйте другие данные docs = open("shakespeare.txt").read().split("\n") # Шекспир вместо имён # 🧪 3. Добавьте регуляризацию def dropout(x, p=0.1): return [xi if random.random() > p else Value(0) for xi in x] # 🧪 4. Визуализируйте градиенты for p in params[:10]: print(f"param grad: {p.grad:.4f}")
📚 Заключение
microGPT — это не просто код. Это манифест образовательной прозрачности в эпоху «чёрных ящиков» ИИ.
✅ Для студентов: Лучший способ понять трансформеры — прочитать 243 строки, а не 243 000.
✅ Для инженеров: Шаблон для создания минимальных прототипов без фреймворков.
✅ Для исследователей: Базовый «атом» для экспериментов с новыми архитектурами.
Скачайте, прочитайте, измените, сломайте, соберите заново. Именно так рождается настоящее понимание.
🔗 Полезные ссылки
📄 Оригинальный gist Karpathy — исходный код
microgpt.py[[9]]📰 Analytics Vidhya: разбор microGPT — детальное объяснение архитектуры [[5]]
💻 Порты на другие языки — C++, Rust, JS, Ruby, PHP от сообщества
🎥 Лекции Karpathy по нейросетям — фундамент для понимания кода
📝 Лицензия: Код
microGPTраспространяется под лицензией MIT — используйте, модифицируйте, делитесь с указанием авторства. [[Авторский комментарий в gist]]
Документ подготовлен на основе статьи Sumit Pandey (Towards Deep Learning) и официальных материалов Andrej Karpathy. Перевод и аннотация выполнены в образовательных целях.
