fix(parametrize): release the dequant cache when forward raises (#2005)#2006
Closed
Anai-Guo wants to merge 1 commit into
Closed
fix(parametrize): release the dequant cache when forward raises (#2005)#2006Anai-Guo wants to merge 1 commit into
Anai-Guo wants to merge 1 commit into
Conversation
…andbytes-foundation#2005) _register_parametrization_hooks pairs a forward pre-hook that increments P._cache_enabled with a plain forward post-hook that decrements it. PyTorch does not run regular forward post-hooks when the module's forward raises, so any exception unwinding out of forward leaves the counter permanently >= 1 and P._cache is never cleared again -- every later forward then pins its dequantized weights for the rest of the process. This is reachable in normal use: non-reentrant torch.utils.checkpoint early-stops recomputation by raising _StopRecomputationError from a saved-tensor pack hook, straight through the module's forward. Combining replace_parameter_4bit with HF gradient_checkpointing_enable() therefore grows memory every step until OOM. Register the post-hook with always_call=True (torch >= 2.1, and the project already requires torch >= 2.4) so it still runs when forward raises, and clamp the counter at zero so an always_call invocation whose matching pre-hook never ran cannot drive it negative -- which would keep the cache pinned just the same. Signed-off-by: Anai-Guo <antai12232931@anaiguo.com>
Member
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #2005.
Problem
_register_parametrization_hooksmanages the global parametrization cache with a pre-hook / post-hook pair:PyTorch does not run regular forward post-hooks when the module's
forwardraises. So if an exception unwinds out offorward,P._cache_enabledstays>= 1forever andP._cacheis never cleared again — every subsequent forward pins its dequantized weights for the rest of the process.This is reachable in ordinary use, not just on error paths: non-reentrant
torch.utils.checkpointimplements early-stopping of recomputation by raising_StopRecomputationErrorfrom a saved-tensor pack hook, straight through the module'sforward. Soreplace_parameter_4bit+ HFgradient_checkpointing_enable()— the natural pairing for 4-bit training of fused-MoE experts on small GPUs (see #1849) — leaks memory every step until OOM.Fix
always_call=True, so it still runs whenforwardraises. This is available since torch 2.1 and the project already requirestorch>=2.4, so no version guard is needed.always_call=Truehooks can fire even when the matching pre-hook never ran (e.g. an earlier pre-hook raised); a negative counter would makeif not P._cache_enabledfalse forever and pin the cache just the same.Verification
Confirmed the underlying hook semantics on torch 2.5.1 — when
forwardraises, the pre-hook runs, a plain post-hook does not, and analways_call=Truepost-hook does.Added
test_cache_released_when_forward_raises, which drives a parametrized module whoseforwardraises after touching the weight, and asserts the cache is released. It reproduces the bug:AssertionError: assert 1 == 0(P._cache_enabledstuck at 1, one tensor pinned)Full
tests/test_parametrize.pysuite passes locally (159 passed, CPU + CUDA), andruff check/ruff formatare clean with the pinned v0.14.3.🤖 Generated with Claude Code