Files
wehub-resource-sync eec33d25b2
pre-commit / pre-commit (push) Failing after 1s
Build Wheel / build (3.11) (push) Failing after 1s
Build Wheel / build (3.12) (push) Failing after 0s
chore: import upstream snapshot with attribution
2026-07-13 12:29:08 +08:00

9.4 KiB

Text-To-Image

Source https://github.com/vllm-project/vllm-omni/tree/main/examples/offline_inference/text_to_image.

Generate images from text prompts using vLLM-Omni's diffusion pipeline entrypoints.

  • text_to_image.py: command-line script for single image generation with advanced options.
  • gradio_demo.py: lightweight Gradio UI for interactive prompt/seed/CFG exploration.

Table of Contents

Overview

This folder provides several entrypoints for experimenting with text-to-image diffusion models using vLLM-Omni. Note that NextStep-1.1 has a different architecture, so it is treated differently regarding running arguments and pipeline.

Supported Models

Model Image Shape Peak VRAM (GiB) * Model Weights (GiB)
Qwen/Qwen-Image 1024 x 1024 60.0 53.7
Qwen/Qwen-Image-2512 1024 x 1024 60.0 53.7
Tongyi-MAI/Z-Image-Turbo 1024 x 1024 24.8 19.2
stepfun-ai/NextStep-1.1 512 x 512 71.8 28.1
meituan-longcat/LongCat-Image 1024 x 1024 71.2 27.3
AIDC-AI/Ovis-Image-7B 1024 x 1024 71.8 17.1
OmniGen2/OmniGen2 1024 x 1024 20.1 14.7
stabilityai/stable-diffusion-3.5-medium 1024 x 1024 20.1 15.6
black-forest-labs/FLUX.1-dev 1024 x 1024 77.6 31.4
black-forest-labs/FLUX.2-klein-4B 1024 x 1024 72.7 14.9
black-forest-labs/FLUX.2-klein-9B 1024 x 1024 37.1 32.3
black-forest-labs/FLUX.2-dev 1024 x 1024 65.7 >80 (CPU offload required)

!!! info *Peak VRAM: based on basic single-card usage, batch size =1, without any acceleration/optimization features. FLUX.2-dev requires --enable-cpu-offload on a single 80 GiB GPU.

Default model: Qwen/Qwen-Image

Quick Start

Python API

Single-prompt generation:

from vllm_omni.entrypoints.omni import Omni

if __name__ == "__main__":
    omni = Omni(model="Qwen/Qwen-Image")
    prompt = "a cup of coffee on the table"
    outputs = omni.generate(prompt)
    images = outputs[0].request_output.images
    images[0].save("coffee.png")

Local CLI Usage

python text_to_image.py \
  --model Qwen/Qwen-Image \
  --prompt "a cup of coffee on the table" \
  --output coffee.png

Key Arguments

Common arguments:

Argument Type Default Description
--prompt str "a cup of coffee on the table" Text description for image generation
--seed int 142 Integer seed for deterministic sampling
--negative-prompt str None Negative prompt for classifier-free conditional guidance
--cfg-scale float 4.0 True CFG scale (model-specific guidance strength)
--guidance-scale float 1.0 Classifier-free guidance scale
--num-images-per-prompt int 1 Number of images per prompt (saved as output, output_1, ...)
--num-inference-steps int 50 Diffusion sampling steps (more steps = higher quality, slower)
--height int 1024 Output image height in pixels
--width int 1024 Output image width in pixels
--output str "qwen_image_output.png" Path to save the generated image
--vae-use-slicing flag off Enable VAE slicing for memory optimization
--vae-use-tiling flag off Enable VAE tiling for memory optimization
--cfg-parallel-size int 1 Set to 2 to enable CFG Parallel
--enable-cpu-offload flag off Enable CPU offloading for diffusion models
--lora-path str Path to PEFT LoRA adapter folder
--lora-scale float 1.0 Scale factor for LoRA weights

NextStep-1.1 specific arguments:

Argument Type Default Description
--guidance-scale-2 float 1.0 Secondary guidance scale (e.g. image-level CFG)
--timesteps-shift float 1.0 Timesteps shift parameter for sampling
--cfg-schedule str "constant" CFG schedule type: "constant" or "linear"
--use-norm flag off Apply layer normalization to sampled tokens

If you encounter OOM errors, try using --vae-use-slicing and --vae-use-tiling to reduce memory usage.

Qwen-Image currently publishes best-effort presets at 1328x1328, 1664x928, 928x1664, 1472x1140, 1140x1472, 1584x1056, and 1056x1584. Adjust --height/--width accordingly for the most reliable outcomes.

More CLI Examples

Tongyi Models

