Skip to content

Strengthen DASC device lifecycle regression - #2400

Merged
kaix-nv merged 1 commit into
feature/dasc-state-sparsity-review-policy-devicefrom
feature/dasc-state-sparsity-review-device-test
Sep 11, 2026
Merged

kaix-nv merged 1 commit into
feature/dasc-state-sparsity-review-policy-devicefrom
feature/dasc-state-sparsity-review-device-test

Conversation

@kaix-nv

@kaix-nv kaix-nv commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Summary

Addresses the sole non-blocking suggestion on approved PR #2399:

  • call export_policy() under the non-CPU ambient default-device context
  • assert validated static horizons are present
  • make the regression fail even if a future checkpoint-save path downgrades validation failures to warnings

Validation

  • targeted lifecycle regression passed
  • pre-commit hooks passed
  • signed commit with DCO sign-off

Summary by CodeRabbit

  • Tests
    • Extended device lifecycle coverage to verify policy export while operating on the meta device.
    • Added validation that static horizon metadata is included in exported policies.

Signed-off-by: kaix-nv <kaix@nvidia.com>
@kaix-nv
kaix-nv requested a review from a team as a code owner September 11, 2026 04:43
@coderabbitai

coderabbitai Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 7d2e2844-12c7-4de7-8ffc-ecb106a188c8

📥 Commits

Reviewing files that changed from the base of the PR and between 48daa95 and 8586b06.

📒 Files selected for processing (1)
  • tests/unit/torch/sparsity/state_sparsity/test_dasc.py

Included review availability: Your plan provides up to 12 included reviews per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The DASC lifecycle test now exports the calibrated policy while the ambient device is meta and verifies that the exported layer policy includes static horizons.

Changes

DASC policy export validation

Layer / File(s) Summary
Validate meta-device policy export
tests/unit/torch/sparsity/state_sparsity/test_dasc.py
The lifecycle test exports the calibrated policy inside the meta device context and checks for static horizon metadata in the exported layer policy.

Priority: ⬇️ Low

Estimated code review effort: 1 (Trivial) | ~3 minutes

Change: Other

Merge Risk: ⚪ Minimal · up to 8586b

This test-only change improves coverage of meta-device policy export without altering production behavior, and validation checks passed.

