Pinned Tweet
Today we are releasing our speculative decoding implementation in our inference engine uzu.
Initially for Qwen3.6 27B, with support for Qwen3.8 27B and Muse Glimmer coming soon.
On Apple M5-series chips, we outperform MTPLX (MLX + speculative decoding) by almost 2x, and llama.cpp by over 3x at comparable quantization levels, with the strongest gains achieved on mathematical reasoning and coding tasks.
Run the model:
Mirai-M: trymirai.com/local-models/alโฆ
Mirai-L: trymirai.com/local-models/alโฆ
Explore the benchmarks:
trymirai.com/metrics
Learn more about our speculative decoding implementation:
trymirai.com/blog/speculativโฆ
Our draft model, quantized checkpoint format, verification algorithm, and GPU kernels are co-designed from the ground up around the latest Apple M5 chips to take maximum advantage of GPU Neural Accelerators.
Unlike popular speculative decoding architectures such as model-native MTP, which produce small draft chains of 3-4 tokens at a time, we use extremely aggressive speculative budgets of 16-32 tokens. This enables us to use Neural Accelerator-backed GEMM kernels, achieving maximum utilization of hardware arithmetic throughput.
Mirai Labs retweeted
Massive breakthrough in speculative decoding!
It made a 9B LLM on my MacBook 4x faster, and 2.6x faster than regular speculative decoding.
I ran Qwen3.5 9B on my M5 MacBook Pro with the same prompt, three ways:
- No speculative decoding: done in 42s
- Regular speculative decoding: done in 30s
- DFlash + Weaver: done in 11s
The video below shows all three side by side.
Here's why it works:
Speculative decoding lets a cheap drafter guess the next few tokens, and the main model checks them all in one pass.
The fastest drafters, like DFlash, guess every position in parallel. But each guess is made on its own, so position 5 never sees what was picked at position 4. One early mismatch and everything after it gets thrown away.
Weaver fixes this. It's a tiny adapter (one Transformer layer) on top of DFlash that:
โณ picks among DFlash's top candidates left to right, so each pick depends on the last
โณ grows a tree of likely continuations instead of a single chain
โณ lets the main model verify the whole tree in one pass
On my Mac, every pass of the model produced 7.5 tokens instead of 1.
On a B200 GPU, the paper reports 4x faster decoding across chat, math and code.
@TryMirai open-sourced the whole stack in their engine, uzu, built for Apple Silicon.
GitHub repo: github.com/trymirai/uzu
(don't forget to star it ๐)
Trying it takes two commands:
๐ฏ๐ฟ๐ฒ๐ ๐ถ๐ป๐๐๐ฎ๐น๐น ๐บ๐ถ๐ฟ๐ฎ๐ถ
๐บ๐ถ๐ฟ๐ฎ๐ถ --๐บ๐ผ๐ฑ๐ฒ๐น ๐๐ฟ๐๐บ๐ถ๐ฟ๐ฎ๐ถ/๐ค๐๐ฒ๐ป๐ฏ.๐ฑ-๐ต๐-๐ -๐บ "๐ช๐ฟ๐ถ๐๐ฒ ๐ฎ ๐ฝ๐๐๐ต๐ผ๐ป ๐ณ๐๐ป๐ฐ๐๐ถ๐ผ๐ป ๐๐ผ ๐บ๐ฒ๐ฟ๐ด๐ฒ ๐๐๐ผ ๐๐ผ๐ฟ๐๐ฒ๐ฑ ๐น๐ถ๐๐๐"
---
I wrote a full breakdown of why local inference is memory-bound and how uzu gets past it, with reproducible code. The article is quoted below.
In the replies, there's an illustration of standard vs. speculative vs. uzu decoding.
Mirai Labs retweeted
Big win for local LLM inference!
This new inference engine runs LLMs 4x faster than llama.cpp:
I ran Qwen3.5 9B on a base M5 MacBook Pro with three engines:
- llama.cpp: 22.0 tokens/s
- MLX: 25.1 tokens/s
- uzu: 92.1 tokens/s
The video below shows all three runs side by side.
The first two numbers don't mean llama.cpp or MLX are badly built. But both are sitting right under a hard limit of local decoding.
When an LLM generates text, every new token needs one full pass through the model, and that pass reads all of the model's weights from memory.
A base M5 reads memory at about 153 GB/s. A 4-bit 9B model weighs about 5.2 GB.
So at one token per pass, the ceiling is roughly 153 รท 5.2 โ 29 tokens/s, however fast the GPU computes.
uzu gets past that ceiling by producing several tokens per pass instead of one:
โณ A small drafter (DFlash) proposes candidates for the next 16 positions at once.
โณ A tiny adapter (Weaver, 56.7M params) picks among them left to right, so the guesses form coherent text, and keeps a few alternative branches as a tree.
โณ The 9B model checks the whole tree in a single pass and keeps the longest path it agrees with. The main model still decides every token that ends up in the output.
GitHub repo: github.com/trymirai/uzu
(don't forget to star it ๐)
In my run, each pass of the 9B model produced 7.5 tokens on average. Ordinary decoding produces exactly 1.
The weights and kernels are designed around this too. uzu ships its own 4-bit checkpoints, and on M5 chips it runs the verification step on the GPU's int8 matrix path.
uzu is an open-source inference engine by Mirai Labs, written in Rust with Metal kernels. It has Swift, Python, TypeScript and Rust bindings, so the same engine runs inside a Mac or iOS app.
I shared the GitHub repo above.
If you want to dive deeper, my co-founder wrote a detailed breakdown of why local inference is memory-bound and how uzu's speculative decoding gets past it.
Read it below.
Today we are publishing our research essay: the computer should know the way.
Read it: trymirai.com/blog/the-computโฆ
About intent, latency, and why the layer that turns what you want into actions belongs on your own Mac. We at Mirai Labs are working on Mac automation. A person expresses an intention, and the system works out how to carry it out. Many of the intentions that matter most never appear in a request log, because the designed route is too long to bother.
We believe the computer should understand the intention, use all the context it has, adapt on the fly, and never interrupt the work.
Mirai Labs retweeted
We have released a new version of uzu and run the latest benchmarks on Qwen-3.8 27B we are by far the fastest at decode, and our checkpoints match Unsloth quality frontier and significantly surpass MLX ones in terms of quality
github.com/trymirai/uzu
882 tok/s prefill on M5 Max for Qwen3.8-27B, with uzu.
Compared to Splash:
prefill: 1.83x faster
time to first token: 1.81x faster
generation: 1.05x faster
Measured on MT-Bench, MATH-500 and HumanEval.
Please note that the evals used (MT-Bench, MATH-500 and HumanEval) are not very representative of the normal agentic use. We show the numbers on those specific datasets for the sake of interpretability of the results. The performance on the long context multi-turn interaction will be different.
Mirai Labs retweeted
We may have cooked a 2-bit version of Qwen3.8 27B which *actually works*, is not deep fried to benchmaxx, and fits in 8.5GB
We have not yet finished evaluating it, and it'll take some time to properly ship it, but if someone wants to try and share feedback please dm me
Mirai Labs retweeted
Mirai Labs (@trymirai) compressed Qwen3.8-27B to 2.4 bits. I ported it to llama.cpp and now it runs on a 12 GB card with 128K context.
With q4 KV cache the 128K window takes 11.3 GB of VRAM, with q8 KV you get 74K in 11.1 GB. Decode is 40 tok/s, still 34-35 tok/s at 62K deep, and prefill around 1000 tok/s. I measured all of it on 1 RTX 3090 at 300 W, capped to what fits in 12 GB.
No requant anywhere. The GGUF carries Mirai's compressed codes bit for bit, and greedy output matches their own vLLM plugin.
Everything in the video was built by this same model as an agent in pi, 11 builds from 1 prompt each, a few needed a follow up and 1 is a blooper. That run was vLLM on my 3090s. Today the same weights run in llama.cpp.
Big thread, all links and recipes ๐
Our team loves to catch unique bugs
Our GPU whisperer @ychnzhn4 wrote a small blogpost about the most annoying bug I have ever seen, which was an absolute nightmare to catch
trymirai.com/blog/tackling-rโฆ
๐ฃ We've just published our latest research on state-of-the-art speculative decoding in interactivity.
Introducing a new approach that achieves a 4.37ร speedup over autoregressive decoding in small batch setting and outperforms the strongest tuned DFlash baseline by 24.7%.
arXiv: arxiv.org/abs/2607.06763
github: github.com/trymirai/sglang
huggingface: huggingface.co/trymirai/weavโฆ
Mirai Labs retweeted
We are releasing our first quantized checkpoints for the Qwen3.5 series of models, co-designed jointly with our inference engine to achieve maximum possible performance on Apple hardware
Starting from 0.8B, 2B and 4B models
trymirai.com/blog/quantizatiโฆ
Google DeepMind released Gemma 4.
Our engineer @norpadon analyzed the architecture
If you've implemented speculative decoding, you've run into this: your speculator predicts the distribution correctly and still gets rejected.
Letโs take an example:
"The random number from 1 to 10 inclusive is"
Ideal LLM: uniform 1/10 across all numbers.
Good speculator: same distribution.
In that situation, the naive scheme takes a random number from the speculator, then takes another random number from an LLM and can only accept the bonus token in 1/10 cases when they happen to match.
We should be able to always take its guess without the loss of generation quality.
The fix is straightforward.
Sample from both the speculator and the LLM using the same seed via the Gumbel-max trick.
Shared randomness means shared outcome when distributions match.
100% acceptance rate in this case. Near-optimal in practice.
We shipped this in github.com/trymirai/uzu
Full kernel implementation: trymirai.com/blog/how-to-impโฆ
Day 0 on-device support of the latest and the smallest @liquidai model
LFM 2.5 350M is now available on @trymirai
Replying to @liquidai
Day 0 support across the stack:
> Hardware: @AMD, @Intel, @Qualcomm
> On-device: @lmstudio , @Cactuscompute, @RunAnywhereAI , @zeticai_ , @trymirai
> Customization: @distil_labs


















