diagnostic(sp22): zero W prior + beta prior to isolate NaN source

First smoke at ff98edc77 produced NaN in:
- q_by_action (dir Qs from q_out_buf)
- a_mag (mag SGEMM forward output)
- v_share_traj + grad_decomp_pinned (all-branch backward)
- WR = 43.40% (below ~46% baseline)

Key clue: a_dir = -0.0029 finite but q_by_action NaN. Raw dir logits
fine, expected Q (with atom-shift) NaN. So atom-shift produces NaN
from finite inputs. Either W or state_121 contains NaN.

This diagnostic zeroes both:
- aux_w_prior_init: W [-0.5, 0, +0.5, 0] -> [0, 0, 0, 0]
- beta scale prior: 0.5 -> 0.0

With W=0 + beta=0, atom-shift and beta are runtime no-ops. All wiring
remains intact (kernels loaded, scratch populated, dW/Adam launched).

Diagnostic outcomes:
- Clean smoke -> bug was W magnitude x downstream interaction. Restore
  W at smaller magnitude.
- Still NaN -> bug is in Step 8/11 backward logic. Investigate
  c51_aux_dw_kernel + adam_w_aux interaction.

Cargo check clean. Ready for diagnostic smoke.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
jgrusewski
2026-05-13 09:00:33 +02:00
parent ff98edc774
commit 617eb61aab
3 changed files with 53 additions and 10 deletions

View File

@@ -51,12 +51,26 @@ extern "C" __global__ void aux_w_prior_init(
int a = threadIdx.x;
if (a >= 4) return;
/* Per-action structural prior:
* a == 0 (Short) → -0.5
* a == 1 (Hold) → 0.0
* a == 2 (Long) → +0.5
* a == 3 (Flat) → 0.0
/* 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.
*
* 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)
*
* Original structural prior [-0.5, 0, +0.5, 0] will be restored once
* the NaN source is identified.
*/
float prior_values[4] = { -0.5f, 0.0f, +0.5f, 0.0f };
float prior_values[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
w_aux_to_q_dir[a] = prior_values[a];
}

View File

@@ -10589,10 +10589,16 @@ 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;
// Structural prior 0.5 — activates β with fixed magnitude
// from epoch 0. SP11 controller's Phase B6 extension will
// later overwrite with adaptive emit anchored on slot 536.
fused.trainer().write_isv_signal_at(SP22_AUX_ALIGN_SCALE_INDEX, 0.5);
// 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);
}
}
_ => {