python text_to_image.py \
  --model Tongyi-MAI/Z-Image-Turbo \
  --prompt "a cup of coffee on the table" \
  --seed 42 \
  --guidance-scale 0.0 \
  --num-images-per-prompt 1 \
  --num-inference-steps 9 \
  --height 1024 \
  --width 1024 \
  --output outputs/coffee.png

Tongyi-MAI/Z-Image-Turbo is a distilled version of Z-Image. Distilled diffusion models usually require less number of inference steps (4~9), and Classifier-Free Guidance (CFG) is usually NOT applied. Similar distilled models are black-forest-labs/FLUX.2-klein-4B and black-forest-labs/FLUX.2-klein-9B.

NextStep Models

NextStep-1.1 supports extra arguments for dual-level CFG control:

python text_to_image.py \
  --model stepfun-ai/NextStep-1.1 \
  --prompt "A baby panda wearing an Iron Man mask, holding a board with 'NextStep-1' written on it" \
  --height 512 \
  --width 512 \
  --num-inference-steps 28 \
  --guidance-scale 7.5 \
  --guidance-scale-2 1.0 \
  --cfg-schedule constant \
  --output nextstep_output.png \
  --seed 42

FLUX.2-dev Models

To run FLUX.2-dev on a single GPU, --enable-cpu-offload is required because the model weights exceed 80 GiB:

python examples/offline_inference/text_to_image/text_to_image.py \
  --model black-forest-labs/FLUX.2-dev \
  --prompt "a lovely bunny holding a sign that says 'vllm-omni'" \
  --seed 42 \
  --tensor-parallel-size 1 \
  --num-images-per-prompt 1 \
  --num-inference-steps 50 \
  --guidance-scale 4.0 \
  --height 1024 \
  --width 1024 \
  --enable-cpu-offload \
  --output flux2-dev.png

Multiple Prompts

You can pass multiple prompts in a single generate call. For diffusion pipelines, each prompt is submitted as a separate logical request; compatible requests may be automatically batched by the scheduler and runner.

from vllm_omni.entrypoints.omni import Omni

if __name__ == "__main__":
    omni = Omni(model="Qwen/Qwen-Image")
    prompts = [
        "a cup of coffee on a table",
        "a toy dinosaur on a sandy beach",
        "a fox waking up in bed and yawning",
    ]
    outputs = omni.generate(prompts)
    for i, output in enumerate(outputs):
        output.request_output.images[0].save(f"{i}.jpg")

!!! info

For diffusion request-level batching controls such as `max_num_seqs`, see
[Request-Level Batching](../../diffusion/request_batching.md).

Negative Prompts

vLLM-Omni supports dictionary prompts for models that accept negative prompts:

from vllm_omni.entrypoints.omni import Omni

if __name__ == "__main__":
    omni = Omni(model="Qwen/Qwen-Image")
    outputs = omni.generate([
        {
            "prompt": "a cup of coffee on a table",
            "negative_prompt": "low resolution"
        },
        {
            "prompt": "a toy dinosaur on a sandy beach",
            "negative_prompt": "cinematic, realistic"
        }
    ])
    for i, output in enumerate(outputs):
        output.request_output.images[0].save(f"{i}.jpg")

You can also pass a negative prompt via the CLI argument --negative-prompt:

python examples/offline_inference/text_to_image/text_to_image.py \
  --model Qwen/Qwen-Image \
  --prompt "a cup of coffee on a table" \
  --negative-prompt "low resolution, blurry" \
  --output coffee.png

Advanced Features

CFG Parallel

Set --cfg-parallel-size 2 to enable CFG Parallel for faster inference on multi-GPU setups. See more examples in the diffusion acceleration user guide.

LoRA

This example supports PEFT-compatible LoRA (Low-Rank Adaptation) adapters for diffusion models. Pass --lora-path to use a LoRA adapter and optionally --lora-scale (default 1.0); omit it to use the base model only.

python text_to_image.py \
  --model Tongyi-MAI/Z-Image-Turbo \
  --prompt "A piece of cheesecake" \
  --lora-path /path/to/lora/ \
  --lora-scale 1.0 \
  --output output.png

LoRA adapters must be in PEFT format. A typical adapter directory structure:

lora_adapter/
├── adapter_config.json
└── adapter_model.safetensors

Web UI Demo

!!! note "Gradio is an optional dependency" The Gradio demo requires the [demo] extras. Install them first:

```bash
pip install 'vllm-omni[demo]'
```

Or, if installing from source: `pip install -e '.[demo]'`

Launch the Gradio demo:

python gradio_demo.py --port 7862

Then open http://localhost:7862/ in your local browser to interact with the web UI.

Example materials

??? abstract "gradio_demo.py" py --8<-- "examples/offline_inference/text_to_image/gradio_demo.py" ??? abstract "text_to_image.py" py --8<-- "examples/offline_inference/text_to_image/text_to_image.py"