Add v0.2 adapters

#9
by simlang - opened
.gitattributes CHANGED
@@ -41,3 +41,5 @@ assets/Pruna-Q-Image-2.1-i2i-2048.png filter=lfs diff=lfs merge=lfs -text
41
  assets/Pruna-Q-Image-2.1-t2i-1024.png filter=lfs diff=lfs merge=lfs -text
42
  assets/Pruna-Q-Image-2.1-t2i-2048.png filter=lfs diff=lfs merge=lfs -text
43
  assets/Pruna-Q-Image-2.1.png filter=lfs diff=lfs merge=lfs -text
 
 
 
41
  assets/Pruna-Q-Image-2.1-t2i-1024.png filter=lfs diff=lfs merge=lfs -text
42
  assets/Pruna-Q-Image-2.1-t2i-2048.png filter=lfs diff=lfs merge=lfs -text
43
  assets/Pruna-Q-Image-2.1.png filter=lfs diff=lfs merge=lfs -text
44
+ assets/*.png filter=lfs diff=lfs merge=lfs -text
45
+ assets/Pruna-Qwen-Image-2.1.png filter=lfs diff=lfs merge=lfs -text
README.md CHANGED
@@ -48,7 +48,7 @@ tags:
48
  <h2>Few-step LoRA adapters for Qwen-Image-2.1</h2>
49
 
50
  <h3>
51
- <span style="color: #9334E9;">5 or 8 steps</span>
52
  &nbsp;Β·&nbsp;
53
  <span style="color: #9334E9;">Up to 6.3x faster</span>
54
  &nbsp;Β·&nbsp;
@@ -61,16 +61,133 @@ tags:
61
 
62
  **Pruna-Q-Image-2.1 is a set of LoRA adapters that let
63
  [`Qwen/Qwen-Image-2.1`](https://huggingface.co/Qwen/Qwen-Image-2.1) generate
64
- and edit images in only 5 or 8 steps. The adapters load on top of the base
65
  model, so the pipeline, text encoder, and VAE stay unchanged. Training is based
66
- on DMD. Improved using Qwen.**
 
 
 
 
67
 
68
  > **v0.1: first release, work in progress.** Pruna-Q-Image-2.1 does not yet match the
69
  > visual quality of the base model. We are still improving the distillation and
70
  > will update this repository as new versions become available.
71
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  ## Variants
73
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  Both adapters are v0.1. Pick one based on whether you need **quality** or **speed**.
75
 
76
  | File | Steps | Trade-off |
@@ -79,9 +196,17 @@ Both adapters are v0.1. Pick one based on whether you need **quality** or **spee
79
  | `p_q_image_2.1_5step_v0.1.safetensors` | 5 | **Higher speed**, with noticeably lower visual quality. |
80
 
81
  Each adapter is trained for its own sigma schedule. Load only one at a time.
 
82
 
83
  ## Prompts, editing, and resolution
84
 
 
 
 
 
 
 
 
85
  The adapters were trained at **1K resolution only**, with a mix of simple and
86
  upsampled prompts, text-to-image generation, and single- and multi-image editing
87
  with **up to 3 reference images**. Prompt upsampling is optional; detailed prompts
@@ -94,7 +219,65 @@ inference speed, not a guarantee of quality at that resolution.
94
 
95
  ## Benchmarking
96
 
97
- Use a table; Hugging Face can otherwise render the `<img>` elements as separate blocks.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
98
 
99
  <table>
100
  <tr>
@@ -123,45 +306,6 @@ KV cache off, as configured for this benchmark. The examples below enable KV cac
123
  Pruna-Q-Image-2.1; the chart has not been remeasured with that setting. LoRAs were unmerged;
124
  no CFG, compilation, or CPU offload. These timings do not imply equal image quality.
125
 
126
- ## Quickstart
127
-
128
- Runs text-to-image and image editing with the same pipeline. Needs a **CUDA GPU**.
129
-
130
- ```bash
131
- pip install 'torch>=2.4.0' 'transformers>=5.17' accelerate peft pillow
132
- pip install git+https://github.com/huggingface/diffusers@6256aa7666cedd47443adc8f82da9a10e110b09c
133
- ```
134
-
135
- ```python
136
- import torch
137
- from PIL import Image
138
- from diffusers import FlowMatchEulerDiscreteScheduler, QwenImage21Pipeline
139
-
140
- STEPS = 8 # 8 for higher quality, 5 for higher speed
141
-
142
- # The terminal sigma 0 is appended by the scheduler.
143
- SIGMAS = {
144
- 5: [1.0, 0.94, 6 / 7, 2 / 3, 0.4],
145
- 8: [1.0, 14 / 15, 6 / 7, 10 / 13, 2 / 3, 6 / 11, 0.4, 2 / 9],
146
- }[STEPS]
147
-
148
- pipe = QwenImage21Pipeline.from_pretrained(
149
- "Qwen/Qwen-Image-2.1", torch_dtype=torch.bfloat16
150
- ).to("cuda")
151
- pipe.load_lora_weights(
152
- "PrunaAI/Pruna-Q-Image-2.1",
153
- weight_name=f"p_q_image_2.1_{STEPS}step_v0.1.safetensors",
154
- )
155
-
156
- # Use the sigmas exactly as given: no extra shifting.
157
- pipe.scheduler = FlowMatchEulerDiscreteScheduler.from_config(
158
- pipe.scheduler.config,
159
- use_dynamic_shifting=False,
160
- shift=1.0,
161
- shift_terminal=None,
162
- )
163
- ```
164
-
165
  ## For Text-to-Image
166
 
167
  Longer, more descriptive prompts give better results.
@@ -199,6 +343,13 @@ image = pipe(
199
 
200
  ### Recommended settings
201
 
 
 
 
 
 
 
 
202
  - **Use the sigma schedule that matches your adapter**, and keep the scheduler
203
  at `shift=1.0` with dynamic shifting off so the sigmas are not shifted twice.
204
  - 8-step: `1 β†’ 14/15 β†’ 6/7 β†’ 10/13 β†’ 2/3 β†’ 6/11 β†’ 0.4 β†’ 2/9 β†’ 0`
@@ -212,6 +363,17 @@ image = pipe(
212
 
213
  ## Limitations
214
 
 
 
 
 
 
 
 
 
 
 
 
215
  - This is a first version. Quality is below that of the base model.
216
  - The 5-step adapter is faster than the 8-step one, but its images are
217
  visibly worse.
 
48
  <h2>Few-step LoRA adapters for Qwen-Image-2.1</h2>
49
 
50
  <h3>
51
+ <span style="color: #9334E9;">6 steps (v0.2), 5 or 8 steps (v0.1)</span>
52
  &nbsp;Β·&nbsp;
53
  <span style="color: #9334E9;">Up to 6.3x faster</span>
54
  &nbsp;Β·&nbsp;
 
61
 
62
  **Pruna-Q-Image-2.1 is a set of LoRA adapters that let
63
  [`Qwen/Qwen-Image-2.1`](https://huggingface.co/Qwen/Qwen-Image-2.1) generate
64
+ and edit images in only 6 steps (v0.2), or 5 or 8 steps (v0.1). The adapters load on top of the base
65
  model, so the pipeline, text encoder, and VAE stay unchanged. Training is based
66
+ on DMD.**
67
+
68
+ > **v0.2: two new 6-step adapters.** A basic distillation for faithful generation
69
+ > and editing, and a first attempt at distilling prompt upsampling into the LoRA.
70
+ > The v0.1 adapters remain available.
71
 
72
  > **v0.1: first release, work in progress.** Pruna-Q-Image-2.1 does not yet match the
73
  > visual quality of the base model. We are still improving the distillation and
74
  > will update this repository as new versions become available.
75
 
76
+ ## Quickstart
77
+
78
+ Runs text-to-image and image editing with the same pipeline. Needs a **CUDA GPU**.
79
+
80
+ ```bash
81
+ pip install 'torch>=2.4.0' 'transformers>=5.17' accelerate peft pillow
82
+ pip install git+https://github.com/huggingface/diffusers@6256aa7666cedd47443adc8f82da9a10e110b09c
83
+ ```
84
+
85
+ ### v0.2
86
+
87
+ Use this setup for either v0.2 adapter.
88
+
89
+ ```python
90
+ import torch
91
+ from PIL import Image
92
+ from diffusers import FlowMatchEulerDiscreteScheduler, QwenImage21Pipeline
93
+
94
+ # Both v0.2 adapters use this unshifted six-step schedule.
95
+ # The scheduler applies the resolution-dependent shift and appends sigma 0.
96
+ STEPS = 6
97
+ VARIANT = "basic" # "basic" or "upsampled"
98
+ WEIGHT_NAME = {
99
+ "basic": "p_q_image_2.1_basic_6_steps_v0.2.safetensors",
100
+ "upsampled": "p_q_image_2.1_upsampled_6_steps_v0.2.safetensors",
101
+ }[VARIANT]
102
+ SIGMAS = [1.0, 0.925, 0.85, 0.625, 0.375, 0.125]
103
+
104
+ pipe = QwenImage21Pipeline.from_pretrained(
105
+ "Qwen/Qwen-Image-2.1", torch_dtype=torch.bfloat16
106
+ ).to("cuda")
107
+ pipe.load_lora_weights(
108
+ "PrunaAI/Pruna-Q-Image-2.1",
109
+ weight_name=WEIGHT_NAME,
110
+ )
111
+
112
+ # Shift the raw sigmas using the base model's resolution-dependent settings.
113
+ pipe.scheduler = FlowMatchEulerDiscreteScheduler.from_config(
114
+ pipe.scheduler.config,
115
+ use_dynamic_shifting=True,
116
+ shift_terminal=None,
117
+ )
118
+ ```
119
+
120
+
121
+ Both variants load on **`Qwen/Qwen-Image-2.1`** using **`QwenImage21Pipeline`**.
122
+ Choose one LoRA with `VARIANT`; the prompt-upsampled variant runs directly on your
123
+ original prompt without a separate prompt-enhancer model. For a local export,
124
+ replace `"PrunaAI/Pruna-Q-Image-2.1"` with the folder containing the chosen
125
+ safetensors file and keep `weight_name=WEIGHT_NAME`.
126
+
127
+ Both files have **rank 64** across **232 linear targets**, including `proj_out`.
128
+ Training used alpha 128; the exported B matrices include the `128 / 64 = 2`
129
+ scale. Load at **LoRA strength 1.0** with the standard pipeline loader.
130
+
131
+ For v0.2 benchmark settings, pass `output_resolution=1024` and
132
+ `use_kv_cache=False` in the generation and editing calls below.
133
+
134
+ ### v0.1
135
+
136
+ ```python
137
+ import torch
138
+ from PIL import Image
139
+ from diffusers import FlowMatchEulerDiscreteScheduler, QwenImage21Pipeline
140
+
141
+ STEPS = 8 # 8 for higher quality, 5 for higher speed
142
+
143
+ # The terminal sigma 0 is appended by the scheduler.
144
+ SIGMAS = {
145
+ 5: [1.0, 0.94, 6 / 7, 2 / 3, 0.4],
146
+ 8: [1.0, 14 / 15, 6 / 7, 10 / 13, 2 / 3, 6 / 11, 0.4, 2 / 9],
147
+ }[STEPS]
148
+
149
+ pipe = QwenImage21Pipeline.from_pretrained(
150
+ "Qwen/Qwen-Image-2.1", torch_dtype=torch.bfloat16
151
+ ).to("cuda")
152
+ pipe.load_lora_weights(
153
+ "PrunaAI/Pruna-Q-Image-2.1",
154
+ weight_name=f"p_q_image_2.1_{STEPS}step_v0.1.safetensors",
155
+ )
156
+
157
+ # Use the sigmas exactly as given: no extra shifting.
158
+ pipe.scheduler = FlowMatchEulerDiscreteScheduler.from_config(
159
+ pipe.scheduler.config,
160
+ use_dynamic_shifting=False,
161
+ shift=1.0,
162
+ shift_terminal=None,
163
+ )
164
+ ```
165
+
166
  ## Variants
167
 
168
+ ### v0.2
169
+
170
+ Pick **basic** for faithful base-model behavior, or **prompt-upsampled** for
171
+ improved visual quality from a short prompt.
172
+
173
+ | File | Steps | Trade-off |
174
+ |---|:---:|---|
175
+ | `p_q_image_2.1_basic_6_steps_v0.2.safetensors` | 6 | **Pure few-step distillation.** Recommended for preserving inputs when editing. |
176
+ | `p_q_image_2.1_upsampled_6_steps_v0.2.safetensors` | 6 | **Improved visual quality.** A first attempt at distilling prompt upsampling into the adapter. |
177
+
178
+ **Basic** is a pure 6-step distillation of the base model, without any additional
179
+ post-training. It is intended as a drop-in replacement for the base model in
180
+ existing generation and editing workflows, using the adapter's step count and
181
+ sigma schedule. It improves on the v0.1 adapters in almost all categories and is
182
+ particularly good at editing tasks where preserving the input matters.
183
+
184
+ **Prompt-upsampled** attempts to distill the prompt upsampler recommended for
185
+ Qwen-Image-2.1 into a 6-step LoRA. It improves visual quality without a separate
186
+ prompt-upsampling call. This is our first attempt: it may not reproduce exactly
187
+ what the actual prompt upsampler would do, and we will continue improving it.
188
+
189
+ ### v0.1
190
+
191
  Both adapters are v0.1. Pick one based on whether you need **quality** or **speed**.
192
 
193
  | File | Steps | Trade-off |
 
196
  | `p_q_image_2.1_5step_v0.1.safetensors` | 5 | **Higher speed**, with noticeably lower visual quality. |
197
 
198
  Each adapter is trained for its own sigma schedule. Load only one at a time.
199
+ For the v0.2 adapters, do not reuse the v0.1 schedules.
200
 
201
  ## Prompts, editing, and resolution
202
 
203
+ For **v0.2**:
204
+
205
+ For **basic**, use the same prompts and reference images you would use with the
206
+ base model. For **prompt-upsampled**, start with your original prompt; the adapter
207
+ is intended to capture the benefit of prompt upsampling during generation.
208
+ Detailed prompts still let you specify the subject, setting, lighting, and style.
209
+
210
  The adapters were trained at **1K resolution only**, with a mix of simple and
211
  upsampled prompts, text-to-image generation, and single- and multi-image editing
212
  with **up to 3 reference images**. Prompt upsampling is optional; detailed prompts
 
219
 
220
  ## Benchmarking
221
 
222
+ ### v0.2: 6-step LoRA and prompt upsampling
223
+
224
+ <table>
225
+ <tr>
226
+ <td>
227
+ <img src="assets/Pruna-Q-Image-2.1-v02-generation.png" alt="Six-step generation latency at 1024 and 2048 pixels" width="100%">
228
+ </td>
229
+ </tr>
230
+ <tr>
231
+ <td>
232
+ <img src="assets/Pruna-Q-Image-2.1-prompt-upsampling.png" alt="Prompt-upsampling latency for text and one to three reference images" width="100%">
233
+ </td>
234
+ </tr>
235
+ </table>
236
+
237
+ One NVIDIA H100 80GB per worker, BF16, batch size 1. Median of 3 requests after
238
+ one warmup per configuration, with seed 42. Wall-clock time is measured around
239
+ the complete request, with CUDA synchronization before and after. Generation
240
+ includes prompt encoding, reference-image
241
+ processing, denoising, and VAE decoding to a PIL image. It excludes model and
242
+ adapter loading, warmup, fixture preparation, file saving, and network transport.
243
+ No CFG, compilation, CPU offload, or diffusion KV caching.
244
+
245
+ Prompt upsampling is measured separately using
246
+ [`Qwen-Image-2.1-PE-T2I`](https://huggingface.co/Qwen/Qwen-Image-2.1-PE-T2I)
247
+ and [`Qwen-Image-2.1-PE-I2I`](https://huggingface.co/Qwen/Qwen-Image-2.1-PE-I2I),
248
+ with their task-specific sampling settings and thinking enabled. Timing includes
249
+ request preparation from in-memory images, image and text processing, text
250
+ generation, and response parsing. It does not include image generation. The
251
+ upsampler uses vLLM in eager mode, without prefix or image-processor caching.
252
+ Each request receives fresh image identifiers, so vision encoding is included
253
+ on repeated requests too. Autoregressive KV caching remains enabled; it is
254
+ separate from diffusion KV caching.
255
+
256
+ Each editing case uses a fixed original prompt and 1, 2, or 3 reference images,
257
+ square-cropped and resized to the requested resolution before timing.
258
+ Text-to-image uses the official Qwen model-card example prompt. Latency depends
259
+ on the prompt, image
260
+ content, and generated rewrite length. These cases are not a controlled
261
+ comparison with the v0.1 chart inputs. Adding the two medians does not
262
+ measure an end-to-end prompt-upsampling-plus-generation request.
263
+
264
+ Software and prompt-upsampling settings
265
+
266
+ Generation uses PyTorch 2.11.0 with CUDA 12.8, Transformers 5.20.1, PEFT 0.21.2,
267
+ and Diffusers commit `6256aa7666cedd47443adc8f82da9a10e110b09c`, the same Diffusers
268
+ revision used in the quickstart. Prompt upsampling uses vLLM 0.19.1, PyTorch
269
+ 2.10.0, and Transformers 5.19.0. These runtime versions are recorded for the new
270
+ measurements; the v0.1 charts have not been rerun in this environment.
271
+
272
+ Both prompt enhancers use their checkpoint's system prompt, thinking enabled,
273
+ `temperature=1.0`, `top_p=0.95`, `top_k=20`, and `min_p=0.0`. Text-to-image uses
274
+ `presence_penalty=1.5` and a 16,256-token output limit; editing uses
275
+ `presence_penalty=0.0` and a 24,000-token output limit. A configuration is
276
+ reported only if all three measured rewrites complete and parse successfully.
277
+ No requests are silently retried.
278
+
279
+ ### v0.1
280
+
281
 
282
  <table>
283
  <tr>
 
306
  Pruna-Q-Image-2.1; the chart has not been remeasured with that setting. LoRAs were unmerged;
307
  no CFG, compilation, or CPU offload. These timings do not imply equal image quality.
308
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
309
  ## For Text-to-Image
310
 
311
  Longer, more descriptive prompts give better results.
 
343
 
344
  ### Recommended settings
345
 
346
+ For **v0.2**, use the unshifted six-step sigmas
347
+ `[1.0, 0.925, 0.85, 0.625, 0.375, 0.125]` with dynamic shifting enabled
348
+ and `shift_terminal=None`, as shown in the v0.2 setup. The scheduler appends
349
+ terminal zero. Keep `true_cfg_scale=1.0` and LoRA strength 1.0.
350
+
351
+ The **v0.1** settings are:
352
+
353
  - **Use the sigma schedule that matches your adapter**, and keep the scheduler
354
  at `shift=1.0` with dynamic shifting off so the sigmas are not shifted twice.
355
  - 8-step: `1 β†’ 14/15 β†’ 6/7 β†’ 10/13 β†’ 2/3 β†’ 6/11 β†’ 0.4 β†’ 2/9 β†’ 0`
 
363
 
364
  ## Limitations
365
 
366
+ ### v0.2
367
+
368
+ - The prompt-upsampled adapter is a first attempt. It can improve visual quality,
369
+ but may not exactly reproduce the output of the actual prompt upsampler.
370
+ - Basic is intended to preserve the base model's behavior in fewer steps;
371
+ distillation does not guarantee identical outputs.
372
+ - Use the step count and sigma schedule that match your v0.2 adapter. Other step
373
+ counts, schedules, or CFG values are not supported.
374
+
375
+ ### v0.1
376
+
377
  - This is a first version. Quality is below that of the base model.
378
  - The 5-step adapter is faster than the 8-step one, but its images are
379
  visibly worse.
assets/{latency_t2i_1k_2k.png β†’ Pruna-Q-Image-2.1-prompt-upsampling.png} RENAMED
File without changes
assets/{edit_grid.jpg β†’ Pruna-Q-Image-2.1-v02-generation.png} RENAMED
File without changes
assets/Pruna-Q-Image-2.1.png CHANGED

Git LFS Details

  • SHA256: cadcd8a0863a2c547a85737c20bc5a51fea3ccec2db1ebfe9109646307cc5f87
  • Pointer size: 133 Bytes
  • Size of remote file: 35.6 MB

Git LFS Details

  • SHA256: b25b7bd02bbee02ab3efc79f56822298b1244bd34a60e73ec1889133bebda4f4
  • Pointer size: 133 Bytes
  • Size of remote file: 37.5 MB
p_q_image_2.1_basic_6_steps_v0.2.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d10a0ab365df3829d460be9196f6a8a7d0e8f5498f5a3f25d924b8f9ee8c94bb
3
+ size 688027008
p_q_image_2.1_upsampled_6_steps_v0.2.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:3c86e69c1242625923d1454ba01ea6cef900f80ee891c5fa245173ed4abac9c2
3
+ size 688027008