fix: stabilize deep recurrence (T>=32) and correct scaling strategy#80
Open
skyhighbg22-jpg wants to merge 1 commit into
Open
fix: stabilize deep recurrence (T>=32) and correct scaling strategy#80skyhighbg22-jpg wants to merge 1 commit into
skyhighbg22-jpg wants to merge 1 commit into
Conversation
Problem: The original recurrent iteration scaling (1B:16, 10B:24, 50B:32, 1T:64) triggers five compounding pathologies at high iteration counts: - Residual drift: transformer_out accumulates without norm control over 64 steps, pushing the hidden state out of its useful encoding region - Norm explosion: residual stream grows as O(sqrt(T)), reaching ~8x its initial magnitude at T=64 - Gradient circulation: 64 unrolled steps through shared weights amplifies the dominant Jacobian eigenvector exponentially - Representation collapse: sinusoidal loop-index embedding only covers dim//8 channels (12.5%), insufficient to differentiate 64 iterations - Compute synchronization: ACT halted positions still require full loop execution with KV cache, wasting 75-87.5% of compute Solution — five stabilization mechanisms: 1. Recurrent state normalization (RMSNorm after LTI injection): Bounds the residual stream magnitude across all iterations, preventing the O(sqrt(T)) norm growth that destabilizes deep recurrence. 2. Stochastic depth recurrence (training-only): Linearly increasing dropout probability with depth (0% at t=0 to recurrence_dropout at t=T-1). Breaks gradient circulation by creating shorter effective gradient paths and forces useful computation at every depth level. Mask dtype matches activation dtype for mixed-precision. 3. ACT with ponder cost regularization: Accumulates a per-position penalty on total steps taken, returned as a scalar alongside the output. Training loop adds model._last_ponder_cost to the LM loss. Encourages early halting for easy tokens. 4. Learned iteration embeddings (nn.Embedding table): Replaces sinusoidal loop-index embedding (dim//8 channels) with a learned embedding covering all dim channels. Each iteration receives a unique learned vector, forcing the shared transformer block to implement functionally distinct operations at each depth. Clamps to last trained embedding for depth extrapolation beyond max_loop_iters. 5. muP (maximal update parameterization) initialization: When mup_enabled=True, scales hidden layer weights by 1/sqrt(width_ratio) and the final logits projection (head) by 1/width_ratio. Ensures activation and gradient magnitudes remain stable across widths so hyperparameters transfer from a small base-width model. Corrected scaling strategy: - 1T: 64 -> 48 loops (reduced gradient path length by 25%) - 500B: 48 -> 40 loops (17% shorter gradient path) - All variants T>=20 get recurrence_dropout, learned embeddings, and ponder cost; T>=10B additionally get muP initialization - Depth extrapolation to 64+ loops at inference preserved via embedding clamping Additional fixes: - Initialize _last_ponder_cost in OpenMythos.__init__ to prevent AttributeError if accessed before first forward() - muP: only head gets 1/width scaling; all other linears (including attention wo and FFN down) correctly get 1/sqrt(width) as hidden layers - Test fixes: slice freqs_cis[:T] in standalone attention/block tests to match how OpenMythos.forward() handles RoPE indexing - LTI test: use <= 1.0+1e-6 for spectral radius check after large grad step (float precision boundary) Tests: 82/82 passing (all new and pre-existing tests verified).
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.
Summary
Fixes five compounding training instabilities triggered by the non-linear recurrent iteration scaling (1B:16 -> 1T:64) and corrects the scaling strategy for trillion-parameter regimes.
Problem
The original 64-loop design at dim=16384 triggers:
transformer_outterms compound, pushing the hidden state out of its useful encoding regionSolution -- Five Stabilization Mechanisms
model._last_ponder_costadded to LM lossnn.Embeddingtable covers all dim channels per iteration, preventing representation collapse; clamps for depth extrapolationCorrected Scaling
Depth extrapolation to 64+ loops at inference preserved via embedding clamping.
Additional Fixes
_last_ponder_costin__init__to preventAttributeErrorheadgets 1/width; attention.woand FFNdowncorrectly get 1/sqrt(width) as hidden layersfreqs_cis[:T]in standalone attention/block tests (pre-existing RoPE dimension mismatch)<= 1.0 + 1e-6for spectral radius after large gradient step (float precision boundary)Testing
82/82 tests passing. All new components verified:
TestLearnedIterationEmbedding(4 tests)TestStochasticDepthRecurrence(3 tests)TestMupInit(3 tests)TestRecurrentBlockextended (5 new tests)Files Changed
open_mythos/main.py-- +218 lines (new classes + RecurrentBlock refactor + muP)open_mythos/variants.py-- +94 lines (corrected scaling + stabilization params)open_mythos/__init__.py-- +2 lines (exportLearnedIterationEmbedding)tests/test_main.py-- +174 lines (20 new tests + pre-existing test fixes)