Что такое Chipformer и почему это не обычный эмулятор
Chipformer превращает эмуляцию CHIP-8 в работу трансформера: decoder-only модель сама выступает игровым движком, исполняет инструкции, обновляет машинную память и рендерит каждый кадр через предсказание следующего токена. Отдельного эмулятора в проекте нет, а каждый сгенерированный токен оказывается записью в память. Нажатия клавиш попадают прямо в контекстное окно модели и меняют то, что она предскажет дальше. Автор проекта описал это в посте на r/LocalLLaMA.
На одних и тех же весах запускаются Pong, Tetris, Space Invaders и ещё более сотни игр CHIP-8. Чтобы сменить игру, достаточно подменить ROM в начальном промпте. Веса при этом не обучались: их скомпилировали из схемы. Конфигурация модели: 18 слоёв, 42 головы внимания и 32 млн параметров, из которых ненулевых только 139 тыс. Считает она в fp64, а загружается через Hugging Face transformers.
Дальше разбираем механику по шагам: как трансформер выполняет роль процессора, как выглядят скомпилированные веса, сколько ресурсов нужно для локального запуска и где заканчиваются возможности подхода.
Как трансформер стал игровым движком
В обычной генерации текста модель предсказывает следующий токен из словаря. В Chipformer тот же механизм выдаёт следующее состояние эмуляции: запись значения по адресу, изменение счётчика команд, пиксель дисплея, обновление таймера. История вычислений целиком лежит в контекстном окне, потому что каждый токен читается как запись в память.
Клавиатура встраивается в ту же последовательность. Когда игрок нажимает кнопку, событие добавляется в контекст, и все последующие предсказания делаются уже с учётом этого ввода. Отдельный обработчик ввода не нужен: реакция на нажатие появляется как следствие следующего сгенерированного токена.
Это принципиально другая роль модели. Здесь трансформер не помощник разработчика и не генератор кода игры, а исполнитель: состояние игры меняется внутри прямого прохода, а не в отдельной программе, написанной по подсказкам нейросети.
Почему это не эмулятор в привычном смысле
CHIP-8 - простая виртуальная машина: монохромный дисплей 64x32 пикселя, 16 регистров по 8 бит, индексный регистр, счётчик команд и короткий набор опкодов. Для неё написаны сотни игр, и классический эмулятор представляет собой интерпретатор, который в цикле выбирает опкод по адресу, декодирует его и выполняет, обновляя регистры, таймеры и видеобуфер. Логика живёт в коде программы, состояние - в массивах в оперативной памяти.
В Chipformer цикл выборки-декодирования-исполнения развёрнут в прямой проход трансформера. Один шаг модели равен одному предсказанию токена, а не одному вызову функции интерпретатора. Отдельного массива памяти тоже нет: актуальные значения лежат в контекстном окне, а правила их изменения - в весах. Запустить Chipformer без трансформера нельзя, а обычный эмулятор CHIP-8, наоборот, работает без нейросети.
Как устроены веса: компиляция вместо обучения
Веса Chipformer не получены обучением на данных. Их скомпилировали из схемы, то есть заранее заданной логики, которую нужно выразить матрицами трансформера: в исходном описании проекта подчёркнуто, что обучение здесь не использовалось. Из этого следуют две особенности: почти все параметры нулевые, а поведение модели предсказуемо на уровне отдельных блоков.
Внимание как чтение памяти
Чтение памяти делает механизм attention. Каждая запись значения по адресу - отдельный токен в контексте, и внимание ищет самую свежую запись для запрошенного адреса. Так реализуется семантика «прочитай то, что было записано последним», без которой не обходится ни одна машина с адресуемой памятью.
По сути это ассоциативная память, собранная из стандартных операций attention: адрес работает как ключ, значение хранится рядом в той же последовательности. Отличие от аппаратной памяти в том, что поиск идёт не по физическим ячейкам, а по списку токенов, поэтому цена чтения растёт вместе с длиной контекста.
ReLU-схемы для арифметики и логики
Вторая часть работы - вычисления. Декодирование опкодов, арифметика, сравнения и битовые операции собраны из ReLU-схем внутри полносвязных слоёв. ReLU с порогом точно выражает ступенчатую функцию, а из ступеней собираются логические вентили, сумматоры и компараторы.
Ближайшая аналогия - FPGA или ASIC: логика не выводится из статистики данных, а зашита в структуру. Разница в носителе, вентили здесь не транзисторы, а взвешенные суммы с порогом. Отсюда и крайняя разреженность весов: считает небольшая часть матриц, остальное - нули.
Роль начального промпта в совместимости
Особенности совместимости закодированы в начальном промпте. Разным играм не нужны разные веса: отличия, которые в обычной практике пришлось бы учитывать в коде, попадают в текст промпта вместе с ROM. Поэтому переход от Tetris к Space Invaders - это правка входной последовательности, а не переобучение и не подмена набора весов.
Технические характеристики и запуск локально
Параметры модели: 18 слоёв, 42 головы, 32 млн параметров
18 слоёв и 42 головы внимания описывают обычный decoder-only трансформер. Необычно другое соотношение: 32 млн параметров при 139 тыс. ненулевых, то есть плотность около 0,43%. У обученных LLM матрицы заполнены почти полностью, здесь же большая часть пространства весов занята нулями, потому что логика задана точечно. Это следствие компиляции схемы, а не результат обрезки обученной модели.
Размер в 32 млн параметров ничего не говорит о вычислительной нагрузке: реально работают 139 тыс. ненулевых весов. Зато цифра сразу отвечает на вопрос про железо. Даже в fp64, где каждый параметр занимает 8 байт, веса весят примерно 256 МБ, и это спокойно помещается в память домашней машины.
Использование fp64 и Hugging Face transformers
Модель считает в двойной точности. Для логических схем это не роскошь: сравнения и вентили в fp32 могут ошибаться на границах порогов, а fp64 держит нужные значения устойчиво. Плата за точность - скорость вычислений и объём памяти.
Загрузка идёт привычным путём через библиотеку transformers:
from transformers import AutoModelForCausalLM
model_id = "<repo-id>" # точный репозиторий указан в исходном посте автора
model = AutoModelForCausalLM.from_pretrained(model_id)
Идентификатор репозитория и параметры загрузки зависят от того, как автор выложил веса; подставлять произвольное имя не стоит, ссылки перечислены в конце статьи.
Смена игр через подмену ROM в промпте
Переключение игр сводится к замене ROM в начальном промпте: веса те же, меняется только входная последовательность. Pong, Tetris, Space Invaders и другие игры CHIP-8 работают на одной модели. Для классических эмуляторов такой сценарий выглядит иначе: каждая игра запускается отдельным бинарником поверх интерпретатора.
Полезно сравнить это с тем, как LLM применяют к играм обычно. Модель пишет код, а играет уже написанная программа: в разборе one shot промптов для клона Super Mario Bros видно, что результат зависит от проверки кода, потому что логика живёт в тексте программы. Ещё один пример - сборка 3D-игры локальной моделью за три часа: там игра тоже появляется как код. У Chipformer роли другие, код не генерируется, а исполняется самой моделью по шагам предсказания.
Ограничения и что стоит учитывать
Производительность и точность: чего мы не знаем
В исходных материалах нет ни данных о скорости эмуляции, ни метрик точности. Неизвестно, сколько токенов уходит на кадр, сколько кадров в секунду выдаёт модель и как часто она расходится с классическим эмулятором. Без этих цифр рекомендовать Chipformer для повседневной игры нельзя: сравнивать его с привычными интерпретаторами просто нечем.
Косвенные соображения тоже не в пользу гейминга. Генерация идёт последовательно, токен за токеном, а один кадр требует множества изменений состояния, то есть длинной цепочки прямых проходов. fp64 добавляет своё: вычисления в двойной точности идут медленнее, чем в fp32 или bf16. Это рассуждение о вероятных узких местах, а не измеренный результат, и до появления бенчмарков его стоит держать в статусе гипотезы.
Сложность компиляции весов
Как именно схема превращается в матрицы, в материалах не раскрыто: нет ни описания инструмента компиляции, ни примеров для другой платформы. Практический вывод простой. Повторить путь Chipformer для Z80 или Game Boy без собственной работы не получится, понадобится свой компилятор логики в веса.
Особенности совместимости, закодированные в промпте, тоже не расшифрованы. На уровне деталей это чёрный ящик, хотя публично описанная архитектура читается как стандартный трансформер.
Что это значит для будущего трансформеров и вычислений
Трансформеры как универсальные вычислители
Chipformer ставит трансформер в позицию процессора: последовательность токенов становится лентой вычислений, внимание работает как чтение памяти, а прямой проход - как такт. Идея не новая, но здесь она доведена до работающей консоли, которую можно нажать и увидеть результат на экране.
Ценность для исследований - в прозрачности. У такой модели почти каждому блоку весов можно приписать смысл: вот чтение памяти, вот декодер опкода, вот сумматор. Разобрать обученную LLM с той же подробностью пока не получается, а скомпилированная схема это позволяет по построению.
Практические сценарии за пределами игр
Сценарии за пределами CHIP-8 в исходных данных не описаны. Можно предположить, и это именно предположение, что компиляция логики в веса пригодится там, где нужна проверяемая точность: формальная верификация, синтез схем, эмуляция других простых виртуальных машин, обучение с подкреплением на детерминированной среде. Подтверждений этим направлениям в материалах нет, так что речь о потенциальных путях, а не о готовых решениях.
Пока проект стоит воспринимать как демонстрацию концепции: один эксперимент, который показывает, что веса трансформера могут хранить детерминированную логику, а не только статистику языка.
Как попробовать Chipformer самостоятельно
Где взять веса и код
Веса опубликованы на Hugging Face, есть демо и код с десктопным приложением. Автор собрал все ссылки в исходном посте: веса, демо и репозиторий с приложением. Проверять сторонние зеркала не нужно, хватит официальных ссылок из описания проекта.
Минимальные шаги для запуска
- Поставить Python и библиотеку transformers.
- Загрузить модель через from_pretrained, указав репозиторий автора.
- Подготовить начальный промпт с ROM нужной игры.
- Запустить генерацию токенов и подавать нажатия клавиш в контекст.
Детали зависят от реализации в репозитории: формат промпта и обработка клавиш задаются кодом автора, а не библиотекой transformers. С памятью запас большой, веса в fp64 занимают около 256 МБ, а основная нагрузка придётся на длину контекста, которая растёт с каждым шагом эмуляции.
Если рядом живут другие локальные модели, планирование ресурсов лучше сделать заранее: разбор выбора между KTransformers и llama.cpp для MoE-моделей показывает, как RAM, VRAM и offload влияют на скорость и время до первого токена.