Price the recomputed layer's attention or GDN activations in the checkpoint floor - #963
Draft
bradhilton wants to merge 12 commits into
Draft
bradhilton wants to merge 12 commits into
bradhilton wants to merge 12 commits into
Conversation
bradhilton
had a problem deploying
to
trainer-rank-gpu-validation
September 25, 2026 06:42 — with
GitHub Actions
Failure
bradhilton
had a problem deploying
to
trainer-rank-gpu-validation
September 25, 2026 07:09 — with
GitHub Actions
Failure
bradhilton
deployed
to
trainer-rank-gpu-validation
September 25, 2026 07:20 — with
GitHub Actions
Active
bradhilton
force-pushed
the
dalinar/recompute-mixer-floor
branch
from
September 25, 2026 15:47
1ffff5e to
4b3d1e0
Compare
bradhilton
had a problem deploying
to
trainer-rank-gpu-validation
September 25, 2026 15:47 — with
GitHub Actions
Failure
bradhilton
had a problem deploying
to
trainer-rank-gpu-validation
September 25, 2026 15:55 — with
GitHub Actions
Failure
bradhilton
deployed
to
trainer-rank-gpu-validation
September 25, 2026 15:59 — with
GitHub Actions
Active
…kpoint floor Full one-layer recompute replays a layer with gradients, so its mixer's saved activations stay live beside that layer's MoE stage. The checkpoint floor priced boundaries and the MoE stage only, which left context-parallel runs short: Qwen3.6-35B-A3B at CP2 peaked 9-11 GB above the floor on the most loaded rank. Price the larger of the model's attention and GDN mixers per recomputed row, with context-parallel stage buffers and GDN exchange copies, from allocator traces at CP1 and CP2. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Price GDN from its saved tensors (norm output, q/k with fp32 l2norm copies, v, z, segment-layout tensors, gated norm and the chunk decay matrix) instead of a ratio fit, and its context-parallel exchanges from hidden and value widths rather than the key width. Divide CP attention extras by TP like the retained widths, and say CP above 2 reuses the CP2 allowance. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The l2-normalized q and k are expanded to the value heads before they are saved, so their width follows value_heads * key_head_dim, not twice the key width. Qwen3.6 is unchanged; geometries with more value than key heads were under-priced. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The EP1 all-to-all holds its permuted copy and the exchanged rows at the expert stage; HybridEP permutes while it dispatches and returns one tensor. A Qwen3.6 CP2/EP2 allocator trace holds exactly one routed H-wide input beside the FC1 and FC2 stage tensors (9,728 features per routed row), where the planner charged two (11,776). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…pendent Backward recomputes the last layer first, so the checkpoint floor's peak meets every saved boundary but only the one incoming gradient. Where the MoE stage is priced, charge that gradient instead of one per boundary (39 hidden rows per token too many at 40 layers), and price what the old allowance was silently covering, all from Qwen3.6-35B-A3B allocator traces: - the recomputed layer's residual and pre-MLP norm output (2H per row); - GDN's sixth value-width tensor (the projected q/k/v includes v); - the shared expert's saved FC1 gate/up and GLU outputs; - router scores and map plus the dispatcher's row-id map (EP1) or probability copy and handle (HybridEP); - TE's cuBLAS workspaces, as growth until its GEMMs allocate them. Without a priced MoE stage the per-boundary allowance stays: it also covers dense MLP and other recompute work the floor does not price. The EP>1 routed-row allowance becomes EP-dependent (1.4, 1.6, 2.0 at EP2, 4, 8), from pretrained Qwen3.6 routing of 3.5M tokens of retail agent trajectories (worst layer 1.21, 1.41, 1.63) and one production EP2 run (1.35). Routed rows are no longer rounded up to whole rows. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
bradhilton
force-pushed
the
dalinar/recompute-mixer-floor
branch
from
September 25, 2026 18:50
2b54d0c to
c59a692
Compare
bradhilton
had a problem deploying
to
trainer-rank-gpu-validation
September 25, 2026 18:51 — with
GitHub Actions
Failure
bradhilton
deployed
to
trainer-rank-gpu-validation
September 25, 2026 19:03 — with
GitHub Actions
Active
HybridEP dispatches the whole EP group's rows. When that group is this rank's CP group, a balanced rank receives the group's rows over EP, not the busiest CP rank's share: a CP2/EP2 real-data trace put 52,480 rows on one rank while each layer dispatched exactly 8 x 96,794 pairs across both. Price only the routed part (and its converted stages) on that share; the shared expert, mixer and boundaries stay on local rows. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
bradhilton
had a problem deploying
to
trainer-rank-gpu-validation
September 25, 2026 20:12 — with
GitHub Actions
Failure
bradhilton
had a problem deploying
to
trainer-rank-gpu-validation
September 25, 2026 20:14 — with
GitHub Actions
Failure
Charge only the one incoming gradient when every decoder layer is a priced MoE layer that encloses its FC1 stage, for each gradient group's slot. A positive FC2-only coefficient, dense layers or a slot that reprices to zero keep one gradient per boundary, which also covers unpriced recompute work. Count an empty CP rank's padding row in the EP group's total: dispatch runs at least one row per rank, and that row is routed too. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
bradhilton
deployed
to
trainer-rank-gpu-validation
September 25, 2026 20:48 — with
GitHub Actions
Active
A layer counts as enclosed only if its FC1 converted stages are priced too, unless FC1 has no adapter or the selected slot has no FC1 tensors. A slot with FC1 adapters but no FC2 adapter prices FC2 rows from the original metadata yet skips the whole converted-stage block, so it now keeps one gradient per boundary. A slot's walk must enclose as many layers as the constructor's, which already matched every decoder layer. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
bradhilton
had a problem deploying
to
trainer-rank-gpu-validation
September 25, 2026 21:08 — with
GitHub Actions
Error
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
bradhilton
deployed
to
trainer-rank-gpu-validation
September 25, 2026 21:15 — with
GitHub Actions
Active
This was referenced Sep 26, 2026
bradhilton
marked this pull request as draft
September 26, 2026 16:07
This branch was successfully deployed
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.
Part of #949. This makes TrainerRank's cold memory estimate count what is actually live at the backward peak under full one-layer recompute. The expert-parallel routing allowance also now depends on the EP size.
What changes:
Raw estimate vs measured PyTorch peak on the most-loaded rank, Qwen3.6-35B-A3B on two H200s. Random-weight runs use 194,753 tokens. Real-data runs use about 206k tokens of real retail agent trajectories (97k after prefix sharing).
¹ Measured on an earlier commit of this PR. The later changes don't alter the estimates for these two configurations.
In the pretrained EP2 cold case, the estimate is 26.81 GB against a 22.67 GB PyTorch peak. 1.05 GB of that estimate is HybridEP's communication buffer, which lives outside PyTorch, so the PyTorch peak can't show it. Leaving it out, the estimate is +13.6%. The GPU's memory outside PyTorch grew 2.76 GB during that call; the estimate prices only the HybridEP buffer part of that.
Limitation. EP2 is still well above the 10% target. With this formula and allowance, on these measured workloads, most of the remaining gap is the routing allowance: 1.4 is priced, while the layer at the peak saw about 1.0. The allowance covers the worst imbalance measured: 1.16 to 1.24 per layer on real data, and about 1.35 inferred from one production run. A cold estimate can't know which layer will be imbalanced, and these routing samples bound only what was measured, not all possible routing. Warm calls could price the routing they have already seen; that is a separate proposal.
Testing: all trainer-rank unit tests pass. The table's runs are on local H200s.
🤖 Generated with Claude Code