От токенизации до генерации: как я с нуля написал GPT для Python-кода. ai.. ai. gpt like.. ai. gpt like. llm.. ai. gpt like. llm. python.. ai. gpt like. llm. python. разработка.

Авторское право и лицензия
Код, представленный в статье, написан Await IT (await.it.bx@gmail.com)
и распространяется под лицензией MIT с обязательным указанием авторства.
Дата публикации кода: 01.06.2026
GitHub репозиторий: https://github.com/Await-IT/GPT-Like
© 2026 Await IT. Все права на исходный код защищены.

Введение: почему своя GPT?

Когда все вокруг пользуются ChatGPT и Claude, возникает естественный вопрос: а что, если попробовать сделать нечто подобное самому? Не для того, чтобы конкурировать с гигантами, а чтобы понять изнутри, как работают современные языковые модели.

Этот проект — моя попытка пройти весь путь: от токенизации текста до генерации кода. Не используя готовые решения от HuggingFace, а реализуя каждый компонент самостоятельно. И знаете что? Это оказалось одновременно сложнее и интереснее, чем я предполагал.

Сложность №1: токенизация кода — это не просто разбить на слова

Проблема

Обычный BPE-токенизатор ломается на Python-коде. Он не понимает:

  • Значимость отступов

  • Разницу между def как ключевым словом и def как частью слова

  • Структуру кода (классы, функции, условия)

Решение: CodeTokenizer с AST-анализом

class CodeTokenizer:
    @staticmethod
    def tokenize_python_code(code):
        tokens = []
        try:
            token_stream = tokenize.generate_tokens(io.StringIO(code).readline)
            for tok in token_stream:
                token_type = tokenize.tok_name[tok.type]
                token_value = tok.string
                
                if token_type == 'INDENT':
                    tokens.append(Config.code_indent_token)
                elif token_type == 'DEDENT':
                    tokens.append(Config.code_dedent_token)
                # ... обработка ключевых слов, строк, чисел
От токенизации до генерации: как я с нуля написал GPT для Python-кода - 1

Что это даёт?

  • <indent>/<dedent> вместо четырёх пробелов — модель учится структуре

  • <def>, <class>, <if> как специальные токены — понимание синтаксиса

  • <string>, <number>, <comment> — типовая информация

Результат

# Исходный код:
def factorial(n):
    if n == 0:
        return 1

# Токенизация:
['<def>', 'factorial', '(', 'n', ')', ':', '<newline>', 
 '<indent>', '<if>', 'n', '==', '<number>', ':', '<newline>',
 '<indent>', '<return>', '<number>', '<newline>', '<dedent>']
От токенизации до генерации: как я с нуля написал GPT для Python-кода - 2

Сложность №2: архитектура Transformer — мои ошибки

Ошибка №1: Encoder вместо Decoder

Первая версия использовала nn.TransformerEncoder — это архитектура BERT, а не GPT. GPT требует маскированного внимания (look-ahead mask), чтобы токен “видел” только предыдущие токены.

# Было (НЕПРАВИЛЬНО):
encoder_layer = nn.TransformerEncoderLayer(...)
self.transformer = nn.TransformerEncoder(encoder_layer, num_layers)

# Стало (правильнее, но ещё не идеально):
def generate_attention_mask(self, seq_len, device):
    mask = torch.triu(torch.ones(seq_len, seq_len, device=device), diagonal=1).bool()
    return mask
От токенизации до генерации: как я с нуля написал GPT для Python-кода - 3

Ошибка №2: устаревшие позиционные эмбеддинги

Использование nn.Embedding для позиций — подход 2018 года. Современные модели используют:

  • RoPE (Rotary Positional Embeddings) — как в LLaMA

  • ALiBi — как в MPT

  • Sinusoidal — классика, но лучше, чем learnable

Я оставил learnable эмбеддинги для простоты, но в README проекта честно указал это как ограничение.

Сложность №3: обучение на маленьких данных

Проблема

У меня не было доступа к терабайтам текста. Только небольшие датасеты с:

  • Примерами Python-кода

  • Диалогами в формате вопрос-ответ

  • Техническими статьями

Решения

  1. Аугментация данных: перестановка строк кода, замена имён переменных

  2. Контролируемая генерация: использование специальных токенов <user>, <bot>

  3. Смешанная точность (AMP): позволила увеличить batch size

def fast_train_step(model, batch, optimizer, scaler=None, use_amp=False):
    if use_amp and scaler is not None:
        with torch.cuda.amp.autocast():  # Mixed precision
            outputs = model(inputs)
            loss = model.compute_loss(outputs, targets)
        scaler.scale(loss).backward()
        scaler.step(optimizer)
        scaler.update()
    # ...
От токенизации до генерации: как я с нуля написал GPT для Python-кода - 4

Что получилось (честные результаты)

