Fix conditioning="physical" so it can actually generalize past training vocab
CI / Lint (ruff check) (push) Successful in 28s
CI / Format (ruff format) (push) Failing after 31s
CI / Sync project version with tag (push) Has been skipped
CI / Type check (ty) (push) Successful in 32s
CI / Tests (push) Successful in 2m27s

The whole point of conditioning="physical" is generalizing to a
species/material outside the training menu, but two independent code
paths still hard-required training-vocab membership:

- giant/data/transforms.py: build_cond_features unconditionally raised
  KeyError on an out-of-vocab pdg/material. _vectorized_map_lookup
  gains a strict=False mode (dummy index instead of raising), used only
  under conditioning="physical" where ConditionEncoder never reads
  cond_cat anyway; "embedding" mode is untouched and still raises,
  since cond_cat IS the conditioning signal there.
- giant/rollout.py: the known_pdg termination gate still killed a track
  on step 1 for any pdg outside pdg_map, regardless of conditioning
  mode. Now skipped entirely under conditioning="physical".
- giant/model/network.py: PdgRouter/ProcessRouter always build their
  own training-vocab nn.Embedding independent of conditioning, silently
  reintroducing the same limitation at the routing layer. build_models
  now raises loudly if conditioning="physical" is paired with either
  router type, rather than silently building a model that can't
  generalize the way it claims to.

This unblocks the held-out-species/material generalization experiment
against the multi-material dataset (see CLAUDE.md roadmap). Each fix
has a regression test, including an end-to-end rollout test seeded
with a resolvable-but-out-of-vocab PDG code.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-03 13:47:59 +02:00
parent 74343d3e48
commit 5b63dfd588
6 changed files with 184 additions and 9 deletions
+15
View File
@@ -119,6 +119,21 @@ def test_rollout_physical_conditioning_end_to_end(fake_material_props):
assert set(np.unique(rec["pdg"]).tolist()) <= set(PDG_MAP.keys())
def test_rollout_physical_conditioning_generalizes_to_out_of_vocab_pdg(
fake_material_props,
):
"""A real, giant.particles-resolvable species outside the training PDG
vocab (muon, 13) must run through physical-property conditioning rather
than terminate via TERM_UNKNOWN_PDG — that generalization is the entire
point of "physical" mode (see build_cond_features(strict=...))."""
seeds = _seeds(6)
seeds["pdg"] = np.full(6, 13, dtype=np.int64)
assert 13 not in PDG_MAP
rec = _run(seeds=seeds, conditioning="physical")
assert len(rec["event_id"]) > 0
assert TERM_UNKNOWN_PDG not in set(rec["termination_reason"].tolist())
def test_seed_frontier_track_ids():
seeds = _seeds(3)
fr, counts = make_seed_frontier(**seeds)