q08

The Model That Ran Until the Chip Changed

2026-09-14 · Edge0-AI/Edge0

Issue number eight on the Edge0 repository has a title that reads like a bug report from a different era: "Garbled, mixed-language output on Apple A18 / A18 Pro." The same 4-bit checkpoint that produces clean prose on an M3 produces mixed-language garbage on the newest silicon. The fix, printed in the project's README, is not a patch to the model. It is a version pin: *pip install 'mlx==0.30.6' 'mlx-metal==0.30.6'*. The weights did not change. The bytes did not change. The chip changed, and the software envelope around the weights — the kernels that multiply them, the runtime that schedules them — was written for the previous generation and silently misbehaves on the next.

Edge0 is worth looking at closely because it is, by the standards of its genre, unusually portable. It is a streaming mixture-of-experts inference framework: expert weights are memory-mapped and streamed from disk on demand, so a 23-gigabyte model runs in roughly 2.9 gigabytes of peak memory; a small trained head predicts expert routing one step ahead so that loading overlaps the forward pass — up to 59 percent more decode throughput, growing with storage latency; and the 4-bit base is frozen while LoRA adapters trained by distillation recover most of the quantization loss, the adapters kept unmerged so one read-only base serves many adapter sets. The architecture is disciplined: all accelerator-specific code lives behind a backend facade, a CUDA slot is reserved, and the core logic depends only on the abstraction. This is a project that thought about portability.

And the portability stops exactly at the envelope. The MLX backend runs on macOS with Apple Silicon — M1 through M4 — and nowhere else. "The CUDA backend is on the roadmap," the README says; "no other platforms are supported yet." The model files are portable by construction: a flat array of numbers has no operating system. The thing that refuses to travel is the runtime contract between the weights and the hardware — the kernels, the allocators, the libraries — and the A18 bug is the tell that exposes what that contract actually is. Quantized kernels are tuned per chip generation: register widths, matrix unit shapes, memory latencies. When the silicon changes underneath them, the kernels written for the previous generation do not crash. They emit garbage. A model emitting mixed-language tokens is a model whose probabilities were computed slightly wrong, by kernels whose assumptions stopped being true, and nothing in the pipeline noticed because nothing in the pipeline checks the arithmetic. The envelope is not packaging around the product. The envelope is the product, and it is a per-generation appliance.

The same boundary shows up from the user side, in the request that keeps getting filed: a one-bit quantization, to halve the memory again and roughly double throughput. On paper it is a flag. In the build system it is a wall: the quantization library compiles only on the machine where the project was born, the optimizer expects a compiler the mobile toolchain does not have, the build script hard-codes a path to a system library that does not exist elsewhere. The request dies as a compilation error before any benchmark runs. Nothing in the model's arithmetic caused it. Every cause is an assumption the envelope makes about where it lives.

The same boundary shapes the lifecycle of every release. Updates are compiled in the home environment and moved to devices by hand: some users run the pinned MLX with the old kernels, some run the new build against the new silicon, some hold a binary that never started. The same weights produce different tokens on different devices because the envelopes differ, and the differences are invisible until a sentence comes out in the wrong language. Version skew is usually described as a distribution problem. Here it is the envelope’s natural state: a contract that is renegotiated per chip generation cannot stay synchronized across devices, because there is nothing written down to synchronize against. The project’s own documentation draws the line honestly — “no other platforms are supported yet” — and the honesty is the point. An abstraction that exists but is not shipped is not a property of the software. It is a plan, and plans do not run on hardware.

There is a template for this problem, and the field solved it once for a nearly identical object. The reason compiled binaries could travel between different machines running one operating system was not that the machines were similar. It was that the community standardized the envelope: a common file format and calling convention — the System V ABI, ELF — an interface that says what a binary is and how it begins, so that a program compiled on one machine has a defined meaning on another. The format did the traveling; the code stayed where it was written. Inference is replaying the pre-ABI world, framework by framework: every project ships its own envelope, per vendor, per chip generation, and the envelope rots on a schedule measured in silicon releases. The A18 bug is what a pre-ABI world looks like in practice — the same program, the same data, different meaning, no error, just garbage.

The second instructive case is the industry's largest one. NVIDIA's moat is not the hardware. It is the envelope: two decades of kernels — cuDNN, cuBLAS, the entire tooling stack — compiled against CUDA, so that every competitor's hardware must reimplement the contract or run slower, and every framework that wants NVIDIA's chips must speak the envelope or not run. Lock-in lives in the software between the weights and the silicon, and the MLX layer is Apple's version of the same structure, one generation deep. The chips are commodities with exceptional marketing; the envelopes are where the money and the incompatibility actually are.

The general claim is simple enough to test against any other framework. Portability is a property of the envelope, and the envelope is the part nobody publishes. A model card lists weights, context length, benchmarks. It does not list kernel assumptions, library pins, or compiler versions — the things that actually determine whether the artifact runs on a given machine. The garbled sentence is the symptom the industry has agreed to tolerate, the way an earlier industry tolerated machines that would not start until the operator arrived with the right cart of punched cards. The A18 bug, the version pin, the unsupported-platform wall — all three are the same envelope seen from three angles: first run, upgrade, and release.

The weights are ready. Everything that stands between the weights and the device is software, and the software is the only part anyone is allowed to keep proprietary. Until the industry produces a runtime contract for models — the moment it already produced twice, for binaries with the ABI and for the browser with WebAssembly — the question "does this model run here" will keep being answered the way issue number eight answered it: with a garbled sentence on the newest chip, and a version pin, and the quiet assumption that the user will wait for the envelope to catch up.

Was this worth your time? yesflatno

Sources & further reading