Document the differentiability position and its validation obligation
CI / Lint (ruff check) (push) Successful in 25s
CI / Format (ruff format) (push) Successful in 27s
CI / Sync project version with tag (push) Has been skipped
CI / Type check (ty) (push) Successful in 25s
CI / Tests (push) Successful in 59s

The categorical type path is not differentiable, and v0.3.0 accepts that:
the expected contribution of the broken path to the total gradient is
assumed negligible. Record it as an assumption with an explicit obligation
to demonstrate it, not as a settled result.

Separates the three things "broken" covers, since they have different
status: per-token loss under teacher forcing is fine (softmax CE needs no
sampling); ST-Gumbel into the critic is biased rather than absent (hard
forward, soft backward); full shower-rollout backprop was already
structurally non-differentiable once secondaries branch, so the switch
costs nothing that was not already lost. The accepted claim concerns only
the middle one.

Lists three ways to falsify it, cheapest first: gradient-magnitude
accounting through the type slice vs the continuous slices, a
detached-type ablation, and an estimator swap against REINFORCE if those
are inconclusive. The first is wired into implementation step 5 so
evidence accrues during the architecture comparison rather than in a
dedicated run afterwards, and the fallback if the ratio is not small is a
config change (target = "physical" or a non-adversarial CE head), not a
redesign.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-06 09:57:44 +02:00
parent 376bdb9d08
commit a489991a3b
+47 -11
View File
@@ -67,7 +67,7 @@ only", "stage 1 flow + stage 2 WGAN", or "one-shot vs autoregressive stage 2".
| 2 | **Full mixed per-stage objectives** | `stage1 = flow` + `stage2 = wgan` must actually run — Stage 1 is good as flow, Stage 2 is what is being iterated on. The train loop becomes one trainer object per stage, each owning its optimizers and update cadence. |
| 3 | **Migration shim for configs *and* checkpoints** | Nothing on `/ceph` goes dead. v0.2 `config.toml` files and v0.2 `model_config` dicts are translated on load. |
| 4 | **Nested objective sub-tables** | `[stage1_model.wgan]`, `[stage2_model.ddpm]` rather than flat `wgan_n_critic` keys — self-documenting about which keys the active generator ignores, and validation can warn on a populated sub-table that is never read. |
| 5 | **Particle type is adversarial: straight-through Gumbel into the critic** | The critic sees a relaxed one-hot alongside energy/direction, so the joint (species, kinematics) distribution is learned rather than factorized. Makes the collapse hypothesis directly testable instead of assumed. |
| 5 | **Particle type is adversarial: straight-through Gumbel into the critic** | The critic sees a relaxed one-hot alongside energy/direction, so the joint (species, kinematics) distribution is learned rather than factorized. Makes the collapse hypothesis directly testable instead of assumed. Accepts a **biased** gradient through the type path — assumed negligible, with a validation obligation in §11.4. |
| 6 | **No charge conservation in v0.3.0** | Explicitly "not yet worked out" in the meeting. No `[stage2_model.conservation]` block at all. Energy conservation stays exact and implicit in the stick-breaking encoding. |
| 7 | **Explicit stage-prefixed CLI flags** | `--stage2-hidden-dim` etc., no generic `--set path=value`. Discoverable via `--help` and tab-completable; the cost is a flag list kept in sync with `DEFAULT_CONFIG` by hand. |
| 8 | **AR history is a config axis, markov default** | Markov (previous token + remaining budget + slot index) is the baseline that makes the meeting's §6 "is attention useful" question answerable by ablation rather than by comparing differently-shaped models. Both sit behind one `history_encoder(prefix) -> vector` interface. |
@@ -907,16 +907,50 @@ All in `giant/config.py`:
the implementation flow (§12 step 8), measured on real hardware using the example
configs — not guessed from the existing calibration constants.
### 11.4 Still open
### 11.4 Accepted with a validation obligation: differentiability
- **Differentiability sanity check with Jan.** The meeting's §5 notes that the
original argument for the continuous type target rested on avoiding a
non-differentiable categorical *sampling* step — but per-token training loss is
differentiable either way under teacher forcing, and full shower-rollout backprop
is already structurally non-differentiable once secondaries spawn branches. The
note flags this as "worth confirming explicitly with Jan rather than assuming
it". Decision 5 rests on this reasoning, so it is worth raising before step 4
rather than after.
**Position taken: differentiability through the categorical type path is broken,
and that is accepted.** The expected contribution of the broken path to the total
gradient is small enough to ignore. **This is an assumption, not a result — it has
to be demonstrated later.**
Recording it precisely, since "broken" covers three distinct things:
| where | status |
|-------|--------|
| Per-token training loss under teacher forcing | **Fine.** Softmax cross-entropy needs no sampling; the loss is differentiable in the logits. |
| ST-Gumbel into the critic (`generator = "wgan"`, §2.1) | **Biased, not absent.** The forward pass is a hard one-hot; the backward pass pretends it was the soft sample. Gradient flows, but it is not the gradient of what was actually computed. |
| Full shower-rollout backprop | **Structurally broken regardless.** Already non-differentiable once secondaries spawn branches, independent of the type representation — so the categorical switch costs nothing that was not already lost. |
The claim being accepted is about the middle row: the straight-through estimator's
bias, propagated into the shared trunk, is expected to be negligible against the
gradient from the continuous paths (stick-breaking energy, direction, and — when
stage 1 is active — the 9D primary target). The third row is the reason this is
tolerable at all: end-to-end differentiability was never available.
**Validation obligation.** Do not treat this as settled until one of the following
has actually been run. Cheapest first:
1. **Gradient-magnitude accounting.** Instrument a training run to log the norm of
the trunk gradient contributed through the type slice against the norm from the
continuous slices. "Negligible" should mean a stable, small ratio — not merely
small at initialization. This is the direct measurement of the claim and costs
almost nothing to add.
2. **Detached-type ablation.** Train with the type path detached from the shared
trunk entirely (type head still learns; no type gradient reaches the trunk)
against the ST-Gumbel default. Comparable species marginals and kinematics mean
the coupling was weak, which is the same conclusion by a different route.
3. **Estimator swap**, only if 12 are inconclusive: compare ST-Gumbel against an
unbiased-but-high-variance estimator (e.g. REINFORCE with a baseline) on a short
run. Agreement in the learned marginals means the bias did not matter.
Option 1 should be added when the AR trunk lands (step 5), so the evidence accrues
during the architecture comparison rather than needing a dedicated run afterwards.
**Why it still matters that this is written down:** decision 5 (adversarial type
via ST-Gumbel) rests on this assumption. If the ratio in test 1 turns out not to be
small, the fallback is not a redesign — it is `particle_type.target = "physical"`
or a non-adversarial CE head, both of which already exist as config options.
---
@@ -935,7 +969,9 @@ All in `giant/config.py`:
action item 1, and it is testable against the one-shot baseline before any AR
work.
5. **`Stage2Autoregressive`** with `history = "markov"`, `teacher_forcing =
"always"`. The meeting's step 3.
"always"`. The meeting's step 3. Add the gradient-magnitude instrumentation of
§11.4 test 1 here, so the differentiability assumption accrues evidence during
the architecture comparison instead of needing its own run later.
6. **`sample.py` / `rollout.py`** — AR generation and class -> PDG decode, so an AR
model can actually be rolled out and put through `giant analyze`. Includes the
L1-distance diagnostic of §11.3.