Diffusion Model Fine-Tuning with NFT#
SD3 and Wan2.2 generation models trained with Diffusion-NFT.#
Fine-tune SD3 or Wan2.2 with Diffusion-NFT to improve text rendering in images and videos. Candidates generated for the same prompt are scored with OCR; relative rewards guide the model update. After the shared setup, select a recipe below, launch training, and inspect rewards and generated samples.
Overview#
Select the output type and matching recipe for your model. For the objective and derivation, see the DiffusionNFT paper and official code.
SD3 / Wan2.2
Diffusion-NFT
Image / Video
OCR / Video OCR
Tasks#
The configs cover image OCR and frame-aware video OCR.
Model |
Config |
Output |
Reward granularity |
|---|---|---|---|
SD3 |
|
Image |
One OCR score per image |
Wan2.2 TI2V 5B |
|
Single frame |
One OCR score per image |
Wan2.2 TI2V 5B |
|
Video |
OCR scores over video frames |
Observation and Action#
Each episode scores one generated image or video for its prompt.
Value |
Meaning |
|---|---|
Observation |
A text prompt containing quoted target text. |
Action |
The generated image or video. |
Reward |
Image OCR similarity or frame-aware video OCR scores. |
Installation and Assets#
Follow the shared installation,
model download, and
OCR dataset download instructions. Wan NFT recipes
use GPU OCR; select the shared --paddle-gpu installation for those configs.
Run Training#
Open the YAML matching your chosen config in examples/diffusion/config/;
for example, use examples/diffusion/config/sd3_nft_ocr.yaml for SD3.
Set actor.model.model_path, env.train.dataset.path, and
env.eval.dataset.path to your downloaded directories. Check
cluster.num_nodes, cluster.component_placement, and the batch settings
against your hardware before launching.
After checking the YAML, run its config name from the repository root:
bash examples/diffusion/run_diffusion.sh sd3_nft_ocr
bash examples/diffusion/run_diffusion.sh wan22_ti2v_5b_nft_video_ocr
The launcher generates candidates, scores them with OCR, updates LoRA
parameters, and writes logs under logs/<timestamp>-<config>/.
Set runner.resume_dir to a checkpoints/global_step_N directory to
resume NFT training, including off-policy EMA rollout weights. If an older
checkpoint lacks EMA weights, the actor logs a warning and initializes EMA from
the restored actor weights; this fallback is not an exact resume.
Configure the NFT Update#
The checked-in recipes combine grouped reward normalization with an NFT update in diffusion velocity space:
For each prompt, generate
group_sizecandidates and compute relative advantages. Image recipes use standard GRPO normalization within each prompt group. The video recipe normalizes frame/chunk rewards over the whole video group.Sample a denoising step and reconstruct the current noisy state (
nft_xcur_source: resample). The rollout/reference model supplies the old velocity \(v_{old}\) and the trainable model predicts \(v_\theta\).Form \(\Delta v = v_\theta - v_{old}\) and the positive/negative candidates \(v_{\pm} = v_{old} \pm \beta\Delta v\).
Convert both candidates to the configured target space. The provided configs use
nft_target_space: x0and compare the predicted clean sample against the rollout target with weighted squared-error energies \(E_{+}\) and \(E_{-}\).Map the relative advantage into
[0, 1]and minimize the configured NFT objective. Better candidates emphasize \(E_{+}\); worse candidates emphasize \(E_{-}\).nft_clip_ratiocan limit the update relative to the old velocity.
nft_tau controls the rollout/reference weights. A scalar 1.0 is
on-policy. A schedule [start_tau, end_tau, start_step, end_step] linearly
anneals the EMA update; for example, [1.0, 0.01, 0, 70] transitions from the
current policy to a slowly updated reference over the first 70 updates.
Option |
Current recipes |
Effect |
|---|---|---|
|
|
Number of candidates compared for each prompt. |
|
|
Scale of the positive/negative velocity perturbation. |
|
|
Space in which candidate prediction errors are measured. |
|
|
Normalizes energy using the detached mean absolute prediction error. |
|
|
Bounds the velocity update relative to \(v_{old}\). |
|
Model-specific annealing schedule |
Controls how quickly rollout/reference weights follow the actor. |
|
|
Trains parameter-efficient adapters instead of all model weights. |
Expected Results#
Reference env/avg reward curves for SD3 image OCR, Wan2.2 image OCR,
and Wan2.2 video OCR training.#
In the reference runs above, all three recipes improve from a low initial OCR
reward toward approximately 0.8. Wan2.2 image and video runs rise more
quickly, while the SD3 run reaches a similar range later. Treat this figure as a
training-shape reference rather than a guaranteed final score: seed, prompts,
model checkpoint, GPU count, dependency versions, and evaluation settings can
change both speed and final reward.
A healthy run should show improving env/avg together with bounded NFT update
statistics. Inspect generated samples as well as scalar reward—OCR can verify
text matching, but it does not by itself measure visual quality or temporal
consistency.
Metric |
Interpretation |
|---|---|
|
Reward selected by |
|
Optimized NFT objective. Interpret it together with reward, not as a standalone quality score. |
|
Current rollout/reference EMA coefficient after schedule interpolation. |
|
Magnitude of the velocity update relative to the rollout/reference prediction. |
|
Fraction of updates affected by NFT clipping; sustained saturation suggests an overly aggressive update. |
|
Positive and negative candidate energies used to build the NFT objective. |
Open TensorBoard on the generated log directory. If media saving is enabled in
env.*.video_cfg, generated samples are written under video_base_dir.
tensorboard --host 0.0.0.0 --logdir logs/
For scalar definitions and logger layout, see Training Metrics.