Qwen-Image FlowGRPO
Last updated: 09/23/2026
See the FlowGRPO trainer guide for installation, OCR data and reward-model setup.
VeOmni LoRA
VeOmni 0.1.12 or newer is required for native LoRA injection and adapter-to-rollout synchronization. Install it as described in Installing VeOmni alongside vLLM 0.30.0:
bash examples/flowgrpo_trainer/qwen_image/run_qwen_image_ocr_lora_veomni.sh
The recipe mirrors run_qwen_image_ocr_lora.sh and replaces the actor and reference backends with VeOmni.
It keeps vLLM-Omni for rollout and uses explicit LoRA target modules because VeOmni does not support the
all-linear shorthand. It runs the legacy (v0) trainer; VeOmni LoRA has not been validated with the V1 trainer.
With VeOmni, actor and reference attention come from veomni_config.attn_implementation, not
model.attn_backend. The VeOmni engine accepts eager, flash_attention_2_hub, and
flash_attention_3_hub for every model (the recipe uses flash_attention_3_hub, matching the rollout’s
FLASH_ATTN_3_HUB).
The tiny LoRA smoke is a standalone script and is not part of the GPU smoke CI:
NUM_GPUS=2 BACKEND=veomni bash tests/special_e2e/run_flowgrpo_qwen_image_veomni_lora.sh
# Check the existing FSDP2 export/binding path with the same smoke:
NUM_GPUS=2 BACKEND=fsdp2 bash tests/special_e2e/run_flowgrpo_qwen_image_veomni_lora.sh
Regional compilation
For FSDP2 with ulysses_sequence_parallel_size=1, regional compilation can
compile the repeated Qwen-Image transformer blocks to improve training
performance. The benchmark recipe enables the configuration validated with
FA3:
bash examples/flowgrpo_trainer/qwen_image/run_qwen_image_ocr_fsdp2_benchmark.sh
Set actor_rollout_ref.model.use_regional_compile=true to enable the feature.
The benchmark uses fullgraph=false because the current FA3 path requires a
graph break, and dynamic=true for prompt-dependent input shapes. Append
actor_rollout_ref.model.use_regional_compile=false to the benchmark command
to compare against eager execution. Other compiler options can be customized
through actor_rollout_ref.model.regional_compile_options; see the
configuration reference
for all defaults and current constraints.
Optional timestep input staging
For Qwen-Image (QwenImagePipeline) FlowGRPO or DiffusionNFT with FSDP/FSDP2 on
GPU and ulysses_sequence_parallel_size=1, the default-off actor option can
reduce the number of trajectory inputs resident on the device:
bash examples/flowgrpo_trainer/qwen_image/run_qwen_image_ocr_lora.sh \
actor_rollout_ref.actor.enable_timestep_staging=true
The same override works with the Qwen-Image DiffusionNFT recipe. It keeps the caller’s trajectory on CPU, copies shared prompt conditions once per micro-batch, then transfers the current timestep’s inputs. FlowGRPO stages the current/next latent pair and matching loss fields; DiffusionNFT keeps the clean latent and shared noise on device and stages per-step noise when present. Consumed tensor inputs must be on CPU without gradients.
Qwen-Image FlowGRPO/DiffusionNFT on GPU with FSDP/FSDP2 and SP=1 is the validated scope. Other models, algorithms and backends are not covered by this feature’s validation; there is no model-name or device allowlist in the shared engine. The trainer’s config validation rejects staging with sequence parallelism. Inference does not stage inputs. Training outputs remain discarded after backward unless explicitly requested.
Transfers are synchronous, without prefetch or an overlap guarantee. Full CPU trajectory storage is unchanged. Measure both peak memory and update time: this trades device memory for transfers, not a guaranteed throughput gain. See output lifetime and staging details.