<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Moe-Inference on ToolGenix — Open-Source AI &amp; Developer Tools: Honest Hands-On Reviews</title>
    <link>https://toolgenix.nxtniche.com/tags/moe-inference/</link>
    <description>Recent content in Moe-Inference on ToolGenix — Open-Source AI &amp; Developer Tools: Honest Hands-On Reviews</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <lastBuildDate>Mon, 03 Aug 2026 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://toolgenix.nxtniche.com/tags/moe-inference/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Kimi K3 on a Potato: C99 Runs a 2.78T Model in 8.24GB RAM</title>
      <link>https://toolgenix.nxtniche.com/posts/article-2026-08-03-main2/</link>
      <pubDate>Mon, 03 Aug 2026 00:00:00 +0000</pubDate>
      <guid>https://toolgenix.nxtniche.com/posts/article-2026-08-03-main2/</guid>
      <description>Moonshot says Kimi K3 needs 16 nodes and ~4.8TB of VRAM. kimi-k3-in-c runs the full 2.78T model on one CPU in 8.24GB RAM. My take, with measured numbers.</description>
      <content:encoded><![CDATA[<p>Moonshot&rsquo;s own docs say Kimi K3 needs 16 nodes and about 4.8TB of VRAM. Then I found a 176KB C99 file that runs the same 2.78-trillion-parameter model on a laptop with 8GB of RAM — no GPU, no BLAS, no framework. Slow? 32 seconds per token. And real? The numbers are all in the repo, measured, not promised.</p>
<p>I almost scrolled past it, because &ldquo;runs a frontier model on a potato&rdquo; is usually marketing. But this one isn&rsquo;t. FareedKhan-dev&rsquo;s <code>kimi-k3-in-c</code> hit 607 stars in its first two days — roughly 300 a day, the third-fastest new AI project on GitHub right now — and by the time I checked the API while writing this it was at 633. That pace alone earned a look. The engineering earned the rest of my evening.</p>
<h2 id="tldr-the-same-model-from-a-cluster-to-a-laptop">TL;DR: the same model, from a cluster to a laptop</h2>
<p>Quick verdict up front. <code>kimi-k3-in-c</code> does not quantize, crop, or approximate Kimi K3. Instead it loads the full 1.56TB checkpoint from NVMe and streams the expert weights in and out of memory as it generates. Peak resident set on the laptop preset is 8.24GB. But these are the same weights Moonshot released — the repo&rsquo;s own <code>docs/data</code> shows the same token IDs emitted byte-identically all the way from an 8GB memory cap up to 224GB. Only the clock changes. The author&rsquo;s line is worth stealing: &ldquo;Give it more memory and the answer does not change, only the clock.&rdquo;</p>
<p>Here&rsquo;s the thing most people miss. This isn&rsquo;t &ldquo;optimized to the point where you don&rsquo;t need a GPU.&rdquo; It&rsquo;s designed so the GPU was never part of the equation. Pure C99, memory-mapped checkpoint, a few labeled pipes between a resident working set on top and the model on NVMe underneath. So compile once, and it runs anywhere Linux x86-64 lives.</p>
<h2 id="the-architecture-four-reductions-instead-of-a-bigger-box">The architecture: four reductions instead of a bigger box</h2>
<p>The whole project is one question: where do the bytes live? Four decisions take a 16-node cluster down to a laptop.</p>
<ol>
<li><strong>The experts already ship at half a byte.</strong> The 1.45TB of routed experts stay packed in their 4-bit form and get multiplied straight out of that — never unpacked to full precision resident in RAM.</li>
<li><strong>KDA attention with a memory that never grows.</strong> A kernel for the attention block keeps its working set flat instead of scaling with sequence length.</li>
<li><strong>MLA collapses 96 heads into one latent.</strong> Multi-head latent attention means one latent vector instead of ninety-six separate heads doing the same job.</li>
<li><strong>Streaming the trunk turns a floor into a dial.</strong> The 93-layer trunk reads layer-by-layer from disk, so the memory ceiling becomes a knob you turn, not a wall you hit.</li>
</ol>
<p>The dense trunk stays resident to whatever depth you choose; the routed experts are never resident at all. Even so, a cache with a configurable budget holds whichever experts you touched most recently, and the shipped trace tells you how big that cache should be. That&rsquo;s the &ldquo;176KB engine, 8.24GB of RAM, 2.78 trillion parameters&rdquo; trick — and it&rsquo;s reproducible, because every number is committed with its measurement output.</p>
<p>Though the README is genuinely hostile to hand-waving. It calls out the quantization crowd directly — once you 3-bit re-encode the expert bank, &ldquo;those weights are no longer the weights Moonshot published.&rdquo; That&rsquo;s a real philosophical split, and I&rsquo;ll get to why both sides are right in the comparison.</p>
<h2 id="verifying-the-engine-what-i-actually-did">Verifying the engine: what I actually did</h2>
<p>Let me be precise about the boundary before I quote any number. I cloned the repo, read the README, <code>docs/PERFORMANCE.md</code>, and the raw output in <code>docs/data/</code>, and I pulled the committed test logs in <code>tests/fixtures/gates/</code>. What I could not do is run <code>make test</code> myself — this machine I&rsquo;m on has no C toolchain and no Linux box handy, and I&rsquo;m not going to pretend otherwise. So everything below about the test suite is the project&rsquo;s own committed output, which I verified exists and matches the README&rsquo;s claims, rather than something I generated.</p>
<p>The honest upside is that you can verify the engine yourself without touching the 1.56TB checkpoint. But even better, you can do it in about a minute.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>git clone https://github.com/FareedKhan-dev/kimi-k3-in-c.git
</span></span><span style="display:flex;"><span>cd kimi-k3-in-c
</span></span><span style="display:flex;"><span>make -j            <span style="color:#75715e"># seconds. Seven C files, a compiler, and OpenMP</span>
</span></span><span style="display:flex;"><span>make test          <span style="color:#75715e"># under a minute</span>
</span></span></code></pre></div><p>The suite ends with a verdict line, not a shrug. From the committed gate log:</p>
<pre tabindex="0"><code>GATE 1  teacher forcing : 32/32 positions match tf_pred
        generated span  : 20/20  &lt;- must be exact
GATE 2  greedy decode   : 20/20 generated tokens match full_ids
GATE 3  incremental    : 20/20 generated tokens match full_ids  &lt;- KV cache + carried KDA state

VERDICT: ENGINE MATCHES THE REFERENCE EXACTLY
</code></pre><p>That&rsquo;s every kernel, the streaming cache, the safetensors reader, the tokenizer, and an end-to-end oracle over a 13-layer model with the same tensor graph as the released one, checked against a PyTorch reference from fixtures committed to the repo. Twenty-two ops tests pass, zero fail. But the point of quoting it: you&rsquo;re not trusting the README, you&rsquo;re trusting a test you can run yourself in under a minute.</p>
<p>Requirements are ordinary except for disk. Linux x86-64, a CPU with AVX2 + FMA (AVX-512 optional), 8GB of RAM up, GCC ≥ 9 or Clang ≥ 10. The gate is storage: 1.56TB checkpoint plus a 109GB packed trunk, ideally on fast local NVMe.</p>
<h2 id="kimi-k3-measured-what-two-presets-actually-do">Kimi K3 measured: what two presets actually do</h2>
<p>The generation numbers below come straight from the README&rsquo;s own examples and the <code>docs/data/</code> measurement campaign. They&rsquo;re the author&rsquo;s measured results on an AMD EPYC 7763 box (228 GiB RAM, 3.2 TB NVMe at 3.2 GB/s O_DIRECT) — quoted so you can see exactly what &ldquo;CPU inference on a frontier model&rdquo; means. So treat them as the project&rsquo;s numbers, not mine.</p>
<table>
	<thead>
			<tr>
					<th style="text-align: left">Preset</th>
					<th style="text-align: center">Generated</th>
					<th style="text-align: center">Time</th>
					<th style="text-align: center">Throughput</th>
					<th style="text-align: center">Peak RSS</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td style="text-align: left">laptop</td>
					<td style="text-align: center">8 tokens</td>
					<td style="text-align: center">261.5 s</td>
					<td style="text-align: center">32.69 s/token</td>
					<td style="text-align: center">8.24 GB</td>
			</tr>
			<tr>
					<td style="text-align: left">server</td>
					<td style="text-align: center">28 tokens</td>
					<td style="text-align: center">299.3 s</td>
					<td style="text-align: center">10.69 s/token</td>
					<td style="text-align: center">127.92 GB</td>
			</tr>
	</tbody>
</table>
<p>Read that second row carefully. 127.92GB of RAM, and you still wait ~11 seconds per token. Yet the answer is byte-identical to what 8GB produced — the only difference is the wall clock. &ldquo;Only the clock&rdquo; is doing real work in that sentence.</p>
<p>One honest caveat the project itself insists on: a third of a single measurement is noise. The <code>docs/data/README.md</code> documents a 33% spread across three identical runs of the same binary, same prompt, same flags. Even so, the ladder numbers are reliable as <em>comparisons across memory budgets</em>, not as the engine&rsquo;s absolute speed. Longer sustained generations (16–32 tokens) actually run faster — 10.66 to 11.79 s/token — because the cold-start pinning cost gets amortized. The 32 s/token laptop figure is the honest worst case, and I&rsquo;d quote it that way.</p>
<p>So the plain-language version: a single sentence takes a couple of minutes, and a short paragraph is a coffee break. Nobody is running this for daily chat. Yet it earns its place in offline research, privacy-sensitive one-shot inference where the weights never leave your disk, teaching experiments, and &ldquo;I want to prove a 2.78T model can run on the box I already own.&rdquo; For interactive use, this is not it, and I&rsquo;ll say that plainly.</p>
<h2 id="the-trade-off-quantization-vs-full-fidelity-streaming">The trade-off: quantization vs. full-fidelity streaming</h2>
<p><code>kimi-k3-in-c</code> sits at one end of a real design spectrum, and it&rsquo;s worth seeing where. It&rsquo;s also the natural sibling to a project I covered last week — <a href="/posts/deltafin-kimi-k3-local-workstation/">deltafin</a> asks how fast frontier inference can go on hardware you own; <code>kimi-k3-in-c</code> asks how little hardware it can run on. Same Kimi K3, opposite philosophies.</p>
<table>
	<thead>
			<tr>
					<th style="text-align: left">Dimension</th>
					<th style="text-align: left">kimi-k3-in-c</th>
					<th style="text-align: left">deltafin</th>
					<th style="text-align: left">llama.cpp / GGUF</th>
					<th style="text-align: left">Cloud API</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td style="text-align: left">Route</td>
					<td style="text-align: left">pure CPU</td>
					<td style="text-align: left">GPU / Metal / CUDA</td>
					<td style="text-align: left">low-bit quantized</td>
					<td style="text-align: left">vendor&rsquo;s GPUs</td>
			</tr>
			<tr>
					<td style="text-align: left">Model fidelity</td>
					<td style="text-align: left">full 1.56TB, byte-identical</td>
					<td style="text-align: left">full, fast</td>
					<td style="text-align: left">lossy (re-encoded)</td>
					<td style="text-align: left">full</td>
			</tr>
			<tr>
					<td style="text-align: left">Min RAM</td>
					<td style="text-align: left">8.24 GB</td>
					<td style="text-align: left">needs your GPU&rsquo;s VRAM</td>
					<td style="text-align: left">a few GB</td>
					<td style="text-align: left">none</td>
			</tr>
			<tr>
					<td style="text-align: left">Disk</td>
					<td style="text-align: left">~1.7 TB</td>
					<td style="text-align: left">checkpoint-sized</td>
					<td style="text-align: left">much smaller</td>
					<td style="text-align: left">none</td>
			</tr>
			<tr>
					<td style="text-align: left">Speed</td>
					<td style="text-align: left">32 s/token (laptop)</td>
					<td style="text-align: left">fast</td>
					<td style="text-align: left">fast (for its size)</td>
					<td style="text-align: left">fast</td>
			</tr>
			<tr>
					<td style="text-align: left">Data leaves machine</td>
					<td style="text-align: left">no</td>
					<td style="text-align: left">no</td>
					<td style="text-align: left">no</td>
					<td style="text-align: left">yes</td>
			</tr>
			<tr>
					<td style="text-align: left">Cost to run</td>
					<td style="text-align: left">your box + disk</td>
					<td style="text-align: left">your box + GPU</td>
					<td style="text-align: left">your box</td>
					<td style="text-align: left">per-token</td>
			</tr>
	</tbody>
</table>
<p>Each row is a different trade. Still, llama.cpp gets you speed through quantization, but those weights aren&rsquo;t the ones Moonshot shipped anymore. <code>kimi-k3-in-c</code> keeps every byte and pays for it in clock time. Deltafin goes the other way and wants a workstation. And a cloud API is instant and costs a subscription, but your prompt leaves your machine. So there&rsquo;s no wrong answer here — just a &ldquo;what are you optimizing for&rdquo; answer.</p>
<p>My take: if model fidelity or data sovereignty is the whole point, the streaming route wins. If you need tokens back in seconds, you don&rsquo;t want this. Different trade-offs, and this project is honest that it picked the slow lane.</p>
<h2 id="can-you-run-kimi-k3-on-a-vps">Can you run Kimi K3 on a VPS?</h2>
<p>This is where the project turns into an infrastructure question, because the two presets map cleanly onto two price tiers.</p>
<p>The laptop preset wants 8.24GB of RAM and roughly 1.7TB of disk. But that&rsquo;s reachable on an 8GB or 16GB droplet for a fraction of what a GPU box costs — and it means the full-fidelity model, not a quantized imitation, running on hardware that isn&rsquo;t pretending to be a data center. While the server preset, at 127.92GB, is a memory-optimized instance problem. Here <a href="https://toolgenix.nxtniche.com/go/do">DigitalOcean&rsquo;s memory-optimized droplets</a> scale up into that range, which makes them the natural fit for the full-budget config.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># On a memory-optimized VPS, once the checkpoint lives on fast NVMe:</span>
</span></span><span style="display:flex;"><span>git clone https://github.com/FareedKhan-dev/kimi-k3-in-c.git
</span></span><span style="display:flex;"><span>cd kimi-k3-in-c <span style="color:#f92672">&amp;&amp;</span> make -j
</span></span><span style="display:flex;"><span>./bin/k3 ~/k3model --trunk ~/k3trunk --preset server <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span>    --tok ~/k3model --prompt <span style="color:#e6db74">&#34;def fibonacci(n):&#34;</span> --gen <span style="color:#ae81ff">28</span> --incremental
</span></span></code></pre></div><p>That&rsquo;s the honest framing the project earns: you don&rsquo;t need a GPU to run a frontier model — you need a box with RAM and disk, and the right preset. A memory-optimized VPS from <a href="https://toolgenix.nxtniche.com/go/do">DigitalOcean</a> gives you the RAM tier the server preset needs; <a href="https://toolgenix.nxtniche.com/go/vultr">Vultr&rsquo;s high-frequency and large-memory lines</a> are a solid regional alternative; and if you&rsquo;re on the 8GB laptop path, <a href="https://toolgenix.nxtniche.com/go/hostinger">Hostinger&rsquo;s budget tier</a> gets you there cheapest. But the 1.56TB checkpoint is the real cost, and it wants a fast 2TB NVMe drive — one of the well-reviewed options from Amazon&rsquo;s storage aisle <em>(affiliate link — ASIN pending verification, see publisher note)</em>.</p>
<p>Another boundary note so I&rsquo;m not overselling: I verified the code and committed data on my side, and I&rsquo;m quoting the project&rsquo;s measured numbers for generation. I did not run a full 1.56TB inference on a rented VPS, so treat those VPS timing expectations as &ldquo;should run&rdquo; rather than &ldquo;I measured this here.&rdquo; If you actually pull down the checkpoint, your mileage will vary at 32 seconds per token — probably by a lot depending on your NVMe and how patient you are.</p>
<h2 id="the-model-weights-are-a-separate-question">The model weights are a separate question</h2>
<p>The code is Apache-2.0, no argument there. But the model itself is Moonshot&rsquo;s Kimi K3, distributed on HuggingFace under its own license — and that&rsquo;s a separate thing from the engine that runs it. If you&rsquo;re going to use this beyond a personal experiment, check the weights&rsquo; license yourself before you deploy anything that touches a business. I&rsquo;m flagging it because &ldquo;the repo is Apache-2.0&rdquo; is easy to read as &ldquo;everything here is free to ship,&rdquo; and the weights are a distinct layer with their own terms. That&rsquo;s not legal advice; it&rsquo;s me telling you to look before you build on it.</p>
<h2 id="who-should-actually-use-this">Who should actually use this</h2>
<ul>
<li><strong>The no-GPU developer</strong> who wants to run a genuine 2.78T model, not a quantized stand-in, on the laptop they already own.</li>
<li><strong>The self-hoster / privacy-first user</strong> whose whole point is that weights never leave the machine.</li>
<li><strong>The engineer curious about MoE inference</strong> — the README is one of the clearest written explanations of expert streaming and attention memory I&rsquo;ve read in this space.</li>
<li><strong>Not</strong> someone who wants conversational speed. 32 s/token is a feature of the trade-off, not a bug, and anyone selling you this as fast is lying to you.</li>
</ul>
<p>If you want the speed side of that coin, a model server like deltafin or a quantized stack is the better tool — different goals. If you want token-cost optimization instead of token-time optimization, my <a href="/posts/headroom-review-2026/">headroom review</a> is the other end of that spectrum, and if you&rsquo;re curious about the fine-tuning side, my <a href="/posts/2026-06-30-llamafactory-quick-review/">llamafactory quick review</a> pairs with this nicely.</p>
<h2 id="the-bottom-line">The bottom line</h2>
<p>Here&rsquo;s my verdict. <code>kimi-k3-in-c</code> is the most honest piece of local-inference engineering I&rsquo;ve seen this month, precisely because it doesn&rsquo;t pretend to be fast. It&rsquo;s a proof that &ldquo;frontier model&rdquo; and &ldquo;8GB of RAM&rdquo; can coexist — not through clever lossy compression, but through ruthless decisions about where every byte lives. The star count went from 607 to 633 while I was writing this, and that tells me I&rsquo;m not the only one who found it.</p>
<p>Run the one-minute test suite first. If the engineering hooks you the way it hooked me, a memory-optimized VPS is genuinely enough to run the real thing — full weights, no GPU, no cloud round-trip. That&rsquo;s not hype. That&rsquo;s what 176KB of C99 buys you.</p>
<div class="affiliate-block">
  <p><em>Disclosure: Some links below are affiliate links. If you sign up or purchase through them, I may earn a commission at no extra cost to you.</em></p>
  <ul>
    <li><a href="https://toolgenix.nxtniche.com/go/do" rel="nofollow sponsored noopener" target="_blank">DigitalOcean</a> — $200 free credit for new users. Their memory-optimized droplets scale into the RAM tier the server preset needs (128GB+).</li>
    <li><a href="https://toolgenix.nxtniche.com/go/vultr" rel="nofollow sponsored noopener" target="_blank">Vultr</a> — $100 trial credit. High-frequency and large-memory lines are a solid regional alternative to DO for the full-budget config.</li>
    <li><a href="https://toolgenix.nxtniche.com/go/hostinger" rel="nofollow sponsored noopener" target="_blank">Hostinger</a> — Budget VPS tier, the cheapest way onto the 8GB laptop path.</li>
  </ul>
</div>
]]></content:encoded>
    </item>
  </channel>
</rss>
