|
| 1 | +[English](FRONTIER.md) · [Français](FRONTIER.fr.md) · **Español** <!-- i18n-switcher --> |
| 2 | + |
| 3 | +# Atome LM — Hallazgos de frontera |
| 4 | + |
| 5 | +> **Actualización 2026-05-11 — el A/B de escalado en 944K invierte el titular.** |
| 6 | +> Misma receta, misma porción de validación, misma auditoría de equidad, una referencia |
| 7 | +> GPT-FP32 vanilla de 944K params (950.608 params, +0,63 % vs los 944.640 de Atome) alcanza |
| 8 | +> pérdida de validación 0,9337 / ppl 2,54, ganando al Atome ternario en 944K por un 11,4 % |
| 9 | +> en pérdida y un 11,5 % en perplejidad. Las ganancias +22 % params-justo / +52 % |
| 10 | +> flash-justo de más abajo se sostienen en el **régimen MCU de 60K params** y solo |
| 11 | +> en ese régimen. Por encima de ~1M params, el sesgo inductivo del bloque |
| 12 | +> de 3 vías deja de sustituir a la capacidad y empieza a restringirla. |
| 13 | +> El encuadre honesto es: *la apuesta de Atome es el régimen de modelo-pequeño — |
| 14 | +> sub-1M params, despliegue de clase MCU, sin red.* Véase |
| 15 | +> [`HONEST_RESULTS.md`](HONEST_RESULTS.es.md) para la lectura completa del 944K. |
| 16 | +> Multisemilla pendiente. |
| 17 | +
|
| 18 | +**Fecha.** 2026-05-09. Solo CPU, sin GPU. |
| 19 | +**Hardware.** Máquina CPU de 4 hilos. PyTorch 2.x, ruta de referencia FP32. |
| 20 | +**Corpus.** Porción de validación de TinyStories, 500 KB UTF-8 (~99,9 % ASCII). |
| 21 | +División entrenamiento/eval 90/10 sobre fragmentos de 64 bytes → 7.030 fragmentos de entrenamiento / |
| 22 | +782 fragmentos apartados (held-out). |
| 23 | +**Optimizador.** AdamW, lr 3e-4, batch 16, seq 64, 3.000 pasos. |
| 24 | +**Semilla única** (semilla 0). Los resultados no se han replicado en varias semillas. |
| 25 | + |
| 26 | +Este documento informa el primer A/B manzanas-con-manzanas entre la arquitectura |
| 27 | +ternaria de 3 vías de Atome y los Transformers decodificador-solo vanilla |
| 28 | +(FP32) a igual número de parámetros y a igual presupuesto de flash. El par |
| 29 | +publicado más cercano es el `Stories260K` de Andrej Karpathy — un transformer |
| 30 | +simple FP32 de 260 K parámetros entrenado sobre TinyStories. La afirmación de frontera |
| 31 | +de Atome es «menos flash, mejor calidad, menos bits por peso, *y* |
| 32 | +desplegable en un microcontrolador de 2 $». Esta página prueba las tres primeras |
| 33 | +de esas afirmaciones directamente; el despliegue MCU se verifica por separado vía |
| 34 | +paridad exacta al bit Python ↔ C ↔ Cortex-M3 (QEMU) (véase `tests/test_qemu_parity.py`). |
| 35 | + |
| 36 | +## En resumen (TL;DR) |
| 37 | + |
| 38 | +| Modelo | Params | Bits/peso | Disco | bpb ↓ | Perplejidad ↓ | |
| 39 | +|---|---:|---:|---:|---:|---:| |
| 40 | +| **Atome 3 vías, ternario** | **60,800** | **1.58** | **15.1 KB**¹ / **17.2 KB**² | **2.66** | **6.31** | |
| 41 | +| GPT vanilla, FP32 (params justo) | 60,808 | 32 | 237.5 KB | 3.02 | 8.12 | |
| 42 | +| GPT vanilla, FP32 (flash justo) | 5,968 | 32 | 23.3 KB | 3.71 | 13.10 | |
| 43 | + |
| 44 | +¹ ATOME01, 4 trits/byte (el motor C actual lee este formato). |
| 45 | +² ATOME02, empaquetado base 3 a 5 trits/byte — 14,4 % más pequeño, cerca del |
| 46 | +piso teórico de la información de `log2(3) ≈ 1,585` bits/trit. Codificador + |
| 47 | +decodificador Python enviados hoy; el decodificador C es un cambio futuro. |
| 48 | + |
| 49 | +## Qué demuestra esto |
| 50 | + |
| 51 | +1. **A igual número de parámetros, la arquitectura ternaria de 3 vías |
| 52 | + gana a un transformer simple por un 22 % en perplejidad (6,31 vs 8,12) |
| 53 | + usando 16× menos disco.** |
| 54 | + |
| 55 | + La referencia vanilla *no* está sobreparametrizada — está emparejada a |
| 56 | + 60,8 K params (`d_model=44, n_layers=3, n_heads=4, d_ff=44`, |
| 57 | + seleccionados por búsqueda exhaustiva para caer a menos de 8 params del |
| 58 | + objetivo). Es la misma arquitectura que usa todo artículo público de LM minúsculo |
| 59 | + (`Stories260K`, el artículo de TinyStories, BitNet a pequeña escala), |
| 60 | + salvo trivialidades. |
| 61 | + |
| 62 | +2. **A igual presupuesto de flash, la arquitectura ternaria de 3 vías gana |
| 63 | + a un transformer simple por un 52 % en perplejidad (6,31 vs 13,10).** |
| 64 | + |
| 65 | + La referencia vanilla flash-justa es `d_model=8, n_layers=2, |
| 66 | + n_heads=4, d_ff=24`. Ocupa el mismo presupuesto de 20-25 KB en disco que |
| 67 | + el binario Atome ATOME01 (15,1 KB) y ATOME02 (17,2 KB). |
| 68 | + |
| 69 | +3. **Los pesos de 1,58 bit cuestan ~22 % de perplejidad vs FP32 a los mismos |
| 70 | + parámetros de arquitectura** — pero la versión FP32 cuesta 16× más |
| 71 | + flash. En cualquier dispositivo donde el flash sea el cuello de botella (cada MCU que |
| 72 | + apuntamos), el ternario gana. En cualquier dispositivo donde el cómputo sea el |
| 73 | + cuello de botella y el flash sea gratis (CPU de servidor), FP32 gana en calidad. |
| 74 | + |
| 75 | +4. **El empaquetado base 3 ATOME02 alcanza 1,6 bit/trit — a menos del 1 % del |
| 76 | + piso teórico de la información de 1,585 bit/trit** — y reduce el |
| 77 | + binario en disco de 20,1 KB a 17,2 KB en el mismo modelo entrenado de |
| 78 | + 60,8 K params. Decodificador C aún pendiente. |
| 79 | + |
| 80 | +## Qué NO demuestra esto |
| 81 | + |
| 82 | +- **Solo semilla única.** Los tres números son de la semilla 0. No hemos ejecutado |
| 83 | + multisemilla para estimar la varianza. Las brechas del 22 % / 52 % son muy |
| 84 | + grandes comparadas con el ruido de semilla típico a esta escala, pero la varianza |
| 85 | + no está medida. |
| 86 | +- **Corpus único.** TinyStories es un objetivo indulgente — historias cortas |
| 87 | + con vocabulario restringido. Corpus de dominio más amplio o de código podrían favorecer |
| 88 | + la atención vanilla. No lo hemos medido. |
| 89 | +- **Horizonte de entrenamiento único.** 3.000 pasos está muy lejos de la |
| 90 | + convergencia. El ranking relativo podría invertirse o amplificarse con más |
| 91 | + entrenamiento. Una ejecución de 10 K pasos está en marcha; actualizaremos esta página si |
| 92 | + cambia el titular. |
| 93 | +- **Sin silicio real.** Todas las afirmaciones MCU están verificadas en QEMU |
| 94 | + Cortex-M3, no en hardware físico RP2040 / STM32. Los tokens/seg y |
| 95 | + los julios/token en silicio real siguen pendientes. |
| 96 | +- **Comparación directa con Stories260K aún pendiente.** La configuración exacta de Karpathy |
| 97 | + es `Stories260K` a 260 K params + un vocabulario SentencePiece de 32 K tokens. Nuestro |
| 98 | + tokenizador de bytes + config 60 K es ~4× más pequeño. Un verdadero |
| 99 | + manzanas-con-manzanas vs `Stories260K` necesitaría o bien (a) que escalemos |
| 100 | + a 260 K params y un tokenizador SentencePiece, o bien (b) la configuración de |
| 101 | + Karpathy reentrenada a 60 K params con un tokenizador de bytes. Ninguna está |
| 102 | + hecha. |
| 103 | + |
| 104 | +## Comparación con la frontera publicada |
| 105 | + |
| 106 | +| Sistema | Objetivo más pequeño | Params | Bits/peso | ¿MCU real? | ¿La arquitectura gana a vanilla? | |
| 107 | +|---|---|---:|---:|---|---| |
| 108 | +| Microsoft BitNet b1.58 | CPU de servidor | 700 M – 3 B | 1.58 | no | (empata a escala) | |
| 109 | +| Meta MobileLLM | smartphone | 125 M – 1 B | 4–8 | no | sí (vs vanilla del mismo tamaño) | |
| 110 | +| Karpathy `Stories260K` | portátil / navegador | 260 K | 32 | sin firmware | n/a (es la referencia vanilla) | |
| 111 | +| llama.cpp en RP2040 (afición) | RP2040 + SD | ~1 B (con swap) | 4 | sí (lento, requiere SD) | no medido | |
| 112 | +| TFLite Micro / Edge Impulse | Cortex-M0+ | – | 8 | sí | sin tareas de lenguaje | |
| 113 | +| **Atome LM (este trabajo)** | **Cortex-M0+, 16 KB SRAM** | **60 K** | **1.58** | **QEMU sí, silicio pendiente** | **+22 % en params-justo, +52 % en flash-justo** | |
| 114 | + |
| 115 | +Más pequeño, más eficiente en bits, *y* gana arquitectónicamente a vanilla en los |
| 116 | +presupuestos que apuntamos. Que sepamos, el LM publicado más pequeño |
| 117 | +donde la victoria de la arquitectura enrutada se ha medido directamente contra |
| 118 | +una referencia vanilla al mismo presupuesto de flash. |
| 119 | + |
| 120 | +## Reproducir |
| 121 | + |
| 122 | +```bash |
| 123 | +# from the repository root |
| 124 | +PYTHONPATH=. python3 scripts/build_corpus.py --source tinystories \ |
| 125 | + --max-bytes 500000 --output data/tinystories.txt |
| 126 | + |
| 127 | +PYTHONPATH=. python3 scripts/run_ab_sweep.py \ |
| 128 | + --train data/tinystories.txt --steps 3000 \ |
| 129 | + --output ab_results.json |
| 130 | +``` |
| 131 | + |
| 132 | +`ab_results.json` contendrá los mismos números que la tabla de arriba |
| 133 | +(salvo redondeo dependiente de la plataforma en los kernels matmul de PyTorch). |
| 134 | + |
| 135 | +## Preguntas abiertas / próximos empujes |
| 136 | + |
| 137 | +- **A1.** Multisemilla (3 semillas × 3 configs) para estimar la varianza en las |
| 138 | + brechas del 22 % / 52 %. |
| 139 | +- **A2.** Entrenar los tres a ≥ 10 K pasos. ¿Se cierra la brecha, se sostiene, |
| 140 | + o se ensancha? |
| 141 | +- **A3.** Ablación: ¿cuál de las tres vías (conv local, SSM |
| 142 | + diagonal, atención dispersa top-k) carga con la mayor parte de la victoria de arquitectura? |
| 143 | + Quita cada una, mide. |
| 144 | +- **A4.** Enviar un decodificador C para ATOME02. Recorta el binario de demo de |
| 145 | + 20,1 KB a 17,2 KB sin cambios de código en otro sitio. |
| 146 | +- **A5.** Silicio real. Flashear un RP2040 con el motor + este ckpt de 60,8 K. |
| 147 | + Medir tokens/seg, julios/token. **El número destacado que |
| 148 | + convierte la afirmación de «frontera» en un hecho.** |
| 149 | +- **A6.** Destilación desde un fuerte LLM profesor (10 MB de texto de dominio |
| 150 | + estrecho curado, generado por un modelo de vanguardia) en el mismo Atome 60 K. |
| 151 | + Pregunta abierta: ¿se compone la ventaja de arquitectura bajo la |
| 152 | + destilación? |
| 153 | +- **A7.** Corrección del Bug A (divergencia SSM con prompt corto entre `generate` de Python |
| 154 | + ↔ `atome_generate` de C). Toca el contrato de paridad exacta al bit |
| 155 | + — necesita aprobación explícita del usuario. |
| 156 | + |
| 157 | +## Archivos de registro |
| 158 | + |
| 159 | +- `ab_results.json` — números y config exactos de la ejecución reportada aquí. |
| 160 | +- Los checkpoints A/B entrenados (`atome_60k_ternary`, `vanilla_60k_fp32`, |
| 161 | + `vanilla_6k_fp32`) *no* se envían — regénéralos con el arnés |
| 162 | + de abajo (este kit se entrena desde cero). |
| 163 | +- `atome_llm/baselines/vanilla_transformer.py` — la referencia. |
| 164 | +- `scripts/run_ab_sweep.py` — el arnés. |
| 165 | +- `tests/test_vanilla_baseline.py` — 10 tests de cordura sobre la referencia. |
| 166 | +- `tests/test_export_packed.py` — 5 tests sobre el ida-y-vuelta ATOME02. |
| 167 | +- `tests/test_trit_packing.py` — 11 tests sobre el empaquetador base 3. |
0 commit comments