W piątek 30 października Drew Breunig pokazał na Hacker News projekt NESformer: procesor 6502 z konsoli NES (rdzeń chipu 2A03), dwa kilobajty pamięci roboczej i 32 kilobajty pamięci kartridża skompilowane do wag zwykłego modelu Qwen3.5. Nikt tych wag nie trenował, każdy bit policzył kompilator. Model przewiduje log wykonania procesora token po tokenie, a mały program-gospodarz dokłada resztę konsoli: rysuje obraz, czyta pada i odpala przerwanie vblank. Do repo trafiły nagrania dwóch uruchomień, w tym World 1-1 z Super Mario Bros., i w tych grach każda klatka zgadza się z wyjściem klasycznego emulatora 6502. Wątek przy moim odczycie w sobotę 31 października miał 245 punktów i 121 komentarzy, a jedna klatka na tym „sprzęcie” trwa od jednej do sześciu sekund.
- Najważniejsze informacje
- Model, który jest procesorem
- Skąd się to wzięło: Qwenputer i dwa prompty
- Skąd pewność, że to działa
- Ile to kosztuje obliczeń
- To nie jest AI grające w Mario
- Co z tego dla Polski
Najważniejsze informacje
| Co | Szczegóły |
|---|---|
| Projekt | NESformer Drewa Breuniga, repo na GitHubie opublikowane 30 października 2026 (15:54 UTC), licencja MIT |
| Co siedzi w wagach | Rdzeń 6502, wszystkie 151 oficjalnych opcode’ów, 2 KB RAM i 32 KB PRG-ROM kartridża; flagi, stos, wejścia BRK i NMI |
| Nośnik | Checkpoint Qwen3_5ForCausalLM: 466,6 mln parametrów w bf16 (933 MB, z tego tylko 9,3 mln niezerowych), 7 warstw Gated DeltaNet |
| Weryfikacja | Thwaite: 1 916 527 tokenów i 600 klatek bez rozbieżności; Full Game: 2 645 885 tokenów i 420 klatek; klatki zgodne 1:1 z emulatorem 6502 |
| Wydajność | Klatka 1-6 sekund, ok. 1650 tokenów/s na jednym rdzeniu CPU; 150-290 razy wolniej od prawdziwej konsoli |
| Gry demo | Super Mario Bros. (World 1-1) i Full Game Douga Frakera; własne ROM-y tylko w formacie NROM |
| Wymagania | Python 3.11+, numpy, scipy, numba, pillow; karta graficzna zbędna |
Model, który jest procesorem
Zwykły model językowy generuje tekst: dostaje tokeny na wejściu i zwraca najbardziej prawdopodobny kolejny token, czyli w praktyce wykonuje zwykłą inferencję. NESformer używa tej samej maszyny, tylko wyjście nie jest zdaniem, tylko wierszem z logu wykonania procesora: STX $4017, BPL $8017, J($8279) dla skoku. Takie wiersze sklejają się w pełny ślad pracy CPU, a program-gospodarz zamienia zapisy do rejestrów graficznych w piksele. Większość instrukcji zajmuje jeden token, ale w realnym kodzie gier wychodzi średnio 1,1-1,3 tokena na instrukcję.
Sercem sztuczki jest architektura Qwen3.5. Zamiast klasycznej uwagi większość warstw tego modelu to Gated DeltaNet, mechanizm, który w każdej głowie trzyma macierz stanu o wymiarze 128 na 128 i aktualizuje ją regułą delta. Kompilator z projektu Qwenputer znalazł w tym pamięć: przy otwartej bramce i kluczu one-hot zapis nadpisuje dokładnie jeden wiersz macierzy, a zapytanie one-hot odczytuje go z powrotem. Każdy wiersz staje się komórką pamięci i właśnie w tych wierszach mieszkają rejestry procesora, RAM i zawartość kartridża. Obwód procesora siedzi więc na stałe w wagach, a stan pamięci dolewa się dopiero przy uruchomieniu gry.
Reszta konsoli jest poza modelem, i to nie dlatego, że zabrakło miejsca. Program-gospodarz rysuje obraz skanlinowo, imituje pad i wstrzykuje tokeny przerwania NMI co klatkę oraz odpowiedzi na odczyty sprzętowe. Autor pisze wprost, że host nigdy nie widzi rejestrów ani RAM-u bezpośrednio, tylko przez ślad wykonania; rozdzielenie jest czyste, a granica między wagami a resztą systemu stoi w tabeli na pierwszym ekranie README.
Skąd się to wzięło: Qwenputer i dwa prompty
NESformer nie wyrósł z niczego. W czwartek 22 października Divyansh Agrawal opublikował Qwenputera, czyli procesor RISC-V skompilowany do wag Qwen3.5-4B, wtedy licznik testów stawał na 18 mln instrukcji bez jednego błędu. Breunig wziął z tego projektu kompilator chipformer i główny trik z pamięcią w wierszach macierzy, a cel przesunął z abstrakcyjnego procesora na konkretny chip z konsoli, na której wyrosło całe pokolenie graczy.
W dyskusji na HN opisał, jak do tego doszło, i ta relacja jest może ciekawsza niż sam projekt. „Opus 5.5 zbudowało działające wagi i kod zaledwie dwoma promptami”, pisze Breunig. Pierwszy kazał modelowi przeczytać artykuł o Qwenputerze i oszacować, czy tą techniką da się odtworzyć chip i pamięć NES-a oraz jaki rozmiar modelu trzeba by zbudować; odpowiedź przyszła w postaci wykresów pokazujących, że każdy wariant będzie wolny. Drugi prompt brzmiał, w tłumaczeniu: „Uważam, że powinniśmy to zbudować. Dla zabawy. Nie szkodzi, że nie będzie szybkie” (oryginał: „I think we should build it! Just for fun. It’s okay if it’s not fast.”).
Do tego Breunig dopisał zdanie, które samo w sobie jest lekcją pracy z modelami: to świetny przykład, co takie modele potrafią, gdy dostaną dobre materiały referencyjne, specyfikacje, testy zgodności i jasny kierunek. Społeczność emulatorów od lat utrzymuje zestawy testowe z ponad trzema tysiącami złotych instrukcji 6502, i to Opus samo je znalazło oraz wbudowało w proces budowy.
Skąd pewność, że to działa
Najciekawsza sekcja README nazywa się „How it was checked”. Referencyjny procesor napisany w Pythonie zgadza się ze złotym logiem testu nestest dla 3 348 instrukcji i z emulatorem py65 na 5,7 mln instrukcji wyciągniętych z kodu gier. Dokładny obwód przewiduje każdy token referencji: całe nestest plus 283 610 pozycji z sekwencji startowych dwóch gier. Checkpoint wczytany do standardowej biblioteki transformers zgadza się na 2 651 pozycjach, również bez rozbieżności.
Najmocniejszy test przeszedł model zostawiony samemu sobie. W trybie wolnego biegu, bez podpowiadania prawidłowych tokenów, wagi wygenerowały 1 916 527 tokenów dla gry Thwaite (600 klatek, 10 sekund czasu NES-a) i 2 645 885 tokenów dla Full Game Douga Frakera (420 klatek, 7 sekund), a wszystkie zapisane klatki były identyczne z wyjściem referencyjnego CPU. W dyskusji autor podsumował to tak: „to jest przypadek, w którym w zasadzie przetestowaliśmy wszystko”, bo testy zgodności społeczności emulacyjnej pokrywają formalnie całą paletę instrukcji.
Ile to kosztuje obliczeń
Zabawa ma cenę podaną bez owijania. Silnik domyślny, skompilowany biblioteką numba, liczy ok. 1650 tokenów na sekundę na jednym rdzeniu procesora komputera; goły wariant numpy osiąga 210, a pełny torch ze standardowego transformers około 10. Prawdziwa konsola NES wymaga ok. 700 tys. tokenów na sekundę, więc NESformer biegnie 150-290 razy wolniej od oryginału. Stąd widełki z README: jedna klatka trwa 1-6 sekund, a 600 klatek, czyli dziesięć sekund gry, to około 25 minut oczekiwania. Pomijanie pętli czekających na vblank tnie liczbę tokenów 2,6 do 4,2 razy i niczego nie zmienia na obrazie.
Sama paczka wag jest ciekawostką. Te same wagi, które w tytule HN liczą się na „~1 GB”, to dokładnie 933 MB w bf16, bo model ma 466,6 mln parametrów. Aż 9,3 mln z nich jest niezerowych, reszta to zera wbite przez kompilator, więc skompresowana paczka waży 3,3 MB. „Ma to sympatyczny skutek uboczny: gigabajt wag ściska się do ~3 MB, bo jest prawie cały pusty”, pisze autor.
Są też granice. W wagach działa tylko kartridż w formacie NROM, bo CPU widzi 32 KB pamięci programu naraz, a większe gry przełączają banki pamięci układami mapper, których tu nie ma. Nieoficjalne opcode’y i skoki do RAM kończą się znakiem HALT, przerwań IRQ nie ma, a dźwięku nie generuje ani wagi, ani host. Efekt: Super Mario Bros., Donkey Kong i Excitebike wchodzą, większe tytuły z końca życia konsoli raczej nie.
To nie jest AI grające w Mario
Warto powiedzieć jasno, czym ten projekt nie jest, bo nagłówek HN mógł podsuwać inne skojarzenia. Kilka dni temu opisywaliśmy swarmy agentów GPT w Minecrafta: tam modele czytają stan świata, planują i naciskają klawisze, gra jest poza nimi. W NESformerze jest odwrotnie. Model niczego nie rozumie, niczego nie planuje i niczym nie steruje; wagi są procesorem, obliczoną maszynowo strukturą, którą kompilator przeliczył z bramek logicznych na macierze DeltaNet. Mario idzie w prawo, bo tak złożyły się przewidywania logu wykonania, a nie dlatego, że ktokolwiek chciał wygrać.
Dyskusja na HN rozjechała się dokładnie wzdłuż tej granicy. Najsuchszą ripostą było „nazywa się emulator NES-a” („It’s called a Nintendo emulator”), z dopiskiem, że zwykły kod potrafi być miliardy razy wydajniejszy od AI i ta przepaść rośnie.Nick jacquesm, weteran niskopoziomowego programowania, chwali te hacki i jednocześnie się nimi przeraża, bo pokazują, jak bardzo drożej liczą się programy niedeterministyczne. Inny komentator zwraca uwagę, że to emulacja dokładna, na poziomie obwodu, a nie nauczane przybliżenie; jak człowiek, który zamiast po prostu przypomnieć sobie fakt, liczy w głowie jego skrót.
Byli też sceptycy. Jedni widzieli w tym Neural Turing Machines z 2014 roku w nowym opakowaniu, inni porównywali projekt do Tetrisa złożonego z samych animacji CSS, a ktoś wprost napisał, że README brzmi jak napisane przez model. Breunig nie ukrywa intencji, bo ją ogłosił w drugim prompcie: miało być fajnie.
Co z tego dla Polski
Uruchomienie jest darmowe i bez karty graficznej. Wagi rozdaje repo w paczce nesformer-weights.zip na licencji MIT, wystarczy Python 3.11 i cztery biblioteki, a silnik domyślny liczy na jednym rdzeniu CPU. Interfejs to wyłącznie terminal: --show rysuje klatki znakami w oknie terminala, po zakończeniu zostaje GIF. Dokumentacja jest po angielsku, interfejsu po polsku nie ma, a w odczytach z 31 października nie znalazłem żadnych polskich doniesień o uruchomieniach, co jest pełnoprawną odpowiedzią, a nie wymówką.
Nie widzę tu narzędzia do grania, i chyba o to nie chodzi. Kto chce pograć w Mario, włączy emulator; kto chce zobaczyć, jak warstwy DeltaNet potrafią stać się pamięcią o zadanym układzie, dostaje gotowy, kompletny przykład z planem warstw w README i testami w pakiecie. Na marginesie: własne ROM-y w formacie NROM podpinasz się jednym poleceniem, więc jeżeli ktoś w Polsce odpali w tym Donkey Konga, chętnie o tym przeczytam w komentarzach.
Źródła
- Repozytorium dbreunig/nesformer , README (sekcje How it works, How it was checked, Speed, Limitations), odczyt 31.10.2026
- Wątek Show HN: A working Nintendo in ~1GB of Qwen weights , 245 punktów i 121 komentarzy przy odczycie, 31.10.2026
- Komentarz autora o dwóch promptach Opus 5.5 , 31.10.2026
- Qwenputer: a fully functioning, deterministic RISC-V CPU inside Qwen3.5 , blog Divyansha Agrawala, wpis z 22.10.2026, odczyt 31.10.2026
- Repozytorium divagr18/qwenputer , kompilator chipformer, odczyt 31.10.2026
- Zestaw testów zgodności nes-test-roms , wskazany w komentarzu autora, odczyt 31.10.2026
- Qwenputer: RISC-V i CHIP-8 w wagach Qwen3.5, nasz wpis , 29.10.2026
- Agenci GPT w Minecrafta, nasz wpis , 30.10.2026
