Skip to content

Add LSQ NVFP4 export support - #1847

Draft
realAsma wants to merge 2 commits into
mainfrom
asma/laq-export-support
Draft

Add LSQ NVFP4 export support#1847
realAsma wants to merge 2 commits into
mainfrom
asma/laq-export-support

Conversation

@realAsma

@realAsma realAsma commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds LSQ NVFP4 support to unified Hugging Face export.

  • Uses the LSQ pre scale to pack FP4 weight codes and serializes the post scale for dequantization.
  • Supports quantized or unquantized pre scales, tied or separate pre/post amax values, and the covered learnable-amax modes.
  • Keeps this PR scoped to the three export/test files; the LSQ rename and quantizer APIs come from Add LSQ (Learned Scale Quantization) support and recipes #1884.

Testing

  • pre-commit run --files modelopt/torch/export/quant_utils.py modelopt/torch/export/unified_export_hf.py tests/unit/torch/quantization/test_nvfp4_static_export_cpu.py
  • pytest_pwd tests/unit/torch/quantization/test_lsq.py tests/unit/torch/quantization/test_nvfp4_static_export_cpu.py -q -x — 66 passed
  • pytest_pwd tests/unit/torch/quantization/test_nvfp4_static_export_cpu.py -q -x — 18 passed

Checklist

  • Backward compatible: ✅
  • New dependency or copied code: N/A
  • Necessary tests added: ✅
  • Changelog update: N/A
  • Claude approval: N/A (draft)

@copy-pr-bot

copy-pr-bot Bot commented Jun 28, 2026

Copy link
Copy Markdown

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.

@coderabbitai

coderabbitai Bot commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 2bd0adfd-d9e5-473a-b2f2-2d1f42fa6601

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch asma/laq-export-support

Comment @coderabbitai help to get the list of available commands.

@realAsma realAsma left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

BB: Rebase this PR to the latest main, remove the unnecessary changes.

@realAsma

Copy link
Copy Markdown
Contributor Author

🤖 Bot comment.

🐝 I’m on it — I’ll rebase onto the latest main, trim the unnecessary changes, and report back here.

@realAsma

Copy link
Copy Markdown
Contributor Author

🤖 Bot comment.

Blocked before rebase: this PR still targets asma/laq-algorithm@6bfefb9, which does not contain latest main@f479e78, and the verified rebase path can only rebase onto the PR’s current base. Please either retarget this PR to main or rebase/update the parent branch onto main; then I can safely rebase and trim the duplicated changes.

@realAsma

Copy link
Copy Markdown
Contributor Author

