[PyTorch] Deferred backward quantization state update (removes first-FP8-module ownership) - #34
Draft
pggPL wants to merge 8 commits into
Draft
[PyTorch] Deferred backward quantization state update (removes first-FP8-module ownership)#34pggPL wants to merge 8 commits into
pggPL wants to merge 8 commits into
Conversation
…ization state update The backward amax reduction for delayed scaling was triggered from the backward of the 'first FP8 module' of an autocast, assuming its backward runs last. That assumption breaks with activation recompute (duplicate forward/backward updates per step) and with branched autograd graphs (ownership can land in a frame whose backward never runs). Instead, module backwards now only request the update (schedule_backward_quantization_update); it is flushed exactly once at the next top-level autocast entry, after the backward pass is complete. Forward updates at autocast exit are skipped during the recompute phase. Removes the is_first_fp8_module save/restore bookkeeping from checkpoint contexts and modules; renames reduce_and_update_fp8_tensors to reduce_and_update_quantization_state (old name kept as alias). Signed-off-by: Pawel Gadzinski <pgadzinski@nvidia.com>
test_recipe and test_fusible_ops asserted backward scales immediately after backward(); with the deferred update they flush explicitly. Drop raw torch.utils.checkpoint mode from new tests (unsupported with FP8 weight caching independently of this change) and relax exact amax history comparison for nested checkpoints (inner checkpoint re-records amaxes during outer recompute; scales unaffected). Signed-off-by: Pawel Gadzinski <pgadzinski@nvidia.com>
…factor # Conflicts: # transformer_engine/pytorch/distributed.py # transformer_engine/pytorch/ops/fuser.py
…tization_update The method only idempotently marks the update as pending, so 'request' is more precise. Context booleans renamed to should_request_backward_quantization_update accordingly. Signed-off-by: Pawel Gadzinski <pgadzinski@nvidia.com>
Keeps them in a file already enumerated by the L0 QA suite instead of adding a new one. Signed-off-by: Pawel Gadzinski <pgadzinski@nvidia.com>
The activation-checkpoint duplicate-update problem and its regression test scenarios were first diagnosed and addressed in NVIDIA#3213; this PR supersedes that approach by removing first-module ownership entirely. Co-authored-by: AlbertYang514 <201034045+AlbertYang514@users.noreply.github.com> Signed-off-by: Pawel Gadzinski <pgadzinski@nvidia.com>
FP8GlobalStateManager now only orchestrates when updates run; how a recipe updates its process-global state is a RecipeState classmethod (reduce_and_update_global_state), no-op by default and overridden by DelayedScalingRecipeState with the amax reduction + scale recompute. The recipe-to-state-class mapping is extracted from RecipeState.create into class_for_recipe and reused for dispatch. Signed-off-by: Pawel Gadzinski <pgadzinski@nvidia.com>
The reduction no longer runs in module backwards, so the old per-module NVTX markers had nothing left to wrap; mark it at its new single execution site in flush_backward_quantization_update instead. Signed-off-by: Pawel Gadzinski <pgadzinski@nvidia.com>
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.
Description
Refactor of how the backward delayed-scaling amax reduction is triggered.
Problem.
reduce_and_update_fp8_tensors(forward=False)was fired from the backward of the first FP8 module in an autocast, on the assumption that its backward runs last. This breaks in two ways:Fix. Module backwards no longer trigger the update. They only request it (
FP8GlobalStateManager.request_backward_quantization_update(), a bool flag). The update is flushed exactly once at the next top-level autocast entry — at that point the previous backward is provably complete, whatever the graph topology or checkpointing scheme. Guards ensure the flush never runs during the recompute phase, inside a running backward (torch._C._current_graph_task_id()), under CUDA graph capture, or under torch.compile tracing. The forward update at autocast exit is skipped during the recompute phase (fixes the duplicate forward update; the recompute-phase flag now lives on the quantization state and also covers Megatron-Core's checkpoint, which wraps its recompute in TE'sactivation_recompute_forward).This removes the
is_first_fp8_moduleconsumption from all eager modules and the save/restore bookkeeping in checkpoint contexts (_is_first_fp8_moduleFIFO, per-module restore hacks). The CUDA-graphs path (graph.py) keeps its own mechanism and is unchanged. Timing note: the backward update now runs at the start of the next step instead of the end of the current backward — in between, nothing reads the affected state, so scale trajectories are unchanged (asserted exactly in the new tests).Naming:
reduce_and_update_fp8_tensors→reduce_and_update_quantization_state(old name kept as an alias since Megatron-Core calls it), since delayed update methods will be used beyond FP8 (e.g. RHT in NVFP4).Supersedes the approach in NVIDIA#3213: instead of scoping ownership to checkpoint frames, ownership is removed.
New tests (in
tests/pytorch/test_recipe.py, already enumerated by the L0 QA suite)Type of change
🤖 Generated with Claude Code