diff --git a/crates/ml/src/cuda_pipeline/aux_w_prior_init_kernel.cu b/crates/ml/src/cuda_pipeline/aux_w_prior_init_kernel.cu index ed9494677..0c4d430fd 100644 --- a/crates/ml/src/cuda_pipeline/aux_w_prior_init_kernel.cu +++ b/crates/ml/src/cuda_pipeline/aux_w_prior_init_kernel.cu @@ -51,26 +51,25 @@ extern "C" __global__ void aux_w_prior_init( int a = threadIdx.x; if (a >= 4) return; - /* SP22 H6 Phase 3 α DIAGNOSTIC (2026-05-13): W zeroed to isolate - * the NaN source. First smoke at commit ff98edc77 with W=[-0.5,0,+0.5,0] - * showed NaN in q_by_action (dir Qs), a_mag (mag SGEMM output), and - * grad_decomp_pinned (all branches' backward gradients). Forward - * a_dir, v, a_ord, a_urg remained finite, ruling out atom-shift in - * compute_expected_q as the source. Hypothesis: either atom-shift - * magnitude × downstream interaction destabilises training, or - * Step 8/11 (c51_aux_dw + adam_w_aux) backward path corrupts W. + /* SP22 H6 Phase 3 α structural prior — RESTORED (2026-05-13): * - * With W = [0, 0, 0, 0]: - * - aux_atom_shift = W[a] * state_121 = 0 for all (a, state_121) - * - Equivalent to atom-shift inactive throughout - * - Step 8/11 still run, dW computed from SP (which depends only on - * state_121 + projection, not W), Adam updates W with this dW - * - If smoke is clean: bug was W magnitude × downstream interaction - * - If smoke NaNs: bug is in Step 8/11 logic (independent of W init) + * Per-action prior reflecting the domain belief that aux conviction × + * position-sign biases toward aligned trades. When state_121 = +1 + * (aux predicts up): + * - W[Short=0] × state_121 = -0.5 × 1 = -0.5 → dir Q for Short + * shifts DOWN by 0.5 → action selection avoids Short. + * - W[Hold=1] × state_121 = 0.0 × 1 = 0.0 → Hold unchanged. + * - W[Long=2] × state_121 = +0.5 × 1 = +0.5 → dir Q for Long + * shifts UP by 0.5 → action selection biases toward Long. + * - W[Flat=3] × state_121 = 0.0 × 1 = 0.0 → Flat unchanged. * - * Original structural prior [-0.5, 0, +0.5, 0] will be restored once - * the NaN source is identified. + * When state_121 = -1 (aux predicts down): symmetric bias toward + * Short and away from Long. + * + * Adam refines W from this prior via projection-derived dW + * (c51_aux_dw_kernel → adam_w_aux_kernel, both with defensive NaN + * guards added in commit 79945987a). */ - float prior_values[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + float prior_values[4] = { -0.5f, 0.0f, +0.5f, 0.0f }; w_aux_to_q_dir[a] = prior_values[a]; } diff --git a/crates/ml/src/trainers/dqn/trainer/training_loop.rs b/crates/ml/src/trainers/dqn/trainer/training_loop.rs index e6aa78dd4..a9566f074 100644 --- a/crates/ml/src/trainers/dqn/trainer/training_loop.rs +++ b/crates/ml/src/trainers/dqn/trainer/training_loop.rs @@ -10589,16 +10589,17 @@ impl DQNTrainer { "sp22_aux_align_scale" => { if let Some(ref fused) = self.fused_ctx { use crate::cuda_pipeline::sp22_isv_slots::SP22_AUX_ALIGN_SCALE_INDEX; - // SP22 H6 Phase 3 α DIAGNOSTIC (2026-05-13): β scale - // ZEROED to deactivate β reward shaping. Earlier 0.5 - // structural prior caused NaN in smoke at ff98edc77 - // — to isolate the NaN source, deactivate β entirely - // alongside W=[0,0,0,0]. If diagnostic smoke is clean, - // bug was in α/β magnitude × downstream interaction. - // If still NaN, bug is in Step 8/11 (c51_aux_dw + - // adam_w_aux) backward logic. Original 0.5 prior to - // be restored once NaN source is identified. - fused.trainer().write_isv_signal_at(SP22_AUX_ALIGN_SCALE_INDEX, 0.0); + // SP22 H6 Phase 3 β scale structural prior — RESTORED + // (2026-05-13): activates β reward shaping with fixed + // magnitude 0.5 from epoch 0. r_aux_align = 0.5 × + // alignment × profit_pos fires at trade close. NaN + // source from earlier smokes was identified as Step + // 8/11 (c51_aux_dw + adam_w_aux) backward path — now + // defensively neutralised via isfinite guards in + // commit 79945987a. Phase B6 (SP11 controller + // extension to emit adaptive scale_β) is the eventual + // upgrade; 0.5 prior bridges that gap. + fused.trainer().write_isv_signal_at(SP22_AUX_ALIGN_SCALE_INDEX, 0.5); } } _ => { diff --git a/docs/dqn-wire-up-audit.md b/docs/dqn-wire-up-audit.md index c49f02db1..2bc5935f1 100644 --- a/docs/dqn-wire-up-audit.md +++ b/docs/dqn-wire-up-audit.md @@ -17447,3 +17447,32 @@ Cargo check clean. Together with the previously-added guards on `state_121` and on `total` (dW write), Adam inputs (`g, lr, m, v`), and `W` in `compute_expected_q`, this provides defense-in-depth across the entire atom-shift path. No NaN can propagate through any of the 4 forward kernels OR the dW/Adam backward. Cargo check clean. + +#### Structural priors RESTORED — full Phase 3 α/β activation (2026-05-13) + +**Verification smoke `train-5t6vb` @ `79945987a` completed cleanly across 3 folds**: +- Fold 0 val WR: 0.4345 +- Fold 2 val WR: 0.4331 +- All HEALTH_DIAG[0] readouts CLEAN — no NaN + +Defensive guards confirmed sound. Wiring infrastructure proven. + +**This commit restores the structural priors** to test the actual α/β mechanism: +- `aux_w_prior_init_kernel.cu`: W = `[-0.5, 0.0, +0.5, 0.0]` (Short/Hold/Long/Flat) +- `training_loop.rs::reset_named_state`: scale_β prior = `0.5` + +The defense-in-depth guards from `79945987a` provide safety net: +- All atom-shift forward kernels guard `w_aux[a]` and `state_121` reads +- c51_aux_dw_kernel guards sp/isw/dz/gamma/done inputs +- adam_w_aux_kernel early-returns on non-finite inputs + +If any of these inputs go non-finite (e.g., from an unidentified upstream NaN), the mechanism gracefully degrades to no-op for that sample instead of cascading NaN. + +**Next smoke verdict** (1 epoch, 3 folds, baseline): +| Pattern | Interpretation | +|---------|---------------| +| WR clean + > 43.45% | H6 Phase 3 α/β mechanism IMPROVES WR — declare success | +| WR clean + ~= 43.45% | Wiring sound but mechanism doesn't help at chosen magnitude — falsified or needs tuning | +| NaN reappears | Defensive guards too aggressive (sanitizing real signal) — investigate root cause | + +Cargo check clean.