|
| 1 | +# Atome LM — Frontier Findings |
| 2 | + |
| 3 | +> **Update 2026-05-11 — scale-up A/B at 944K reverses the headline.** |
| 4 | +> Same recipe, same val slice, same fairness audit, a 944K-param vanilla |
| 5 | +> GPT-FP32 baseline (950,608 params, +0.63 % vs Atome's 944,640) reaches |
| 6 | +> val loss 0.9337 / ppl 2.54, beating Atome ternary at 944K by 11.4 % |
| 7 | +> in loss and 11.5 % in perplexity. The +22 % param-fair / +52 % |
| 8 | +> flash-fair gains below hold at the **60K-param MCU regime** and only |
| 9 | +> that regime. Above ~1M params the inductive bias of the 3-pathway |
| 10 | +> block stops substituting for capacity and starts constraining it. |
| 11 | +> The honest framing is: *Atome's bet is the small-model regime — |
| 12 | +> sub-1M params, MCU-class deployment, no network.* See |
| 13 | +> [`HONEST_RESULTS.md`](HONEST_RESULTS.md) for the full 944K reading. |
| 14 | +> Multi-seed pending. |
| 15 | +
|
| 16 | +**Date.** 2026-05-09. CPU only, no GPU. |
| 17 | +**Hardware.** 4-thread CPU box. PyTorch 2.x, FP32 reference path. |
| 18 | +**Corpus.** TinyStories validation slice, 500 KB UTF-8 (~99.9 % ASCII). |
| 19 | +Train/eval split 90/10 over 64-byte chunks → 7,030 train chunks / |
| 20 | +782 held-out chunks. |
| 21 | +**Optimizer.** AdamW, lr 3e-4, batch 16, seq 64, 3,000 steps. |
| 22 | +**Single seed** (seed 0). Results have not been replicated across seeds. |
| 23 | + |
| 24 | +This document reports the first apples-to-apples A/B between Atome's |
| 25 | +3-pathway ternary architecture and vanilla decoder-only Transformers |
| 26 | +(FP32) at fixed parameter count and at fixed flash budget. The closest |
| 27 | +published peer is Andrej Karpathy's `Stories260K` — a 260 K-parameter |
| 28 | +FP32 plain transformer trained on TinyStories. Atome's frontier claim |
| 29 | +is "smaller flash, better quality, smaller bits-per-weight, *and* |
| 30 | +deployable on a $2 microcontroller." This page tests the first three |
| 31 | +of those claims directly; MCU deployment is verified separately via |
| 32 | +bit-exact Python ↔ C ↔ Cortex-M3 (QEMU) parity (see `tests/test_qemu_parity.py`). |
| 33 | + |
| 34 | +## TL;DR |
| 35 | + |
| 36 | +| Model | Params | Bits/wt | Disk | bpb ↓ | Perplexity ↓ | |
| 37 | +|---|---:|---:|---:|---:|---:| |
| 38 | +| **Atome 3-pathway, ternary** | **60,800** | **1.58** | **15.1 KB**¹ / **17.2 KB**² | **2.66** | **6.31** | |
| 39 | +| Vanilla GPT, FP32 (param-fair) | 60,808 | 32 | 237.5 KB | 3.02 | 8.12 | |
| 40 | +| Vanilla GPT, FP32 (flash-fair) | 5,968 | 32 | 23.3 KB | 3.71 | 13.10 | |
| 41 | + |
| 42 | +¹ ATOME01, 4 trits/byte (current C engine reads this). |
| 43 | +² ATOME02, 5 trits/byte base-3 packing — 14.4 % smaller, near |
| 44 | +information-theoretic floor of `log2(3) ≈ 1.585` bits/trit. Python |
| 45 | +encoder + decoder shipped today; C decoder is a future change. |
| 46 | + |
| 47 | +## What this proves |
| 48 | + |
| 49 | +1. **At the same parameter count, the 3-pathway ternary architecture |
| 50 | + beats a plain transformer by 22 % on perplexity (6.31 vs 8.12) |
| 51 | + while using 16× less disk.** |
| 52 | + |
| 53 | + The vanilla baseline is *not* over-parameterized — it's matched at |
| 54 | + 60.8 K params (`d_model=44, n_layers=3, n_heads=4, d_ff=44`, |
| 55 | + selected by brute-force search to land within 8 params of the |
| 56 | + target). This is the same architecture every public tiny-LM paper |
| 57 | + (`Stories260K`, the TinyStories paper, BitNet at small scale) uses, |
| 58 | + modulo trivia. |
| 59 | + |
| 60 | +2. **At the same flash budget, the 3-pathway ternary architecture beats |
| 61 | + a plain transformer by 52 % on perplexity (6.31 vs 13.10).** |
| 62 | + |
| 63 | + The flash-fair vanilla baseline is `d_model=8, n_layers=2, |
| 64 | + n_heads=4, d_ff=24`. It sits in the same 20–25 KB on-disk budget as |
| 65 | + the Atome ATOME01 binary (15.1 KB) and ATOME02 binary (17.2 KB). |
| 66 | + |
| 67 | +3. **The 1.58-bit weights cost ~22 % perplexity vs FP32 at the same |
| 68 | + architecture parameters** — but the FP32 version costs 16× more |
| 69 | + flash. On any device where flash is the bottleneck (every MCU we |
| 70 | + target), ternary wins. On any device where compute is the |
| 71 | + bottleneck and flash is free (server CPUs), FP32 wins on quality. |
| 72 | + |
| 73 | +4. **ATOME02 base-3 packing reaches 1.6 bits/trit — within 1 % of the |
| 74 | + information-theoretic floor of 1.585 bits/trit** — and reduces the |
| 75 | + on-disk binary from 20.1 KB to 17.2 KB on the same trained |
| 76 | + 60.8 K-param model. C decoder still pending. |
| 77 | + |
| 78 | +## What this does NOT prove |
| 79 | + |
| 80 | +- **Single seed only.** All three numbers are seed 0. We have not run |
| 81 | + multi-seed yet to estimate variance. The 22 % / 52 % gaps are very |
| 82 | + large compared to typical seed-noise at this scale, but the variance |
| 83 | + is unmeasured. |
| 84 | +- **Single corpus.** TinyStories is a forgiving target — short stories |
| 85 | + with restricted vocabulary. Wider-domain or code corpora may favor |
| 86 | + vanilla attention. We have not measured. |
| 87 | +- **Single training horizon.** 3,000 steps is well short of |
| 88 | + convergence. The relative ranking might swap or amplify with more |
| 89 | + training. A 10 K-step run is in flight; we'll update this page if it |
| 90 | + changes the headline. |
| 91 | +- **No real silicon.** All MCU claims are verified on QEMU |
| 92 | + Cortex-M3, not on physical RP2040 / STM32 hardware. Tokens/sec and |
| 93 | + Joules/token on real silicon are still pending. |
| 94 | +- **Stories260K direct comparison still pending.** Karpathy's exact |
| 95 | + setup is `Stories260K` at 260 K params + a 32 K-token SentencePiece |
| 96 | + vocab. Our byte-tokenizer + 60 K config is ~4× smaller. A direct |
| 97 | + apples-to-apples vs `Stories260K` would need either (a) us to scale |
| 98 | + up to 260 K params and a SentencePiece tokenizer, or (b) Karpathy's |
| 99 | + setup retrained at 60 K params with a byte tokenizer. Neither is |
| 100 | + done. |
| 101 | + |
| 102 | +## Comparison with the published frontier |
| 103 | + |
| 104 | +| System | Smallest target | Params | Bits/wt | Real MCU? | Architecture beats vanilla? | |
| 105 | +|---|---|---:|---:|---|---| |
| 106 | +| Microsoft BitNet b1.58 | server CPU | 700 M – 3 B | 1.58 | no | (matches at scale) | |
| 107 | +| Meta MobileLLM | smartphone | 125 M – 1 B | 4–8 | no | yes (vs same-size vanilla) | |
| 108 | +| Karpathy `Stories260K` | laptop / browser | 260 K | 32 | no firmware | n/a (is the vanilla baseline) | |
| 109 | +| llama.cpp on RP2040 (hobby) | RP2040 + SD | ~1 B (swapped) | 4 | yes (slow, requires SD) | not measured | |
| 110 | +| TFLite Micro / Edge Impulse | Cortex-M0+ | – | 8 | yes | no language tasks | |
| 111 | +| **Atome LM (this work)** | **Cortex-M0+, 16 KB SRAM** | **60 K** | **1.58** | **QEMU yes, silicon pending** | **+22 % at param-fair, +52 % at flash-fair** | |
| 112 | + |
| 113 | +Smaller, more bit-efficient, *and* architecturally beats vanilla at |
| 114 | +the budgets we target. To our knowledge, the smallest published LM |
| 115 | +where the routed-architecture win has been measured directly against |
| 116 | +a vanilla baseline at the same flash budget. |
| 117 | + |
| 118 | +## Reproduce |
| 119 | + |
| 120 | +```bash |
| 121 | +# from the repository root |
| 122 | +PYTHONPATH=. python3 scripts/build_corpus.py --source tinystories \ |
| 123 | + --max-bytes 500000 --output data/tinystories.txt |
| 124 | + |
| 125 | +PYTHONPATH=. python3 scripts/run_ab_sweep.py \ |
| 126 | + --train data/tinystories.txt --steps 3000 \ |
| 127 | + --output ab_results.json |
| 128 | +``` |
| 129 | + |
| 130 | +`ab_results.json` will contain the same numbers as in the table above |
| 131 | +(modulo platform-dependent rounding in PyTorch's matmul kernels). |
| 132 | + |
| 133 | +## Open questions / next pushes |
| 134 | + |
| 135 | +- **A1.** Multi-seed (3 seeds × 3 configs) to estimate variance on the |
| 136 | + 22 % / 52 % gaps. |
| 137 | +- **A2.** Train all three to ≥ 10 K steps. Does the gap close, hold, |
| 138 | + or widen? |
| 139 | +- **A3.** Ablate: which of the three pathways (local conv, diagonal |
| 140 | + SSM, top-k sparse attention) carries most of the architecture win? |
| 141 | + Drop each, measure. |
| 142 | +- **A4.** Ship a C decoder for ATOME02. Cuts the demo binary from |
| 143 | + 20.1 KB to 17.2 KB without code changes elsewhere. |
| 144 | +- **A5.** Real silicon. Flash an RP2040 with the engine + this 60.8 K |
| 145 | + ckpt. Measure tokens/sec, Joules/token. **The headline number that |
| 146 | + turns the claim from "frontier" into a fact.** |
| 147 | +- **A6.** Distillation from a strong teacher LLM (10 MB of curated |
| 148 | + narrow-domain text generated by a frontier model) into the same 60 K Atome. |
| 149 | + Open question: does the architecture advantage compound under |
| 150 | + distillation? |
| 151 | +- **A7.** Bug A fix (Python `generate` ↔ C `atome_generate` |
| 152 | + short-prompt SSM divergence). Touches the bit-exact-parity |
| 153 | + contract — needs explicit user sign-off. |
| 154 | + |
| 155 | +## Files of record |
| 156 | + |
| 157 | +- `ab_results.json` — exact numbers and config of the run reported here. |
| 158 | +- Trained A/B checkpoints (`atome_60k_ternary`, `vanilla_60k_fp32`, |
| 159 | + `vanilla_6k_fp32`) are *not* shipped — regenerate them with the harness |
| 160 | + below (this kit is train-from-scratch). |
| 161 | +- `atome_llm/baselines/vanilla_transformer.py` — the baseline. |
| 162 | +- `scripts/run_ab_sweep.py` — the harness. |
| 163 | +- `tests/test_vanilla_baseline.py` — 10 sanity tests on the baseline. |
| 164 | +- `tests/test_export_packed.py` — 5 tests on ATOME02 round-trip. |
| 165 | +- `tests/test_trit_packing.py` — 11 tests on the base-3 packer. |
0 commit comments