Paint pixels. Write prose. Prove every stage.
pictor is a Pure Rust inference stack for generative models at the extreme end of quantization — 1-bit and ternary weights, GGUF on disk, Metal and CUDA on GPU, and a CPU reference path on every kernel. One codebase runs text-to-image (FLUX.2-Klein) and LLM inference (Qwen3 Bonsai) without a Python runtime or opaque C++ shim in the default build.
Name: Pictor is Latin for painter. The project paints images from prompts and composes text from tokens — same brush, different canvas.
North star: pictor is building toward a sovereign generative inference substrate — one Pure Rust, oracle-validated runtime for every modality that can be expressed as quantized tensor programs. Image and LLM ship today; audio, video, multimodal agent sessions, and browser/edge deployment share the same kernel fabric, GGUF artifact model, and parity contract tomorrow. See ROADMAP.md for the full horizon.
Lineage: pictor continues oxibonsai (COOLJAPAN OU, Apache-2.0). See NOTICE and docs/CONTRIBUTING.md before redistributing or contributing.
Most generative stacks split the problem in two: a Python reference you trust, and a production path you hope matches it. pictor inverts that contract.
Parity is the product. Image stages gate at cosine ≥ 0.999 against MLX goldens. LLM kernels cross-check reference, AVX2, AVX-512, NEON, and GPU tiers. A faster kernel that fails the oracle is a regression — not a release note.
Extreme quantization is first-class. Q1_0_g128 (1-bit) and TQ2_0_g128
(ternary {-1, 0, +1}) are not experiments bolted onto an FP16 engine. The
dequant, GEMV, GEMM, fused full-forward, and flash-attention paths were built for
sub-byte weights from the ground up.
One engine, many modalities. GGUF I/O, kernel dispatch, and GPU graph execution are shared infrastructure. Diffusion and autoregression are the first two pipelines on the same metal — not the last. The goal is a single auditable artifact from laptop to datacenter, without a Python reference runtime and a production runtime you hope match.
| Typical generative stack | pictor | |
|---|---|---|
| Runtime | Python + PyTorch / MLX + C++ helpers | Pure Rust workspace |
| Weight formats | FP16/BF16 checkpoints | Q1 / TQ2 / K-quant / FP8 in GGUF |
| Correctness story | "Looks fine" / eyeball | Oracle parity harnesses per stage |
| GPU | Framework-managed | Native Metal + NVRTC CUDA Graphs |
| CPU fallback | Often missing or slow | Always available (Rayon + SIMD) |
| Serving | Separate server project | OpenAI-compatible runtime built in |
| Default FFI | CUDA/cuBLAS, Python extensions | Zero in default build |
A complete Bonsai-Image port: prompt in, PNG out, every intermediate tensor measured against reference taps.
prompt
│
▼
┌─────────────┐ ┌──────────────────┐ ┌─────────────┐ ┌─────┐
│ Qwen3 TE │───▶│ FLUX.2 DiT │───▶│ VAE decode │───▶│ PNG │
│ 4-bit MLX │ │ TQ2_0_g128 GGUF │ │ safetensors │ └─────┘
└─────────────┘ └──────────────────┘ └─────────────┘
te_parity dit_parity (59) vae_parity (11)
cos ≥ 0.999 each stage
| Platform | Backend | 512×512, 4 steps |
|---|---|---|
| Apple Silicon (M3-class) | Metal | ≈ 52–62 s |
| NVIDIA A4000-class | CUDA | ≈ 31.7 s |
| Any | CPU (Rayon + NEON) | ≈ 10–15 min |
GPU wins are independently validated: v10 ternary GEMM (~3.8× over v9), joint
flash-attention (~5.5× over CPU), implicit-GEMM VAE conv (~3.2× over CPU). Details:
crates/pictor-image/README.md.
Autoregressive generation with production-grade sampling, constraints, and serving.
prompt
│
▼
┌────────────┐ ┌─────────────────────┐ ┌──────────┐ ┌────────┐
│ Tokenizer │───▶│ Qwen3 transformer │───▶│ Sampler │───▶│ tokens │
│ BPE/WP/UG │ │ Q1 / TQ2 weights │ │ + grammar│ └────────┘
└────────────┘ └─────────────────────┘ └──────────┘
KV cache · speculative decode
Metal/CUDA fused full-forward
Grammar constraints (BNF, GBNF, JSON Schema, regex), tool-calling API,
speculative decoding, beam search, continuous batching, prefix cache, RAG hooks,
and /v1/chat/completions — all in-tree. Details:
crates/pictor-runtime/README.md.
pictor does not ship "close enough" numerics for core inference paths.
Image oracle gates
| Harness | What it checks |
|---|---|
te_parity |
Text-encoder hidden states vs MLX |
dit_parity |
59 DiT forward taps, each cos ≥ 0.999 |
vae_parity |
11 VAE decode taps |
vae_safetensors_parity |
Native loader vs reference weights, bit-identical |
LLM kernel gates — scalar reference is law; SIMD and GPU tiers must match within tolerance on randomized fixtures before they ship.
RNG — Threefry seeding reproduces MLX latents byte-for-byte in the image path.
That discipline is why FP32 accumulate is kept through the image pipeline: no TF32 or FP16-MAC shortcuts that trade parity for benchmark charts.
Ten crates, one policy: Pure Rust, test-heavy, oracle-gated.
| Crate | Role | Tests |
|---|---|---|
pictor-core |
GGUF parser, quant blocks, model config | 207+ |
pictor-kernels |
1-bit / ternary / FP8 GEMV·GEMM, SIMD + GPU | 675+ |
pictor-model |
Qwen3 transformer, KV cache, attention | 673+ |
pictor-runtime |
Inference engine, sampling, server hooks | 796+ |
pictor-tokenizer |
BPE / Unigram / WordPiece, HF tokenizer.json
|
268+ |
pictor-rag |
Chunking, embedder, vector store, pipeline | 871+ |
pictor-eval |
Perplexity, BLEU, ROUGE harness | — |
pictor-serve |
Standalone OpenAI-compatible server binary | 260+ |
pictor-image |
FLUX.2 text-to-image pipeline | parity harness |
pictor |
Facade — re-exports the LLM stack | — |
┌──────────── pictor (facade) ────────────┐
│ │
pictor-image ────┤ core ◄──► kernels ◄──► model │
│ │ │ │ │
│ │ runtime ◄──► tokenizer │
│ │ │ │
└───────────┤ serve · rag · eval │
└─────────────────────────────────────────┘
CPU · Metal · CUDA
- Rust 1.86+ — rustup
- Model assets — HuggingFace downloads for Bonsai-Image / Bonsai LLM GGUF (see crate READMEs)
-
GPU feature —
metalon macOS,native-cudaon Linux/Windows
git clone https://github.com/vbasky/pictor.git
cd pictor
# Apple Silicon
cargo build --release --features metal
# NVIDIA
cargo build --release --features native-cuda
# CPU only (always works)
cargo build --release# Cargo.toml
[dependencies]
pictor-image = { path = "crates/pictor-image", features = ["metal"] }use std::path::PathBuf;
use pictor_image::pipeline::{text_to_image, TeSource, TextToImageCfg};
let cfg = TextToImageCfg {
prompt: "a tiny bonsai tree in a ceramic pot".into(),
seed: 42,
steps: 4,
width: 512,
height: 512,
guidance: 1.0,
dit_gguf: PathBuf::from("./bonsai-dit.gguf"),
vae_weights_dir: PathBuf::from("./bonsai-vae/vae/diffusion_pytorch_model.safetensors"),
te_source: TeSource::Mlx4bit(PathBuf::from("./bonsai-te/text_encoder-mlx-4bit/model.safetensors")),
tokenizer_dir: PathBuf::from("./bonsai-te/text_encoder-mlx-4bit"),
golden_override: None,
};
let out = text_to_image(&cfg)?;
std::fs::write("bonsai.png", &out.png)?;Asset paths can also be set via PICTOR_DIT_GGUF, PICTOR_TE_4BIT, PICTOR_VAE_WEIGHTS,
and related env vars — see crates/pictor-image/README.md.
[dependencies]
pictor-runtime = { path = "crates/pictor-runtime", features = ["metal"] }use pictor_runtime::{EngineBuilder, SamplingPreset};
let engine = EngineBuilder::new()
.model_path("models/Bonsai-8B.gguf")
.preset(SamplingPreset::Balanced)
.max_seq_len(4096)
.build()?;Or pull the full stack through the facade:
[dependencies]
pictor = { path = "crates/pictor", features = ["full", "metal"] }| Feature | Backend | Platform | Notes |
|---|---|---|---|
metal |
Apple Silicon | macOS | Fused TQ2 forward, flash-attn, VAE — default-on |
native-cuda |
NVIDIA NVRTC + CUDA Graphs | Linux / Windows | DiT, VAE, LLM prefill paths |
| (none) | CPU | everywhere | AVX2 / AVX-512 / NEON auto-detect via KernelDispatcher
|
Metal and CUDA are mutually exclusive at build time (target_os). The CPU path
is always compiled in.
Toggle runtime GPU stages with PICTOR_DIT_GPU, PICTOR_DIT_ATTN_GPU, PICTOR_VAE_GPU,
and PICTOR_TE_GPU — documented in the image crate README.
0.1.x — dual pipelines shipping, parity gates enforced, 4 000+ tests across the
workspace. Image path is stable at 512²; LLM runtime is feature-complete (grammar,
tool calling, speculative decode, OpenAI server). CUDA batched-prefill correctness
fixes are the top open P0 — see ROADMAP.md.
pictor is derived from oxibonsai (COOLJAPAN OU). Do not relicense inherited code to BSD or MIT without upstream permission. Read docs/CONTRIBUTING.md before opening a PR.
High-leverage open work: CUDA Q1/TQ2 prefill parity, VAE tiling for >512px, unified CLI.
Apache-2.0 — derived from oxibonsai (COOLJAPAN OU). See LICENSE and NOTICE. Modifications © 2026 Vikram Bhaskaran.
Sibling projects viser and revelo are independent originals under BSD-2-Clause — different lineage, different license.

