Skip to content

Fix MGDLoss teacher gradient leak and enforce abstract loss balancer - #2668

Merged
AAnoosheh merged 1 commit into
NVIDIA:mainfrom
LinCanNerd:fix/distill-mgd-detach-abc-balancer
Oct 9, 2026
Merged

AAnoosheh merged 1 commit into
NVIDIA:mainfrom
LinCanNerd:fix/distill-mgd-detach-abc-balancer

Conversation

@LinCanNerd

@LinCanNerd LinCanNerd commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

What does this PR do?

Type of change: Bug fix

Fixes two verified defects listed under "Smaller items" in #1926:

  • MGDLoss backpropagates into the teacher. Unlike LogitsDistillationLoss and MFTLoss, MGDLoss passed the teacher feature map to F.mse_loss without detaching it, so standalone use (outside DistillationModel, which runs the teacher under no_grad) populated teacher gradients, wasting memory and compute and updating the teacher if its params are in the optimizer. The teacher target is now detached.
  • DistillationLossBalancer did not enforce its abstract forward. It used @abc.abstractmethod without ABCMeta, so a subclass missing forward() instantiated fine and only failed with a bare NotImplementedError at the first loss call. The base class now uses metaclass=abc.ABCMeta, so such subclasses raise TypeError at construction. Both in-tree subclasses (StaticLossBalancer, Megatron's LogitsAndIntermediatesLossBalancer) implement forward and are unaffected.

Usage

No API changes.

Testing

  • Added test_mgd_loss_does_not_backprop_into_teacher and test_loss_balancer_requires_forward to tests/unit/torch/distill/test_distill.py; both fail on main and pass with this change.
  • pytest tests/unit/torch/distill (CPU, torch 2.14.1): 36 passed.
  • pre-commit run on the changed files: all hooks pass.

Before your PR is "Ready for review"

Make sure you read and follow Contributor guidelines and your commits are signed (git commit -s -S).

Make sure you read and follow the Security Best Practices (e.g. avoiding hardcoded trust_remote_code=True, torch.load(..., weights_only=False), pickle, etc.).

  • Is this change backward compatible?: ✅ (a DistillationLossBalancer subclass without forward() now fails at construction instead of at first call; such a subclass was already unusable)
  • If you copied code from any other sources or added a new PIP dependency, did you follow guidance in CONTRIBUTING.md: N/A
  • Did you write any new necessary tests?: ✅
  • Did you update Changelog?: N/A (minor fix)
  • Did you get Claude approval on this PR?: N/A

Additional Information

Addresses the MGDLoss and DistillationLossBalancer items in #1926 (the issue tracks other unrelated items, so it should stay open).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Distillation training now computes loss without propagating gradients through teacher features, while student outputs continue to receive gradients.
    • Loss balancers that do not implement the required forward method can no longer be instantiated.
  • Tests

    • Added coverage for gradient behavior during distillation and validation of loss-balancer implementations.

@LinCanNerd
LinCanNerd requested review from a team as code owners October 6, 2026 07:59
@LinCanNerd
LinCanNerd requested a review from AAnoosheh October 6, 2026 07:59
@copy-pr-bot

copy-pr-bot Bot commented Oct 6, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: NVIDIA/Model-Optimizer/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Enterprise
  • Run ID: 6b8ed855-1add-4c3e-8c51-fda4041360ad

📥 Commits

Reviewing files that changed from the base of the PR and between 61496a2 and c4282e2.


📒 Files selected for processing (3)
  • modelopt/torch/distill/loss_balancers.py
  • modelopt/torch/distill/losses.py
  • tests/unit/torch/distill/test_distill.py

Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 11 remain after this review.



📝 Walkthrough

Walkthrough

MGDLoss now detaches teacher features when calculating its MSE loss. DistillationLossBalancer now enforces its abstract forward method.

Changes

Distillation loss behavior

Layer / File(s) Summary
Detach teacher features in MGD loss
modelopt/torch/distill/losses.py, tests/unit/torch/distill/test_distill.py
MGDLoss calculates MSE against detached teacher features. A test checks that gradients reach student outputs but not teacher layer weights.
Enforce the loss balancer abstract contract
modelopt/torch/distill/loss_balancers.py, tests/unit/torch/distill/test_distill.py
DistillationLossBalancer uses abc.ABCMeta. A test checks that a subclass without a forward implementation cannot be instantiated.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix


Merge Risk: ⚪ Minimal · up to c4282

The change prevents teacher-side gradient flow and rejects balancers missing forward; current in-tree implementations satisfy the contract, so no actionable merge-blocking risk remains.

🚥 Pre-merge checks | ✅ 5 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 6 functions across 3 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly summarizes both primary changes: preventing teacher gradients in MGDLoss and enforcing the abstract forward method on DistillationLossBalancer.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Security Anti-Patterns Passed PASS. The reviewed PR changes only modelopt/torch/distill/loss_balancers.py, modelopt/torch/distill/losses.py, and a distillation test. The added code only enables abc.ABCMeta and detaches a ten…


  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR


  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

@codecov

codecov Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 78.10%. Comparing base (5a7bb67) to head (c4282e2).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2668      +/-   ##
==========================================
+ Coverage   71.69%   78.10%   +6.41%     
==========================================
  Files         642      642              
  Lines       71285    71285              
==========================================
+ Hits        51109    55679    +4570     
+ Misses      20176    15606    -4570     
Flag Coverage Δ
examples-diffusers 20.26% <50.00%> (+0.01%) ⬆️
examples-gpt-oss 13.48% <50.00%> (+0.01%) ⬆️
examples-hf_ptq 23.42% <50.00%> (+0.01%) ⬆️
examples-llm_distill 13.54% <50.00%> (+0.01%) ⬆️
examples-llm_eval 17.32% <50.00%> (+0.01%) ⬆️
examples-llm_qat 17.54% <50.00%> (+<0.01%) ⬆️
examples-llm_sparsity 15.86% <50.00%> (+0.01%) ⬆️
examples-megatron_bridge 26.48% <50.00%> (-0.14%) ⬇️
examples-specdec_bench 13.26% <50.00%> (+0.01%) ⬆️
examples-speculative_decoding 17.61% <50.00%> (-0.06%) ⬇️
examples-torch_onnx 21.61% <50.00%> (+<0.01%) ⬆️
examples-torch_trt 15.25% <50.00%> (+0.01%) ⬆️
examples-vllm_serve 13.92% <50.00%> (+0.01%) ⬆️
gpu 58.85% <50.00%> (+25.30%) ⬆️
regression 15.11% <50.00%> (+0.01%) ⬆️
unit 59.85% <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.

@AAnoosheh

Copy link
Copy Markdown
Contributor

/ok to test b8f1a0d

@LinCanNerd
LinCanNerd force-pushed the fix/distill-mgd-detach-abc-balancer branch from b8f1a0d to 61496a2 Compare October 8, 2026 08:57
@LinCanNerd

Copy link
Copy Markdown
Contributor Author

@AAnoosheh Thanks for kicking off CI. The two failed required checks weren't caused by this PR; the branch was just based on an old main:

I rebased onto the latest main without changing the diff, and the distill unit tests pass locally. Could you post /ok to test 61496a2b to re-run CI? Thanks!

@AAnoosheh

Copy link
Copy Markdown
Contributor

/ok to test 61496a2

MGDLoss now detaches the teacher feature map like the other distillation
losses, so standalone use no longer backpropagates into the teacher.
DistillationLossBalancer now uses ABCMeta, so subclasses missing forward()
fail at instantiation instead of at the first loss call.

Addresses the MGDLoss and DistillationLossBalancer items in NVIDIA#1926.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: LinCanNerd <lincanecdl@gmail.com>
@LinCanNerd
LinCanNerd force-pushed the fix/distill-mgd-detach-abc-balancer branch from 61496a2 to c4282e2 Compare October 9, 2026 08:50
@AAnoosheh

Copy link
Copy Markdown
Contributor

/ok to test c4282e2

@AAnoosheh
AAnoosheh merged commit 91bbe8f into NVIDIA:main Oct 9, 2026
55 checks passed
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.

2 participants