test(recon): confirm PGDReconLayerwiseLoss fresh-PGD per-site independence (#918 item 6)#933
Open
ocg-goodfire wants to merge 1 commit into
Open
test(recon): confirm PGDReconLayerwiseLoss fresh-PGD per-site independence (#918 item 6)#933ocg-goodfire wants to merge 1 commit into
ocg-goodfire wants to merge 1 commit into
Conversation
…em 6) Confirms via a pure-structure assertion that `PGDReconLayerwiseLoss` factors into one fresh-PGD entry per site, each on exactly its own single site in canonical order. Combined with the step's per-entry key derivation (`fold_in(term_key, entry_idx)` in `train.py`), this is what draws an independent fresh adversarial source per site — the JAX counterpart of torch `PGDReconLayerwiseLoss.update`'s per-layer `pgd_masked_recon_loss_update` loop (fresh `_init_adv_sources` under a `LayerRouter` routing only that layer). Closes the "inferred, not read line-by-line" gap tracked as #918 item 6. Co-Authored-By: Claude Fable 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.
What
Closes item 6 of the Stage-4 adversary/source parity tracker (#918): "Confirm
PGDReconLayerwiseLossfresh-PGD per-site path by line-by-line read" — previously marked done but inferred from LOSS_PARITY_DESIGN, not read line-by-line vs torch.Adds one pure-structure test pinning that
PGDReconLayerwiseLossfactors into one fresh-PGD entry per site, each on exactly its own single site in canonical order.Line-by-line confirmation (torch-oracle vs JAX)
Torch (
PGDReconLayerwiseLoss.update→pgd_masked_recon_loss_update→_init_adv_sources/_run_pgd_loop, git tagtorch-oracle):target_module_pathslayer; per layer callspgd_masked_recon_loss_updatewith a freshLayerRouter(layer_name=layer)._init_adv_sourcesfreshly initializes sources per call → independent per layer.LayerRouter.get_masks= all-ones for that one layer, all-zeros elsewhere → only that layer decomposed-masked; others take the frozen path._run_pgd_loop:n_stepsofadd_(step_size * grad.sign())thenclamp_(0,1); routing fixed across steps.Σ_layer sum_loss / Σ_layer n= mean over (layer, example).JAX (
recon.pyPGDReconLayerwiseLossConfigcase +train.pyfresh-PGD block +adversary.init_fresh_pgd_sources):make_plan(per_site(site_names), AllRoutingConfig(), FreshPGDSources(...), n_samples=1)→ oneReconForwardper site,live_sites=(s,).train.py:term_key = fold_in(key, 1+term_idx); per entryrouting_key, init_key = split(fold_in(term_key, entry_idx)). Distinctentry_idxper site ⇒ distinctinit_key⇒ independent fresh source.sign_ascend_body:clip(sources + step_size*sign(grad), 0, 1), scannedn_steps— matches torch.AllRoutingConfigover the single live site == torchLayerRouterall-ones on that one layer.Σ_entry recon / n_entries(n_draws=1) = mean over sites. Equivalent to torch (equal per-entry n).Structural note (equivalent, not a divergence): torch inits fresh sources for all modules per layer but routes only one (non-routed sources contribute nothing to the forward/gradient → no-op); JAX inits only the one live site. Loss value + ascent gradient identical; only RNG consumption differs — and torch (global RNG) vs JAX (split keys) already differ, so numeric goldens use deterministic init.
Fixture decision
No numeric torch golden exists for the fresh-PGD layerwise path (the equivalence suite covers faith/imp/stoch/ppgd only; fresh-PGD as a whole isn't in the goldens). The layerwise path shares byte-identical fresh-PGD ascent machinery with
PGDReconLoss/PGDReconSubsetLoss, differing only in chunking (per_sitevsone_chunk); per-entry independence is the generic plan-entry keying. Per the item's acceptance clause, I took the confirm + document branch (a torch golden would need the deprecated torch-oracle regen flow) and pinned the plan-side invariant with a pure-JAX structural test.🤖 Generated with Claude Code