Repository navigation
[1/2] Unified export: quantized-weight state capture - #2777
Conversation
Signed-off-by: Meng Xin <164952785+mxinO@users.noreply.github.com>
|
Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually. Contributors can view more details about this message here. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Merge Risk: ⚪ Minimal · up to
|
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #2777 +/- ##
==========================================
+ Coverage 69.48% 78.36% +8.88%
==========================================
Files 648 649 +1
Lines 71791 72005 +214
==========================================
+ Hits 49881 56426 +6545
+ Misses 21910 15579 -6331
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Follow-ups for this two-PR series, carried over from the scope comment on #2251:
These exclusions apply to the new functional API, not ModelOpt's existing offline exporter. Follow-up integration is tracked in Megatron-Bridge #4804; Bridge #5812 and NeMo-RL #3945 consume the complete two-part API. |
cjluo-nv
left a comment
There was a problem hiding this comment.
Bot review (gpt-6.1-sol) — DM the bot to share feedback.
Nudge: 657 added core-logic lines remain over budget, and the snapshot abstraction needs design rationale and broader capture tests.
Needs action:
- ✂️ Split
export/(649 lines, itself over budget) by file:[1/3]sharedquant_utils.py/quant_format.py/convert_hf_config.pyfixes;[2/3]quantization/plugins/custom.pyrestoration;[3/3]quantized_weight_export.pycapture APIs andexport/__init__.py. - Keep the series acyclic and linearly ordered; document merge order, link siblings, and ensure each slice builds with its own tests and passing CI without later slices.
- Explain in the PR body why extending
quant_utils.pyscale helpers or adaptingget_quantizer_state_dict()is insufficient, and why dedicated dataclass snapshots are preferred over existing Pydantic state representations. - Add capture tests in
tests/unit/torch/export/test_quantized_weight_state.pyfor per-channel/block FP8, dynamic NVFP4, and MXFP4/MXFP8; verify scale values, axis/block metadata, detached-copy independence, and missing-calibration failures.
No action needed:
- The existing mixed-format assertion change is justified by the new exclusion behavior; existing coverage is retained.
- New-file headers match
LICENSE_HEADER. - Tests were inspected, not executed.
Signed-off-by: Meng Xin <164952785+mxinO@users.noreply.github.com>
|
Addressed the capture coverage and rationale feedback from this review. The new cases cover scale values, axis/block metadata, detached-copy independence and required-calibration failures; the independent capture snapshot passes 169 CPU/GPU tests with no skips. The PR body explains the extra layout metadata and use of dataclasses for internal state rather than persisted configuration. Keeping the agreed two-part capture/consumer split for this series instead of another three-way split. Both parts are independently buildable and tested. |
cjluo-nv
left a comment
There was a problem hiding this comment.
Bot review (gpt-6.1-sol) — DM the bot to share feedback.
Nudge: capture coverage and design rationale are resolved, but 659 added core-logic lines still exceed the review budget.
Needs action:
- ✂️ Split
modelopt/torch/export(651 lines, itself over budget) by file:[1/3]sharedquant_utils.py/quant_format.py/convert_hf_config.pyfixes;[2/3]modelopt/torch/quantization/plugins/custom.pyrestoration;[3/3]quantized_weight_export.pycapture APIs andexport/__init__.py. - 💬 Author retains the two-part capture/consumer series — further subdivide capture; keep dependencies acyclic and linearly ordered, document merge order, link siblings, and give each slice its own tests and passing CI without later slices.
No action needed:
- ✔️ Resolved since the last review: requested format/scale/axis/block, detached-copy and calibration-failure coverage; snapshot design rationale.
- The problem is independent per-weight export capture with layout metadata. Reusing scale helpers, adapting
get_quantizer_state_dict(), and existing Pydantic representations were considered; the body reasonably explains detached dataclass state versus persisted configuration. - The existing mixed-format assertion edit remains justified by retained exclusions; existing coverage is preserved. New headers match
LICENSE_HEADER. - Tests were inspected, not executed.
There was a problem hiding this comment.
My understanding is that this file is capturing the quantization state. Could we rename the file to better reflect that? Maybe something like quantization_export_state.py or quantization_weight_state.py
sugunav14
left a comment
There was a problem hiding this comment.
Left a minor readability comment. Otherwise LGTM!
#2769 #2770 #2719 #2796 #2801 #2794 #2787 #2682 #2793 #2791 #2792 #2766 #2823 #2777 #2773 #2813 #2832 #2795 #2684 #2822 #2838 #2807 #2772 #2837 #2820 (#2843) ## Cherry-picked PRs - #2647 - #2700 - #2718 - #2578 - #2580 - #2711 - #2731 - #2726 - #2697 - #2769 - #2770 - #2719 - #2796 - #2801 - #2794 - #2787 - #2682 - #2793 - #2791 - #2792 - #2766 - #2823 - #2777 - #2773 - #2813 - #2832 - #2795 - #2684 - #2822 - #2838 - #2807 - #2772 - #2837 - #2820 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Expanded quantized model export support for MXFP4, MXFP8, FP8, and additional block-quantization formats. * Added quantization support for GPT-OSS and Step-family models, plus export support for native FP8 experts. * Added chat JSONL data preparation for Megatron workflows and an option to freeze the student MTP head during distillation. * Added model recipes for Kimi, Gemma, DiffusionGemma, and GLM variants. * **Bug Fixes** * Improved ONNX quantization and export compatibility, distributed calibration consistency, and handling of packed attention caches. * Improved safe model loading and low-precision quantization accuracy. * **Documentation** * Updated the 0.48.0 changelog and guidance for data preparation and quantization recipes. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Also includes a partial backport of #2656 (only the `_validate_fold_weight` hook and the `mtq.fold_weight` pre-check), which #2820 depends on. --------- Signed-off-by: Shengliang Xu <shengliangx@nvidia.com> Signed-off-by: Rohan Joshi <rohjoshi@nvidia.com> Signed-off-by: Juhi Mittal <juhim@nvidia.com> Signed-off-by: Fridah-nv <201670829+Fridah-nv@users.noreply.github.com> Signed-off-by: Chenjie Luo <chenjiel@nvidia.com> Signed-off-by: yingguo-trt <244492186+yingguo-trt@users.noreply.github.com> Signed-off-by: weimingc <17592131+meenchen@users.noreply.github.com> Signed-off-by: Yue <yueshen@nvidia.com> Signed-off-by: joe-nv <222375587+joe-nv@users.noreply.github.com> Signed-off-by: ajrasane <131806219+ajrasane@users.noreply.github.com> Signed-off-by: Ajinkya Rasane <131806219+ajrasane@users.noreply.github.com> Signed-off-by: ColinM-sys <cmcdonough@50words.com> Signed-off-by: Keval Morabia <28916987+kevalmorabia97@users.noreply.github.com> Signed-off-by: Meng Xin <164952785+mxinO@users.noreply.github.com> Signed-off-by: gcunhase <4861122+gcunhase@users.noreply.github.com> Signed-off-by: Chad Voegele <cvoegele@nvidia.com> Co-authored-by: Shengliang Xu <106840466+shengliangxu@users.noreply.github.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Co-authored-by: Juhi Mittal <39641197+juhi10071998@users.noreply.github.com> Co-authored-by: Frida Hou <201670829+Fridah-nv@users.noreply.github.com> Co-authored-by: Chenjie Luo <108829653+cjluo-nv@users.noreply.github.com> Co-authored-by: yingguo-trt <244492186+yingguo-trt@users.noreply.github.com> Co-authored-by: Wei-Ming Chen <17592131+meenchen@users.noreply.github.com> Co-authored-by: yueshen2016 <39203804+yueshen2016@users.noreply.github.com> Co-authored-by: joe <222375587+joe-nv@users.noreply.github.com> Co-authored-by: Ajinkya Rasane <131806219+ajrasane@users.noreply.github.com> Co-authored-by: Colin McDonough <cmcdonough@50words.com> Co-authored-by: Keval Morabia <28916987+kevalmorabia97@users.noreply.github.com> Co-authored-by: mxinO <164952785+mxinO@users.noreply.github.com> Co-authored-by: Gwena Cunha <4861122+gcunhase@users.noreply.github.com> Co-authored-by: Chad Voegele <chadvoegele@users.noreply.github.com>
…2778) ### What does this PR do? Type of change: New feature. Part 2 of 2: consume per-weight snapshots to pack weights and sidecars, build canonical HF quantization configuration, align state with logical weight merge/selection and separate metadata from tensors for typed transport. ModelOpt owns packing and format metadata; callers retain model naming and topology conversion. Export covers FP8 variants, MXFP8, MXFP4 and supported NVFP4 variants, including mixed configurations. Engine support must be checked separately. AWQ, SmoothQuant, SVDQuant, integer formats and weight-only MXFP4 remain outside this functional API. The existing offline save path is not migrated here. Unlike `preprocess_linear_fusion` and the mutating offline packing entry point, these APIs leave the source modules usable for training and repeated export. State merge/selection follows the caller's logical weight conversion before packing. HF config construction rejects activation settings the canonical format cannot represent, including tensorwise FP8 with its input quantizer disabled. ### Usage For a supported, converted and calibrated module: ```python from modelopt.torch.export import ( build_hf_quantization_config, capture_quantized_weight_export_state, export_quantized_weight_tensors, get_quantized_weight_export_spec, ) name = "model.layers.0.mlp.down_proj.weight" spec = get_quantized_weight_export_spec(module) config = build_hf_quantization_config({name: spec}) # Recapture mutable state immediately before exporting current weights. state = capture_quantized_weight_export_state(module, cpu=False) tensors = export_quantized_weight_tensors(module.weight, state, module.weight.dtype, name) ``` ### Testing Frozen-source container run: 209 focused CPU/GPU tests passed, no skips. Covers functional packing/parity, mixed HF schemas, activation-setting rejection, state transforms/transport and ordinary offline export. All six new activation-contract cases reproduce the bug against the previous builder. The independent [1/2] snapshot passes its 169 cases. All changed-file pre-commit checks pass. These are export regressions, not a new training-convergence claim. ### Before your PR is "*Ready for review*" - Backward compatible: Yes; additive APIs. - New dependency or externally copied code: None. - Necessary tests: State transforms/transport, mixed HF schemas and GPU packing parity, alongside ordinary offline export regressions. - Changelog: Updated. - Claude approval: Not requested; the same independent reviewer approved both slices. ### Additional Information Split of #2251; the original PR is unchanged. Depends on #2777 ([1/2]) and targets `mxin/quant-export-state`; merge #2777 first, then this PR. The extracted implementation includes the follow-up activation-contract and capture-coverage fixes. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added support for exporting quantized weights as checkpoint tensors, including MXFP4 weights. * Quantized-weight export state can be split, restored, merged across compatible shards, and selected by index while preserving quantization-block requirements. * Hugging Face quantization configurations support additional formats and validate activation settings and consistency across weights. * Megatron exports now identify W4A16 MXFP4 quantization, and the W4A8 MXFP4/FP8 preset uses the `max` algorithm. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Meng Xin <164952785+mxinO@users.noreply.github.com>
…2778) ### What does this PR do? Type of change: New feature. Part 2 of 2: consume per-weight snapshots to pack weights and sidecars, build canonical HF quantization configuration, align state with logical weight merge/selection and separate metadata from tensors for typed transport. ModelOpt owns packing and format metadata; callers retain model naming and topology conversion. Export covers FP8 variants, MXFP8, MXFP4 and supported NVFP4 variants, including mixed configurations. Engine support must be checked separately. AWQ, SmoothQuant, SVDQuant, integer formats and weight-only MXFP4 remain outside this functional API. The existing offline save path is not migrated here. Unlike `preprocess_linear_fusion` and the mutating offline packing entry point, these APIs leave the source modules usable for training and repeated export. State merge/selection follows the caller's logical weight conversion before packing. HF config construction rejects activation settings the canonical format cannot represent, including tensorwise FP8 with its input quantizer disabled. ### Usage For a supported, converted and calibrated module: ```python from modelopt.torch.export import ( build_hf_quantization_config, capture_quantized_weight_export_state, export_quantized_weight_tensors, get_quantized_weight_export_spec, ) name = "model.layers.0.mlp.down_proj.weight" spec = get_quantized_weight_export_spec(module) config = build_hf_quantization_config({name: spec}) # Recapture mutable state immediately before exporting current weights. state = capture_quantized_weight_export_state(module, cpu=False) tensors = export_quantized_weight_tensors(module.weight, state, module.weight.dtype, name) ``` ### Testing Frozen-source container run: 209 focused CPU/GPU tests passed, no skips. Covers functional packing/parity, mixed HF schemas, activation-setting rejection, state transforms/transport and ordinary offline export. All six new activation-contract cases reproduce the bug against the previous builder. The independent [1/2] snapshot passes its 169 cases. All changed-file pre-commit checks pass. These are export regressions, not a new training-convergence claim. ### Before your PR is "*Ready for review*" - Backward compatible: Yes; additive APIs. - New dependency or externally copied code: None. - Necessary tests: State transforms/transport, mixed HF schemas and GPU packing parity, alongside ordinary offline export regressions. - Changelog: Updated. - Claude approval: Not requested; the same independent reviewer approved both slices. ### Additional Information Split of #2251; the original PR is unchanged. Depends on #2777 ([1/2]) and targets `mxin/quant-export-state`; merge #2777 first, then this PR. The extracted implementation includes the follow-up activation-contract and capture-coverage fixes. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added support for exporting quantized weights as checkpoint tensors, including MXFP4 weights. * Quantized-weight export state can be split, restored, merged across compatible shards, and selected by index while preserving quantization-block requirements. * Hugging Face quantization configurations support additional formats and validate activation settings and consistency across weights. * Megatron exports now identify W4A16 MXFP4 quantization, and the W4A8 MXFP4/FP8 preset uses the `max` algorithm. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Meng Xin <164952785+mxinO@users.noreply.github.com> (cherry picked from commit 83b1e69) Signed-off-by: Keval Morabia <28916987+kevalmorabia97@users.noreply.github.com>
What does this PR do?
Type of change: New feature and bug fix.
Part 1 of 2: expose exact per-weight quantizer-state capture and metadata-only export specs. Capture is non-mutating and handles numbered grouped weights and supported transposed layouts. Callers can inspect deployment metadata without retaining tensor state.
This also fixes shared format detection, grouped quantizer restoration and HF export metadata, including unquantized-layer exclusions in mixed configurations. Existing offline packing remains on its current path.
Existing scale helpers are reused. The opaque snapshot also records logical weight shape, quantization axes, block sizes and packing layout, which a quantizer-buffer dictionary alone does not provide. It is detached in-memory state, not a new serialized configuration model.
Usage
For a converted and calibrated module:
Capture returns
Nonefor an unquantized weight. The second PR adds consumers of these snapshots. Recapture state for each export when quantizer values may change.Testing
Frozen-source container run: 169 focused CPU/GPU tests passed, no skips. Covers capture/spec, known scale values and axis/block metadata, detached-clone independence, required-calibration failures, ordinary offline export, GPU packing and TE grouped restoration. All changed-file pre-commit checks pass. This validates the extracted API and existing export paths, not training convergence.
Before your PR is "Ready for review"
Additional Information
Split of #2251; the original PR is unchanged. Merge this first, then #2778 ([2/2]), which targets this branch. Megatron-Bridge and NeMo-RL integration require both.
Summary by CodeRabbit