Skip to page content
SAVRN
Search Plan a project

Open-weight model · Text to image

Bonsai-Image-ternary-4B

by LiteRT Community (FKA TFLite) litert-community/Bonsai-Image-ternary-4B

Bonsai-Image-ternary-4B is an open-weight model for text to image from LiteRT Community (FKA TFLite), released under Apache License 2.0. Its published files total 12.2 GB. It draws 3.5k downloads a month.

LiteRT is Google's on-device runtime, the new name for TensorFlow Lite (Android: com.google.ai.edge.litert:litert), and litert-torch, the renamed ai-edge-torch, is its PyTorch converter: a PyTorch model converted unmodified with literttorch.convert matched…

Parameters—
Context—
Weights12.1 GB
Licenseapache-2.0
AccessOpen weights
Monthly Downloads3.5k

Model Card

By LiteRT Community (FKA TFLite), published under apache-2.0, revision d276d6c8501c.

LiteRT is Google's on-device runtime, the new name for TensorFlow Lite (Android: com.google.ai.edge.litert:litert), and litert-torch, the renamed ai-edge-torch, is its PyTorch converter: a PyTorch model converted unmodified with literttorch.convert matched the original to 4e-7 on a Galaxy S26 (measured, LiteRT 2.2.0, Android 16, 2026-09-05). PrismML Bonsai Image 4B — a ternary-weight diffusion transformer built on the FLUX.2-klein-4B architecture — converted to LiteRT for on-device text-to-image. The whole pipeline runs in three fixed-shape.tflite graphs; the host does only tokenization, the FlowMatch-Euler loop, and latent unpatchify (generate.py in this repo, ~150 lines, no torch and no…

Read LiteRT Community (FKA TFLite)'s full model card

LiteRT is Google's on-device runtime, the new name for TensorFlow Lite (Android: com.google.ai.edge.litert:litert), and litert-torch, the renamed ai-edge-torch, is its PyTorch converter: a PyTorch model converted unmodified with litert_torch.convert matched the original to 4e-7 on a Galaxy S26 (measured, LiteRT 2.2.0, Android 16, 2026-09-05).

Bonsai Image 4B — LiteRT (.tflite)

PrismML Bonsai Image 4B — a ternary-weight diffusion transformer built on the FLUX.2-klein-4B architecture — converted to LiteRT for on-device text-to-image. The whole pipeline runs in three fixed-shape .tflite graphs; the host does only tokenization, the FlowMatch-Euler loop, and latent unpatchify (generate.py in this repo, ~150 lines, no torch and no diffusers).

graph file recipe size
DiT (Flux2Transformer2DModel, 3.88 B) dit_int4b32.tflite int4 block-32 2.11 GiB
DiT — GPU-shaped export (Apple GPU / Metal) dit_gpu_int4b32.tflite int4 block-32, same weights 2.11 GiB
DiT — 256×256 export (16×16 patch grid, 256 image tokens) dit_256_int4b32.tflite int4 block-32, same weights 2.11 GiB
text encoder (Qwen3-4B, top 9 layers pruned) textenc_int4.tflite int4 block-128 DRQ 1.68 GiB
text encoder — higher-fidelity variant textenc_int8_weightonly.tflite int8 weight-only 2.91 GiB
VAE decoder (AutoencoderKLFlux2) vae_dec_fp32.tflite fp32 0.19 GiB
VAE decoder — 256×256 export (32×32 latent) vae_dec_256_fp32.tflite fp32 0.19 GiB

Smallest working set: 3.97 GiB (int4 text encoder). Output is 512×512 with the default pair of graphs, or 256×256 with the dit_256 / vae_dec_256 pair (generate.py --size 256; variants.256 in pipeline_meta.json) — the text encoder, tokenizer and latent constants are shared by both sizes; 256 prompt tokens and 4 sampling steps by default (the model is step-distilled; more steps also work).

The ternary weights survive int4 exactly

The vendor ships the DiT with ternary weights (every block linear uses values {−scale, 0, +scale} per 128-group). In the int4 block-32 container those land as exactly {−7, 0, +7} — zero rounding decisions, verified in the converted artifact. The int4 file is a lossless container for this model's weights, at 2.11 GiB versus 14.4 GiB fp32.

