Skip to content

Add Qwen-Image 2.1 family support and a 1-GPU PickScore Flow-GRPO recipe - #256

Merged
Rockdu merged 21 commits into
mainfrom
feat/qwen-image-21
Oct 19, 2026
Merged

Rockdu merged 21 commits into
mainfrom
feat/qwen-image-21

Conversation

@niehen6174

@niehen6174 niehen6174 commented Sep 21, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Adds qwen_image21 as a separate train/rollout family from Qwen-Image 1.0, plus one official 1-GPU T2I recipe: Flow-GRPO + PickScore.

2.1 is Qwen3-VL conditioning, single-stream block-causal DiT, RGBA VAE, and CFG-distilled (default guidance 1.0). This PR only covers the T2I path. I2I is served by the engine but has no recipe yet.

Qwen-Image 2.1 support is already on sglang main and diffusers main (landed via sglang #39983 and diffusers #14804). This PR does not pin those packages to a released version yet; until miles-diffusion's default deps include them, point SGLANG_21_PYTHON / DIFFUSERS_21_SRC at current main checkouts.

What's included

Train config (qwen_image21)

  • Timesteps ÷ 1000 (matches diffusers t / 1000)
  • CFG combine without cond-norm rescale
  • Rebuild img_mask / img_shapes from --diffusion-height/width
  • Slice noise pred to the image tail ([:, -target_tokens:])
  • Rebuild RoPE caches on CUDA after materialize
  • LoRA targets: to_q/k/v, to_out.0, img_mlp.{proj,out,gate_layer}

Rollout patch group qwen_image21

  • Disable 2.1 fused kernels
  • Wipe prefix caches every step so the engine reruns the full joint sequence (same as train)
  • Reuse the 1.0 PEFT-ordered LoRA forwards for IPC-synced adapters

Recipe

  • scripts/run_diffusion_grpo_qwenimage21_pickscore_1gpu_v2.py
  • 512² / 10 steps / CFG 1.0 / SDE 3–5 / LoRA 64/128
  • 16 prompts × 16 samples, lr 1e-4, 200 rollouts
  • --rollout-return-full-trajectory so SDE-window conversion can index a full 0..T latent array

Docs / tests

  • Family page: docs/models/qwen-image/qwen-image-21.md
  • Listed in README / docs index / CLI help
  • Fast tests for config, registry, FSDP plan, and patch-group registration

How to run

Recipes must pass --diffusion-model-family qwen_image21. A bare qwen-image substring (including Qwen/Qwen-Image-2.1) still resolves to the 1.0 family.

python3 scripts/run_diffusion_grpo_qwenimage21_pickscore_1gpu_v2.py \
  --hf-checkpoint /path/to/Qwen-Image-2.1 \
  --prompt-data /path/to/flowgrpo_pickscore

If the installed sglang / diffusers are not yet new enough, set SGLANG_21_PYTHON and DIFFUSERS_21_SRC at current main checkouts. Real-weight GRPO needs ≥80GB; 32GB only finished generate.

Results

PickScore reward_mean

raw_mean2

log_prob_mean_abs_diff
log_prob_diff2

Out of scope / follow-ups

  • Pin sglang / diffusers (and any related extras) to released versions that already include 2.1, so recipes do not need SGLANG_21_PYTHON / DIFFUSERS_21_SRC
  • Engine echo of latent_step_indices — this PR uses --rollout-return-full-trajectory instead
  • Bitwise train/rollout (needs a joint engine forward + more op patches; dummy alignment is log_prob_mean_abs_diff ≈ 5e-5)
  • I2I recipe

Test plan

  • Fast tests: qwen_image21 config / registry / FSDP plan / patch group
  • Dummy alignment: log_prob_mean_abs_diff ~5e-5
  • Real ckpt generate
  • 1-GPU GRPO on ≥80GB with the v2 recipe

Register the single-stream T2I family so FSDP can load the 2.1 DiT, rebuild
joint img_mask/img_shapes, and slice the image tail of the noise prediction.
Disable 2.1 fused kernels, wipe prefix KV before every denoise step, and
reuse the PEFT-ordered LoRA add so IPC-synced adapters match the trainer.
Colocate train, sglang, and PickScore for a wiring and log_prob_diff check
at 512^2. 2.1 checkouts are prepended only when SGLANG_21_PYTHON or
DIFFUSERS_21_SRC is set.
Scale the 1.0 flow_grpo window to one GPU: 8x8 samples, lr 3e-4, 400
rollouts. Keep CFG at 1.0 because 2.1 is distilled.
After the 8x8 long run collapsed, use 16x16 samples and lr 1e-4 so each
update sees a larger group with less noisy steps.
Point the model list and CLI help at family key qwen_image21, and note
that HF ids still matching qwen-image need an explicit family flag.
@Rockdu Rockdu added the run-ci-basic Authorize and run only basic unlabeled CI tests label Sep 22, 2026
Comment thread docs/models/qwen-image/qwen-image-21.md
Comment thread docs/user-guide/cli-reference.md Outdated
Comment thread docs/index.md Outdated
Comment thread miles/backends/fsdp_utils/configs/qwen_image21.py Outdated
Qwen-Image-2.1 contains the 1.0 substring qwen-image, so first-match resolution selected the wrong family.
Qwen/Qwen-Image-2.1 now resolves to qwen_image21 without an explicit family flag.
That pad only kept Qwen-Image 1.0 bitwise with the pre-refactor whole-window collate.
Record the 200-rollout reward curve and the train/rollout log-prob gap.
The index names the recipe, not the topology it was first run on.
# Conflicts:
#	docs/user-guide/cli-reference.md
#	docs/user-guide/customization.md
#	docs/user-guide/recipe-verification.md
…t and task check

Signed-off-by: rockdu <kangrdu@gmail.com>
…uts out of the rollout env

Signed-off-by: rockdu <kangrdu@gmail.com>
…ollate branches

Signed-off-by: rockdu <kangrdu@gmail.com>
…vars and full trajectory

Signed-off-by: rockdu <kangrdu@gmail.com>
…uplicate timestep case

Signed-off-by: rockdu <kangrdu@gmail.com>
…-miles and diffusers 0.41

Signed-off-by: rockdu <kangrdu@gmail.com>
@Rockdu
Rockdu force-pushed the feat/qwen-image-21 branch from d744d21 to dd19550 Compare October 18, 2026 23:46
@Rockdu
Rockdu merged commit 7ca0581 into main Oct 19, 2026
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

run-ci-basic Authorize and run only basic unlabeled CI tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants