Back Original

I'm making LLMs work on small and old devices

smolmaxxing, by Hyperion: run the biggest model you can on the smallest hardware you own. 260K to 16B parameters.

Hacker News rank via HackerGit

Run the biggest language model you can on the smallest hardware you own.

TV boxes, old tablets, single-board computers and routers all have a CPU, some RAM and flash storage that sit idle most of the day. smolmaxxing finds the biggest model each of them can really run, then pushes it further with custom kernels, careful memory use and weights streamed from flash. Every number in this repo was measured on the device itself.

📺 Xiaomi TV Box S (3rd Gen) 📱 iPad Air (2013)
Chip Amlogic S7D, 4× Cortex-A55 Apple A7, 2 cores
RAM 1.9 GB (about 1 GB usable) 1 GB (about 700 MB usable)
OS Android 14, no root iOS 12.5.7, jailbroken
Everyday model Qwen3.5-2B at 7.7 tok/s Bonsai-1.7B (1-bit) at 24-26 tok/s
Biggest model Ling-mini-2.0, 16B, at 5.1 tok/s Ling-mini-2.0, 16B, at 2.6-4.5 tok/s
Full results docs/tv-box.md ipad-air/README.md

Both devices run 8B and 16B mixture-of-experts models on about 1 GB of RAM by keeping only part of each model in memory and reading the rest from flash as it's needed.

Best generation speed per size class on the two 1 GB devices: 2B class TV 7.7 (Qwen3.5-2B) vs iPad 23.7 (Bonsai-1.7B, 1-bit); 4B 4.3 vs 9.4; 8B dense 5.2 vs 0.08; 8B MoE 7.2 vs 3.5; 16B MoE 5.1 vs 4.5 with the same cache bias

More devices (phones, single-board computers, routers) are coming. The techniques aren't tied to one box: the 1-bit kernel needs only basic NEON, and the flash streaming works on any Linux or Android device with more model than RAM.

The live token-stream page served by llama-server on the TV box

All of it is a patch on llama.cpp. The main ideas:

  • Kernels built for the chip. A 1-bit lookup-table kernel, repacked 2-bit and ternary formats for the Cortex-A55, and versions of them for the A7, which has no dot-product instructions.
  • Less RAM per model. Most of a small model's vocabulary is rarely used, so we drop those output rows. On the TV, a "headless" mode also stops the launcher and Google services while a model runs.
  • Experts paged from flash. A mixture-of-experts model only uses a few experts per token. We keep the popular ones in RAM, read the others from flash on demand and prefetch the next layer's. This is how 8B and 16B models run on 1 GB.
  • Streaming for dense models bigger than RAM, at the flash's full speed.

docs/how-it-works.md has every technique with its measured gain.

The quickest start is a ready-made model file from Hugging Face. They need the patched llama.cpp: stock llama.cpp can't load them.

Page What's in it
docs/tv-box.md device #1: every model run on the TV box, speed and quality
ipad-air/README.md device #2: the iPad Air results, setup and scripts
docs/how-it-works.md the kernels, memory tricks, expert pager and streaming engine
docs/models.md downloads for both devices, rebuild targets and checksums
docs/lessons.md what we learned, including what didn't work
EXPERIMENT.md the full lab notebook: 160 experiments, failures included
Path What
patches/ every change to llama.cpp for the TV box (the iPad's patch is in ipad-air/patches/)
tools/ model rebuilding, GGUF rewriting, benchmarks and kernel checks
tv-llm-ui/ the live token-stream chat page and its launcher
ipad-air/ device #2: iOS 12 build, smolchat, deploy and benchmark scripts
bench/ every chat benchmark (results.jsonl) and the raw logs
data/ vocabulary lists and evaluation texts
tiny-llm-web/ the first experiment: a 260K-parameter story model
zigcc/ zig wrappers for cross-compiling static aarch64 binaries
Star History Chart

MIT. The llama.cpp patches are derivatives of llama.cpp (MIT). Model weights keep their own licenses, and the evaluation texts are Wikipedia excerpts (CC BY-SA 4.0).

Built on llama.cpp and llama2.c. Models from Qwen, unsloth (GGUFs and importance matrices), PrismML (Bonsai), inclusionAI (Ling-mini-2.0), tablinum (Moon-Beam), bartowski and mradermacher (GGUFs), Google (Gemma) and stories260K. The iPad is jailbroken with Amethyst. The banner uses Archivo (SIL OFL) and is rendered by tools/banner/render.sh. The 🤏 logo is the pinching-hand emoji from Google's Noto Emoji (Apache 2.0).