A Ternary LLM on a Pixel, From One Pasted Line
You can now paste one line into the terminal on a Pixel and end up with a ternary-quantised
LLM serving on 127.0.0.1:8080, which the browser then finds by itself:
curl -fsSL "https://aitherium.com/install-bonsai.sh?v=11" | sh
No account. No API key. No Hugging Face token. No compiler, no Python, no root.
The interesting part is not the one-liner. It is everything the one-liner had to learn to do, and we learned all of it the same way: by running it on a real phone and watching it fail.
The phone is a real computer now
Android 16 ships a Linux terminal on Pixel — a genuine Debian VM on the Android
Virtualization Framework. uname says aarch64, apt works, and prebuilt llama.cpp binaries
for linux-arm64 run natively. No emulation, no proot gymnastics.
That is what makes this possible at all. The model is not being streamed from anywhere. It is a file on the phone, served by a process on the phone, answering a page on the phone.
Five things that broke, and what each one taught
1. The installer failed after the multi-gigabyte download
Everything downloaded. The weights came down. Then:
llama-server: error while loading shared libraries: libgomp.so.1
libgomp is the OpenMP runtime, and it is not in a minimal Debian image — which is exactly
what the phone's Linux terminal is. The worst possible shape: a long wait ending in a loader
error.
The fix was not "install libgomp". It was to smoke-test the binary before downloading
anything large, enumerate every missing library with ldd, map each to a package across
apt/dnf/apk/pacman/zypper, install them, and loop — because fixing one library routinely
reveals the next.
2. The error message named the binary, not the library
The first version of that resolver reported:
missing libraries with no known package mapping: /home/droid/.../llama-server
It told the user to install their own binary. The cause was a one-character-class bug: ldd
has two failure shapes, and a bare /not found/ match caught both. The second shape is a
library that is present but too old, where the offending line begins with the binary's path.
Matching => not found fixed it.
3. glibc 2.36 was not enough, and the reason was hiding in a bundled library
The phone reported glibc 2.36. The main llama-server binary needs 2.34, so that looked fine.
It was not — and readelf said why:
llama-server libllama-server-impl.so floor
x64 2.34 2.34 2.34
arm64 2.34 2.38 2.38 ← binding constraint
The bundled library needs 2.38. Debian 12 is 2.36. Checking only the main binary declares a 2.36 system healthy and then fails at load.
Applying arm64's 2.38 everywhere would have been a worse bug: it rejects x64 Debian 12, which we had already verified end-to-end. The floor is per-architecture.
And glibc cannot be upgraded in place — every binary on the system links it, including apt
and the shell you are typing in. So the installer does not try. It builds a newer userspace
and re-enters itself inside it: proot-distro on Termux, a debian:13 container where
Docker exists, or debootstrap into ~/.aitherium/bonsai/trixie and chroot. Nothing on the
host is modified; the new userspace is a directory you can delete.
4. Termux cannot run these binaries at all, and no package fixes that
Read from the ELF rather than guessed:
interpreter = /lib/ld-linux-aarch64.so.1 → glibc
RUNPATH = $ORIGIN → bundled .so resolve fine
These are glibc binaries. Termux is Android/bionic. A glibc binary cannot exec under
bionic at any price, so the installer detects Termux and routes to a real distro under
proot-distro instead of failing with something inscrutable.
5. The success message was a lie
This one is the reason to write any of this down.
After the escape worked, a run ended:
curl: (6) Could not resolve host: aitherium.com
installed inside .../trixie - it still serves on 127.0.0.1:8080
The inner install had died and the outer declared victory. The cause is old and well known:
curl … | sh reports the last command's status, so when curl fails, sh reads empty
input and exits 0.
We had that exact trap written down in our own debt ledger. It was quoted in the commit
message that introduced this bug. Then the verification script we wrote to prove the fix used
sh script | tail -6, which reports tail's zero — so the check said EXIT=0 while the script
had exited 1.
Three instances in one session, one of them inside the check meant to catch the other two. Knowing a failure mode is documented is not the same as not making it.
The bridge nobody warns you about
The server runs inside the Linux VM. Chrome runs outside it, in Android. They do not share a
loopback interface — so 127.0.0.1:8080 in the browser reaches Android's own loopback and
finds nothing.
The Terminal app has a port-forwarding toggle, off by default. Turn it on and the page finds the model immediately. It is one switch, it is invisible until you know, and it is now the last thing the installer prints rather than a warning that scrolled past thousands of lines earlier.
What it costs
| Model | Ternary-Bonsai, ~2.1 bits/weight |
| Phone-sized | 4B, ~1.07 GB on disk |
| Server | prebuilt llama.cpp (arm64), ~13 MB |
| Account required | none |
| Data leaving the device | none |
The installer sizes the model from available RAM and caps a phone at 4B, because 8B fits on paper and then gets reaped the moment you switch apps.
Why bother
A model you rent can be withdrawn, repriced, deprecated, or quietly swapped for a smaller one. A model that is a file on your phone cannot. It works on a plane. It works when our fleet is down — which it was, twice, during the week we built this.
That is the whole argument, and it only means anything if the thing actually installs on hardware someone already owns. Which is why every fix above exists.
Honest limits
- macOS is unrun. The Metal path and the LaunchAgent are written and never executed.
- The in-browser runtime is separate from this and still loads one-bit weights; the ternary Q2_0 kernels are ported and verified against the reference implementation, but have not yet run on a GPU against real weights.
- The port-forwarding step is manual. We could not find a CLI for it. If one exists, we want to know.
- "First" is our belief, not a measurement. We have not found anyone else doing this end-to-end on a phone, but absence of evidence is exactly that.
The installer is a single shell script and you can read every line of it before you run it: aitherium.com/install-bonsai.sh.