File size: 5,965 Bytes
e79ec1f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7dd5835
e79ec1f
 
 
 
 
 
 
 
7dd5835
e79ec1f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7dd5835
e79ec1f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7dd5835
e79ec1f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
---
language:
- en
- zh
- ru
license: other
license_name: qwen-research
license_link: LICENSE
base_model:
- Qwen/Qwen-Image-2.1
- Viggle/Qwen-Image-2.1-viggle-turbo
- madebyollin/texture-fix-vae-for-qwen-image-2.1
base_model_relation: merge
library_name: diffusers
pipeline_tag: text-to-image
tags:
- diffusers
- text-to-image
- image-editing
- qwen-image
- turbo
- few-step
- distillation
---

# Turbo-Image-2.1

[Qwen-Image-2.1](https://huggingface.co/Qwen/Qwen-Image-2.1) with the
[Viggle turbo v0.2.1](https://huggingface.co/Viggle/Qwen-Image-2.1-viggle-turbo) distillation LoRA merged into the
transformer and the [Texture-Fix VAE](https://huggingface.co/madebyollin/texture-fix-vae-for-qwen-image-2.1) in place
of the stock decoder. Text-to-image and editing with reference images in **6 steps without guidance**, loaded by the
stock `QwenImage21Pipeline`. Built with Qwen.

A 4-bit build with a quantized text encoder is published as
[WaveCut/Turbo-Image-2.1-OrbitQuant-W4A4](https://huggingface.co/WaveCut/Turbo-Image-2.1-OrbitQuant-W4A4).

![examples](media/examples.jpg)

| Component | Contents | Size |
| --- | --- | ---: |
| `transformer/` | Qwen-Image-2.1 DiT, Viggle turbo v0.2.1 (rank 256) merged in fp32 and stored in fp16 | 14.2 GB |
| `text_encoder/` | Qwen3-VL-8B, unchanged | 17.5 GB |
| `vae/` | Texture-Fix VAE, fp32 | 1.35 GB |
| `scheduler/` | Viggle turbo config: dynamic shift, `shift_terminal` null | |

## Run

```bash
pip install -U torch "transformers>=5.17,<6" accelerate safetensors pillow
pip install "git+https://github.com/huggingface/diffusers.git@80c7ed262aeffbeb43ef13ae04baeb9b84515a69"
```

```python
import torch
from diffusers import QwenImage21Pipeline

pipe = QwenImage21Pipeline.from_pretrained("WaveCut/Turbo-Image-2.1", dtype=torch.float16)
pipe.enable_model_cpu_offload()

SIGMAS = [1.0, 0.9375, 0.875, 0.75, 0.5, 0.25]
image = pipe(
    prompt="A studio portrait of an old fisherman mending a net, warm rim light, 85mm",
    width=1024, height=1024,
    num_inference_steps=6, sigmas=SIGMAS,
    generator=torch.Generator("cuda").manual_seed(0),
).images[0]

edited = pipe(
    prompt="Replace the background of <image1> with a sunset beach; keep the man unchanged.",
    image=[image], output_resolution=1024,
    num_inference_steps=6, sigmas=SIGMAS,
    generator=torch.Generator("cuda").manual_seed(0),
).images[0]
```

Load the pipeline in **fp16**. The merge keeps 99.7 % of the LoRA update in fp16; loading the same weights in bf16
rounds away about a third of it (64 % kept). The text encoder and the VAE work in fp16 as well: text embeddings match
bf16 at cosine 0.998–0.9997, VAE decodes match fp32 at 58–64 dB PSNR.

All weights together are 33 GB, so a 32 GB card needs `enable_model_cpu_offload()` (≈22 s per 1024² image on an
RTX 5090, most of it host transfers). Encoding a batch of prompts first and then running the transformer and the VAE
takes 2.69 s per 1024² image hot (6 steps, peak 22.5 GB) and 17.9 s at 2048². The
[OrbitQuant build](https://huggingface.co/WaveCut/Turbo-Image-2.1-OrbitQuant-W4A4) keeps every component resident in
13.6 GB and needs 2.25 s.

Keep the VAE untiled in fp16. Tiled decoding in fp16 produces non-finite pixels; for 2048² text-to-image cast it
first: `pipe.vae.to(torch.bfloat16); pipe.vae.enable_tiling()` (54 dB PSNR against fp32).

## Sampling recipes

Tested at 1024² on 8 prompts (photo, poster, anime, product, night scene, two Russian-text prompts) with fixed
seeds, plus 4 edits. Times are transformer + VAE on an RTX 5090.

![recipes](media/recipes.jpg)

*Columns: default, 8 steps, 4 steps, static shift 3, CFG 2.*

| Recipe | Settings | Result | Time |
| --- | --- | --- | ---: |
| **Default** | 6 steps, `sigmas=[1, 0.9375, 0.875, 0.75, 0.5, 0.25]`, shipped scheduler, no CFG | Sharpest detail and textures; Latin and Cyrillic text mostly right | 2.9 s |
| **Text, posters, natural skin** | the same 6 sigmas with a static shift of 3: `pipe.scheduler = FlowMatchEulerDiscreteScheduler.from_config(pipe.scheduler.config, use_dynamic_shifting=False, shift=3.0)` | Cleanest lettering in the set (long Russian paragraph almost error-free), smoother skin, calmer micro-texture | 2.9 s |
| Dense text | 8 steps, `sigmas=[1, 0.9375, 0.875, 0.75, 0.625, 0.5, 0.25, 0.125]` | Same composition as the default, small print slightly cleaner | 3.8 s |
| Guidance | 6 steps, `true_cfg_scale=2` with a negative prompt | Higher contrast and saturation, bolder type | 5.8 s |
| Avoid | 4 steps `[1, 0.75, 0.5, 0.25]` | Ghosted double contours, garbled text | 2.0 s |
| Avoid | static shift 5 | Soft, smeared detail | |

Editing: reference images are `<image1>`, `<image2>`, … in the prompt, in the order passed; the canvas follows the last
reference unless `width`/`height` are given; references are encoded at `output_resolution`² area.

## Merge

| | Value |
| --- | --- |
| LoRA | Viggle turbo v0.2.1, rank 256, alpha 256, 227 projections (attention, image MLP, modulation, timestep embedder) |
| Factors | F32 from `peft_v0.2.1/` |
| Update size | median 0.11 % of the weight norm, max 1.6 % |
| Kept after rounding | fp16 99.7 % (rounding noise 18.7 % of the update); bf16 would keep 64 % |
| Output vs runtime LoRA | 0.4–2.8 % latent difference at the same precision and seed |

Everything outside the 227 projections is the upstream bf16 value stored in fp16.

## Files

`transformer/`, `text_encoder/`, `processor/`, `vae/`, `scheduler/`, `model_index.json` — the diffusers pipeline;
`media/` — example images; `LICENSE`, `NOTICE` — license and attribution.

## License

Derivative of Qwen-Image-2.1 under the Qwen RESEARCH LICENSE AGREEMENT (`LICENSE`): non-commercial research and
evaluation only. `NOTICE` lists the modified files and the upstream notices of Viggle and madebyollin.

> Qwen is licensed under the Qwen RESEARCH LICENSE AGREEMENT, Copyright (c) 2026 Hangzhou Tongyi Laboratory Technology
> Co., Ltd. All Rights Reserved.