fix: precommit audit — gradient offset s1_input_dim + q_attn_params zero-init
CRITICAL: backward_full used state_dim for goff_b_s1 offset but compute_param_sizes uses s1_input_dim (smaller with bottleneck active). All downstream gradient offsets were misaligned. Fixed: sd → s1d. HIGH: q_attn_params used alloc_f32 (potentially non-zero) instead of alloc_zeros. Cross-branch Q-attention residual connection needs near-zero init for stability. Fixed: alloc_zeros. MEDIUM (deferred): VSN masking bypassed for magnitude branch — mag_concat reads raw h_s2 instead of vsn_masked. No impact while W_vsn2 is zero-init (identity mask). Will fix when VSN backward is wired. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -815,7 +815,7 @@ impl CublasBackwardSet {
|
||||
// We compute these inline from the config dimensions.
|
||||
// grad_buf is now f32, so byte offsets use sizeof(f32) = 4.
|
||||
let f32 = std::mem::size_of::<f32>() as u64;
|
||||
let sd = self.state_dim as u64;
|
||||
let s1d = self.s1_input_dim as u64; // CRITICAL: must match compute_param_sizes (not state_dim)
|
||||
let sh1 = self.shared_h1 as u64;
|
||||
let sh2 = self.shared_h2 as u64;
|
||||
let vh = self.value_h as u64;
|
||||
@@ -828,7 +828,7 @@ impl CublasBackwardSet {
|
||||
|
||||
// GOFF byte offsets (must match compute_param_sizes order)
|
||||
let goff_w_s1: u64 = 0;
|
||||
let goff_b_s1: u64 = goff_w_s1 + sh1 * sd * f32;
|
||||
let goff_b_s1: u64 = goff_w_s1 + sh1 * s1d * f32;
|
||||
let goff_w_s2: u64 = goff_b_s1 + sh1 * f32;
|
||||
let goff_b_s2: u64 = goff_w_s2 + sh2 * sh1 * f32;
|
||||
let goff_w_v1: u64 = goff_b_s2 + sh2 * f32;
|
||||
|
||||
@@ -2694,7 +2694,8 @@ impl GpuDqnTrainer {
|
||||
info!("GpuDqnTrainer: mag_concat_qdir + strided_accumulate kernels loaded");
|
||||
|
||||
// ── Cross-Branch Q Attention buffers ──────────────────────────
|
||||
let q_attn_params = alloc_f32(&stream, 624, "q_attn_params")?;
|
||||
let q_attn_params = stream.alloc_zeros::<f32>(624)
|
||||
.map_err(|e| MLError::ModelError(format!("alloc q_attn_params: {e}")))?;
|
||||
let q_attn_adam_m = stream.alloc_zeros::<f32>(624)
|
||||
.map_err(|e| MLError::ModelError(format!("alloc q_attn_adam_m: {e}")))?;
|
||||
let q_attn_adam_v = stream.alloc_zeros::<f32>(624)
|
||||
|
||||
Reference in New Issue
Block a user