Quality

Converting without quantizing anything is essentially exact (76.8 dB vs the PyTorch pipeline). With quantization, low PSNR against the PyTorch sample is sampler drift, not degradation: a small weight perturbation amplified through 4 sampling steps lands on a different draw from the same distribution. Across a 6-prompt stress set (legible text, a face, macro texture, a smooth gradient, a cluttered scene), reference-free sharpness stays flat across every recipe (Laplacian variance 1086 → 1069 at the lowest-PSNR variant), text stays legible, and faces stay correct in all columns. Pick a text encoder by size, not by fear: int4 if you want the smallest set, int8 weight-only if you want to track the reference sample more closely.

Run it

pip install ai-edge-litert numpy pillow transformers jinja2 huggingface_hub
python generate.py --model-dir . --prompt "a red fox sitting in fresh snow at sunrise" --seed 42 --out fox.png
python generate.py --model-dir . --size 256 --prompt "a red fox sitting in fresh snow at sunrise" --seed 42 --out fox_256.png

The same sample is maintained in Google's litert-samples repository (models/bonsai/bonsai_image_4b).

Performance

All rows are for one 512×512 image at the default 4 sampling steps with a 256-token prompt. The pipeline is three graphs — text encoder once, DiT once per step, VAE decoder once — so the DiT column dominates.

Device Backend Text encoder DiT (per step) VAE Total per image Peak memory
Apple-silicon Mac CPU, 8 threads 2.6 s 3.9 s 1.3 s ~19 s —
Apple-silicon Mac GPU (Metal, fp32) — DiT only on CPU 0.74 s on CPU ~6 s steady state ~22 GB
iPhone 17 Pro CPU/XNNPACK, 6 threads 1.8 s 13 s 3.1 s ~64 s ~2.9 GiB
Pixel 8a (8 GB) CPU — — — ~7–8 min —

Conditions worth knowing before you read those numbers:

  • The Metal row uses dit_gpu_int4b32.tflite and needs fp32 GPU precision (gpu_options TOML precision = 2) — the default fp16 overflows this DiT's activation range. It also pays a one-time ~40 s Metal compile per launch, which the steady-state figure excludes, and its fp32-resident weights are what put memory near 22 GB, so a 32 GB+ Mac is the practical target. The CPU-shaped dit_int4b32.tflite does not run on the Metal accelerator at all (rank-5 rotary tensors).
  • The iPhone DiT loads and prepares in ~4.5 s before the first step. Attach the XNNPACK delegate explicitly, with your thread count, when using the C API — without it the runtime falls back to reference kernels, which are orders of magnitude slower on this model.
  • Device output is bit-exact against the Mac run: every DiT step matches to the last float, and the final PNG scores 51.2 dB PSNR.
  • The full-app measurements land in the same place: ~62 s per image on an iPhone 17 Pro. Treat 8 GB of RAM as the floor and 12 GB+ as the practical target on Android.

On-device (iPhone 17 Pro, CPU via XNNPACK, 6 threads): the 2.11 GiB DiT loads and prepares in ~4.5 s; 13 s per DiT step, text encoder 1.8 s, VAE 3.1 s — ~64 s per 512×512 image at 4 steps, ~2.9 GiB peak memory. Device output is bit-exact against the Mac run (every DiT step matches to the last float; 51.2 dB PSNR on the final PNG). One integration note: attach the XNNPACK delegate explicitly (with your thread count) when using the C API — without it the runtime falls back to reference kernels, which are orders of magnitude slower on this model.

256×256