🚥 Pre-merge checks | ✅ 6
✅ Passed checks (6 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and clearly describes the main change: strengthening the DASC device lifecycle regression.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 1 files.
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 pull request changes only tests/unit/torch/sparsity/state_sparsity/test_dasc.py. SECURITY.md states that its coding rules apply to code except tests. The added lines only call `mtss.expo…
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/dasc-state-sparsity-review-device-test

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

@kaix-nv

kaix-nv commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

/claude review

@kaix-nv

kaix-nv commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor
⚠️ Action not completed

Review rate limited.


Your included review limit is currently reached under our Fair Usage Limits Policy. This review may still proceed through usage-based billing if eligible. Your next included review will be available in 1 minute.

@kaix-nv

kaix-nv commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor
⚠️ Action not completed

Review rate limited.


Your included review limit is currently reached under our Fair Usage Limits Policy. This review may still proceed through usage-based billing if eligible. Your next included review will be available in 13 seconds.

state = mto.modelopt_state(calibrated)
policy = mtss.export_policy(calibrated)
assert state["modelopt_state_dict"][0][0] == "dasc"
assert policy["layers"]["linear_attn"]["static_horizons"]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[SUGGESTION] This assertion can never fail on its own, so it carries less signal than it looks like it does.

DASCLayerPolicy.static_horizons is declared list[float] = Field(min_length=1) and validate_partition additionally requires len(static_horizons) == num_heads with every value finite and > 0.0 (modelopt/torch/sparsity/state_sparsity/config.py:215-225). By the time export_policy() returns a dumped policy, a non-empty list is guaranteed by the schema — a truthiness check is tautological beyond confirming the layers/linear_attn/static_horizons key path exists and that export_policy() didn't raise.

That said, the placement is the valuable part and it is correct: every horizon path pins CPU explicitly (policy.py:121-122, 214-215, 331-332, 523), so if a future change dropped one of those pins, the horizons/bounds tensors would materialize on meta and either the CPU-vs-meta comparison in validate_dasc_decay_parameters or the .tolist() in the dump would raise inside the torch.device("meta") block. This does close the gap the PR describes.

To make the assertion itself meaningful, tie the exported horizons to values computed on the normal CPU path — that catches a silently-wrong-but-non-empty policy, not just an exception:

def test_policy_lifecycle_ignores_the_default_device():
    """Keep calibration and checkpoint metadata validation on their declared CPU path."""
    model = TinyGatedDeltaNetForCausalLM()
    expected_horizons = mtss.analyze_gdn_decay(model)["linear_attn"].tolist()
    with torch.device("meta"):
        calibrated = mtss.calibrate(model, _config(wmax_candidates=[7]), [_candidate(7)])
        state = mto.modelopt_state(calibrated)
        policy = mtss.export_policy(calibrated)
    assert state["modelopt_state_dict"][0][0] == "dasc"
    assert policy["layers"]["linear_attn"]["static_horizons"] == pytest.approx(expected_horizons)

Non-blocking — the current form is a net improvement over not calling export_policy() under the ambient device at all.

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.

Thanks. No further code change here: the load-bearing guard is that export_policy() executes inside the meta default-device context and propagates any validation failure. The truthiness check is retained only as a structural/schema assertion; exact horizon numerics and storage-canonical equality are already covered by dedicated tests, so duplicating that comparison here would mix concerns.

@kaix-nv

kaix-nv commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.

@claude

claude Bot commented Sep 11, 2026

Copy link
Copy Markdown

Claude review summary

Findings: CRITICAL: 0 · IMPORTANT: 0 · SUGGESTION: 1

Scope

Full review. The PR changes exactly one file (tests/unit/torch/sparsity/state_sparsity/test_dasc.py, +2/-0), so no coverage cap applied. I also read the production code the new lines exercise: state_sparsity/api.py (export_policy), state_sparsity/policy.py (horizon analysis plus the two validators), and state_sparsity/config.py (DASCLayerPolicy).

Assessment

The change does what the description claims. Moving export_policy(calibrated) inside the torch.device("meta") block is the right way to close the gap left open by #2399: export_policy runs validate_dasc_model_structure and validate_dasc_decay_parameters, and every horizon computation on that path pins CPU explicitly — compute_gdn_decay_horizons (policy.py:121-122), _analyze_gdn_modules (214-215), _storage_cast_horizon_bounds (331-332), and the stored tensor (523). If any of those pins were dropped, the tensor would land on meta and the ensuing CPU-vs-meta comparison — or the .tolist() during model_dump — would raise inside the context manager. So the regression genuinely fails on a device leak, and it fails via an exception rather than depending on a validation error being raised, which is the 'fails even if a future path downgrades validation failures to warnings' property the description asks for.

The ["layers"]["linear_attn"] key path matches existing usage in this file (lines 125-126, 387, 442) and linear_attn is the GDN submodule name on TinyGatedDeltaNetForCausalLM, so the lookup is correct.

No mode-registration, config-schema, public-API, or export-path surface is touched; modelopt_state schema and restore behavior are unchanged. No backward-compatibility or performance concerns.

The one suggestion (non-blocking)

assert policy["layers"]["linear_attn"]["static_horizons"] is effectively tautological: static_horizons is Field(min_length=1) and validate_partition already enforces one finite positive value per head (config.py:215-225), so a successfully constructed policy always yields a truthy list. Its real signal is key-path existence plus 'export_policy did not raise'. Comparing against horizons computed on the ordinary CPU path would additionally catch a silently-wrong-but-non-empty policy — details inline.

Risk

Low. Test-only change that strictly tightens an existing regression; no production code paths affected.

🤖 Generated with Claude Code

@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

@kaix-nv
kaix-nv merged commit 431bb04 into feature/dasc-state-sparsity-review-policy-device Sep 11, 2026
29 checks passed
@github-actions

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-09-11 04:49 UTC

@codecov

codecov Bot commented Sep 11, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 68.75%. Comparing base (48daa95) to head (8586b06).
⚠️ Report is 1 commits behind head on feature/dasc-state-sparsity-review-policy-device.

Additional details and impacted files
@@                                Coverage Diff                                @@
##           feature/dasc-state-sparsity-review-policy-device    #2400   +/-   ##
=================================================================================
  Coverage                                             68.75%   68.75%           
=================================================================================
  Files                                                   548      548           
  Lines                                                 64244    64244           
=================================================================================
  Hits                                                  44173    44173           
  Misses                                                20071    20071           
Flag Coverage Δ
unit 57.47% <ø> (ø)

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.

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