Успехи

  1. Токенизатор работает отлично — корректно разбирает сложный Python-код

  2. Модель обучается — loss стабильно снижается

  3. Генерация синтаксически корректного кода (в простых случаях)

Пример генерации

Вход: <user> Напиши функцию для суммы двух чисел

Выход: <bot> <start>
def add_numbers(a, b):
    result = a + b
    return result
<end>
От токенизации до генерации: как я с нуля написал GPT для Python-кода - 5

Неудачи

  1. Логические ошибки — модель генерирует синтаксически правильный, но семантически бессмысленный код

  2. Ограниченный контекст — 1024 токена недостаточно для сложных программ

  3. Переобучение на маленьких данных — модель запоминает примеры, а не учится общим принципам

Технические детали реализации

Архитектура

class TransformerModel(nn.Module):
    def __init__(self, vocab_size, d_model=256, n_head=8, 
                 num_layers=6, d_ff=2048, dropout=0.1):
        super().__init__()
        self.token_embedding = nn.Embedding(vocab_size, d_model)
        self.position_embedding = nn.Embedding(max_seq_len, d_model)
        # ... Transformer слои
От токенизации до генерации: как я с нуля написал GPT для Python-кода - 6

Параметры модели:

  • d_model: 256 (микроскопически мало, но для обучения достаточно)

  • Слои: 6

  • Головы внимания: 8

  • Всего параметров: ~10 миллионов (GPT-3: 175 миллиардов)

Pipeline обучения

# 1. Токенизация данных
tokenizer.train(Config.pretrain_file, Config.vocab_size)

# 2. Создание датасета
dataset = DialogDataset(file_path, tokenizer, max_length)

# 3. Обучение модели
model = train_fast(model, train_loader, val_loader, epochs=30)

# 4. Генерация
text = generate_text(model, tokenizer, prompt, max_length=100)
От токенизации до генерации: как я с нуля написал GPT для Python-кода - 7

Что я узнал (ключевые инсайты)

1. Токенизация — ключ к успеху

Плохая токенизация = плохая модель. Особенно для кода.

2. Данные важнее архитектуры

Можно иметь идеальную архитектуру, но без качественных данных модель не научится.

3. Отладка LLM — это сложно

Когда модель генерирует ерунду, непонятно: проблема в данных, архитектуре или обучении?

4. Сообщество — лучший учитель

Каждый issue и PR на GitHub учил меня чему-то новому.

Как использовать проект

Для обучения

git clone https://github.com/Await-IT/GPT-Like
cd educational-gpt-python
pip install -r requirements.txt
python train.py
От токенизации до генерации: как я с нуля написал GPT для Python-кода - 8

Для экспериментов

from src.tokenizer import ImprovedBPETokenizer
from src.model import TransformerModel

# Создайте свою модель
model = TransformerModel(vocab_size=50000)
# Обучите на своих данных
# Экспериментируйте с архитектурой
От токенизации до генерации: как я с нуля написал GPT для Python-кода - 9

Ограничения и что дальше

Текущие ограничения

  1. Слишком маленькая модель

  2. Устаревшие компоненты (нет RoPE, SwiGLU)

  3. Нет эффективных оптимизаций (FlashAttention)

  4. Только Python (хотя токенизатор можно расширить)

Планы на будущее

  1. Реализация RoPE — уже в работе

  2. Поддержка больше языков — JavaScript, Java, C++

  3. Увеличение масштаба — переход к моделям на 100M+ параметров

  4. Интеграция с IDE — плагин для VSCode

Выводы

Этот проект — не про создание конкурента ChatGPT. Это про понимание. Про то, чтобы за красивым интерфейсом и плавными ответами увидеть сложную систему из эмбеддингов, внимания и слоев нормализации.

Самые важные уроки:

  1. Начинайте с простого — даже минимальная работающая модель даёт невероятное понимание

  2. Не бойтесь ошибок — каждая ошибка в архитектуре учит лучше, чем успех

  3. Делитесь кодом — обратная связь от сообщества бесценна

Ссылки

  • GitHub репозиторий: https://github.com/Await-IT/GPT-Like

  • Colab ноутбук для быстрого старта: (в разработке)

  • Документация API: (в разработке)

Лицензия

Проект распространяется под MIT лицензией. Вы можете:

  • Использовать код в коммерческих проектах

  • Модифицировать и распространять изменения

  • Использовать в академических работах

Единственное условие: сохранение уведомления об авторских правах.


Это учебный проект. Для production использования рекомендую библиотеки типа HuggingFace Transformers, которые реализуют современные архитектуры с оптимизациями.


Для тех, кто хочет глубже: в репозитории есть issues с пометкой “good first issue” — отличные задачи для начала контрибьютинга. А если у вас есть идеи, как улучшить токенизатор или архитектуру — welcome to PR!

P.S. Если статья была полезной, посетите наш Телеграмм канал

https://t.me/Await_IT

Автор: Await-IT

Источник

Rambler's Top100