Qwen-Image 2.1 in 2 Steps: DMD2 LoRA at CFG 1
A DMD2 distillation LoRA runs Qwen-Image 2.1 text-to-image and multi-reference editing in 2 steps at CFG 1, with a live Space demo and Banodoco test reports.
Sketch to photo, hairstyle, expression and photo restoration, same input, prompt and seed. Each row runs input, the LoRA at 2 steps, then the base model at 20 steps.
Why 2 steps is a different tier
Qwen-Image 2.1 ships at 40 steps, and the accelerators published so far land at 8 (Alibaba's own Turbo checkpoint) and 4 (LightX2V's Lightning LoRA). This adapter targets the floor of that range, and the schedule is fixed rather than recommended:
| Setting | Value |
|---|---|
| Steps | 2 |
| Sigma schedule | [1.0, 0.5], fixed |
| CFG | 1 (true_cfg_scale=1.0) |
| LoRA rank / alpha | 32 / 32 |
| Adapted modules | attention only: to_q, to_k, to_v, to_out.0 |
| File size | 64 MB (256 tensors) |
The card is explicit that the LoRA was trained on that exact pair of sigmas, so the scheduler has to be pinned with use_dynamic_shifting=False and shift=1.0. Leaving dynamic shifting on rescales the sigmas per resolution, and the adapter is no longer sampling the path it was distilled on.
Adapting attention only is the other deliberate choice. The card argues it preserves the input image more faithfully for editing than also adapting the feed-forward blocks, which is where the earlier few-step adapters for this model spent most of their budget.
How it was trained
DMD2 (Distribution Matching Distillation) with on-policy distribution matching and teacher CFG guidance, no regression loss and no GAN loss in the objective. Training ran 2,000 steps on a single H100 over multi-aspect crops at roughly 1 MP, which matches the resolution range the demos use. The 20-step teacher is the reference the card compares against, not the model's 40-step default.
What survives at 2 steps
Editing and multi-reference composition both keep working. Qwen-Image 2.1 takes a list of condition images and the prompt refers to them positionally, so a two-step run still resolves prompts like "place the cat from Picture 1 on the beach from Picture 2" without collapsing to a single reference:
image = pipe(
prompt="Place the cat from Picture 1 on the beach from Picture 2.",
image=[cat, beach],
num_inference_steps=2,
sigmas=[1.0, 0.5],
true_cfg_scale=1.0,
).images[0]Text to image is the same call with the image argument dropped. RGBA output is unchanged, since the alpha channel comes from the base model rather than from the adapter.
The author's demo Space, Qwen Image 2.1 Realtime, puts the same schedule behind a live interface: realtime mode streams a 512px result that updates as the prompt changes, and the full-quality mode jumps to 1024 and 1536.
Community runs
In the Banodoco #qwen-image channel, testers ran the adapter inside ComfyUI on top of the native Qwen-Image 2.1 nodes and posted step comparisons. RuneX reported that a 2-step head swap works and that one extra step was slightly better, over Euler, ER-SDE and LCM samplers. patientx measured 2, 3 and 4 steps back to back and found 3 steps "very close to the real deal", 4 usable and 8 a regression, with the total run time barely moving between 2 and 4 steps because model loading dominates.
The one snag for ComfyUI is the naming. The safetensors is saved in diffusers/PEFT form, transformer.transformer_blocks.N.attn.to_q.lora.down.weight and matching .lora.up tensors, while ComfyUI's loader keys on the model's own parameter names starting at transformer_blocks.N. The leading transformer. has to be stripped before the loader maps anything, otherwise it reports the keys as unmapped and the LoRA does nothing.
Availability
LoRA weights: linoyts/Qwen-Image-2.1-DMD2-2steps on Hugging Face. Base model: Qwen/Qwen-Image-2.1. Demo: Qwen Image 2.1 Realtime.
Comments
Sign in with GitHub to join the discussion.