A language model generates text on a Game Boy Color. Another answers questions on a Nintendo 64. The fourth platform's CPU shipped in 1975. None of that is the interesting part.
The interesting part is that we can tell you exactly how many cycles each one takes, and we can tell you which of our own conclusions turned out to be wrong.
| Platform | CPU | Result | Instrument |
|---|---|---|---|
| Game Boy Color | Sharp SM83 @ 4.19 MHz | 10.09× faster, output byte-identical | frame counts, two independent emulators |
| Sega Genesis | Motorola 68000 @ 7.67 MHz | 1.674×, 1.32 → 2.21 tok/s | exact 68000 bus cycles |
| Nintendo 64 | MIPS R4300i + RSP | 1.78× on the vector unit, 1.22 → 2.16 tok/s | vblank counts, cross-checked against CP0 |
| Super Nintendo | Ricoh 5A22 (65816) @ 3.58 MHz | primitives measured; ternary 2.02× over int8 | exact 65816 cycles |
| NES / Famicom | Ricoh 2A03 (6502) @ 1.79 MHz | 0.624 s/token, 1,216/1,216 tokens exact, generates English | exact 6502 cycles |
Every number comes from a real ROM running under an accurate emulator. Where a figure is an extrapolation rather than a measurement, we say so.
Ternary weights (−1, 0, +1) measured 41% faster than int8 on the Nintendo 64's MIPS core, and 12% slower on the same console's RSP vector unit.
Both figures are sparsity-matched. Our shipped ternary model is 32% zeros and our ternary kernel skips them where the int8 kernel does not — the raw kernel-pair comparison reads 57%. Remove the zero skip from the ternary kernel and re-measure the same weights on the same ROM and it is 41%; add a zero skip to the int8 kernel instead and it is 49%. The missing multiply is worth 71% of the gap, the skipped zeros the other 29%. The RSP figure needs no such correction: a vector lane cannot skip a zero.
That is not a contradiction, and we tested both candidate explanations rather than picking one. The density advantage was real: ternary moved 3.74× fewer weight bytes. The unit was not bandwidth-bound either, running at roughly a fifth of RDRAM throughput. The cost was unpacking — 0.656 issue slots per weight against int8's 0.375.
The win was never that ternary is smaller. It was that ternary deletes a multiply.
On a vector unit whose vmadh performs eight 16×16 multiply-accumulates in a single instruction, there is no multiply to delete, so you pay only the unpack. On the 6502 the same question resolved a third way: a 4-bit weight with a lookup table is quick to read, but building the table index requires the accumulator, and the 6502 has no way to build it elsewhere. In the weight matmul, where both operands vary per element, the 4-bit design has to spill the accumulator to memory: measured at +6 cycles per element, 20 against 14. Ternary keeps the accumulator in A, and it does not store its zeros at all — at our model's density it costs 5.0 cycles per weight against the 4-bit design's 16.5 with a matched zero test, a 3.3× gap that survives matching the sparsity.
We had been calling that three different constraints — instruction set on the MIPS core, issue slots on the RSP, register pressure on the 6502. Then we measured a fourth machine and found we had been wrong about all of them.
The Super Nintendo has a signed hardware multiply in its picture processor: 16×8 into 24 bits, available with no wait states. On a console whose CPU runs at 3.58 MHz that should be decisive, and we predicted int8 would finally beat ternary there.
It does not. Measured before any engine was written, in exact cycles:
| Primitive | Cycles per multiply-accumulate | vs ternary |
|---|---|---|
| software 8×8 shift-add | 1503.9 | 13.8× |
| square-table lookup | 570.9 | 5.2× |
| CPU multiply register | 317.3 | 2.9× |
| PPU signed multiply, tuned | 220.5 | 2.0× |
| ternary gather | 109.2 | 1.00× |
Ternary is 2.02× cheaper, and the multiply is not why. The PPU multiply is genuinely free — every one of the 214 cycles in that arm is data movement.
Ternary touches three memory locations per accumulate. Int8 touches six.
That is the whole mechanism, and it replaces our three explanations with one. Ternary's advantage is not that it deletes a multiply. It is that it halves the number of operands the machine has to fetch — and it therefore lasts exactly as long as the machine charges per operand:
| Unit | Ternary advantage |
|---|---|
| SNES 65816, slow ROM | 2.02× |
| SNES 65816, fast ROM | 2.07× |
| SNES SuperFX coprocessor | 1.27× |
| N64 RSP vector unit | inverts — int8 wins |
It decays monotonically as machines get better at moving data, and it flips on the one unit that fetches eight operands in a single transaction. The RSP was never an exception to a rule about multipliers; it was the end of a gradient about memory.
This also makes a prediction we can be wrong about later: on any new target, ternary's margin should track memory transactions per accumulate, and should not care how good the multiplier is.
Post-training ternarization with round-to-nearest destroys our N64 model. The corpus is byte-level, so ln(256) = 5.545, and round-to-nearest with a BitNet-absmean quantizer lands above that in every seed we ran — worse than uniform random over bytes. But round-to-nearest is not the state of the art. Running GPTQ instead, on the same checkpoint and emitting the same 2,031,628-byte ternary blob, post-training quantization comes back to 0.3 to 1.4 depending on the seed. Training with the quantizer in the loop still wins — both arms sit at 0.101 ± 0.001 against a full-precision control at the same place — but by roughly 3–14×, not by 66×. Post-training quantization of this model is also far higher-variance: our QAT and full-precision arms move by 0.001 nats across seeds, our PTQ arms by one to two.
We checked whether quantization-aware training works by finding weights that happen to quantize well. It does not. The trained latent weights are 11.6% larger in mean magnitude than the float control's (0.0827 against 0.0741, across three seeds) — but that is the one statistic a mean-magnitude threshold cannot see: scale every weight by any constant and the ternary codes come out identical. The statistic that decides which weights survive barely moves: 42.7% zeros against 42.9%. The rest of the network absorbs the error during training instead.
The practical consequence is direct: quantization-aware training let a 2.80× larger model fit the same console memory at no measured difference in training loss, where the int8 version of that shape overruns it by 2.4×.
Every genuine gain here appeared only after a measurement tool existed — and every first tool was wrong in a way that silently reversed a conclusion.
tokens × 60 / loop-iterations while the loop generated exactly one token per iteration. The expression reduces to the constant 60. It reported 60.00 tok/s on two builds whose real speeds differ by 1.8×, and that number reached a repo README, a video description, this article and a company homepage before anyone tried to reproduce it. The honest figure is 1.22.Reproducibility is not validity. A tool can be perfectly repeatable and still measure the wrong thing.
That last one is the variety worth fearing. A false positive gets caught, because someone eventually looks for the win and cannot find it. A false null is never investigated — it does not look like a bug, it looks like an idea that did not pan out. We had already declined this optimization once on a risk judgement. The second refusal would have been backed by a number, and the number would have been real, and it would have been measuring the wrong ROM.
The Ricoh 2A03 shipped in 1975. Backpropagation was published in 1986. Cartridge bank switching, battery-backed memory, and every other primitive our NES port depends on were shipping consumer technology by 1985.
Our 6.36-million-parameter model represents on the order of 1015 training operations. A Cray-1 sustained roughly 160 MFLOPS in 1976, putting that at three to four months of machine time — expensive, and the kind of allocation researchers actually received.
The transformer architecture was published in 2017.
So the constraint was never the silicon. Small-scale neural inference was physically available for decades while the field pursued symbolic approaches: expert systems, LISP machines, hand-built ontologies. The hardware sat there the entire time.
Nobody could have built GPT-2 on a home console in 1985. 1.5 billion parameters fits in no cartridge, and the emergent behaviour that word now carries lives at scales that era could not train.
What we can now support with cycle counts rather than speculation is narrower: a small transformer speaking coherent English on 1980s consumer hardware was physically possible, and the barrier was an idea rather than a machine.
Full analysis: this section has its own page — Could a Cray Have Run GPT-2? When LLMs Became Buildable.
Consumer hardware is one budget; a national laboratory is another, and the distinction lands somewhere surprising.
A Cray-2 (1985) could be configured with up to 4 GB of memory. Fifteen hundred million 8-bit weights occupy about 1.5 GB, so they fit. Inference costs roughly two operations per parameter per token, which at that machine's ~1.9 GFLOPS works out to a second or two per token. A GPT-2-sized model could plausibly have been run — not trained — on mid-1980s supercomputing hardware.
Training is where it stops. GPT-2's training run is on the order of 1021 operations. At 1.9 GFLOPS that is roughly seventeen thousand years.
So the era could have executed a large model and could not have produced one — which makes the same point from the other end. The missing ingredient was never the machine. It was the architecture, and the compute to fill it.
Full analysis: this section has its own page — Could a Cray Have Run GPT-2? When LLMs Became Buildable.
"Impossible" and "expensive" are different claims, and the boundary between them has a date. Below is the fastest computer on Earth in each year, against a single GPT-2 training run. The range reflects two credible estimates of that run's cost; the exact token count is debated.
| Year | Fastest machine | Sustained | Years to train GPT-2 |
|---|---|---|---|
| 1985 | Cray-2 | 1.9 GF | 1,501 – 25,017 |
| 1993 | Fujitsu Numerical Wind Tunnel | 124 GF | 23 – 383 |
| 1994 | Intel Paragon XP/S 140 | 143 GF | 20 – 332 |
| 1996 | Hitachi CP-PACS | 368 GF | 7.7 – 129 |
| 1997 | ASCI Red | 1,068 GF | 2.7 – 45 |
| 1999 | ASCI Red (upgraded) | 2,380 GF | 1.2 – 20 |
Roughly 27 Cray-2 systems were ever manufactured. All of them, running flat out for a year, complete somewhere between 1.8% and 0.1% of one training run. The 1980s could not have done this for any amount of money — the hardware did not exist in sufficient quantity on Earth.
By 1993 that collapses from twenty-five thousand machine-years to about twenty. By 1999 a single existing machine does it in a year.
What follows is speculative engineering. Every component shipped, every figure is arithmetic on published specifications, and the machine itself never existed. We are labelling that boundary rather than blurring it.
Nobody had to wait for a single fast computer. The render farm was already the state of the art: Beowulf clustering of commodity hardware was published in 1994, and television 3D animation was being produced on banks of Amigas by 1992. Shard the work instead.
| Node | Per CPU | CPUs for a 2-year run | Blades @ 32/blade |
|---|---|---|---|
| Pentium Pro 200 (1995) | 50 MF | 28,519 | 891 |
| PowerPC 604e 233 (1996) | 100 MF | 14,260 | 446 |
That design already existed. ASCI Red, delivered to Sandia in 1997, was 9,298 Pentium Pro 200 processors on a custom mesh. A GPT-2 run on it works out to 2.7 years.
The catch is not arithmetic, it is the network. Data-parallel training must all-reduce the entire gradient every step — 1.5 billion parameters at 32-bit is 6 GB. Over 10 Mbit links that is 9,600 seconds per step, and blades do not help: they reduce the number of slow links, not the bytes each one carries. A hundred thousand steps is thirty years of pure communication.
The lever is gradient accumulation, which is neither modern nor subtle — take fewer, larger steps.
| Accumulation | Steps | Time spent communicating |
|---|---|---|
| K = 1 | 100,000 | 30.4 years |
| K = 100 | 1,000 | 0.30 years |
| K = 1000 | 100 | 0.03 years |
At K = 100 the network cost falls to about four months, comfortably inside a two-year compute budget on 10 Mbit links.
Roughly 900 blades of 32 commodity CPUs, a 10 Mbit interconnect, gradient accumulation, and about two years. Every component shipped by 1996.
It was expensive rather than impossible — a national-laboratory budget, not a miracle. Nobody built it, because the architecture it would have trained was not published until 2017.
Elyan Labs runs a blockchain that rewards vintage hardware for participating. Older silicon earns a higher multiplier, verified by hardware fingerprinting that emulators cannot fake. The premise is that old machines have worth beyond nostalgia.
This work is the other half of that argument. Not "old hardware deserves credit for existing", but "old hardware can do the thing everyone assumes requires a datacenter". A Game Boy Color generating a sentence is a stronger claim about antiquity than any multiplier we could assign it.
We had two frontier models adversarially review these conclusions. They removed several, and the ones that survived are stated at the strength the evidence supports.
tokens × 60 / loop-iterations, and the loop generated exactly one token per iteration, so it reduced to the literal constant 60 — it printed 60.00 on two builds whose real speeds differ by 1.8×. Re-measured against vertical blanks, the honest figures are 1.22 tok/s scalar and 2.16 with the vector unit. The RSP vector build has never been on silicon, and its speedup is 1.78×, not the 4.769× we published earlier — that figure was a cycle ratio on a weight format the cartridge does not ship. The Game Boy Color and NES ports are emulator-only. Two independent emulators agreeing is not silicon: our Game Boy assembly disables interrupts while the stack pointer walks an activation array, and a real console with a live display controller is less forgiving.All four ports, the measurement harnesses and the findings journals are public.
Scottcjn/gbc-transformer — Game Boy Color, 10.09×Scottcjn/legend-of-elya-genesis — Sega Genesis, exact 68000 cyclesScottcjn/legend-of-elya-n64 — Nintendo 64, RSP vector matmulScottcjn/elya-nes — NES / Famicom, 0.689 s/token, token-exactThe harnesses matter more than the ports. If you take one thing from this, take the habit: build the instrument, calibrate it against something you can derive by hand, and check it against a second implementation before trusting any number it gives you.