Repository navigation
fix: restore tokenizer causality and checkpoint continuation lost in the icml port - #11
Merged
Merged
Conversation
… input `DMRITokenizerPPP` was missing the `embed_cfgs` override it carries on the icml branch, so it inherited `DMRITokenizer.embed_cfgs` and its `idx_tokens * model_mask` masking. That masking is wrong for this tokenizer. `embed_model_mask` packs cfg token `j` into decoder position `j`, and `loss_fn` aligns `logits[i]` with `model_mask[i]`, so zeroing the index token of an inactive component writes bit `j` into the exact position that has to predict it. The model-selection head could read its target off its own input, and the shortcut broke at sample/log_prob time where the mask is not known. Restore the override so the mask reaches the decoder only through `embed_model_mask`, shifted by one position. Flipping one bit at a time now perturbs only position `j+1`, matching the icml behaviour exactly: before flip bit 0 -> positions [0, 1] (leak) after flip bit 0 -> positions [1] Add a regression test asserting that causality directly, and a note on why `__call__` deliberately bypasses `out_norm`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…works `checkpoint_dir` was derived from `output_dir`, the per-launch Hydra directory (`results/<name>/<timestamp>/0/checkpoints`). Every relaunch gets a fresh timestamp, so `continue_training: true` looked in an empty directory, logged "No existing checkpoints found; starting fresh" and silently restarted from scratch. `configure_environment` already computes and logs `output_super_dir` for this purpose, but `_main` discarded it. Use it, matching the icml layout of `results/<name>/checkpoints`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`ArrayRestore` was called without restore args, so the saved RNG key came back with the sharding it was written with rather than the one the running job expects. Pass the live key's sharding explicitly. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Port the four `all_*_model_prior` presets to the schema-v2 config tree, and pin their composition with tests so the frozen architectures stay reproducible. The two `updated_*` presets continue from the icml checkpoints (`results/<name>/checkpoints`) with the tokenizer fix active, hence `continue_training: true` and the `_rician_fixed_continued` run names. Note `updated_all_3_4_8_128_model_prior.yaml` configures a 3/6/8 architecture despite its filename; the filename is kept for continuity with the icml preset it was ported from. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Collapses the over-wrapped `compose_config` calls the new preset tests were added with. No behaviour change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.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.
Summary
These are all refactoring/merge regressions, not new bugs. Every fix here restores behaviour that the icml branch already had and that was lost when that code was ported into this repo. No new functionality, no intentional behaviour changes.
Found while investigating why
updated_all_3_6_8_128_model_prior_rician_fixed_from_scratchtrained far more spikily than the equivalent icml run.1.
DMRITokenizerPPPleaked each mask bit into its own decoder inputThe port dropped the
embed_cfgsoverride thatDMRITokenizerPPPcarries on the icml branch, so it inheritedDMRITokenizer.embed_cfgsand itsidx_tokens * model_maskmasking.That masking is correct for the base tokenizer but wrong here.
embed_model_maskpacks cfg tokenjinto decoder positionj, andloss_fnalignslogits[i]withmodel_mask[i]— so zeroing an inactive component's index token writes bitjinto the exact position that must predict it. The model-selection head could read its target off its own input, and the shortcut broke atsample/log_probtime where the mask isn't known.Flipping one mask bit at a time, measuring which decoder positions change:
[0, 1]leak[1, 2]leak[2, 3]leak[3, 4]leak[1][2][3][4][1][2][3][4]Restoring the override reproduces icml exactly. Added a regression test that asserts the causality directly; confirmed it fails when the bug is reinstated (
mask bit 0 leaks into position(s) [0, 1]).2.
continue_trainingcould never find a checkpointcheckpoint_dirwas derived fromoutput_dir, the per-launch Hydra directory (results/<name>/<timestamp>/0/checkpoints). Every relaunch gets a new timestamp, socontinue_training: truelooked in an empty directory, logged "No existing checkpoints found; starting fresh" and silently restarted from zero.configure_environmentalready computes and logsoutput_super_dirfor exactly this, but_maindiscarded it withlog, output_dir, _ = .... Now used, restoring icml'sresults/<name>/checkpointslayout.3. RNG restored with the wrong sharding
ArrayRestorewas called without restore args, so the saved key came back with the sharding it was written with rather than the running job's. Passes the live key's sharding explicitly.4. Config presets
Ports the four
all_*_model_priorpresets to the schema-v2 tree, with composition tests pinning the frozen architectures.Two pre-existing assertions in
test_config_composition.pywere already failing on this branch before these changes (they expected run names without the_from_scratchsuffix, andrestart_optimizer is True); updated to match the configs.Validation
Verified the icml checkpoints restore cleanly into the current model before relaunching: 701/701 leaves (non-conv) and 733/733 (conv), no missing keys, no shape mismatches.
Both runs are now training from the icml checkpoints with the fix active — non-conv resumed at step 2,000,000, conv at 3,380,000.
Note the icml checkpoints predate the
add_rician_noiseRNG-split fix, so these runs resume across that distribution shift as well as the tokenizer fix.Test suite was run before the changes were finalised; it should be re-run on a compute node rather than the login node.
🤖 Generated with Claude Code