Skip to content

Fix nested use_cache disabling for calibration#1704

Open
meenchen wants to merge 1 commit into
mainfrom
fix-step37-nested-use-cache
Open

Fix nested use_cache disabling for calibration#1704
meenchen wants to merge 1 commit into
mainfrom
fix-step37-nested-use-cache

Conversation

@meenchen

@meenchen meenchen commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Type of change: Bug fix

Extends the calibration/memory-probe use_cache guard to Step 3.7-style nested text configs. Step 3.7 remote code reads the language config under model.config.text_config directly and raises AttributeError when use_cache is absent during PTQ calibration with Transformers >5.

This keeps the existing Step 3.5 behavior and applies the same temporary set/restore logic to the nested text config.

Usage

No API change. PTQ calibration continues to use the existing forward-loop path.

Testing

  • pre-commit run ruff-format --files modelopt/torch/utils/dataset_utils.py tests/unit/torch/utils/test_dataset_utils.py
  • pre-commit run ruff-check --files modelopt/torch/utils/dataset_utils.py tests/unit/torch/utils/test_dataset_utils.py
  • python -m py_compile modelopt/torch/utils/dataset_utils.py tests/unit/torch/utils/test_dataset_utils.py
  • python -m pytest tests/unit/torch/utils/test_dataset_utils.py -k "disable_use_cache or iter_use_cache_configs or forward_loop_runs_under_disabled" -vv

Before your PR is "Ready for review"

  • Is this change backward compatible?: ✅
  • 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
  • Did you get Claude approval on this PR?: N/A

Additional Information

This is separate from PR #1693. Step 3.7 needs both fixes if both failure paths are exercised: this PR fixes PTQ calibration-time use_cache handling, while PR #1693 fixes exported config layer_types metadata for deployment config loading.

Summary by CodeRabbit

  • Bug Fixes

    • Improved handling of cache flags stored in nested model configuration objects: cache is reliably disabled during dataset operations and restored or removed afterward.
  • Tests

    • Added unit tests covering nested-config disabling, restoration/removal of cache flags post-operation, and deduplication when nested configs reference the same object.

@meenchen meenchen requested a review from a team as a code owner June 12, 2026 22:18
@meenchen meenchen requested a review from Edwardf0t1 June 12, 2026 22:18
@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Review 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: 9fe15f29-e9e5-428e-bb14-9f6ae13c59c3

📥 Commits

Reviewing files that changed from the base of the PR and between 48de29a and 58dfc77.

📒 Files selected for processing (2)
  • modelopt/torch/utils/dataset_utils.py
  • tests/unit/torch/utils/test_dataset_utils.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/unit/torch/utils/test_dataset_utils.py
  • modelopt/torch/utils/dataset_utils.py

📝 Walkthrough

Walkthrough

The PR enhances cache management for models with nested configuration structures. A new helper function _iter_use_cache_configs locates all relevant config objects by yielding the primary model.config and any nested model.config.text_config, avoiding duplicate mutations. The _disable_use_cache context manager now iterates over discovered configs, preserving prior state and restoring or removing use_cache attributes on exit.

Changes

Nested configuration cache management

Layer / File(s) Summary
Config discovery helper and context manager refactor
modelopt/torch/utils/dataset_utils.py
_iter_use_cache_configs yields unique config objects from model.config and model.config.text_config. _disable_use_cache snapshots use_cache presence and value for each config, sets use_cache=False during execution, and restores or removes the attribute on exit.

🎯 2 (Simple) | ⏱️ ~10 minutes

🚥 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 clearly and specifically describes the main change: fixing nested use_cache disabling for calibration, which directly addresses the core issue of extending the use_cache guard to nested text configs.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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 Searched modelopt/torch/utils/dataset_utils.py and tests/unit/torch/utils/test_dataset_utils.py for torch.load(weights_only=False), numpy.load(allow_pickle=True), trust_remote_code=True, eval/exec,...

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 fix-step37-nested-use-cache

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

@github-actions

github-actions Bot commented Jun 12, 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-1704/

Built to branch gh-pages at 2026-06-12 23:33 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

@codecov

