Instructions to use WaveCut/Image21-Turbo-OrbitQuant-W4A4 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Diffusers
How to use WaveCut/Image21-Turbo-OrbitQuant-W4A4 with Diffusers:
pip install -U diffusers transformers accelerate
import torch from diffusers import DiffusionPipeline # switch to "mps" for apple devices pipe = DiffusionPipeline.from_pretrained("WaveCut/Image21-Turbo-OrbitQuant-W4A4", dtype=torch.bfloat16, device_map="cuda") prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k" image = pipe(prompt).images[0] - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- Draw Things
- DiffusionBee
Image21 Turbo OrbitQuant W4A4
OrbitQuant build of WaveCut/Image21-Turbo: Qwen-Image-2.1 with the Viggle turbo v0.2.1 LoRA merged and the Texture-Fix VAE. The diffusion transformer is W4A4, the Qwen3-VL-8B text encoder is W6A6; the few projections that create or cancel massive activations stay in fp16 in both. Text-to-image and editing in 6 steps without guidance, with every component resident in 13.6 GB. Built with Qwen.
The preview links to the lossless 4096Γ6576 matrix: twelve pairs at the native 1024Γ1024, same prompt, seed and
settings in each pair, tiles concatenated without resizing. The 24 PNGs are in
artifacts/generations/.
At a glance
| Item | Value |
|---|---|
| Source | WaveCut/Image21-Turbo (Qwen-Image-2.1 790c9263 + Viggle turbo v0.2.1 + Texture-Fix VAE) |
| Transformer | 214 linears OrbitQuant W4A4; fp16: img_in, txt_in, modulation.1, img_mlp.out of blocks 0, 4β11, 13, timestep embedder, norm_out, proj_out |
| Text encoder | 341 linears OrbitQuant W6A6 (language model, vision tower, lm_head); fp16: decoder layers 6, 16, 34, 35 |
| Quantization | RP-BH rotation, Lloyd-Max codebooks, no calibration data, OrbitQuant 0.9.8 |
| Sampling | 6 steps on the turbo sigmas, no CFG |
| Storage | transformer 4.52 GB (fp16 14.23 GB), text encoder 8.33 GB (bf16 17.5 GB), VAE 1.35 GB |
| Benchmark | RTX 5090 32 GB, torch 2.8.0+cu128, diffusers 0.41.0.dev0 80c7ed26, transformers 5.17.0 |
Install and run
pip install -r https://huggingface.co/WaveCut/Image21-Turbo-OrbitQuant-W4A4/resolve/main/runtime-requirements.txt
orbitquant kernels-install
import torch
import orbitquant
from diffusers import QwenImage21Pipeline
pipe = QwenImage21Pipeline.from_pretrained("WaveCut/Image21-Turbo-OrbitQuant-W4A4", dtype=torch.float16).to("cuda")
SIGMAS = [1.0, 0.9375, 0.875, 0.75, 0.5, 0.25]
image = pipe(
prompt="A rain-soaked Warsaw street seen through a tram window",
width=1024, height=1024,
num_inference_steps=6, sigmas=SIGMAS,
generator=torch.Generator("cuda").manual_seed(0),
).images[0]
edited = pipe(
prompt="Turn <image1> into a snowy winter night; keep the composition unchanged.",
image=[image], output_resolution=1024,
num_inference_steps=6, sigmas=SIGMAS,
generator=torch.Generator("cuda").manual_seed(0),
).images[0]
import orbitquant registers the loaders; kernels-install fetches the native kernel wheel for the running
torch/CUDA ABI (--build compiles it when no prebuilt variant matches). Keep the VAE untiled in fp16: tiled fp16
decoding produces non-finite pixels; for 2048Β² text-to-image use pipe.vae.to(torch.bfloat16); pipe.vae.enable_tiling().
scripts/run_inference.py
wraps the same calls with the turbo schedules.
Latency and VRAM
RTX 5090, fp16 compute, 6 steps, 10 prompts, median of two hot sweeps after a cold one. The fp16 source does not fit 32 GB with all components resident, so both builds are also measured staged: text encoder on the GPU for encoding, then transformer and VAE.
| Metric | Image21 Turbo fp16 | OrbitQuant | Change |
|---|---|---|---|
| 1024Β², staged, hot end-to-end | 2.685 s | 2.122 s | β21 % |
| 1024Β², transformer 6 steps | 2.426 s | 1.816 s | β25 % |
| 1024Β², prompt encode | 0.035 s | 0.077 s | +0.04 s |
| 1024Β², VAE decode | 0.224 s | 0.229 s | |
| 1024Β², all resident, hot end-to-end | does not fit | 2.248 s | |
| 2048Β², hot end-to-end (tiled VAE) | 17.88 s staged | 13.95 s resident | β22 % |
| Peak VRAM, encode stage | 17.53 GB | 8.96 GB | β49 % |
| Peak VRAM, transformer + VAE stage, 1024Β² | 22.45 GB | 13.40 GB | β40 % |
| Peak VRAM, all resident, 1024Β² / 2048Β² | β | 21.15 / 16.44 GB | |
| Load from page cache to GPU | 8.4 s | 3.3 s | β61 % |
| Learned-weight storage | 33.1 GB | 14.2 GB | β57 % |
VRAM is nvidia-smi (NVML) and includes the CUDA context. Raw records are in
benchmark/.
What 4-bit breaks here and what stays in fp16
Both Qwen stacks carry massive activations β single channels of a few special tokens that grow to thousands. A module that writes or cancels such a value turns a routine 2β5 % quantization error into an error of the same order as the signal that survives:
- Text encoder. Layer 16's MLP writes β9000 into channel 2276 of the user-turn
<|im_start|>token, layers 34β35 cancel it to a few hundred, and the pipeline reads exactly that pre-norm last hidden state. Layer 6 writes β13000 into the same channel of the system-turn<|im_start|>token. With W4A4 everywhere the embeddings drop to cosine 0.86 (token 0: 0.36) and the images change composition. - Transformer. Text tokens carry values up to β9000 written by
img_mlp.outof blocks 0, 4β11 and 13; the text stream feeds every image token through attention and the prefix KV cache.
The fix keeps those projections in fp16 and runs the rest of the text encoder at W6A6. Isolation on seven prompts (PSNR / SSIM against the fp16 pipeline; the fp16 pipeline with a bf16 text encoder scores 30.8 / 0.968):
| Text encoder | Transformer | PSNR | SSIM | Encoder + transformer |
|---|---|---|---|---|
| W4A4 | W4A4 | 14.49 dB | 0.610 | 10.0 GB |
| fp16 | W4A4 | 17.31 dB | 0.707 | |
| fp16 | W4A4 + fp16 massive-activation writers | 19.11 dB | 0.763 | |
| W4A4 | fp16 | 15.27 dB | 0.640 | |
| W6A6 + fp16 layers 6, 16, 34, 35 | fp16 | 24.42 dB | 0.909 | |
| W6A6 + fp16 layers 6, 16, 34, 35 | W4A4 + fp16 massive-activation writers | 18.66 dB | 0.757 | 12.85 GB |
Every transformer row keeps img_in, txt_in and modulation.1 in fp16.
Keeping all 32 img_mlp.out projections in fp16 instead of the ten writers costs 1.7 GB more and scores lower
(18.84 dB). Across the twelve pairs of the matrix the final build scores 19.73 dB PSNR / 0.777 SSIM.
Sampling recipes
Measured on the fp16 Image21 Turbo pipeline, which this build follows step for step.
| Recipe | Settings | Result |
|---|---|---|
| Default | 6 steps, sigmas=[1, 0.9375, 0.875, 0.75, 0.5, 0.25], shipped scheduler, no CFG |
Sharpest detail; Latin and Cyrillic text mostly right |
| Text, posters, natural skin | same sigmas, pipe.scheduler = FlowMatchEulerDiscreteScheduler.from_config(pipe.scheduler.config, use_dynamic_shifting=False, shift=3.0) |
Cleanest lettering, smoother skin, same speed |
| Dense text | 8 steps, sigmas=[1, 0.9375, 0.875, 0.75, 0.625, 0.5, 0.25, 0.125] |
Same composition, small print slightly cleaner, +30 % time |
| Guidance | 6 steps, true_cfg_scale=2 with a negative prompt |
More contrast and saturation, 2Γ time |
| Avoid | 4 steps [1, 0.75, 0.5, 0.25]; static shift 5 |
Ghosted double contours; soft, smeared detail |
Editing: reference images are <image1>, <image2>, β¦ in the prompt, in the order passed; references are encoded at
output_resolutionΒ² area and the canvas follows the last reference unless width/height are given.
Comparison protocol
| # | Prompt | Stress category | Seed |
|---|---|---|---|
| 01 | studio-product |
product detail | 61000 |
| 02 | human-portrait |
portrait | 61001 |
| 03 | mucha-poster |
public-domain artist style | 61002 |
| 04 | hokusai-wave |
public-domain artist style | 61003 |
| 05 | bauhaus-risograph |
popular image style | 61004 |
| 06 | technical-cutaway |
technical diagram | 61005 |
| 07 | long-latin-text |
long Latin text | 61006 |
| 08 | long-cyrillic-text |
long Cyrillic text | 61007 |
| 09 | mixed-diagram |
mixed Latin/Cyrillic diagram | 61008 |
| 10 | wide-city-scene |
dense scene composition | 61009 |
| 11 | edit-background |
edit of pair 02's fp16 output | 61010 |
| 12 | edit-winter |
edit of pair 10's fp16 output | 61011 |
1024Γ1024, 6 steps, turbo sigmas, no CFG. Both columns of an edit pair start from the same fp16 input. Prompts are in
benchmark/prompts.json.
It is a deployment check, not an FID, CLIP or preference benchmark.
Repository contents
transformer/,text_encoder/β OrbitQuant components;processor/,vae/,scheduler/,model_index.jsonβ the rest of the diffusers pipeline.assets/β lossless comparison matrix, preview and its manifest with SHA-256 of every tile.artifacts/generations/β 12 fp16 and 12 OrbitQuant PNGs.benchmark/β timings, memory, prompts, environment, pairwise PSNR/SSIM.scripts/run_inference.pyβ command-line runner;scripts/quantize.pyβ rebuilds both components fromWaveCut/Image21-Turbo.quantization_manifest.jsonβ every quantized and fp16 module with parameter counts.LICENSE,NOTICEβ license, modified files, upstream notices.
Limitations
- W4A4 moves the 6-step trajectory: object placement, faces and small print can differ from the fp16 build at the same seed; long Cyrillic text and dense mixed-script diagrams degrade more than Latin text.
- The first call compiles Triton kernels for new shapes; measure hot latency after a warm-up.
- Numbers are for one RTX 5090; other GPUs, drivers and torch builds differ.
- Non-commercial: the Qwen RESEARCH LICENSE AGREEMENT applies to all weights.
License
Derivative of Qwen-Image-2.1 under the Qwen RESEARCH LICENSE AGREEMENT (LICENSE), research and evaluation only.
NOTICE lists the modified files and the Viggle and madebyollin notices.
Qwen is licensed under the Qwen RESEARCH LICENSE AGREEMENT, Copyright (c) 2026 Hangzhou Tongyi Laboratory Technology Co., Ltd. All Rights Reserved.
- Downloads last month
- -
Model tree for WaveCut/Image21-Turbo-OrbitQuant-W4A4
Base model
WaveCut/Image21-Turbo