Dev.to AI πŸ€– Ai πŸ‘ 0 πŸ“– 4 min read

A working Nintendo lives in 1GB of Qwen weights. I ran it and counted the nonzero ones.

A working Nintendo lives in 1GB of Qwen weights. I ran it and counted the nonzero ones. Today's Show HN is the kind of project that sounds like a joke until you read the mechanism: an NES CPU compiled into the weights

A working Nintendo lives in 1GB of Qwen weights. I ran it and counted the nonzero ones.

Today's Show HN is the kind of project that sounds like a joke until you read the mechanism: an NES CPU compiled into the weights of a stock Qwen3.5 model. No training. A compiler computed every weight. The model's Gated DeltaNet state is the machine's memory β€” each attention head keeps a 128x128 state matrix, and with the gate held open and a one-hot key, one update overwrites exactly one row. Rows are memory cells. The cartridge, the RAM, and the registers all live in rows.

The repo, dbreunig/nesformer, was created today (2026-10-30, one commit, 137 stars when I fetched it). The headline number is "~1GB of Qwen weights." I downloaded the weights and counted, because "1GB" is doing a lot of work in that sentence.

What I actually downloaded

The repo ships a 3,344,154-byte zip. Unzipped, it is a 933,307,736-byte model.safetensors. That is the first joke the project plays on you: the file compresses 279x, because almost all of it is zeros.

I parsed the safetensors header directly β€” 111 tensors, no torch needed β€” and counted nonzero bf16 values:

import json, struct, numpy as np
path = "weights/model.safetensors"
with open(path, "rb") as f:
    n = struct.unpack("<Q", f.read(8))[0]
    header = json.loads(f.read(n))
    header.pop("__metadata__", None)
    total = nonzero = 0
    for name, info in header.items():
        count = 1
        for d in info["shape"]:
            count *= d
        total += count
        arr = np.memmap(path, dtype=np.uint16, mode="r",
                        offset=8 + n + info["data_offsets"][0], shape=(count,))
        nonzero += int(np.count_nonzero(arr))
tensors:        111
total params:   466,647,616
nonzero params: 9,340,331
nonzero pct:    2.002%
bf16 bytes:     933,295,232  (933.3 MB)
zip bytes:      3,344,154    (3.3 MB, 279x compression)
sha256sum:      weights/model.safetensors: OK

So the README's numbers check out exactly: 466.6M parameters, 9.3M nonzero, 933 MB on disk. But "1GB of weights" is really "9.3 million numbers doing the work, and 457 million zeros holding the shape." A stock Qwen3.5-4B-shaped checkpoint β€” hidden size 768, 7 Gated DeltaNet layers plus one all-zero attention layer that only exists because Hugging Face's cache code wants it β€” with 98% of its weights zeroed. The checkpoint loads in stock transformers with no custom code, which is the whole point: the CPU is smuggled inside a model file that any inference stack will happily serve.

Then I ran it

The repo's check command runs the weights and a reference 6502 side by side and stops at the first difference. I ran it on the bundled nestest ROM with the plain numpy engine (no numba on this box):

$ python3 -m nesformer check roms/nestest.nes --engine numpy --tokens 2000
OK: the weights generated 2,000 tokens identical to the reference CPU's trace
(0 frames, frames identical: True; 193 tok/s)

2,000 tokens, zero mismatches, 193 tokens per second. The README claims about 210 tok/s for the numpy engine, so my box lands in the same neighborhood β€” the claim is not inflated. A 40-token trace shows what the machine actually does first:

GO P(000100 px0 L1) P(000100 px0 L1) X($FF c0 v0 px0 L2) S($FF L1)
IOR($2002) IN($00) A($00 c0 v0 px0 L3) J($C009)
IOR($2002) IN($00) A($00 c0 v0 px0 L3) J($C009) ...

That repeating IOR($2002) is the boot code polling PPUSTATUS, waiting for vblank. The weights are not approximating a CPU. They are executing the same wait loop your emulator executes, one token at a time, because each token is one instruction's commit record.

The honest ledger

Here is where I pump the brakes, because the Show HN title says "a working Nintendo" and the README is careful about what that means:

  • The CPU is in the weights. The console is not. The PPU (a scanline renderer), the controllers, and the vblank timing all live in a host program. The host injects IN tokens for I/O reads and NMI tokens at vblank. The model never sees a pixel.
  • NROM cartridges only (iNES mapper 0). Super Mario Bros., Donkey Kong, Excitebike β€” yes. Anything with a mapper chip β€” no.
  • Speed is the real punchline. A real NES needs about 700,000 tokens per second. My numpy run did 193. The README's numba engine claims 1,650 tok/s, and with the idle-loop skip (the host fast-forwards vblank wait loops, cutting tokens 2.6x to 4.2x) the project lands at 150–290x slower than the console. Ten seconds of NES time takes around 25 minutes of wall clock for 600 frames.
  • The verification is genuinely thorough, though. The reference CPU matches nestest's golden log for 3,348 instructions and the py65 emulator on 5.7 million instructions of game code; the exact circuit predicts all of nestest plus 283,610 positions of two games' boot sequences; free-running, the weights reproduce 1,916,527 tokens of Thwaite with all 300 saved frames matching.

Why this is more than a stunt

The lineage matters. This builds on Qwenputer, which compiled a CHIP-8 and then a RISC-V CPU into Qwen3.5-4B the same way. The NES is a bigger machine β€” all 151 official 6502 opcodes, every addressing mode, flags, stack, BRK and NMI entry, 2 KB of work RAM, 32 KB of PRG-ROM stored twice (one copy for instruction fetch, one for data reads) β€” and it still fits in 9.3 million nonzero weights.

The uncomfortable implication is the one the author doesn't need to spell out: if a compiler can put a deterministic machine inside a model checkpoint, then "the weights are just numbers" was never a safety boundary. A checkpoint that loads in stock transformers can contain a CPU, a memory, and a program β€” and 98% of it can be zeros and still run. The 1GB is not the payload. The 9.3 million nonzero values are.

Sources: dbreunig/nesformer (GitHub, created 2026-10-30); README "How it was checked" and "Speed" sections; my own measurements above (safetensors parse, check and trace runs, 2026-10-30).

πŸ“° Read the original article on Dev.to AI

Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes β€” full credit and traffic to the original publisher.