[feat] QAD 5090: QAT training recipe — finetune + DMD distillation (12/12) - #1462
Conversation
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>
Merge ProtectionsYour pull request matches the following merge protections and will not be merged until they are valid. 🔴 PR merge requirementsWaiting for
This rule is failing.
|
…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>
There was a problem hiding this comment.
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.
| 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 |
There was a problem hiding this comment.
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.
| 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>
|
/merge |
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 thepreprocessed Parquet dataset, and the two-stage recipe how-to.
mixkit/finetune_qat.sh: stage 1 — QAT finetune. Attn-QAT attention isconfig-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 DMDdistillation. Teacher (
real_score) + critic (fake_score) load with the_loading_teacher_critic_modelflag; mask thenvfp4_qatquant and the globalATTN_QAT_TRAINenv for them, so only the generator runs fake-quant. Nomonkey-patching.
fastvideo/models/loader/fsdp_load.py: bugfix — convertNVFP4QATQuantizeMethodlayers to FP4 at load time, so Wannvfp4_qatinference doesn't crash on a missing
_fp4_weight.Test Results (Blackwell GB200 / sm_100)
ATTN_QAT_TRAIN, fwd+bwd run,loss/grad healthy, validation generates videos, checkpoint saved.
ATTN_QAT_TRAINwhileteacher/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.
nvfp4_qatruns real FP4 linearinference end-to-end.
Notes
ATTN_QAT_TRAIN, so the recipe depends on [feat] QAD 5090: Wire the Attn-QAT training attention backend (10/12) #1459 (wiring)is also 4-bit during training) is a follow-up.
Part of #1225.