oxibonsai
Library Listed
Pure Rust 1-bit LLM inference engine for PrismML Bonsai models — umbrella crate
- Downloads
- 1
- Dependents
- 0
- Stars
- 137
- Forks
- 21
- Contributors
- 1
- Commits
- 10
- Latest release
- 0.2.3 ·
About
(オキシ盆栽)
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.
Read the full README
Documentation
- CLI reference — every
oxibonsaiandoxibonsai-servesubcommand, flag, and environment variable. - Deployment guide — which binary to run in production, reverse-proxy/TLS setup, bearer auth, admission limits, and Prometheus scraping.
- Image-generation guide — end-to-end Bonsai-Image (FLUX.2-Klein) text-to-image walkthrough.
- Known Limitations — honest current-reality notes on GPU-tier coverage, standalone (not-yet-wired) building blocks, and a mitigated CUDA/FP8 batch-prefill note (disabled-by-default, no correctness impact).
Status
Version 0.2.3 — 2026-07-21 · 5,158 tests passing · ~197k lines of Rust · Pure Rust
| Crate | Status | Tests |
|---|---|---|
| oxibonsai-core | Stable | 465 |
| oxibonsai-kernels | Stable | 508 |
| oxibonsai-model | Stable | 1,209 |
| oxibonsai-runtime | Stable | 1,667 |
| oxibonsai-tokenizer | Stable | 375 |
| oxibonsai-rag | Stable | 212 |
| oxibonsai-eval | Stable | 274 |
| oxibonsai-serve | Stable | 178 |
| oxibonsai-image | Stable | 86 |
| oxibonsai (facade) | Stable | 1 |
| oxibonsai-cli | Stable | 183 |
Features
Sub-2-Bit Native Inference
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 |
- Full Qwen3 architecture: multi-layer decoder, GQA, SwiGLU, RoPE, RMSNorm
{-1, 0, +1}ternary encoding:0b00→−1, 0b01→0, 0b10→+1, 0b11→0- Correctness gate: at
--temperature 0 --seed 42, CPU and Metal produce byte-identical output
Acceleration Tiers
| 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 | CPU SIMD fallback † | cuda |
† The
cuda(scirs2-core) tier currently runs on CPU, not GPU. scirs2-core retired its cudarc-based CUDA backend in 0.6.x, sois_accelerated()always returnsfalsefor this tier and the dispatcher transparently falls back to CPU SIMD — output is correct, just not GPU-accelerated. Usenative-cudafor real NVIDIA GPU acceleration. See Known Limitations.
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.
Fused GPU Full-Forward Path
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:
- Pre-attn RMSNorm
- Fused QKV GEMV (Q ‖ K ‖ V concatenated in weight SoA)
- Fused QK-norm + RoPE
- Fused KV-store
- Batched attention: scores V2 → softmax → weighted-sum
- Attn output GEMV + residual add
- FFN RMSNorm
- Gate + Up GEMV (gate ‖ up concatenated)
- Batched SwiGLU
- Down GEMV + residual add
= 14 dispatches/layer × N layers per command buffer. This is what unlocks the Metal and CUDA throughput numbers below.
Observability
- Structured logging via
tracingwith env-filter and JSON output - Inference metrics: tokens/sec, prefill/decode latency, request counts
- Health endpoint (
/health) with readiness checks - Circuit breaker for overload protection
- Per-request tracing IDs via
RequestId(RFC 4122 UUIDv4, nouuidcrate dependency) - Per-request rate metrics via
RequestRateTracker— TBT p50/p95, EWMA tokens/sec, queue-wait - Workload aggregator —
RequestRateAggregatorrolls per-request snapshots intooxibonsai_request_tokens_per_second,oxibonsai_inter_token_latency_p50/p95_seconds, andoxibonsai_queue_wait_secondsPrometheus gauges
Runtime Controllers (0.1.4)
Two 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: computes a target FP16 / Q8 / Q4 level from EWMA pressure
// with hysteresis. NOTE: this is advisory/telemetry only today — `observe()`
// drives the `/admin/*` JSON endpoint and a Prometheus gauge, it does not
// itself change the model's actual KV-cache storage precision (see
// "Known Limitations").
let kv = KvCachePolicy::default();
let level = kv.observe(0.92); // → target 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
OpenAI-Compatible API
/v1/chat/completionsendpoint (POST)- Streaming SSE support for real-time token output
/v1/modelsendpoint- CORS and tower middleware
Builder Pattern API
use oxibonsai_runtime::{EngineBuilder, SamplingPreset};
let engine = EngineBuilder::new()
.model_path("models/Ternary-Bonsai-1.7B.gguf")
.preset(SamplingPreset::Balanced)
.max_seq_len(4096)
.build()?;
Sampling Presets
| 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 |
Bonsai Model Family
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.
Installation
CLI (recommended for end users)
cargo install oxibonsai-cli
This installs the oxibonsai binary. Rust 1.86+ required.
Library (for Rust projects)
[dependencies]
oxibonsai = "0.2.3"
Build from source (for development)
git clone https://github.com/cool-japan/oxibonsai
cd oxibonsai
cargo build --release
# binary at: target/release/oxibonsai
Configuration (.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
Quick Start
If you installed via
cargo install oxibonsai-cli, start from Step 2. Theoxibonsaibinary is already on your PATH.
Step 1 — (source builds only) Build
cargo build --release
export PATH="$PWD/target/release:$PATH"
Step 2 — Get a model
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.
Step 3 — Get the tokenizer
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.
Step 4 — Run inference
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
CLI Smoke & Benchmark Scripts
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:
- Builds a
--releasebinary with the requested feature flags - Runs inference (
oxibonsai run) - Prints model info (
oxibonsai info) and validates the GGUF (oxibonsai validate) - Reports the measured tok/s
# 1-bit flow (Bonsai-8B)
./scripts/cli.sh # CPU SIMD
./scripts/cli.sh metal # Metal GPU (macOS)
./scripts/cli.sh cuda # CUDA GPU (Linux/Windows)
# Ternary flow — fetch + convert once, then run as many times as you like
./scripts/download_ternary.sh 1.7b
./scripts/cli_ternary.sh # CPU SIMD
./scripts/cli_ternary.sh metal # Metal GPU — fused TQ2 full-forward path
./scripts/cli_ternary.sh cuda # native CUDA backend
./scripts/bench_ternary.sh # CPU vs Metal, 3-run average + best
Measured Throughput
End-to-end decode, averaged over 3 runs. "fused full-forward" = single GPU command buffer per token.
| Model | Backend | Hardware | tok/s |
|---|---|---|---|
| Ternary-Bonsai-1.7B | Metal (fused TQ2) | Apple Silicon (M-series) | ~50 (best ~57) |
| Ternary-Bonsai-1.7B | CUDA (fused TQ2) | NVIDIA GPU | ~21.9 |
| Ternary-Bonsai-1.7B | CPU SIMD (NEON) | Apple Silicon | ~7–8 |
| Bonsai-8B | Metal (fused Q1) | Apple Silicon (M-series) | ~14.6 |
Numbers come from scripts/bench_ternary.sh / scripts/cli_ternary.sh. CPU baseline varies with thermal and background load; GPU numbers are the steady-state figures.
Configuration
OxiBonsai supports TOML configuration files with --config:
[model]
path = "models/Ternary-Bonsai-1.7B.gguf"
max_seq_len = 4096
[sampling]
temperature = 0.7
top_k = 40
top_p = 0.9
repetition_penalty = 1.1
[server]
host = "127.0.0.1"
port = 8080
[observability]
log_level = "info"
json_logs = false
Crate Structure
oxibonsai/
├── crates/
│ ├── oxibonsai-core/ GGUF loader, tensor types, config, error types
│ ├── oxibonsai-kernels/ Q1 + TQ2 kernels (dequant, GEMV, GEMM, SIMD tiers,
│ │ tiled, parallel) + GPU backends:
│ │ gpu_backend/metal_* (Metal graph + fused
│ │ full-forward, Q1 & TQ2)
│ │ gpu_backend/cuda_* (native NVRTC kernels)
│ │ gpu_backend/scirs2_backend (scirs2-core CUDA/Metal)
│ ├── oxibonsai-tokenizer/ Pure Rust BPE tokenizer, vocabulary, ChatTemplate
│ ├── oxibonsai-model/ Qwen3 Transformer (GQA, SwiGLU, RoPE, RMSNorm,
│ │ paged KV-cache, Q1 + TQ2 weight loaders)
│ ├── oxibonsai-rag/ RAG pipeline (chunking, embedders, vector store)
│ ├── oxibonsai-runtime/ Inference engine, sampling, OpenAI-compatible server,
│ │ SSE streaming, metrics, health, circuit breaker
│ ├── oxibonsai-eval/ Evaluation harness (ROUGE, perplexity, MMLU)
│ └── oxibonsai-serve/ Standalone server binary
├── src/main.rs CLI entry point (run, chat, serve, info, benchmark,
│ convert, quantize, validate, image, repl)
├── src/cli/
│ ├── repl.rs `oxibonsai repl` — resident `ImageSession` (loads
│ │ DiT/VAE/TE once, renders many prompts); Kitty
│ │ graphics protocol inline display (Ghostty detection)
│ └── term.rs Terminal detection helpers (Ghostty / Kitty protocol)
├── benches/ Criterion kernel benchmarks
├── examples/ Usage examples
├── tests/ Integration + feature flag tests
└── scripts/ Publish, CLI smoke tests, ternary benchmarks
Examples
See the examples/ directory:
basic_inference.rs— Load a model and run single-shot inferencestreaming.rs— Server-sent event streamingcustom_sampling.rs— Custom sampling parameters and presets
# 1-bit
cargo run --example basic_inference -- --model models/Bonsai-8B.gguf
# Ternary
cargo run --example basic_inference -- --model models/Ternary-Bonsai-1.7B.gguf
COOLJAPAN Ecosystem
OxiBonsai (Pure Rust sub-2-bit LLM inference — Q1 + TQ2, CPU + Metal + CUDA)
├── SciRS2 v0.4.x (tensor primitives, activation functions)
├── OxiBLAS v0.2.x (GEMM/GEMV + 1-bit/ternary compute kernels)
├── OxiFFT v0.2.x (optional RoPE acceleration)
└── NumRS2 v0.3.x (N-dimensional array backend)
All default-feature dependencies are Pure Rust — zero C/C++/Fortran, zero FFI. GPU backends (metal, native-cuda, cuda) are opt-in features that bring in vendor drivers.
Development Roadmap
| Phase | Description | Status |
|---|---|---|
| Phase 0 | Foundation (workspace, GGUF loader, metadata) | ✅ |
| Phase 1 | 1-Bit Kernels (dequant, GEMV, GEMM) | ✅ |
| Phase 2 | Transformer Engine (Qwen3-8B forward pass) | ✅ |
| Phase 3 | Inference Runtime (KV cache, sampling, CLI) | ✅ |
| Phase 4 | Production Hardening (SIMD, parallel, tests, observability) | ✅ |
| Phase 5 | Ecosystem Integration (SSE streaming, WASM, API, Bonsai family) | ✅ |
| Phase 6 | Advanced Infrastructure (Multi-GPU, CUDA/Metal, PagedAttention) | ✅ * |
| Phase 7 | Production Features (model merging, flash decoding, RAG, eval) | ✅ |
| Phase 8 | Final Polish (K-quant, streaming GGUF, kernel tuning, tests) | ✅ |
| Phase 9 | Ternary Bonsai (TQ2_0_g128 kernels, model variants, GGUF surface, export) | ✅ |
| Phase 10 | Ternary CPU SIMD tiers (AVX2 / AVX-512 / NEON TQ2 GEMV) | ✅ |
| Phase 11 | Metal TQ2 GEMV + per-kernel dispatch | ✅ |
| Phase 12 | Native CUDA backend (NVRTC, fused Q1 + TQ2 full-forward) | ✅ |
| Phase 13.x | Fused Metal TQ2 full-forward (single command buffer, ~13× speedup on 1.7B) | ✅ |
| Phase 13.y | Ternary LM head on GPU — closes all 7 OutputWeight::Ternary guard sites (4 Metal + 3 CUDA); +5 tok/s on Metal | ✅ |
* Phase 6 items marked complete are implemented and tested, but several are standalone building blocks not yet wired into the default inference path, or are honestly-labeled simulations rather than the literal capability their name suggests — see Known Limitations immediately below for the itemized, current-reality breakdown.
Known Limitations
Everything below is implemented, tested, and either self-documented in its own module doc comments or tracked in TODO.md's Production-Release Audit section — nothing here is a secret, but several roadmap/README lines elsewhere in this document are easy to over-read as "fully wired into inference." This section is the honest, consolidated version.
Acceleration & scaling
cuda(scirs2-core) tier is a CPU fallback, not GPU acceleration.is_accelerated()always returnsfalsefor CUDA because scirs2-core retired its cudarc-based backend in 0.6.x; the dispatcher silently falls back to CPU SIMD. Output is correct — there is no garbage-token risk — it is simply not GPU-accelerated. Usenative-cudafor real NVIDIA GPU throughput.- "True multi-GPU inference" is a rayon CPU simulation of NCCL-style collectives, not real inter-GPU communication.
multi_gpu.rs's own doc comment says as much ("a real GPU backend would swap in NCCL/cuBLAS calls").DeviceMesh/multi_gpu.rsis not wired into any actual multi-device dispatch path. - "Distributed serving" is an in-memory routing topology, not a networked serving layer.
distributed.rsimplements consistent-hash-ring request routing and a node registry entirely in-process; its own doc comment states "no actual TCP connections are made." There is no cross-node request forwarding anywhere in this codebase.
GPU platform coverage
- Metal now has full Q4_0/Q8_0/K-quant (Q2_K–Q8_K) and FP8 batch-prefill coverage (closed 2026-07-21). Two gaps that shipped as documented limitations through 0.2.3's first hardening pass are now resolved: (1) Metal GEMV kernels + host dispatch exist for all 8 standard/K-quant formats, and the corresponding model-layer
Linear*::forward()implementations now try Metal first (mirroring the pre-existing CUDA short-circuit) before falling back to CPU on any error — macOS users loading Q4_0/K-quant GGUFs now get real GPU acceleration, not silent CPU-only execution. (2) Metal FP8 batch prefill is implemented as a hybrid design: the heavy linear projections (fused QKV, attn-output, fused gate/up SwiGLU, FFN down) run as batched FP8 GEMMs on the GPU, while q/k-norm, RoPE, attention, and the K/V store stay on the CPU against the same cache per-token decode reads — this avoids the split-KV-cache bug class described below by construction (contrast the CUDA FP8 note immediately below, which took the split-cache route and stays disabled). Both are parity-validated on Apple-Silicon M3 (GEMV ≤1e-4 rel / 5e-3 abs; FP8 prefill logit cos=1.000000 + identical greedy continuation). - FP8 CUDA batch prefill is intentionally disabled-by-default (KV-cache-handoff bug fixed 2026-07-20). The FP8 batch-prefill path wrote the prompt K/V into its own private GPU KV cache, separate from the CPU cache per-token CUDA decode reads — the same bug class found and fixed for Q1/ternary and disabled-by-default for Q4_0/Q8_0/K-quant. It now carries the identical split-cache guard: FP8 CUDA batch prefill returns early so
forward_prefillfalls back to the bit-correct sequential per-token path (which populates the CPU KV cache decode reads), plus a context-length guard that turns an over-long prompt into a cleanSequenceTooLonginstead of a panic. Practical impact: none for correctness — FP8 E4M3/E5M2 CUDA models now decode correctly at any prompt length (verified by a CPU↔CUDA synthetic-model prefill→decode parity gate). The one cost is that FP8 CUDA prompt prefill runs the sequential per-token path rather than the fused batch GEMM; settingOXIBONSAI_FORCE_CUDA_SPLIT_PREFILL=1re-enables the fused (decode-incorrect) path for throughput microbenchmarks only. Note the Metal FP8 path above deliberately avoided this bug class rather than mitigating it after the fact — it never writes a GPU-private cache. Tracked inTODO.md.
Building blocks implemented and tested, but not wired into the default forward path
BonsaiModel::forward/forward_prefill run a single dense GQA-attention + dense-SwiGLU-FFN Qwen3 layer stack. The following are complete, unit-tested library primitives usable by external consumers of the crates, but none of them execute inside that default forward path today:
- PagedAttention (
PagedKvCache/BlockPool/BlockTable/KvPage,oxibonsai-model/src/paged_kv_cache.rs) — the shipping engine uses the contiguousKvCacheinstead. - KV-cache quantization (
QuantizedKvCache,Fp8KvCache,kv_cache_quant.rs) — never constructed by the model or runtime. Separately,oxibonsai-runtime'sKvCachePolicycomputes an adaptive FP16/Q8/Q4 target level from memory pressure, but only feeds a Prometheus gauge and an admin endpoint — it does not reconfigure the actual cache. ItsFp8tier is additionally unreachable (no threshold selects it). - Attention-variant layers — attention sink / StreamingLLM, sparse attention (local/strided/BigBird/Longformer/dilated), flash decoding's alternate path, cross-attention, Mixture-of-Depths, and the MoE router/expert modules all have zero call sites in
TransformerBlock::forwardoutside their own test suites. - Sliding-window attention (
TransformerBlock::forward_with_sliding_window,block/types/forward_sw.rs) — a complete, unit-tested ~330-line implementation (RoPE, QK-norm, windowed KV lookup, parallel/sequential attention, fused FFN) with the same integration gap as the attention variants above:BonsaiModel::forward/forward_prefillcall only the dense/full-attentionblock.forward(...), andQwen3Confighas nosliding_windowfield at all, so no shipped GGUF metadata can currently select it. - RoPE-scaling variants — YaRN (
yarn_rope.rs) and the linear/DynamicNTK/LLaMA-3.1/LongRoPE strategies (rope_scaling.rs) are fully implemented, but the productionRopeTableonly ever builds plain unscaled RoPE; no shipped native Bonsai GGUF metadata currently selects a scaling strategy.
Chat prompt template
- The OpenAI-compatible server always assembles a hardcoded ChatML prompt (
<|im_start|>role\ncontent<|im_end|>, inbuild_promptinoxibonsai-runtime/src/server.rsandbuild_extended_promptinoxibonsai-runtime/src/api_extensions.rs), regardless of which model is loaded.oxibonsai-tokenizerseparately implements a real multi-familyChatTemplateKind(ChatML, Llama-3, Mistral, Gemma, Qwen) with arender/render_with_generation_promptAPI, but the server never calls into it, and no code path reads a per-modelchat_templatefield fromtokenizer.jsonto auto-select the right family. All shipped Bonsai models use Qwen3 (ChatML-compatible), so this is not a correctness bug for the models this project ships — but serving a non-ChatML fine-tune through the OpenAI-compatible API today gets the wrong prompt format with no warning.
Speculative decoding
- The production two-engine path is
SpeculativeDecoder::generate_verified(&mut target_engine, ...)— it drafts against the delta-KV path and verifies against a real, separate targetInferenceEngine, and its accepted output is token-identical to plain greedy decoding of the target model. - The originally-shipped
generate_speculative/verifyAPI is retained only as a#[doc(hidden)]synthetic test harness (mock draft probability, synthesized target logits) — it is not exposed as a production entry point.
Sponsorship
OxiBonsai is developed and maintained by COOLJAPAN OU (Team Kitasan).
The COOLJAPAN Ecosystem represents one of the largest Pure Rust scientific computing efforts in existence — spanning 40+ projects, 500+ crates, and millions of lines of Rust code across scientific computing, machine learning, quantum computing, geospatial analysis, legal technology, multimedia processing, and more. Every line is written and maintained by a small dedicated team committed to a C/Fortran-free future for scientific software.
If you find OxiBonsai or any COOLJAPAN project useful, please consider sponsoring to support continued development.
https://github.com/sponsors/cool-japan
Your sponsorship helps us:
- Maintain and expand the COOLJAPAN ecosystem (40+ projects, 500+ crates)
- Keep the entire stack 100% Pure Rust — no C/Fortran/system library dependencies
- Develop production-grade alternatives to OpenCV, FFmpeg, SciPy, NumPy, scikit-learn, PyTorch, TensorFlow, GDAL, and more
- Provide long-term support, security updates, and documentation
- Fund research into novel Rust-native algorithms and optimizations
License
Apache License, Version 2.0
Copyright 2026 COOLJAPAN OU (Team KitaSan)
Compatibility
- Runs on
- CUDA, Metal
What shows it
- CUDA: oxibonsai-cli feature cuda, oxibonsai-image feature cuda, oxibonsai-kernels feature native-cuda (dependency cudarc)
- Metal: oxibonsai-cli feature metal, oxibonsai-image feature metal, oxibonsai-kernels feature metal (dependency metal), oxibonsai-model feature metal, oxibonsai-runtime feature metal, oxibonsai-serve feature metal
- Native code
- None found
- No native code found
- Python bindings
- No Python binding crate found
- License
- Apache-2.0
Compare with similar projects
Order: strongest tier first, then most downloads, then name, with unmeasured values last. A library counts downloads over 30 days. An app counts binary downloads per release. An app with none counts its crate downloads over 30 days. ML Rust runs this catalogue, so its closest project always gets a row.
| Project | Downloads | Dependents | Stars | Latest release | Runs on (GPU) | Native code | License |
|---|---|---|---|---|---|---|---|
|
Pure Rust 1-bit LLM inference engine for PrismML Bonsai models — umbrella crate |
1 downloads over 30 days | 0 | 137 | 0.2.3 | CUDA, Metal | No native code found | Apache-2.0 |
|
ctranslate2-rs Listed
Rust bindings for OpenNMT/CTranslate2 Also in Run and serve models. |
10,244 downloads over 30 days | 6 | 63 | 0.10.4 | CUDA | Binds native code: cxx, link-cplusplus, intel-onemkl-prebuild (feature mkl), onednn-src (feature dnnl), openblas-src (feature openblas) and 1 more. Build uses a native toolchain: cmake, cxx-build | MIT |
|
oxionnx Listed
Pure Rust ONNX inference engine — zero C/C++ dependencies Also in Run and serve models. |
550 downloads over 30 days | 24 | 20 | 0.1.7 | CUDA, WebGPU | No native code found | Apache-2.0 |
|
Inference server for LLMs, speech and embeddings: OpenAI-compatible routes with streaming, plus speech synthesis (TTS) and transcription (ASR). Serves Llama, Mistral, Qwen, Mamba2, MLA+MoE and hybrid models from SafeTensors, AWQ, GPTQ and GGUF. Also in Build LLM apps and agents. |
8 binary downloads per release | Not applicable | 7 | 0.7.1 | CUDA, WebGPU | Binds native code: ring (feature distributed) | Apache-2.0 |
|
Pure Rust + CUDA LLM inference engine — no PyTorch, OpenAI-compatible, serves Qwen3 to Kimi-K2 Also in Build LLM apps and agents. |
6 binary downloads per release | Not applicable | 738 | Not measured | Not measured | Apache-2.0 | |
|
furnace New
Fast, unified, Rust-native, Axum-compatible inference endpoints and nervous system for tensor models and LLMs: KServe / Triton and OpenAI APIs from one pure-Rust server Also in Build LLM apps and agents. |
241 downloads over 30 days | 0 | 66 | 0.16.2 | CUDA, WebGPU, Metal | No native code found | MIT |
|
baseRT New
Safe Rust bindings for the BaseRT LLM inference engine (Apple Silicon) Also in Build LLM apps and agents. |
49 downloads over 30 days | 2 | 247 | 0.4.6 | GPU support unknown | Binds native code: baseRT, baseRT-sys | Apache-2.0 |
All projects in Build LLM apps and agentsAll projects in Run and serve modelsAll projects in Text, embeddings and search
Why ListedNo archive, New or Featured rule places it, so it is Listed.
What it lacks for Featured
- It has 0 active dependents and 0 new dependents in 365 days. Featured needs 11 active dependents or 9 new dependents in 365 days. The repository route reads 137 stars, 21 forks and 1 contributor. It needs 4,539 stars, 434 forks and 79 contributors together.
- The check finds no release commit or manifest that ties the crate to the repository.
What else the check found
- The last activity is on 22 Jul 2026, 110 days ago. The rules expect an update within 365 days. Dormancy rule
Check notes
- published from commit bdce3da77d794dee2a4fb84d6127ac2c4880c742 that no branch or tag of the repo holds
Exact rules: Listed, Featured library. The check on applied thresholds version 9.
Every rule outcome, as the check records it
expected-interval: version 0.2.3 base 300, raised to the 365-day floor: E = 365 daysdormancy: last activity 2026-07-22, 110 days ago, E = 365: activefeatured: not featured: active_users 0 < 11 and new_adopters 0 < 9 and repository route stars 137 (needs 4539), forks 21 (needs 434), contributors 1 (needs 79); repository link not verifiedlisted: listed: no archive, new or featured rule applies
Crates11 crates
Measurements and sources
Each signal row shows the raw value, its source and the fetch date. The Sources list gathers every distinct source on this page. Movement needs more history.
Sources6 sources
- Description: the crates.io description
- crates.io database dump, fetched
- RustSec advisory database, fetched
- GitHub repository, fetched
- crates.io package, fetched
- GitHub contributors, fetched
Adoption0 active dependents, 0 new dependents in 365 days1 not measured
| Signal | Value | Source | Fetched | Counts |
|---|---|---|---|---|
| Active dependents | 0 | crates.io database dump | Yes | |
| New dependents (365 days) | 0 | crates.io database dump | Yes | |
| Peak active dependents | 0 | crates.io database dump | Yes | |
| Active dependents as a share of the peak | 1 | crates.io database dump | Yes | |
| Binary downloads per release | Not measured | Yes |
MaintenanceLatest human commit: 3 months ago3 not measured
| Signal | Value | Source | Fetched | Counts |
|---|---|---|---|---|
| Latest human commit | 2026-07-22 | GitHub repository | Yes | |
| Latest release | 2026-07-22 | crates.io database dump | Yes | |
| First release | 2026-04-12 | crates.io database dump | Yes | |
| Latest version | 0.2.3 | crates.io database dump | Yes | |
| Days the oldest outside issue waits for a reply | 110 | GitHub repository | Yes | |
| Maintainer replies over 365 days | 20 | GitHub repository | Yes | |
| Repository archived | false | GitHub repository | Yes | |
| Repository gone | false | GitHub repository | Yes | |
| Release commit or manifest in the repo | false | crates.io package | Yes | |
| Published docs | true | crates.io database dump | Yes | |
| Latest release fails cargo check | Not measured | Yes | ||
| Build check date | Not measured | Yes | ||
| Build check toolchain | Not measured | Yes |
SecurityUnpatched vulnerabilities: none
| Signal | Value | Source | Fetched | Counts |
|---|---|---|---|---|
| Unpatched vulnerabilities past the grace window | none | RustSec advisory database | Yes | |
| RustSec unmaintained advisory | none | RustSec advisory database | Yes | |
| Deprecation notice | none | crates.io database dump | Yes | |
| Deprecated requirement | none | crates.io database dump | Yes |
Distribution10 releases, 1 downloads over 30 days5 not measured
| Signal | Value | Source | Fetched | Counts |
|---|---|---|---|---|
| Releases | 10 | crates.io database dump | Yes | |
| Downloads over 30 days | 1 | crates.io database dump | Yes | |
| Binary downloads over the last 3 releases | Not measured | Yes | ||
| Homebrew installs on request over 365 days | Not measured | Yes | ||
| Repology repository families | Not measured | Yes | ||
| Docker pull growth over 90 days | Not measured | Yes | ||
| Docker pulls at the growth baseline | Not measured | Yes | ||
| Every version a prerelease | false | crates.io database dump | Yes | |
| Every version 0.0.x | false | crates.io database dump | Yes | |
| Every version yanked | false | crates.io database dump | Yes | |
| Crate deleted from crates.io | false | crates.io database dump | Yes |
Repository137 stars, 21 forks, 1 contributors, 10 commits. Stars alone never qualify a project.
| Signal | Value | Source | Fetched | Counts |
|---|---|---|---|---|
| GitHub stars | 137 | GitHub repository | Yes — one part of the repository route | |
| GitHub forks | 21 | GitHub repository | Yes — one part of the repository route | |
| Contributors with a GitHub account | 1 | GitHub contributors | Yes — one part of the repository route | |
| Commits on the default branch | 10 | GitHub repository | No | |
| Repository's main crate left out of the entry | none | crates.io database dump | Yes |
Facts that never count
| Signal | Value | Source | Fetched | Counts |
|---|---|---|---|---|
| License | Apache-2.0 | crates.io database dump | No | |
| Runs on, from listed crates and their direct dependencies | CUDA, Metal | crates.io database dump | No | |
| What shows each backend | CUDA: oxibonsai-cli feature cuda, oxibonsai-image feature cuda, oxibonsai-kernels feature native-cuda (dependency cudarc); Metal: oxibonsai-cli feature metal, oxibonsai-image feature metal, oxibonsai-kernels feature metal (dependency metal), oxibonsai-model feature metal, oxibonsai-runtime feature metal, oxibonsai-serve feature metal | crates.io database dump | No | |
| Native code, from listed crates and their dependencies | No native code found | crates.io database dump | No | |
| Python bindings, from direct dependencies of listed crates | No Python binding crate found | crates.io database dump | No | |
| Crates that depend on a listed crate directly | 0 | crates.io database dump | No |
Corrections and review history
No correction applies to this entry.
Judgments
A judgment enters only through an approved issue and a merged pull request.
No judgment applies to this entry.