BB: Can you rebase this PR to latest main and only add the changes required to enable export with LSQ? (btw, I have renamed LAQ to LSQ, see #1884)

@realAsma

Copy link
Copy Markdown
Contributor Author

BB: Please update PR description and PR title after addressing #1847 (comment)

@realAsma

Copy link
Copy Markdown
Contributor Author

🤖 Bot comment.

🐝 I’m on it — I’ll rebase onto the latest main, then narrow the PR to the changes needed for LSQ export.

@realAsma

Copy link
Copy Markdown
Contributor Author

🤖 Bot comment.

🐝 Acknowledged this instruction. I’ll update the PR title and description after addressing the linked feedback.

@realAsma

Copy link
Copy Markdown
Contributor Author

🤖 Bot comment.

🐝 Got it — I’ll update the PR title and description to match the narrowed LSQ-export scope after the branch changes are prepared.

@realAsma

Copy link
Copy Markdown
Contributor Author

🤖 Bot comment.

Blocked for now: the PR still declares asma/laq-algorithm as its base, so the guarded rebase followed that base and paused locally on conflicts instead of rewriting onto main. Nothing was committed or pushed. The title/description update is also deferred until an LSQ-only candidate exists. The next safe step is to retarget this PR to main, clear the wrong-base local rebase, and rerun the LSQ-only preparation.

@realAsma

Copy link
Copy Markdown
Contributor Author

🤖 Bot comment.

Blocked outcome for the title/description request: the guarded pass paused because the PR still targets asma/laq-algorithm, not main. No commit, push, title, or description change was made. I’ll update the metadata after a correct-base LSQ-only candidate is prepared; details are in the branch-work outcome.

@realAsma

Copy link
Copy Markdown
Contributor Author

BB: Yes please retarget this PR to latest main. then address #1847 (comment)

@realAsma

Copy link
Copy Markdown
Contributor Author

🤖 Bot comment.

🐝 Acknowledged — I’ll retarget this PR to the latest main, then address the LSQ export request.

@realAsma

Copy link
Copy Markdown
Contributor Author

🤖 Bot comment.

Blocked after the requested retarget attempt: I safely cleared the unpublished wrong-base rebase and restored asma/laq-export-support cleanly at the exact remote head. The guarded GitHub interface available in this run cannot edit a PR’s base branch, so I could not change the live base to main or start the LSQ-only fix pass. Please retarget this PR to main; the active monitor will pick it up and continue automatically.

@realAsma
realAsma changed the base branch from asma/laq-algorithm to main July 22, 2026 22:17
@realAsma

Copy link
Copy Markdown
Contributor Author

BB: Done, I manually rebase to main. do the rest.

@realAsma

Copy link
Copy Markdown
Contributor Author

🤖 Bot comment.

Update: the live PR base is now main at 0baad6453a8, and the canonical head remains clean at 30e8b91986. This retarget blocker is cleared. The enabled controller monitor will start the fresh LSQ-only pass under the next dispatch; no code or history was published in this completed one-pass dispatch.

@realAsma

Copy link
Copy Markdown
Contributor Author

🤖 Bot comment.

🐝 Got it — I’m taking over from the manual rebase and will finish the LSQ export work, validation, and PR metadata updates.

@realAsma

Copy link
Copy Markdown
Contributor Author

🤖 Bot comment.

I verified the PR now targets main, but the branch head itself was not rebased: it is still on the old commit, 195 commits behind, and GitHub reports conflicts. I preserved the clean branch and recorded the exact guarded rebase handoff; the next monitored controller pass will rebase safely, then prepare the LSQ-export-only changes and update the title/description. No code or history was published in this pass.

@realAsma
realAsma force-pushed the asma/laq-export-support branch from 30e8b91 to 448e58e Compare July 22, 2026 23:09
@realAsma realAsma changed the title Add LAQ NVFP4 export support Add LSQ NVFP4 export support Jul 22, 2026
@realAsma

Copy link
Copy Markdown
Contributor Author

🤖 Bot comment.

🐝 Updated this PR to the requested LSQ-export-only scope.

  • Rebased cleanly onto current main with one signed and signed-off commit (448e58e3c).
  • Live diff is limited to the two export files and one focused CPU test file.
  • PR title and description now use LSQ terminology and reference Add LSQ (Learned Scale Quantization) support and recipes #1884 for the LSQ rename/API dependency.
  • File-scoped pre-commit passed; focused tests passed (66 passed, including the 18 passed export subset).
  • GitHub now reports the PR mergeable. DCO and initial file-change checks pass; the remaining fresh CI jobs are running.

The PR remains draft; no ready-for-review promotion or reviewer notification was made.

@github-actions

github-actions Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://NVIDIA.github.io/Model-Optimizer/pr-preview/pr-1847/

Built to branch gh-pages at 2026-07-30 02:50 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

@codecov

codecov Bot commented Jul 22, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 60.22%. Comparing base (c94405e) to head (540d2fc).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1847      +/-   ##
==========================================
+ Coverage   60.21%   60.22%   +0.01%     
==========================================
  Files         519      519              
  Lines       59377    59385       +8     
==========================================
+ Hits        35755    35767      +12     
+ Misses      23622    23618       -4     
Flag Coverage Δ
unit 55.15% <100.00%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@realAsma realAsma left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

BB: For now I want to support export only for LSQ tied variant. Can you update this PR for that? I think with LSQ ted variant only support, we can significantly simplify the PR (because its looks similar to the NVFP4 with MSE/four-over-six weights?

You can raise an error if Dual LSQ is tried to export.

@realAsma

Copy link
Copy Markdown
Contributor Author

🤖 Bot comment.

🐝 Got it — I’ll update the PR to support export only for tied LSQ, simplify the implementation, and reject Dual LSQ export.

@realAsma

Copy link
Copy Markdown
Contributor Author

🤖 Bot comment.

🐝 I triaged this as a valid fix: tied LSQ export only, with Dual LSQ export rejected. The PR is currently five commits behind main, so the guarded workflow requires an exact pre-code rebase before the implementation pass can edit it. This pass verified the branch is clean and conflict-free, but did not receive the explicit rebase authorization tuple, so it made no code changes. The PR monitor remains active and the next controller pass can resume from the recorded rebase handoff.

Signed-off-by: realAsma <akuriparambi@nvidia.com>
Signed-off-by: realAsma <akuriparambi@nvidia.com>
@realAsma
realAsma force-pushed the asma/laq-export-support branch from 448e58e to 540d2fc Compare July 30, 2026 02:46
@realAsma

Copy link
Copy Markdown
Contributor Author

🤖 Bot comment.

Published the review fix at 540d2fc38: NVFP4 export now accepts tied LSQ quantizers only and rejects unsupported separate or non-LSQ learnable-amax variants. Focused validation passed (66 tests). The PR description still needs its scope wording refreshed for the tied-only behavior; requesting fresh review on this head.

@realAsma

Copy link
Copy Markdown
Contributor Author

/claude review

Comment thread modelopt/torch/export/quant_utils.py

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Claude review passed — no blocking issues found. LGTM

Scope

Full review of all 4 changed files (+118/-1): quant_utils.py, unified_export_hf.py, nvfp4_tensor.py, and the CPU test. Small PR — reviewed in full, nothing deprioritized.

Findings

  • CRITICAL: 0
  • IMPORTANT: 0
  • SUGGESTION: 1 (guard reachability from non-HF export entry points — non-blocking)

Assessment

The change is tightly scoped and correct.

Algorithm correctness (verified end-to-end): For the only exportable variant — tied-amax LSQ with quantize_scales=True and quantize_pre_scale=True — the training forward (_fake_quantize) uses scale_pre == scale_post == _block_scale_from_amax(amax_post, quantize=True). The export path reconstructs the identical fp8-quantized block scale via weight_scale * weight_scale_2, and the new test asserts exactly this equality against _block_scale_from_amax(amax_post, True). The rejected set (tied_amax=False, quantize_pre_scale=False, quantize_scales=False) is precisely where scale_pre != scale_post or scales aren't fp8 — i.e. the configs that could not round-trip — so the NotImplementedError guard draws the boundary in the right place.

State/compat: No modelopt_state schema change, no public API signature change. The nvfp4_tensor.py fallback (getattr(_amax, None) then .amax) preserves existing static-quantizer behavior (they retain _amax) and only diverges for tied LSQ where enable_lsq deleted _amax. Backward compatible.

Test coverage: Good — parametrized over learnable-amax sets, an end-to-end _export_quantized_weight registration check, and rejection of all three unsupported variants.

Low risk. The single suggestion is a defense-in-depth nicety about which export entry points route through the guard, not a correctness issue for the current HF-export scope.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant