Skip to content

[feat] QAD 5090: QAT training recipe — finetune + DMD distillation (12/12) - #1462

Merged
SolitaryThinker merged 4 commits into
mainfrom
pr1225_recipe
Jun 17, 2026
Merged

[feat] QAD 5090: QAT training recipe — finetune + DMD distillation (12/12)#1462
SolitaryThinker merged 4 commits into
mainfrom
pr1225_recipe

Conversation

@alexzms

@alexzms alexzms commented Jun 15, 2026

Copy link
Copy Markdown
Collaborator

Purpose

Finale of the QAD 5090 stack (#1225). The full quantization-aware training
recipe for Wan2.1-T2V-1.3B: reproduce the MixKit data, run QAT finetune, then
QAT DMD distillation down to 3 steps — plus the loader fix that makes Wan NVFP4
inference work. Every stage was verified end-to-end on Blackwell (GB200/sm_100).

Changes

  • mixkit/download_mixkit_data.sh + README.md: one-line download of the
    preprocessed Parquet dataset, and the two-stage recipe how-to.
  • mixkit/finetune_qat.sh: stage 1 — QAT finetune. Attn-QAT attention is
    config-driven (FASTVIDEO_ATTENTION_BACKEND=ATTN_QAT_TRAIN).
  • mixkit/distill_dmd_qat.sh: stage 2 — QAT DMD distillation to 3 steps,
    generator init from the stage-1 checkpoint.
  • fastvideo/models/loader/component_loader.py: generator-only QAT for DMD
    distillation. Teacher (real_score) + critic (fake_score) load with the
    _loading_teacher_critic_model flag; mask the nvfp4_qat quant and the global
    ATTN_QAT_TRAIN env for them, so only the generator runs fake-quant. No
    monkey-patching.
  • fastvideo/models/loader/fsdp_load.py: bugfix — convert
    NVFP4QATQuantizeMethod layers to FP4 at load time, so Wan nvfp4_qat
    inference doesn't crash on a missing _fp4_weight.

Test Results (Blackwell GB200 / sm_100)

  • Stage 1 (finetune): generator selects ATTN_QAT_TRAIN, fwd+bwd run,
    loss/grad healthy, validation generates videos, checkpoint saved.
  • Stage 2 (DMD distillation): generator loads ATTN_QAT_TRAIN while
    teacher/critic load full precision (per-model gating verified in the logs); the
    DMD double loop runs (generator updates every generator_update_interval,
    critic every step, healthy loss), 3-step validation generates videos,
    checkpoint saved.
  • Inference: with the loader fix, nvfp4_qat runs real FP4 linear
    inference end-to-end.

Notes

Part of #1225.

alexzms and others added 2 commits June 15, 2026 19:33
First piece of the QAD training recipe (final PR): reproduce the MixKit
training data. download_mixkit_data.sh pulls the preprocessed Parquet dataset
(weizhou03/HD-Mixkit-Finetune-Wan: VAE latents + text embeddings, 480x832, 77f,
16fps) ready for training; README also documents building the Parquet from raw
videos via fastvideo.pipelines.preprocess.v1_preprocessing_new.

Part of #1225.
- examples/.../mixkit/finetune_qat.sh: quantization-aware finetune of
  Wan2.1-T2V-1.3B; selects the Attn-QAT training attention backend via
  FASTVIDEO_ATTENTION_BACKEND=ATTN_QAT_TRAIN (config-driven, no monkey-patch).
  Verified end-to-end on Blackwell (GB200/sm_100): backend selected (not
  fallback), fwd+bwd run, loss/grad healthy, validation generates videos,
  checkpoint saved.
- fastvideo/models/loader/fsdp_load.py: also convert NVFP4QATQuantizeMethod
  layers to FP4 at load time (convert_model_to_fp4), not just the LTX2
  NVFP4QuantizeMethod path. Without this, Wan-2.1 nvfp4_qat inference crashed
  with "'ReplicatedLinear' object has no attribute '_fp4_weight'" since the
  pre-quantized buffers were never registered. Verified: nvfp4_qat inference
  now runs end-to-end and saves a video.
- README: train + inference how-to (use the nvfp4_qat config instance for Wan,
  not the LTX2-only NVFP4 string).

Part of #1225.

Co-authored-by: William Lin <SolitaryThinker@users.noreply.github.com>
Co-authored-by: Loay Rashid <42599591+loaydatrain@users.noreply.github.com>
Co-authored-by: Kaiqin Kong <k1kong@ucsd.edu>
@mergify mergify Bot added type: feat New feature or capability scope: training Training pipeline, methods, configs scope: model Model architecture (DiTs, encoders, VAEs) labels Jun 15, 2026
@mergify

mergify Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Merge Protections

Your pull request matches the following merge protections and will not be merged until they are valid.

🔴 PR merge requirements

Waiting for

  • check-success=fastcheck-passed
  • check-success=full-suite-passed
This rule is failing.
  • check-success=fastcheck-passed
  • check-success=full-suite-passed
  • #approved-reviews-by>=1
  • check-success~=pre-commit
  • title~=(?i)^\[(feat|feature|bugfix|fix|refactor|perf|ci|doc|docs|misc|chore|kernel|new.?model|skill|skills|infra)\]

alexzms added a commit that referenced this pull request Jun 15, 2026
…fig instance

End-to-end testing on Blackwell showed this example was doubly wrong for Wan-2.1:
- transformer_quant was passed as a string, which is NOT resolved on the
  from_pretrained kwarg path (AttributeError: 'str' has no get_quant_method).
- "NVFP4" is the LTX2-specific config; its fp4_layers never match Wan's layer
  prefixes, so it silently quantizes nothing (runs as bf16).

Use the nvfp4_qat config INSTANCE (get_quantization_config("nvfp4_qat")()), which
matches Wan's to_q/k/v/out + ffn layers via substring match. Verified on a
Blackwell node: Wan2.1-T2V-1.3B now runs real FP4 linear inference end-to-end
(requires the loader convert fix shipped in the recipe PR #1462).

Co-authored-by: William Lin <SolitaryThinker@users.noreply.github.com>
Co-authored-by: Loay Rashid <42599591+loaydatrain@users.noreply.github.com>
Co-authored-by: Kaiqin Kong <k1kong@ucsd.edu>

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces the MixKit training data recipe (QAD 5090) for finetuning Wan2.1-T2V-1.3B, including documentation, a data download script, and a quantization-aware finetuning script. It also updates the FSDP model loader to support converting loaded model weights for NVFP4-QAT linear layers. Feedback on the loader implementation suggests scanning the model for all present quantization methods before converting, rather than returning early on the first match, to prevent silently skipping conversions in mixed-method models.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines 57 to +66
for mod in model.modules():
if isinstance(getattr(mod, "quant_method", None),
NVFP4QuantizeMethod):
qm = getattr(mod, "quant_method", None)
if isinstance(qm, NVFP4QuantizeMethod):
logger.info("Converting loaded model weights for NVFP4 linear layers")
convert_model_to_nvfp4(model)
return
if isinstance(qm, NVFP4QATQuantizeMethod):
logger.info("Converting loaded model weights for NVFP4-QAT linear layers")
convert_model_to_fp4(model)
return

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The current implementation returns early on the first match of either NVFP4QuantizeMethod or NVFP4QATQuantizeMethod. If a model contains a mix of both quantization methods, the second method will be silently skipped, which could lead to runtime errors. Scanning the model first to identify all present quantization methods and then running the conversions sequentially is more robust.

Suggested change
for mod in model.modules():
if isinstance(getattr(mod, "quant_method", None),
NVFP4QuantizeMethod):
qm = getattr(mod, "quant_method", None)
if isinstance(qm, NVFP4QuantizeMethod):
logger.info("Converting loaded model weights for NVFP4 linear layers")
convert_model_to_nvfp4(model)
return
if isinstance(qm, NVFP4QATQuantizeMethod):
logger.info("Converting loaded model weights for NVFP4-QAT linear layers")
convert_model_to_fp4(model)
return
has_nvfp4 = False
has_nvfp4_qat = False
for mod in model.modules():
qm = getattr(mod, "quant_method", None)
if isinstance(qm, NVFP4QuantizeMethod):
has_nvfp4 = True
elif isinstance(qm, NVFP4QATQuantizeMethod):
has_nvfp4_qat = True
if has_nvfp4:
logger.info("Converting loaded model weights for NVFP4 linear layers")
convert_model_to_nvfp4(model)
if has_nvfp4_qat:
logger.info("Converting loaded model weights for NVFP4-QAT linear layers")
convert_model_to_fp4(model)

…ipe finale (12/12)

Completes the QAD training recipe: quantization-aware DMD distillation of
Wan2.1-T2V-1.3B down to 3 sampling steps, with generator-only Attn-QAT.

- component_loader.py: generator-only QAT for DMD distillation. The teacher
  (real_score) and critic (fake_score) transformers load with the
  _loading_teacher_critic_model flag; mask the nvfp4_qat quant and the global
  ATTN_QAT_TRAIN attention env for them so only the generator runs fake-quant
  attention. Config-driven, no monkey-patching, reuses the existing flag.
- distill_dmd_qat.sh: stage-2 DMD distillation script (3-step, generator init
  from the stage-1 finetune checkpoint).
- README: the full two-stage recipe (QAT finetune -> QAT DMD distill to 3 steps).

Verified end-to-end on Blackwell (GB200/sm_100): the generator loads with
ATTN_QAT_TRAIN while teacher/critic load full precision; the DMD double loop
runs (generator updates every generator_update_interval, critic every step,
healthy loss), 3-step validation generates videos, checkpoint saved.

Part of #1225.

Co-authored-by: William Lin <SolitaryThinker@users.noreply.github.com>
Co-authored-by: Loay Rashid <42599591+loaydatrain@users.noreply.github.com>
Co-authored-by: Kaiqin Kong <k1kong@ucsd.edu>
@alexzms alexzms changed the title [feat] QAD 5090: QAT finetune recipe + MixKit data + NVFP4-QAT inference fix [feat] QAD 5090: QAT training recipe — finetune + DMD distillation (12/12) Jun 16, 2026
@SolitaryThinker

Copy link
Copy Markdown
Collaborator

/merge

@github-actions github-actions Bot added the ready PR is ready to merge label Jun 17, 2026
@SolitaryThinker
SolitaryThinker merged commit e60601d into main Jun 17, 2026
14 of 22 checks passed
@SolitaryThinker
SolitaryThinker deleted the pr1225_recipe branch June 17, 2026 22:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready PR is ready to merge scope: model Model architecture (DiTs, encoders, VAEs) scope: training Training pipeline, methods, configs type: feat New feature or capability

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants