Repository navigation
fix(trainer): recompile AC-recomputed compiled blocks with the forward's dynamo settings - #3951
Closed
faresobeid wants to merge 1 commit into
Closed
faresobeid wants to merge 1 commit into
faresobeid wants to merge 1 commit into
Conversation
…d's dynamo settings
faresobeid
marked this pull request as ready for review
October 10, 2026 15:16
This was referenced Oct 12, 2026
garrett361
added a commit
that referenced
this pull request
Oct 12, 2026
…ith an fp32 router (#4037) Reverts #3925. With an fp32 router and activation checkpointing, #3925 changed checkpointed MoE blocks from `compile(AC(block))` to `AC(compile(block))`, which makes the checkpoint recompute re-enter Dynamo on the autograd thread. Since then, MoE RL runs with context parallelism, activation checkpointing and compile crash in an early backward with `aten.empty_like.default` or `aten.empty.memory_format encountered during backward but not found in storage`. That happens with both ring and ulysses CP, which shows that reverting #3925 removes the crash on the same batches). The runs in #3925 (no CP) never hit this, and the root cause is not yet understood. This PR restores the previous layout and the `AC -> Compile -> FSDP` order until it is. The cost is #3925's speedup: MoE blocks with an fp32 router and AC run eager again (GLM-4.5-Air about 5.2 to 6.2 s/step, Qwen3-30B-A3B 4.5 to 6.0 s/step in #3925's benchmarks). A follow-up will root-cause the crash and decide whether to re-land #3925 together with #3951. This conflicts with #4029, which edits the unwrap block removed here. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
samsja
reviewed
Oct 19, 2026
samsja
left a comment
Member
There was a problem hiding this comment.
not relevnat anymore since we removed ring cp ?
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.
Status on main
compile(AC(block))). The recompute then runs inside the graph and_checkpoint_contextstakes itstorch.compiler.is_compiling()early return: theactivation_checkpointing.pyhunk is a no-op on main today. It becomes active when perf(trainer): avoid eager fallback of MoE blocks with an fp32 router and activation checkpointing #3925 re-lands.model.pyhunk (ring-CPDYNAMIC_INT_ARGS) is active now: ring CP reads these ints inside the compiled block, so without it every micro batch recompiles.Problem
MoE RL with context parallelism, activation checkpointing and compile crashes in the first backward:
RuntimeError: aten.empty_like.default encountered during backward but not found in storage.Repro:
samsja/mini-glm-moe, reverse-text,--trainer.model.cp 2on 2 trainer GPUs, defaultac/compile/moe_router_dtype(fp32 in RL). Ring CP crashes withempty_likefrom the quack RMSNorm. Ulysses CP crashes withaten.empty.memory_formatfrom inductor autotuning, which runs during the recompute.Root cause
hidden_states._base. The recompute input is not a view. So the recompute compiles its own entries on the autograd thread.recompile_limit,capture_scalar_outputsanddynamic_sources(includingmax_seqlen) are set on the main thread only. The recompute compiles with the defaults:recompile_limit8, ints specialized,.item()breaks the graph.max_seqlen_q/kandlocal_k_slicefrom ring_flash_attn'sDATA_PARAMSinside the compiled block. These change every micro batch, so each micro batch recompiles in both threads (112 of 137 recompile reasons on fake data).recompile_limit (8), Dynamo runs the block eagerly. The SAC storage only holds the compiled region from the forward, so the replay fails. With ulysses, the recompute compiles a different graph than the forward. Its autotuning allocations run under the SAC replay mode, and the replay fails.Fix
activation_checkpointing.py: the recompute context applies the forward thread'srecompile_limit,capture_scalar_outputsanddynamic_sources. It is skipped when the checkpoint itself is compiled; the recompute then runs inside the graph.model.py:max_seqlen_q,max_seqlen_kandlocal_k_sliceare added toDYNAMIC_INT_ARGS, so ring CP stops recompiling per micro batch.Checks
mini-glm-moe, reverse-text, 2 trainer GPUs, cp 2):hit config.recompile_limit (8)on the autograd thread)aten.empty.memory_format ... not found in storage)pytest -m "not gpu" tests/unit/orchestrator tests/unit/test_configs.py tests/unit/train/models/test_checkpointing.py: 302 passed.ruff check/ruff format --check: clean.Note
Medium Risk
Touches activation-checkpoint recompute and torch.compile dynamic-source configuration on the training hot path; incorrect settings could affect compile stability or performance, but the change is narrowly scoped to AC + compile + CP failure modes.
Overview
Fixes first-backward crashes when activation checkpointing,
torch.compile, and context parallelism run together (e.g. MoE RL with ring/Ulysses CP).Activation checkpointing now routes selective checkpoint contexts through
_checkpoint_contexts, which wraps the recompute path with the forward thread’s Dynamo/compiler settings (recompile_limit,capture_scalar_outputs,dynamic_sources) so autograd-thread recomputation of compiled blocks matches the forward compile instead of hitting default limits and eager fallback that breaks SAC replay. That patch is skipped when the checkpoint itself is compiled.Compile setup extends
DYNAMIC_INT_ARGSwith ring CP sequence/slice keys (max_seqlen_q,max_seqlen_k,local_k_slice) so those ints are symbolic from the first compile and stop per–micro-batch recompiles inside compiled blocks.Reviewed by Cursor Bugbot for commit db948c3. Bugbot is set up for automated code reviews on this repo. Configure here.
Recipe confirmation: GLM-4.5-Air, cp=4 ulysses + full AC + ac_offloading, 2 nodes (1 train + 1 inference): main crashes in step 2 backward (
aten.empty.memory_format ... not found in storage); with this PR, 8/8 steps, mismatch KL 0.0017-0.0053, peak memory 54-61 GiB.