Views
No views yet

![]() 4-step samples from RTDMD-distilled FLUX.2 4B (no classifier-free guidance). |
![]() Qualitative comparison for few-step diffusion models (4 NFE). |

| Stage | Trainer | Key knobs |
|---|---|---|
| 1. AC-DMD cold start | ACDMDTrainer (--trainer ac_dmd) | sub-interval renoising, consistency weight γ, CPS sampler η = 0.9 |
| 2. RTDMD RL fine-tune | RTDMDTrainer (--trainer rtdmd) | SubGRPO + final-step BP + AC-DMD |
.
├── cold_start/
│ └── generator_ema.pt # Stage-1 AC-DMD LoRA (4 NFE base)
└── rtdmd/
└── generator_ema.pt # Stage-2 RTDMD LoRA (stacked on top of cold_start)generator_ema.pt is a torch.save-d state_dict containing only LoRA
adapter keys (lora_A / lora_B, rank 32, alpha 64). The two adapters
are designed to be stacked: the cold-start LoRA distills FLUX.2-klein 4B
down to 4 NFE, and the RTDMD LoRA further fine-tunes that distilled model with
reward-tilted RL.1git clone https://github.com/Harahan/RTDMD.git && cd RTDMD
2pip install -r requirements.txt && pip install -e .
3
4# Download this repo
5huggingface-cli download Harahan/FLUX2-4B-RTDMD --local-dir ./ckpts/flux2_4b
6
7# Run 4-NFE inference (single GPU)
8python inference.py configs/inference/flux2_4b.yaml \
9 --override lora_paths='["./ckpts/flux2_4b/cold_start/generator_ema.pt","./ckpts/flux2_4b/rtdmd/generator_ema.pt"]' \
10 --override eval_reward=false \
11 --prompt "a cute cat sitting on a windowsill"1import torch
2from diffusers import Flux2KleinPipeline, Flux2Transformer2DModel
3from huggingface_hub import hf_hub_download
4
5base = "black-forest-labs/FLUX.2-klein-4B"
6pipe = Flux2KleinPipeline.from_pretrained(base, torch_dtype=torch.bfloat16).to("cuda")
7
8# Inject LoRA adapters with the rank/alpha used during training
9TARGETS = [
10 "to_q", "to_k", "to_v", "to_out.0",
11 "add_q_proj", "add_k_proj", "add_v_proj", "to_add_out",
12 "to_qkv_mlp_proj",
13] + [f"single_transformer_blocks.{i}.attn.to_out" for i in range(20)]
14pipe.transformer.add_adapter(
15 LoraConfig(r=32, lora_alpha=64, target_modules=TARGETS, init_lora_weights="gaussian")
16)
17
18# Sequentially load cold-start then RTDMD weights into the same adapter
19for ckpt in ["cold_start/generator_ema.pt", "rtdmd/generator_ema.pt"]:
20 path = hf_hub_download("Harahan/FLUX2-4B-RTDMD", ckpt)
21 state = torch.load(path, map_location="cpu", weights_only=False)
22 pipe.transformer.load_state_dict(state, strict=False)
23
24# 4-step CPS sampling
25pipe(prompt="a cute cat sitting on a windowsill",
26 num_inference_steps=4, guidance_scale=1.0).images[0].save("out.png")Note: RTDMD is trained on the CPS (Coefficients-Preserving Sampling) scheduler withη = 0.9. Using the default Flow-Matching Euler scheduler will still produce reasonable samples at 4 NFE, but the RTDMD inference CLI is the only entry point that reproduces the paper numbers exactly.
1@misc{huang2026reinforcingfewstepgeneratorsrewardtilted,
2 title={Reinforcing Few-step Generators via Reward-Tilted Distribution Matching},
3 author={Yushi Huang and Xiangxin Zhou and Ruoyu Wang and Chi Zhang and Jun Zhang and Tianyu Pang},
4 year={2026},
5 eprint={2605.26108},
6 archivePrefix={arXiv},
7 primaryClass={cs.CV},
8 url={https://arxiv.org/abs/2605.26108},
9}black-forest-labs/FLUX.2-klein-4B
is governed by its own license; please review and comply with it separately.