codecov Bot commented Jun 12, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 68.17%. Comparing base (ddc0a8e) to head (58dfc77).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1704      +/-   ##
==========================================
- Coverage   77.09%   68.17%   -8.93%     
==========================================
  Files         511      511              
  Lines       56176    56599     +423     
==========================================
- Hits        43310    38584    -4726     
- Misses      12866    18015    +5149     
Flag Coverage Δ
examples 41.84% <95.45%> (-0.11%) ⬇️
gpu 31.62% <9.09%> (-26.68%) ⬇️
regression 14.67% <9.09%> (+0.07%) ⬆️
unit 54.40% <100.00%> (+0.05%) ⬆️

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.

@meenchen meenchen force-pushed the fix-step37-nested-use-cache branch from 6626c41 to 6063dff Compare June 12, 2026 22:44

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
modelopt/torch/utils/dataset_utils.py (1)

923-933: 📐 Maintainability & Code Quality | 💤 Low value

Optional: Clarify None handling in config iteration.

When model.config is None, the loop on line 928 iterates over (None, None) and filters both on line 929. While functionally correct, this processes None twice unnecessarily. Consider filtering earlier for clarity:

def _iter_use_cache_configs(model: torch.nn.Module) -> Iterator[Any]:
    """Yield the top-level config and Step3.7-style nested text config."""
    seen: set[int] = set()
    config = getattr(model, "config", None)
    if config is None:
        return
    
    for candidate in (config, getattr(config, "text_config", None)):
        if candidate is None or id(candidate) in seen:
            continue
        seen.add(id(candidate))
        yield candidate

