<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>1bit engine</title><link href="https://1bit.gg/"/><link rel="self" href="https://1bit.gg/feed.xml"/><id>https://1bit.gg/</id><updated>2026-09-24T00:00:00Z</updated><author><name>bong-water-water-bong</name></author><entry><title>1bit.MONSTER is now 1bit engine</title><link href="https://1bit.gg/blog-new-direction-from-1bit-monster.html"/><id>https://1bit.gg/blog-new-direction-from-1bit-monster.html</id><updated>2026-09-24T00:00:00Z</updated><summary>1bit.MONSTER grew fast: an inference engine, a model zoo, benchmarks, a store, a voice assistant and a lot of experiments, all in one repository with all of its history. The engine that came out of it is now its own project, 1bit engine, and this site is its home.</summary><category term="announcement"/><category term="engine"/><content type="html">&lt;p&gt;1bit.MONSTER grew fast: an inference engine, a model zoo, benchmarks, a store, a voice assistant and a lot of experiments, all in one repository with all of its history. The engine that came out of it is now its own project, &lt;strong&gt;1bit engine&lt;/strong&gt;, and this site is its home.&lt;/p&gt;
&lt;h2 id=&quot;what-changed&quot;&gt;What changed&lt;a class=&quot;anchor&quot; href=&quot;#what-changed&quot; title=&quot;Permanent link&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;A clean repository.&lt;/strong&gt; The engine lives in &lt;a href=&quot;https://github.com/1bit-MONSTER/engine&quot;&gt;1bit-MONSTER/engine&lt;/a&gt;. It holds verified code only, without the development history. Each piece is ported over once it passes its end-to-end test on Strix Halo, and the &lt;a href=&quot;PORTING.html&quot;&gt;porting map&lt;/a&gt; shows what has moved and what is next.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Apache-2.0.&lt;/strong&gt; The old repository was GPL-3.0. The engine is Apache-2.0, with a copyright and license notice on every file, enforced in CI, and every third-party project it builds on credited in its NOTICE.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Inside Lemonade, not around it.&lt;/strong&gt; The old engine vendored its own copy of Lemonade. Now &lt;a href=&quot;lemonade.html&quot;&gt;Lemonade&lt;/a&gt; is the server you talk to (its catalog, downloads, router and UI), and it runs the engine as one of its backends, through &lt;code&gt;1bit serve&lt;/code&gt;, the same way it runs &lt;code&gt;llama-server&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Upstream, pinned and kept current.&lt;/strong&gt; The XDNA driver and XRT, AMD&#x27;s HRX pair, llama.cpp for Vulkan, ZINC, the Linux kernel, Hugging Face tokenizers and the Laya router are each pinned to upstream, and the pins are bumped automatically, so new models and fixes arrive soon after upstream ships them.&lt;/p&gt;
&lt;h2 id=&quot;what-it-runs-on&quot;&gt;What it runs on&lt;a class=&quot;anchor&quot; href=&quot;#what-it-runs-on&quot; title=&quot;Permanent link&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;One &lt;code&gt;1bit serve&lt;/code&gt; drives:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the &lt;a href=&quot;npu.html&quot;&gt;XDNA 2 NPU&lt;/a&gt;, on full ELFs generated in C++;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;hrx.html&quot;&gt;HRX and Vulkan&lt;/a&gt; on the Radeon iGPU, one llama.cpp build with both;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;zinc.html&quot;&gt;ZINC&lt;/a&gt;, which also reaches NVIDIA GPUs through CUDA;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;apple.html&quot;&gt;MLX&lt;/a&gt; on Apple Silicon.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Measured numbers live on the &lt;a href=&quot;https://github.com/1bit-MONSTER/engine/wiki&quot;&gt;wiki&lt;/a&gt;. &lt;a href=&quot;blog-first-week-milestones.html&quot;&gt;The first week of 1bit engine&lt;/a&gt; lists what the first three days produced.&lt;/p&gt;
&lt;h2 id=&quot;the-old-site&quot;&gt;The old site&lt;a class=&quot;anchor&quot; href=&quot;#the-old-site&quot; title=&quot;Permanent link&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The 1bit.MONSTER site and its posts stay online in the &lt;a href=&quot;https://1bit-monster.github.io/1bit-MONSTER/&quot;&gt;1bit.MONSTER archive&lt;/a&gt;, and old links land on a page that points at their archived copy. The blog page here lists the old posts worth keeping. 1bit JARVIS, the voice assistant, is not part of the engine for now; it will come back later as its own piece.&lt;/p&gt;</content></entry><entry><title>Prefill on HRX, decode on Vulkan, one KV cache</title><link href="https://1bit.gg/blog-hrx-prefill-vulkan-decode.html"/><id>https://1bit.gg/blog-hrx-prefill-vulkan-decode.html</id><updated>2026-09-24T00:00:00Z</updated><summary>On Strix Halo&#x27;s Radeon iGPU, AMD&#x27;s HRX runtime prefills a prompt faster than Vulkan, and Vulkan decodes faster than HRX. 1bit serve --device vulkan --prefill-device hrx now uses both on the same request, and the key-value cache never gets copied between them.</summary><category term="hrx"/><category term="vulkan"/><category term="zero-copy"/><content type="html">&lt;p&gt;On Strix Halo&#x27;s Radeon iGPU, AMD&#x27;s HRX runtime prefills a prompt faster than Vulkan, and Vulkan decodes faster than HRX. &lt;code&gt;1bit serve --device vulkan --prefill-device hrx&lt;/code&gt; now uses both on the same request, and the key-value cache never gets copied between them.&lt;/p&gt;
&lt;h2 id=&quot;the-idea&quot;&gt;The idea&lt;a class=&quot;anchor&quot; href=&quot;#the-idea&quot; title=&quot;Permanent link&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A request has two phases. &lt;strong&gt;Prefill&lt;/strong&gt; reads the whole prompt at once and is compute-bound; &lt;strong&gt;decode&lt;/strong&gt; makes one token at a time and is bound by memory bandwidth. Our one llama.cpp build carries both GPU backends, &lt;code&gt;HRX0&lt;/code&gt; and &lt;code&gt;Vulkan0&lt;/code&gt;, so the engine loads the model on each, runs the prompt prefix on HRX, and hands the rest of the request to Vulkan.&lt;/p&gt;
&lt;p&gt;The hand-off is the hard part. Prefill&#x27;s output is the KV cache: every layer&#x27;s keys and values for every prompt token. Copying it from one backend to the other would cost the time the split saves.&lt;/p&gt;
&lt;h2 id=&quot;zero-copies&quot;&gt;Zero copies&lt;a class=&quot;anchor&quot; href=&quot;#zero-copies&quot; title=&quot;Permanent link&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;So both contexts use &lt;strong&gt;one&lt;/strong&gt; KV cache:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;HRX allocates it in its own device memory and exports it as a &lt;strong&gt;dma-buf&lt;/strong&gt; (through HSA).&lt;/li&gt;
&lt;li&gt;Vulkan imports the same memory with &lt;code&gt;VK_EXT_external_memory_dma_buf&lt;/code&gt; and reads it in place, at 110.6 GB/s against 113.2 GB/s for its own allocations.&lt;/li&gt;
&lt;li&gt;The only thing that moves between them is the cache&#x27;s bookkeeping: which cells hold which positions of which sequence.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We tried sharing host memory first. It worked, but it cost Vulkan half its decode speed; device memory through a dma-buf does not.&lt;/p&gt;
&lt;p&gt;Both sides compute the cache&#x27;s layout independently, so they must agree on it exactly: tensors on 4 KiB boundaries, split into chunks of at most 1 GiB (Vulkan reads garbage from a single buffer past about 4 GiB), and a hash of the layout checked on both sides. HRX&#x27;s prefill is fastest in whole batches, so only whole ubatches of the prompt go to HRX, and short prompts skip the split: below 1024 tokens (&lt;code&gt;--prefill-min-tokens&lt;/code&gt;) it does not pay.&lt;/p&gt;
&lt;h2 id=&quot;measured&quot;&gt;Measured&lt;a class=&quot;anchor&quot; href=&quot;#measured&quot; title=&quot;Permanent link&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;llama-server on Strix Halo, prefill and whole request:&lt;/p&gt;
&lt;div class=&quot;table&quot;&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Prompt&lt;/th&gt;
&lt;th&gt;Vulkan alone&lt;/th&gt;
&lt;th&gt;HRX prefill + Vulkan&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Qwen2.5-7B Q4_K_M&lt;/td&gt;
&lt;td&gt;2048&lt;/td&gt;
&lt;td&gt;1541 / 4314 ms&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1078&lt;/strong&gt; / 3890 ms (-10%)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qwen2.5-7B Q4_K_M&lt;/td&gt;
&lt;td&gt;8192&lt;/td&gt;
&lt;td&gt;7347 / 10376 ms&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;4646&lt;/strong&gt; / 7668 ms (&lt;strong&gt;-26%&lt;/strong&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qwen3-0.6B Q4_K_M&lt;/td&gt;
&lt;td&gt;8192&lt;/td&gt;
&lt;td&gt;1289 / 2267 ms&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1089&lt;/strong&gt; / 2032 ms (-10%)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;p&gt;Decoding on the shared cache runs within 3% of Vulkan with its own cache. The output is the same model: against Vulkan alone, teacher-forced over 64 tokens, the mean KL divergence is 0.0002-0.0006 nats and the top token agrees on 64-65 of 65 positions. For scale, Q4_K_M quantization itself is 0.063 against BF16.&lt;/p&gt;
&lt;h2 id=&quot;where-it-lives&quot;&gt;Where it lives&lt;a class=&quot;anchor&quot; href=&quot;#where-it-lives&quot; title=&quot;Permanent link&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The patches are in our llama.cpp fork, on top of AMD&#x27;s tested HRX commit, and are rebased onto every new AMD pair automatically: dma-buf export in ggml-hrx, dma-buf import in ggml-vulkan, the cache sharing in llama, and the prefill hand-off in llama-server. The weights are loaded twice, once per device, so it suits machines with memory to spare; Strix Halo&#x27;s unified memory is one. The details are in the &lt;a href=&quot;hrx.html&quot;&gt;HRX docs&lt;/a&gt;.&lt;/p&gt;</content></entry><entry><title>The first week of 1bit engine</title><link href="https://1bit.gg/blog-first-week-milestones.html"/><id>https://1bit.gg/blog-first-week-milestones.html</id><updated>2026-09-24T00:00:00Z</updated><summary>The clean repository started on 2026-09-22. In its first three days, the engine came up on every device it targets, inside Lemonade, with each step verified on real hardware before it merged. These are the milestones, with the numbers and where they come from.</summary><category term="milestones"/><category term="npu"/><category term="hrx"/><category term="vulkan"/><category term="zinc"/><content type="html">&lt;p&gt;The clean repository started on 2026-09-22. In its first three days, the engine came up on every device it targets, inside Lemonade, with each step verified on real hardware before it merged. These are the milestones, with the numbers and where they come from.&lt;/p&gt;
&lt;h2 id=&quot;the-npu-on-full-elfs-generated-in-c&quot;&gt;The NPU, on full ELFs generated in C++&lt;a class=&quot;anchor&quot; href=&quot;#the-npu-on-full-elfs-generated-in-c&quot; title=&quot;Permanent link&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The XDNA 2 NPU now runs without an xclbin and without per-context kernel files. The engine generates each kernel&#x27;s full ELF (the design plus its control code) in C++ when the model loads, and XRT opens it directly; for each token, the host submits every layer and the lm head as one runlist (&lt;a href=&quot;https://github.com/1bit-MONSTER/engine/pull/8&quot;&gt;#8&lt;/a&gt;, &lt;a href=&quot;https://github.com/1bit-MONSTER/engine/pull/9&quot;&gt;#9&lt;/a&gt;).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Qwen3-0.6B decodes at &lt;strong&gt;91 tok/s&lt;/strong&gt; (11.0 ms per token), and &lt;strong&gt;87 tok/s&lt;/strong&gt; served through Lemonade.&lt;/li&gt;
&lt;li&gt;The XDNA driver and its XRT are pinned to upstream and built privately (&lt;a href=&quot;https://github.com/1bit-MONSTER/engine/pull/12&quot;&gt;#12&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;The layer kernel itself is being rebuilt from scratch as our own open kernel (&quot;dx&quot;, on IRON and Peano). RMSNorm, RoPE and attention pass their tests so far, correctly rounded to bf16.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;hrx-and-vulkan-in-one-build-then-both-at-once&quot;&gt;HRX and Vulkan in one build, then both at once&lt;a class=&quot;anchor&quot; href=&quot;#hrx-and-vulkan-in-one-build-then-both-at-once&quot; title=&quot;Permanent link&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The Radeon iGPU has two devices in one llama.cpp build: &lt;code&gt;HRX0&lt;/code&gt; on AMD&#x27;s HRX runtime and &lt;code&gt;Vulkan0&lt;/code&gt;. HRX follows AMD&#x27;s live ggml-hrx, pinned to the pair AMD tests and bumped daily (&lt;a href=&quot;https://github.com/1bit-MONSTER/engine/pull/11&quot;&gt;#11&lt;/a&gt;); Vulkan has its own pin on upstream llama.cpp&#x27;s latest release (&lt;a href=&quot;https://github.com/1bit-MONSTER/engine/pull/28&quot;&gt;#28&lt;/a&gt;).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;HRX went from 3-5x slower than Vulkan to close behind it.&lt;/strong&gt; Its prefill is now 1.3-1.7x Vulkan&#x27;s, and its decode within 10% on 4-bit files.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Our patches make HRX correct on more models&lt;/strong&gt; (&lt;a href=&quot;https://github.com/1bit-MONSTER/engine/pull/29&quot;&gt;#29&lt;/a&gt;): an IQ3_XXS kernel, and op claims that only take the nodes HRX can actually run. &lt;code&gt;test-backend-ops&lt;/code&gt; on HRX0 went from about 1150 failures to &lt;strong&gt;791 passing, 0 failing&lt;/strong&gt;, and Unsloth&#x27;s sub-4-bit files, which failed on HRX, now come within 1% of Vulkan&#x27;s perplexity.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Prefill on HRX, decode on Vulkan, with zero copies&lt;/strong&gt; (&lt;a href=&quot;https://github.com/1bit-MONSTER/engine/pull/30&quot;&gt;#30&lt;/a&gt;): a whole 8192-token request on Qwen2.5-7B finishes &lt;strong&gt;26% sooner&lt;/strong&gt;. &lt;a href=&quot;blog-hrx-prefill-vulkan-decode.html&quot;&gt;How it works&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;beyond-amd&quot;&gt;Beyond AMD&lt;a class=&quot;anchor&quot; href=&quot;#beyond-amd&quot; title=&quot;Permanent link&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;NVIDIA, through ZINC&#x27;s CUDA backend&lt;/strong&gt; (&lt;a href=&quot;https://github.com/1bit-MONSTER/engine/pull/14&quot;&gt;#14&lt;/a&gt;): Qwen3.5-9B at &lt;strong&gt;167-173 tok/s&lt;/strong&gt; on an RTX 5090, and 295 tok/s through ZINC&#x27;s Vulkan backend on Strix Halo.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Apple Silicon&lt;/strong&gt;, through Lemonade&#x27;s &lt;code&gt;mlx&lt;/code&gt; recipe and lemon-mlx-engine, verified on an M4 (&lt;a href=&quot;https://github.com/1bit-MONSTER/engine/pull/10&quot;&gt;#10&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;underneath&quot;&gt;Underneath&lt;a class=&quot;anchor&quot; href=&quot;#underneath&quot; title=&quot;Permanent link&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Tokenizers:&lt;/strong&gt; Hugging Face &lt;code&gt;tokenizers&lt;/code&gt; v0.23.2 behind our C ABI reads any model&#x27;s &lt;code&gt;tokenizer.json&lt;/code&gt;, byte-exact on 18 models (&lt;a href=&quot;https://github.com/1bit-MONSTER/engine/pull/19&quot;&gt;#19&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Quantization:&lt;/strong&gt; on the GPU, Unsloth&#x27;s Dynamic UD-Q4_K_XL beats Q4_K_M: 17% lower KL divergence for 2% more size. On the NPU, a ternary model converts to 4-bit exactly, and XDNA 2 multiplies int8 by int4 natively (&lt;a href=&quot;https://github.com/1bit-MONSTER/engine/wiki/Quantization&quot;&gt;wiki&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Linux kernel&lt;/strong&gt; is pinned to upstream v7.3-rc4 with &lt;code&gt;amdxdna&lt;/code&gt; in-tree (&lt;a href=&quot;https://github.com/1bit-MONSTER/engine/pull/17&quot;&gt;#17&lt;/a&gt;), and the &lt;strong&gt;Laya router&lt;/strong&gt;&#x27;s source and checkpoints are pinned and hash-verified (&lt;a href=&quot;https://github.com/1bit-MONSTER/engine/pull/18&quot;&gt;#18&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;next&quot;&gt;Next&lt;a class=&quot;anchor&quot; href=&quot;#next&quot; title=&quot;Permanent link&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Step 4 is the Laya router, which decides where each request runs. After it: every Hugging Face architecture, kept current by a daily census. The &lt;a href=&quot;PORTING.html&quot;&gt;porting map&lt;/a&gt; tracks it, and the &lt;a href=&quot;https://github.com/1bit-MONSTER/engine/wiki&quot;&gt;wiki&lt;/a&gt; keeps every measured number with how it was taken.&lt;/p&gt;</content></entry></feed>
