akhaliq/Qwen-Image-Flash
Qwen-Image-Flash
Custom-frontend Gradio Space that generates images from text prompts using `nvidia/Qwen-Image-Flash` — a four-step, DMD2-distilled version of `Qwen/Qwen-Image`.
Architecture
This Space is built with `gradio.Server` rather than gr.Blocks: it pairs a custom vanilla-HTML/CSS/JS frontend (index.html) with Gradio's backend engine — the queue, concurrency control, ZeroGPU allocation, and gradio_client compatibility — without rendering a Gradio component UI.
- `app.py` — a
gradio.Server(FastAPI subclass) app: @app.get("/")serves the staticindex.htmlfrontend.@app.api def generate_image(...)/@spaces.GPUis the queued backend endpoint the JS client calls. The 20B pipeline loads lazily inside the GPU-decorated handler (so it never triespipe.to("cuda")on the CPU-only Space builder).- `index.html` — self-contained frontend (no build step). It uses the Gradio JS client (
@gradio/client) viaconst c = await Client.connect(window.location.origin); c.predict("/generate_image", {...})so requests go through Gradio's queue instead of a rawfetch(). Add aprompt, negative prompt, width/height/steps/seed, click Generate, and download the PNG.
The endpoint is also callable programmatically:
from gradio_client import Client
c = Client("<your-space>") # or your Space id, e.g. "user/qwen-image-flash"
filedata, seed, info = c.predict(
prompt="A red fox in a snowy pine forest at golden hour, photorealistic, sharp focus, soft bokeh",
negative_prompt="",
width=1024, height=1024,
num_inference_steps=4,
seed=42, randomize_seed=False,
api_name="/generate_image",
)How the model works
The model is distributed as a full Diffusers QwenImagePipeline. The student retains the base Qwen-Image transformer architecture; its weights are replaced by DMD2-distilled student weights. Because the teacher target used CFG=4.0 during distillation, that guidance is internalized by the student, so inference uses true_cfg_scale=1.0 (and guidance_scale=None / negative_prompt=None by default) to avoid applying guidance a second time. The packaged shift-3 FlowMatch Euler scheduler runs four denoising steps.
The tested output setting is 1024 × 1024; width and height must be divisible by 16 (the app enforces this for you).
Defaults in this Space
A negative prompt box is exposed for experimentation, but note the distillation assumes no negative prompt. Seeds can be fixed or randomized.
Run locally
pip install -r requirements.txt
python app.py
# then open the local URL it prints (e.g. http://127.0.0.1:7860)Requires a CUDA GPU (Hopper H100 / Blackwell B200 family). The first generate request triggers the ~20B pipeline download + .to("cuda"), so expect a long warm-up. On a Hugging Face Space this runs under ZeroGPU via the @spaces.GPU decorator.
Usage (library)
import torch
from diffusers import QwenImagePipeline
pipe = QwenImagePipeline.from_pretrained(
"nvidia/Qwen-Image-Flash",
torch_dtype=torch.bfloat16,
).to("cuda")
image = pipe(
prompt="A red fox in a snowy pine forest at golden hour, photorealistic, sharp focus, soft bokeh",
width=1024,
height=1024,
num_inference_steps=4,
true_cfg_scale=1.0,
guidance_scale=None,
negative_prompt=None,
generator=torch.Generator(device="cuda").manual_seed(42),
).images[0]
image.save("qwen-image-flash.png")License
Use of this model is governed by the NVIDIA Open Model Agreement (additional info: Apache License 2.0). The model does not include a safety checker — deployers should add appropriate safeguards.