The 256×256 pair is the same weights traced at 256 image tokens (16×16 patch grid) and a 32×32 latent, so it changes the time per image, not the memory: the DiT file is the same 2.11 GiB, and its peak memory on a Galaxy S26 is the same 4.1 GB at both sizes. Per-graph times on the S26 (CPU with XNNPACK, 6 threads, one call per graph with LiteRT's benchmark_model, the binary behind litert benchmark --android --cpu, 3 runs):

Graph, one call 512×512 256×256
text encoder (shared) 1.8 s 1.8 s
DiT, per step 14.6 s 4.3 s
VAE decoder 4.9 s 1.1 s
sum for one image, 4 steps ~65 s ~20 s

The sum is the sum of per-graph benchmarks, not an app run. On an Apple-silicon Mac (CPU, 8 threads, same session) the DiT step goes 5.5 s → 2.6 s and the VAE decode 1.0 s → 0.24 s. Fidelity at 256: with the same prompt embeds and the same initial noise, the all-tflite image scores 39.2 dB PSNR against the torch pipeline at 256×256 (Laplacian variance 873 vs 865, the same sharpness). The six prompts of the quality grid at both sizes, 256 shown at 2×:

Snapdragon NPU (Hexagon)

  • dit_gpu_int4b32.tflite — neither accelerator produced a usable row on the S26. NPU: the ahead-of-time compile for SM8850 failed on the host. GPU: the benchmark process was killed, most likely out of memory.
  • dit_int4b32.tflite — neither accelerator produced a usable row on the S26. NPU: the ahead-of-time compile for SM8850 failed on the host. GPU: the benchmark process was killed, most likely out of memory.
  • textenc_int4.tflite — neither accelerator produced a usable row on the S26. NPU: the ahead-of-time compile for SM8850 failed on the host. GPU: the benchmark process was killed, most likely out of memory.
  • textenc_int8_weightonly.tflite — neither accelerator produced a usable row on the S26. NPU: the ahead-of-time compile for SM8850 failed on the host. GPU: the benchmark process was killed, most likely out of memory.
  • vae_dec_fp32.tflite — neither accelerator produced a usable row on the S26. NPU: the graph compiles and then fails to run (LiteRtException: Failed to invoke the compiled model). GPU: LiteRtException: Failed to compile model.

Target: Samsung Galaxy S26 (Snapdragon 8 Elite Gen 5 / SM8850, Hexagon v81, Android 16).

GPU wiring: GPU guide. NPU recipe: NPU guide.

Run it on-device (Android / iOS)

Complete single-screen apps for both platforms — including Swift/Kotlin ports of the Qwen3 tokenizer (token-exact against the Python tokenizer), the FlowMatch-Euler loop, and the latent unpatchify — are at hf-to-litertlm/bonsai_image_work/device (BonsaiApp for iOS, BonsaiAppAndroid for Android). Measured: iPhone 17 Pro ~62 s per image; Pixel 8a (8 GB RAM) completes at ~7–8 min per image, so treat 8 GB as the floor and 12 GB+ as the practical target. The apps run the 512×512 pair; the 256×256 pair needs the three host-side changes listed under the graph contract below.

Run it on the Apple GPU (macOS)

dit_gpu_int4b32.tflite is the same DiT re-exported GPU-clean — rope tables precomputed with the pipeline's constant position ids and the interleaved rotation rewritten rank-4, same weights, verified numerically identical at export. On an Apple-Silicon Mac the LiteRT Metal accelerator runs it at ~0.74 s/DiT-step, ~6 s per 512×512 image steady-state (one-time ~40 s Metal compile per launch). Force fp32 GPU precision (gpu_options TOML precision = 2) — default fp16 overflows this DiT's activation range. A complete macOS SwiftUI app (DiT on Metal, text encoder + VAE on CPU) is BonsaiAppMac in the same device directory linked above; the fp32-resident GPU weights put steady-state memory around 22 GB, so a 32 GB+ Mac is recommended. The CPU-shaped dit_int4b32.tflite does not run on the Metal accelerator (rank-5 rotary tensors), so pick the file that matches your target.

Load the graphs through the LiteRT CompiledModel API, on the CPU with XNNPACK, as the Python host loop here and the iOS and macOS apps do; the litert-samples page above carries the three rules for a port: map inputs by argument position (args_<n>), never by shape; load one graph at a time, freeing it before the next; keep the graphs on XNNPACK. LiteRT-LM and the Gallery app load .litertlm bundles, not these graphs. The graph contract:

  1. text encoder: args_0 ids (1, 256) int32, args_1 mask (1, 256) int32 → output_0 embeds (1, 256, 7680) float32
  2. DiT, once per step: args_0 latents (1, 1024, 128), args_1 embeds, args_2 sigma (1,), args_3 img_ids (1024, 4), args_4 txt_ids (256, 4), all float32 → velocity (1, 1024, 128); lat += (sigma[k+1] - sigma[k]) * velocity
  3. VAE decoder: args_0 z (1, 32, 64, 64) float32 → image (1, 3, 512, 512) float32, clamp(y / 2 + 0.5)

At 256×256 the DiT takes latents (1, 256, 128) and img_ids (256, 4), and the VAE decoder takes z (1, 32, 32, 32) → image (1, 3, 256, 256). img_ids and txt_ids then share a shape, which is why inputs are mapped by argument position. On the host, the position grid is 16×16, the unpatchify target is (1, 32, 32, 32), and the sigma schedule's mu is a function of the image-token count (flowmatch_sigmas in generate.py).

Conversion

Converted with [litert-torch] via the recipe published at hf-to-litertlm (export scripts, quantization, and the two conversion gotchas: Flux2's float64 RoPE frequency table must be forced to float32 to legalize tfl.pow, and blockwise zero-scales in all-zero blocks need patching for XNNPACK). The text encoder is exported as a prompt embedder — the pipeline reads hidden states from layers (9, 18, 27) only, so the top 9 of 36 layers and the LM head are pruned for free.

License

Apache-2.0, following the upstream prism-ml/bonsai-image-ternary-4B-unpacked release.

Identity and Version

Repository
litert-community/Bonsai-Image-ternary-4B
Publisher
LiteRT Community (FKA TFLite)
Task
Text to image
Modality
Image
Library
litert
Parameters
Not stated by the source
Languages
on-device
Revision
d276d6c8501c43c3d167fdb96e5fbd1b1869fff0
First published
2026-07-29
Last updated
2026-09-27

Files and Weights

21 files, 12.2 GB in total. The weights are 7 files totalling 12.1 GB in tflite.

Weights7 files · 12.1 GB
Configuration4 files · 16.6 KB
Tokenizer4 files · 15.9 MB
Documentation1 file · 12.8 KB
Other4 files · 15.1 MB
Repository1 file · 1.7 KB
Every file
FileTypeSizeSHA-256
dit_256_int4b32.tfliteWeights2.3 GB 4a8f6c12382a
dit_gpu_int4b32.tfliteWeights2.3 GB a03df73c3068
dit_int4b32.tfliteWeights2.3 GB 580c3485d2a8
textenc_int4.tfliteWeights1.8 GB 12937850e4a1
textenc_int8_weightonly.tfliteWeights3.1 GB 18f3cb08387e
vae_dec_256_fp32.tfliteWeights198.8 MB f3ac3b1bca6a
vae_dec_fp32.tfliteWeights198.8 MB 96fff2562ecb
generate.pyConfiguration8.7 KB —
pipeline_meta.jsonConfiguration6.6 KB —
tokenizer/added_tokens.jsonConfiguration707 B —
tokenizer/special_tokens_map.jsonConfiguration613 B —
README.mdDocumentation12.8 KB —
fox.pngOther393.8 KB 6914b3de4a0c
grid_512_vs_256.pngOther3.6 MB 59a2e7569239
quality_grid.pngOther11.1 MB 29a3f7ed9e3b
tokenizer/chat_template.jinjaOther4.2 KB —
.gitattributesRepository1.7 KB —
tokenizer/merges.txtTokenizer1.7 MB —
tokenizer/tokenizer.jsonTokenizer11.4 MB aeb13307a71a
tokenizer/tokenizer_config.jsonTokenizer5.4 KB —
tokenizer/vocab.jsonTokenizer2.8 MB —

License and Download

License
apache-2.0
Access
Open weights, no gate
Download size
12.1 GB
Download from LiteRT Community (FKA TFLite)

Released by LiteRT Community (FKA TFLite) through its official repository on Hugging Face. Read the license.

Built From

  • Derived from prism-ml/bonsai-image-ternary-4B-unpacked
  • Quantized from prism-ml/bonsai-image-ternary-4B-unpacked

Memory Requirements

PrecisionWeights in memory
As published12.1 GB

Weights only, from the published parameter count; the key-value cache and runtime add to this.

Questions About Bonsai-Image-ternary-4B

Can I use Bonsai-Image-ternary-4B commercially?

Yes. Bonsai-Image-ternary-4B is released under Apache License 2.0. The Apache License 2.0 is a permissive open-source license. It permits commercial use, modification and redistribution. It requires keeping the license and copyright notices and any NOTICE file, stating significant changes, and it includes an express patent grant from contributors.

Similar Models

GGUF, Safetensors, and MLX quantized formats of Qwen/Qwen-Image-2.1 for local image generation using the original upstream base weights. Q4KM is recommended for the best balance of size and quality for GGUF. INT8 ConvRot and NVFP4 offer high performance on supported GPUs, while MLX formats are optimized for Apple Silicon. Companion model files packaged for ComfyUI: Use the model with ComfyUI and ComfyUI-GGUF. All required companion files (GGUF transformer, text encoder, and VAE) are hosted directly in this repository. Download the files and place them in their respective ComfyUI directories: 1. Install ComfyUI-GGUF: Use the maintained fork with native Qwen-Image 2.1 support by cloning…

Open weights other gguf

GGUF quantizations of Qwen/Qwen-Image-2.1 for local image generation using the original upstream base weights. Q4KM is recommended for the best balance of size and quality. Companion model files packaged for ComfyUI: Use the model with ComfyUI and ComfyUI-GGUF. All required companion files (GGUF transformer, text encoder, and VAE) are hosted directly in this repository. Download the files and place them in their respective ComfyUI directories: 1. Install ComfyUI-GGUF: Use the maintained fork with native Qwen-Image 2.1 support by cloning leejet/ComfyUI-GGUF into your custom nodes: (Note: If you have the older city96/ComfyUI-GGUF installed and encounter an Unknown model architecture! error…

Open weights other gguf

Model · Text to image

Qwen-Image-2.1-GGUF

Unsloth AI

This is a GGUF quantized version of Qwen-Image-2.1. unsloth/Qwen-Image-2.1-GGUF uses Unsloth Dynamic 2.0 methodology for SOTA performance. - Important layers are upcasted to higher precision, per tensor, from a measured sensitivity scan. - Run these with Unsloth Desktop, stable-diffusion.cpp and more. A GGUF is the denoiser only, so it needs the VAE and the Qwen3-VL text encoder alongside it. See below for image editing operating inside of Unsloth Desktop: Rendered with the Q4KM denoiser and the Q4KM text encoder, 1024x1024, 20 steps, cfg 6.0, euler. We are excited to open-source Qwen-Image-2.1, a unified text-to-image generation and image editing model in the Qwen family. With just 7B…

Open weights other

Model · Text to image

Z-Image-Turbo-GGUF

Unsloth AI

Welcome to the official repository for the Z-Image(造相)project! Z-Image is a powerful and highly efficient image generation model with 6B parameters. Currently there are three variants: - Z-Image-Turbo – A distilled version of Z-Image that matches or exceeds leading competitors with only 8 NFEs (Number of Function Evaluations). It offers sub-second inference latency on enterprise-grade H800 GPUs and fits comfortably within 16G VRAM consumer devices. It excels in photorealistic image generation, bilingual text rendering (English & Chinese), and robust instruction adherence. - Z-Image-Base – The non-distilled foundation model. By releasing this checkpoint, we aim to unlock the full potential…

Open weights apache-2.0 ggml

Model · Text to image

Juggernaut-XL-v9

RunDiffusion

The SDXL ecosystem is the single most mature corner of open image generation, and v9 is its most refined photorealism checkpoint. Choose Juggernaut XL v9 when you want: - Photorealism that holds up under scrutiny — skin texture, micro-contrast, and natural lighting that translates from concept to print. - Reasonable hardware — runs comfortably on 8 GB of VRAM, unlike newer DiT-based models that demand 16+ GB. - The full SDXL toolbox — drop-in compatibility with the thousands of SDXL ControlNets, IP-Adapter variants, AnimateDiff, regional prompting tools, and LoRAs already in your workflow. - Battle-tested reliability — 26+ months in production, used in agencies, studios, and shipping…

Open weights creativeml-openrail-m diffusers

Model · Text to image

Qwen-Image-Lightning

Lightx2v

Please refer to Qwen-Image-Lightning github to learn how to use the models. make sure to install diffusers from main (pip install git+https://github.com/huggingface/diffusers.git)

Open weights apache-2.0 diffusers