Pure Rust Sub-2-Bit LLM Inference Engine for PrismML Bonsai Models
OxiBonsai is a zero-FFI, zero-C/C++ inference engine for PrismML's sub-2-bit Bonsai family — both the 1-bit line (Q1_0_g128) and the ternary line (TQ2_0_g128). It runs on CPU (SIMD), Apple Silicon (Metal), and NVIDIA (CUDA) without depending on llama.cpp, BLAS, or any C/Fortran runtime. Built entirely on the COOLJAPAN ecosystem — SciRS2, OxiBLAS, OxiFFT — it delivers sovereign AI inference in Pure Rust.
To our knowledge, OxiBonsai is the first pure-Rust — C/C++/Fortran-free, zero-FFI — inference engine for the Bonsai 1-bit/ternary model family, and the first to bring its FLUX.2-Klein text-to-image (Bonsai-Image) to pure Rust, built entirely on the COOLJAPAN ecosystem.
oxibonsai and oxibonsai-serve subcommand, flag, and environment variable.Version 0.2.2 — 2026-06-08 · 4,671 tests passing · ~177k lines of Rust · Pure Rust
| Crate | Status | Tests |
|---|---|---|
| oxibonsai-core | Stable | 207 |
| oxibonsai-kernels | Stable | 675 |
| oxibonsai-model | Stable | 673 |
| oxibonsai-runtime | Stable | 796 |
| oxibonsai-tokenizer | Stable | 206 |
| oxibonsai-rag | Stable | 871 |
| oxibonsai-eval | Stable | 513 |
| oxibonsai-serve | Stable | 260 |
| oxibonsai-image | Stable | 72 |
| oxibonsai (facade) | Stable | 352 |
Two native quantization families, each with dedicated dequant / GEMV / full-forward kernels:
| Family | Encoding | Bits/weight | Block size | Example models |
|---|---|---|---|---|
| 1-bit | Q1_0_g128 | 1.0 | 128 weights, FP16 group scale | Bonsai-8B |
| Ternary | TQ2_0_g128 | ≈1.585 | 128 weights / 34 B, FP16 scale | Ternary-Bonsai-8B / 4B / 1.7B |
{-1, 0, +1} ternary encoding: 0b00→−1, 0b01→0, 0b10→+1, 0b11→0--temperature 0 --seed 42, CPU and Metal produce byte-identical output| Tier | Target | Width / Device | Feature Flag |
|---|---|---|---|
| Reference | All platforms | Scalar | (default) |
| AVX2 + FMA | x86-64 | 256-bit | simd-avx2 |
| AVX-512 | x86-64 | 512-bit | simd-avx512 |
| NEON | AArch64 | 128-bit | simd-neon |
| Metal | Apple Silicon | GPU, fused full-forward | metal |
| CUDA (native) | NVIDIA GPU | GPU, NVRTC kernels | native-cuda |
| CUDA (scirs2) | NVIDIA GPU | GPU via scirs2-core | cuda |
Auto-detection via KernelDispatcher::auto_detect() selects the best CPU tier at runtime. GPU backends are opt-in at build time.
Note on CPU tiers: The CPU tier is chosen entirely at runtime via
is_x86_feature_detected!— the dispatcher picks AVX-512 only when AVX-512F+BW+VL are all present, otherwise AVX2+FMA, otherwise the scalar reference path. Each SIMD function carries a per-function#[target_feature(...)]attribute, so a single x86-64 binary is safe on every x86-64 CPU and automatically falls back (AVX-512 → AVX-2 → scalar) with no SIGILL. Thesimd-avx2/simd-avx512/simd-neonFeature Flags above are accepted for compatibility but do not gate tier selection — all tiers are always compiled in and chosen at runtime.AVX-512 has been absent from Intel consumer CPUs since Alder Lake (Raptor Lake, Meteor Lake, Arrow Lake and Lunar Lake have none); it mainly benefits Xeon / HEDT and AMD Zen 4+. On consumer hardware the AVX-2 tier is selected automatically.
There is currently no INT8 dot-product tier (AVX-VNNI
vpdpbusd/ NEON-UDOTvdotq_s32): the 1-bit and ternary kernels expand weights to ±scale and accumulate in FP32 FMA. An INT8 dot-product tier — which would require quantizing activations to INT8 — is a possible future enhancement.
Both the 1-bit and ternary forward passes are encoded into a single GPU command buffer rather than one submission per GEMV. Per-layer dispatch sequence:
= 14 dispatches/layer × N layers per command buffer. This is what unlocks the Metal and CUDA throughput numbers below.
tracing with env-filter and JSON output/health) with readiness checksRequestId (RFC 4122 UUIDv4, no uuid crate dependency)RequestRateTracker — TBT p50/p95, EWMA tokens/sec, queue-waitRequestRateAggregator rolls per-request snapshots into oxibonsai_request_tokens_per_second, oxibonsai_inter_token_latency_p50/p95_seconds, and oxibonsai_queue_wait_seconds Prometheus gaugesTwo adaptive controllers shipped in 0.1.4 let the runtime self-tune as the workload changes:
use oxibonsai_runtime::{KvCachePolicy, AdaptiveLookahead, AdaptiveLookaheadConfig};
// KV cache policy: FP16 ↔ Q8 ↔ Q4 driven by EWMA pressure with hysteresis.
let kv = KvCachePolicy::default();
let level = kv.observe(0.92); // → escalates to Q8 once smoothed pressure crosses 0.80
// Speculative-decoding draft length: continuously updated from acceptance EWMA.
let mut k = AdaptiveLookahead::new(AdaptiveLookaheadConfig::default());
k.observe_step(5, 4); // proposed=5, accepted=4 → k drifts toward 5
A worked end-to-end example lives in examples/runtime_controllers.rs:
cargo run --example runtime_controllers
/v1/chat/completions endpoint (POST)/v1/models endpointuse oxibonsai_runtime::{EngineBuilder, SamplingPreset};
let engine = EngineBuilder::new()
.model_path("models/Ternary-Bonsai-1.7B.gguf")
.preset(SamplingPreset::Balanced)
.max_seq_len(4096)
.build()?;
| Preset | Temperature | Top-K | Top-P | Use Case |
|---|---|---|---|---|
| Greedy | 0.0 | 1 | 1.0 | Deterministic |
| Balanced | 0.7 | 40 | 0.9 | General |
| Creative | 1.0 | 100 | 0.95 | Creative writing |
| Code | 0.2 | 10 | 0.8 | Code generation |
OxiBonsai supports PrismML's full Bonsai lineup across both quantization families:
| Model | Arch | Params | Format | Size | Context |
|---|---|---|---|---|---|
| Bonsai-8B | Qwen3-8B | 8.19 B | Q1_0_g128 | 1.15 GB | 65,536 |
| Ternary-Bonsai-8B | Qwen3-8B | 8.19 B | TQ2_0_g128 | ~1.75 GB | 65,536 |
| Ternary-Bonsai-4B | Qwen3-4B | ~4 B | TQ2_0_g128 | ~900 MB | 65,536 |
| Ternary-Bonsai-1.7B | Qwen3-1.7B | ~1.7 B | TQ2_0_g128 | ~390 MB | 65,536 |
Ternary weights trade roughly +600 MB (at 8B scale) for ~5 additional benchmark points over the 1-bit line. All models share the same Qwen3 architecture (GQA, SwiGLU, RoPE, RMSNorm), so the runtime, tokenizer, and server are identical across the family.
Note: PrismML publishes Ternary Bonsai as unpacked safetensors. Use
scripts/download_ternary.sh(oroxibonsai convert --quant tq2_0_g128) to fetch and repack as GGUF before loading. Anonnx-communityONNX release (MatMulNBits bits=2) is also supported viaoxibonsai convert --onnx.
cargo install oxibonsai-cli
This installs the oxibonsai binary. Rust 1.86+ required.
[dependencies]
oxibonsai = "0.2.2"
git clone https://github.com/cool-japan/oxibonsai
cd oxibonsai
cargo build --release
# binary at: target/release/oxibonsai
.env)The CLI auto-loads a .env file from the current directory (or any parent), so you can
omit the model/path flags. Precedence: --flag > shell env var > .env > built-in default.
# Fetch the template from GitHub …
curl -fsSL https://raw.githubusercontent.com/cool-japan/oxibonsai/master/.env.example -o .env
# … or, in a source checkout: cp .env.example .env
# Edit .env to point at your model files
$EDITOR .env
Keys:
| Key | Used by | Purpose |
|---|---|---|
OXI_MODEL |
run / chat / serve / info |
GGUF model path (omit --model) |
OXI_TOKENIZER |
run / chat / serve |
tokenizer.json/dir (optional) |
OXI_DIT_GGUF |
image |
FLUX.2 Klein ternary DiT GGUF |
OXI_VAE_WEIGHTS |
image |
VAE decoder weights dir |
OXI_TE_4BIT |
image |
2.1 GB 4-bit MLX text-encoder model.safetensors |
OXI_TE_TOKENIZER_DIR |
image |
text-encoder tokenizer dir |
OXI_DIT_ATTN_GPU |
image / repl |
Enable Metal/CUDA DiT flash-attention (default: on for Metal) |
OXI_VAE_GPU |
image / repl |
Enable Metal/CUDA VAE decode (default: on for Metal) |
OXI_TE_GPU |
image / repl |
Enable GPU text-encoder (experimental; default off) |
With .env in place, the flags become optional:
oxibonsai run --prompt "Explain ternary quantization in one sentence."
oxibonsai image --prompt "a tiny bonsai tree in a ceramic pot" --out bonsai.png
If you installed via
cargo install oxibonsai-cli, start from Step 2. Theoxibonsaibinary is already on your PATH.
cargo build --release
export PATH="$PWD/target/release:$PATH"
Pick one of the two families (or grab both):
# ── Option A: 1-bit Bonsai-8B (1.16 GB pre-quantized GGUF — single curl) ─
mkdir -p models
curl -L -o models/Bonsai-8B.gguf \
https://huggingface.co/prism-ml/Bonsai-8B-gguf/resolve/main/Bonsai-8B.gguf
# ── Option B: Ternary Bonsai (download safetensors + convert to GGUF) ────
# Fetches unpacked safetensors from HF and runs `oxibonsai convert`
# to produce models/Ternary-Bonsai-<size>.gguf + models/tokenizer.json.
./scripts/download_ternary.sh 1.7b # also: 4b | 8b
Ternary prerequisite:
scripts/download_ternary.shuses the HuggingFacehfCLI — install withpip install huggingface_hub.
A tokenizer is required for all inference commands.
Option B above already downloads it automatically.
For Option A (or cargo install users):
oxibonsai tokenizer download # saves to models/tokenizer.json
The tokenizer is pulled from Qwen/Qwen3-8B on HuggingFace (~2.7 MB).
Use --output to save elsewhere, --repo to use a different HF repo.
Tip: set
OXI_MODEL(and optionallyOXI_TOKENIZER) in.env(see Configuration) to omit--model.
# 1-bit Bonsai-8B
oxibonsai run --model models/Bonsai-8B.gguf \
--prompt "Explain quantum computing in simple terms" \
--max-tokens 512 --temperature 0.7 --top-p 0.9
# Ternary Bonsai (same CLI, different file)
oxibonsai run --model models/Ternary-Bonsai-1.7B.gguf \
--prompt "Explain quantum computing in simple terms" \
--max-tokens 512 --temperature 0.7 --top-p 0.9
# Interactive chat, model info, server — all model-agnostic:
oxibonsai chat --model models/Bonsai-8B.gguf
oxibonsai info --model models/Ternary-Bonsai-1.7B.gguf
oxibonsai serve --model models/Ternary-Bonsai-1.7B.gguf \
--host 127.0.0.1 --port 8080
# Interactive image REPL — loads DiT/VAE/TE once, renders many prompts
oxibonsai repl --seed 42 --steps 4 --width 512 --height 512
# Convert safetensors → GGUF (HuggingFace unpacked safetensors dir)
oxibonsai convert \
--from <unpacked-safetensors-dir> \
--to models/my-model.gguf \
--quant tq2_0_g128 # or q1_0_g128
# Convert ONNX → GGUF (MatMulNBits bits=2, e.g. onnx-community/Ternary-Bonsai-1.7B-ONNX)
oxibonsai convert --onnx \
--from path/to/model.onnx \
--to models/my-model.gguf
Two parallel smoke tests — one per quantization family — plus a throughput benchmark and the ternary downloader.
| Script | Target model | Prerequisite | Purpose |
|---|---|---|---|
scripts/cli.sh [metal\|cuda] |
models/Bonsai-8B.gguf |
curl one-liner in Quick Start | Build + end-to-end CLI test on 1-bit Bonsai-8B |
scripts/cli_ternary.sh [metal\|cuda\|cuda-scirs] |
models/Ternary-Bonsai-1.7B.gguf (default; --model to override) |
run scripts/download_ternary.sh first |
Build + end-to-end CLI test on Ternary Bonsai with a tok/s summary line |
scripts/bench_ternary.sh |
models/Ternary-Bonsai-1.7B.gguf |
scripts/download_ternary.sh |
CPU vs Metal throughput benchmark (averaged over N runs) |
scripts/download_ternary.sh [8b\|4b\|1.7b] |
— | pip install huggingface_hub |
Download Ternary Bonsai safetensors from HF and convert to GGUF |
Each CLI script:
1. Builds a --release binary with the requested featu
$ claude mcp add oxibonsai \
-- python -m otcore.mcp_server <graph>