Small language models now run entirely in your browser. But a big slice of every download is the token-embedding table — and a real conversation touches under 0.3% of its rows. We measured it across the most popular models. Then we built the fix.
Share of the total model download (q4f16 ONNX, browser build) that is the token-embedding table. Bigger bar = more of your download is a lookup table you barely use.
config.json (vocab × hidden × dtype) and
ONNX file sizes; validated byte-exact against three models loaded in full. Reproduce with
research/survey/leaderboard.py.Paste a Hugging Face ONNX repo (or pick one). Your browser fetches its
config.json + file sizes directly from HF and computes the embedding share live —
nothing hits our servers.
Language is heavy-tailed (Zipf) and its vocabulary grows sublinearly with length (Heaps' law — we measure β≈0.75, R²=0.996 on 714k real tokens). So a whole conversation only ever needs a few hundred of a model's 100k–260k embedding rows. Yet every serving stack — Transformers.js, onnxruntime-web, llama.cpp, Google's own LiteRT-LM — downloads or memory-maps the entire table before the first token.
SparseGemma fetches only the byte ranges for the tokens actually used (HTTP Range requests), caches them across sessions, and — using the draft model already run for speculative decoding as a free prefetch oracle — hides the latency. On the hardest case (Gemma-4-E2B's 1.59 GB table) the live demo fetches hundreds of KB instead of gigabytes, with byte-identical output.
Open source (MIT). The technique should be free and everywhere — that's the point.