GLM-5.3-Flash on Apple Silicon WARP, an embeddable inference engine written in C, now runs the full 2.78-trillion-parameter Kimi K3 model on a 64 GB MacBook Pro at about 0.6 tokens per second, and the 313-billion-parameter GLM-5.3-Flash at about 3.9 tokens per second, according to the project's documentation. The engine keeps the model trunk in memory, streams selected experts from disk, and uses a bounded expert cache, achieving these speeds without distillation or pruning. The project aims to run huge frontier models on consumer hardware, with the ultimate goal of executing Kimi K3 locally to improve itself. WARP is an embeddable inference engine written in C, with no third-party runtime dependencies. It keeps the model trunk in memory, streams selected experts directly from disk, and uses the remaining RAM as a bounded expert cache. The project is driven by humans: the ideas, hypotheses, priorities, tests, and decisions are human. The code is written by LLMs. At this scale, that is the only way to iterate on new algorithms and test hypotheses fast enough. The goal is to run huge frontier models such as Kimi K3 on consumer hardware. Today, the complete 2.78-trillion-parameter Kimi K3 runs on a 64 GB MacBook Pro at about 0.6 tokens per second , and the 313-billion-parameter GLM-5.3-Flash — text and images — at about 3.9 . Ultimately we want WARP to execute Kimi K3 locally to improve itself we are currently using Opus 5 with extra thinking . WARP is intentionally narrow, and it exists to find out how far local inference can be pushed when model weights live mostly on fast storage instead of RAM. bash $ waste run ~/models/k3.waste 'What is the capital of Italy?' waste: no --budget, using 46.39 GB of 64.00 GB expert cache 17.56 GB The capital of Italy is Rome . 16 tokens, 26.87 s, 0.60 tok/s | experts 9000 hit / 14552 miss = 38% This is the full model, not a distilled or pruned version. Its published weights occupy 1.42 TB; the converted WARP container is 982 GB. Kimi K3 is a mixture-of-experts model. It has 2.78 trillion parameters, but only about 4% of them are active for each token. WARP keeps the shared part of the model in RAM and reads only the selected experts from disk. The container is arranged so that one expert requires one aligned read. Those reads overlap with computation, while unused RAM becomes a bounded expert cache. A lookahead router predicts the experts needed by the next layer and starts reading them early; the real router still makes the decision, so this changes timing, not the result. Experts use 3-bit residual vector quantization, while the more sensitive shared weights remain at 4 or 8 bits. K3's linear attention and compressed latent KV cache also matter: at 4K context, the KV cache is about 0.21 GB instead of 11.25 GB. The result is an engine that needs 29.19 GB to open K3 and uses the rest of the available memory to avoid repeated disk reads. For the full design and measurements, see docs/ENGINE.md /sqliteai/warp/blob/main/docs/ENGINE.md and docs/EFFICIENCY.md /sqliteai/warp/blob/main/docs/EFFICIENCY.md . The on-disk layout is documented in docs/FORMAT.md /sqliteai/warp/blob/main/docs/FORMAT.md , while docs/KDA.md /sqliteai/warp/blob/main/docs/KDA.md describes Kimi Delta Attention. Measured on a 64 GB MacBook Pro with an M5 Pro and the model container on the internal SSD: | Model | Container | Minimum RAM | 64 tokens | 200 tokens | |---|---|---|---|---| | Kimi K3 2.78T | 982 GB | 29.19 GB | 0.45–0.62 tok/s | — | | GLM-5.3-Flash 313B | 112 GB | 5.14 GB | 3.32 tok/s | 3.86 tok/s | | Kimi-Linear 48B | 19 GB | 1.32 GB | 14.29 tok/s | 17.22 tok/s | The longer run is faster because the expert cache is still filling during the first few dozen tokens; both columns are what the same command prints, not a steady state extrapolated from it. K3 has no 200-token column here because one run of it takes ten minutes and reads 4.6 TB. For K3, 64 GB is the practical minimum. A 32 GB machine can open the model but will page heavily. The default memory budget on the test machine is 46.39 GB, including a 17.56 GB expert cache. Kimi-Linear's figure is the one that moved: the automatic budget used to stop three working sets short of the machine, so a 19 GB container got a 1.65 GB cache on a 64 GB laptop. It now climbs to the container's whole expert set when the machine has the room — 18.48 GB resolved, every expert resident — and that is worth 11.13 → 12.60 tok/s over 64 tokens, with the bytes read falling from 66.3 GB to 17.7. On top of it the thread pool stopped waking its efficiency cores for jobs too small to hide the ~54 µs that costs, which is another 14.41 → 16.74 over 150 tokens. K3 is unchanged by both: its 962.83 GB of experts do not fit on any machine here, and at 465 GB read per 20 tokens neither residency nor dispatch is where its time goes. docs/LEARNED.md /sqliteai/warp/blob/main/docs/LEARNED.md §66, §67. Most of that requirement is the 27.28 GB resident trunk rather than the cache. Shrinking the expert cache from 17.32 GB to 3.32 GB costs about 10% of throughput; enlarging it past the default costs everything. Measured across four cache sizes in one process: | expert cache | hit rate | decode | |---|---|---| | 3.32 GB | 29.1% | 0.56–0.58 tok/s | | 17.32 GB | 36.2% | 0.63 tok/s | | 23.32 GB | 38.4% | 0.07–0.09 tok/s | | 29.32 GB | 41.3% | 0.07–0.08 tok/s | The last two rows are the failure mode worth knowing about: the hit rate keeps climbing and the bytes read keep falling while throughput drops eightfold. The engine is inside its budget and the machine is not, so a cache hit becomes a page fault. Giving the process more memory is not always faster. Decoding with fewer experts per token is a knob rather than a rebuild: num experts per token in the container manifest. K3 ships at 16. Measured on this machine, one load with the arms interleaved: | experts/token | decode | KL from top-16 | working set | |---|---|---|---| | 16 | 0.59 tok/s | — | 17.01 GiB | | 12 | 0.70 tok/s | 0.007 | 12.76 GiB | 8 | 0.89 tok/s | 0.037 | 8.50 GiB | | 4 | 1.06 tok/s | 0.118 | 4.25 GiB | Top-8 is 1.49x for a divergence twice that of a quantization this project rejects elsewhere, and it reproduces top-16's greedy continuation on the prompts tested. Top-4 does not: its next-token distribution still looks close, and it stops following the prompt within a few tokens — which is why the gate here is a continuation and not a KL. This is a quality trade and the default stays 16. Storage is the main constraint. A cold K3 token reads about 17 GB of experts. The internal SSD sustains 12.78 GB/s; a tested USB enclosure managed 0.94 GB/s. Put the converted container on internal NVMe storage. If you have more than one drive, since 0.7.2 the expert banks can be spread across them: WASTE BANK SHARDS=/mnt/a,/mnt/b reads expert e from shard e % N , so the k experts a single token routes to land on different devices instead of queueing behind one. tools/split banks.py writes and byte-verifies the shard sets, and the logits are identical either way. No speedup is claimed here — that needs two drives of comparable speed and a real container. Striping across the internal SSD and the USB enclosure above would measure the enclosure, not the striping. The mechanism ships; the measurement does not. All layers are checked against a PyTorch reference. Final logits agree within 3.6e-06, and the vision tower agrees with its oracle within 2.3e-06. Additional measurements, profiling data, router-lookahead results, and quantization experiments are collected in docs/TECHNICAL.md /sqliteai/warp/blob/main/docs/TECHNICAL.md . Kimi K3 and GLM-5.3-Flash are both multimodal, and WARP can use one or more images together with text. Pass --image once per image: ./waste run ~/models/k3.waste "Describe this image" --image photo.jpg ./waste run ~/models/k3.waste "Compare these images" \ --image before.png --image after.png In interactive mode, /image FILE attaches an image to the next message. An image is expanded into many prompt positions: an 896×896 image uses 256 positions at the default patch budget. The vision tower takes about 15.7 seconds for 1024 patches on the test machine, but most of the cost comes afterward because every image position passes through the language model like a text position. In the current K3 measurements, that is about 2.8 seconds per image position. GLM's tower is a different one and cheaper to feed: the 200×140 picture in the GLM section glm-53-flash costs 40 prompt positions, and generation after it runs at the same speed as without it. Its tower is 282 MB against K3's 434 MB, and both are loaded only when images are asked for. See docs/K3.md /sqliteai/warp/blob/main/docs/K3.md and docs/GLM.md /sqliteai/warp/blob/main/docs/GLM.md for the two vision architectures and their measurements, and examples/README.md /sqliteai/warp/blob/main/examples/README.md for CLI, C, and HTTP multimodal examples. K3 is the target and the best-tested model, and Kimi-Linear is the small one to start with. Since 0.6.8 the converter and the engine also handle the DeepSeek-V3 family — V3, R1 and Kimi K2 , which needed two changes rather than one. convert.py now reads fp8 block-scaled weights, applying the per-tile scales these checkpoints ship in a companion tensor, and normalises DeepSeek's MoE tensor and config names to the single spelling the engine reads. And MLA now applies rotary to its rope dims. The engine had implemented none: the Kimi models set mla use nope and pass those dims through unrotated, which is correct for them and wrong for everything in the V3 family, where in MLA those dims are the only positional signal there is. A container built before this was not degraded, it was unordered — it could not tell which turn of a conversation came first. No throughput figures here, because nobody on this project has a K2 container. What has been measured, by @fab2s https://github.com/fab2s who contributed both changes: a Kimi-K2-Instruct conversion — 61 layers, 384 experts top-8, VQ3R, a 354 GB expert set and a 6.9 GB trunk — opens and reports 1.03 T parameters total, 31.69 B active per token; and the rotary arithmetic agrees to 0.000023% relative L2 with an oracle whose YaRN helpers are taken verbatim from the DeepSeek release's own modeling deepseek.py . Kimi K3 and Kimi-Linear are unaffected: their forward pass is byte-identical to 0.6.7, by construction rather than by a runtime branch. zai-org/GLM-5.3-Flash — 313 B parameters, 328 GB of fp8 as published — is converted and running, text and images. bash $ waste run ~/models/glm53.waste "What is the capital of Italy? Answer in one sentence." waste: no --budget, using 46.37 GB of 64.00 GB expert cache 41.36 GB The user is asking a simple factual question: What is the capital of Italy? They want the answer in one sentence. The capital of Italy is Rome. This is a well-established fact. I should answer in one sentence as requested.