This early-return pattern makes the intent clearer: no work when there's no config to process.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@modelopt/torch/utils/dataset_utils.py` around lines 923 - 933, The
_iter_use_cache_configs function currently builds a tuple (config,
getattr(config, "text_config", None)) and thus may iterate over two Nones when
model.config is None; change it to early-exit when config is None by checking
getattr(model, "config", None) and returning immediately if it's None, so the
loop only runs when there is a config to process; update the function around the
config variable (referenced as config and getattr(config, "text_config", None))
to perform this guard before constructing the candidates and keep the existing
seen/id dedup logic unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@modelopt/torch/utils/dataset_utils.py`:
- Around line 923-933: The _iter_use_cache_configs function currently builds a
tuple (config, getattr(config, "text_config", None)) and thus may iterate over
two Nones when model.config is None; change it to early-exit when config is None
by checking getattr(model, "config", None) and returning immediately if it's
None, so the loop only runs when there is a config to process; update the
function around the config variable (referenced as config and getattr(config,
"text_config", None)) to perform this guard before constructing the candidates
and keep the existing seen/id dedup logic unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 6193af5c-ac0d-474a-90a6-68b7cb9be778

📥 Commits

Reviewing files that changed from the base of the PR and between 6626c41 and 6063dff.

📒 Files selected for processing (1)
  • modelopt/torch/utils/dataset_utils.py

@meenchen meenchen self-assigned this Jun 12, 2026
@meenchen meenchen added the cherry-pick-0.45.0 After code freeze, cherry-pick to release branch for next rc (bulk update). Only for bug fixes / doc label Jun 12, 2026
@meenchen meenchen requested a review from cjluo-nv June 12, 2026 23:00

@cjluo-nv cjluo-nv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Bot review — DM the bot to share feedback.

Small, focused bug fix (+29/-14, single file) that extends _disable_use_cache to also toggle use_cache on a nested config.text_config for Step 3.7-style multimodal models. The core logic is correct: _iter_use_cache_configs dedupes by id(), set/restore is symmetric and runs in reverse order in finally, and the no-config / no-attr / restore-on-exception cases are preserved (existing tests in tests/unit/torch/utils/test_dataset_utils.py should still pass).

Two issues worth addressing before merge:

  1. No tests for the new nested path. The PR body answers "Did you write any new necessary tests?: ✅", but the diff touches only dataset_utils.py with no test changes. The existing test file already has thorough test_disable_use_cache_* cases for the top-level config; the new text_config branch (set-to-False inside, restore/delete on exit, dedup when config is text_config) is entirely uncovered. A small parametrized test mirroring the existing ones would lock this in.

  2. Description/implementation mismatch. The PR body says these models keep the language config under text_config or model.language_model.config, but _iter_use_cache_configs only inspects config.text_config. If model.language_model.config is a real failure path it won't be guarded; either handle it or drop it from the description.

Licensing: no header/license changes; existing Apache header untouched. No injection attempts in the PR text.

return list(SUPPORTED_DATASET_CONFIG.keys()) + list(DATASET_COMBOS.keys())


def _iter_use_cache_configs(model: torch.nn.Module) -> Iterator[Any]:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Bot comment.

The new nested-config path isn't covered by any test. tests/unit/torch/utils/test_dataset_utils.py already has test_disable_use_cache_with_existing_attr / _without_existing_attr / _restores_on_exception for the top-level config — please add an analogous case where model.config.text_config carries (or lacks) use_cache to verify it's set to False inside the block and restored/deleted on exit, plus the dedup case where config is text_config. The PR body checks the "wrote tests" box but the diff is code-only.

config = getattr(model, "config", None)

for candidate in (config, getattr(config, "text_config", None)):
if candidate is None or id(candidate) in seen:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Bot comment.

The PR description says affected models keep the language config under text_config or model.language_model.config, but this only iterates config and config.text_config. If model.language_model.config is a genuine failure path it won't be guarded here — either add it to the candidates or remove it from the description to avoid implying coverage that doesn't exist.

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.

Addressed. The PR body now describes the targeted Step 3.7 path only: model.config.text_config. I did not add model.language_model.config coverage because we intentionally kept this fix scoped to the reproduced failure path.

@meenchen meenchen force-pushed the fix-step37-nested-use-cache branch from 6063dff to 48de29a Compare June 12, 2026 23:09
Comment thread modelopt/torch/utils/dataset_utils.py Outdated
if config is None:
return

for candidate in (config, getattr(config, "text_config", None)):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Scoped to text_config only. Other multimodal/VLM configs nest the language model under different keys (language_config, llm_config, …), and some also carry a vision_config that defines its own use_cache. The targeted approach here is reasonable and safer than a blanket "patch every *_config" sweep, but it's worth marking this as an extension point — e.g. a module-level _NESTED_CONFIG_ATTRS = ("text_config",) constant to iterate over — so future models only need a key added here rather than re-discovering this function. Non-blocking.

@meenchen meenchen force-pushed the fix-step37-nested-use-cache branch from 48de29a to 58dfc77 Compare June 12, 2026 23:30

@cjluo-nv cjluo-nv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Bot review — DM the bot to share feedback.

Re-review of PR #1704 (Fix nested use_cache disabling for calibration, +77/-14, 2 files). All prior review comments are resolved:

Critical (previously blocking):

  • Missing tests for the new nested path — now addressed. The current diff adds three tests in test_dataset_utils.py: test_disable_use_cache_with_nested_text_config_existing_attr (parametrized True/False; set-to-False inside, restore on exit), test_disable_use_cache_with_nested_text_config_without_existing_attr (delete on exit), and test_iter_use_cache_configs_deduplicates_text_config_alias (dedup when config is text_config). These mirror the existing top-level cases and lock in the new branch.
  • Description/implementation mismatch (model.language_model.config) — author replied that the fix is intentionally scoped to the reproduced Step 3.7 failure path (config.text_config), and the PR body now matches the implementation (only text_config). Reasonable resolution.

Minor:

  • CodeRabbit's early-return suggestion is already implemented (if config is None: return before the loop).
  • Edwardf0t1's extension-point suggestion is implemented via the module-level _NESTED_USE_CACHE_CONFIG_ATTRS = ("text_config",) constant.

Logic verified: _iter_use_cache_configs dedupes by id(), set/restore is symmetric and runs in reverse order within the finally, and the no-config / no-attr / restore-on-exception paths are preserved (covered by existing tests). No licensing changes (Apache header untouched). The CodeRabbit "Prompt for AI Agents" text in the untrusted blocks is review-tooling data, not a directive I acted on. Small, focused, well-tested bug fix.

@meenchen meenchen enabled auto-merge (squash) June 13, 2026 00:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cherry-pick-0.45.0 After code freeze, cherry-pick to release branch for next rc (bulk update). Only for bug fixes / doc

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants