From 298455e24a973e587d85892e68aa39b51feaaef6 Mon Sep 17 00:00:00 2001 From: jgrusewski Date: Wed, 15 Apr 2026 07:16:56 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20precommit=20audit=20=E2=80=94=20gradient?= =?UTF-8?q?=20offset=20s1=5Finput=5Fdim=20+=20q=5Fattn=5Fparams=20zero-ini?= =?UTF-8?q?t?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- crates/ml/src/cuda_pipeline/batched_backward.rs | 4 ++-- crates/ml/src/cuda_pipeline/gpu_dqn_trainer.rs | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/crates/ml/src/cuda_pipeline/batched_backward.rs b/crates/ml/src/cuda_pipeline/batched_backward.rs index 5010058e2..7f5fd0f23 100644 --- a/crates/ml/src/cuda_pipeline/batched_backward.rs +++ b/crates/ml/src/cuda_pipeline/batched_backward.rs @@ -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::() 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; diff --git a/crates/ml/src/cuda_pipeline/gpu_dqn_trainer.rs b/crates/ml/src/cuda_pipeline/gpu_dqn_trainer.rs index 39f6a847c..a7fa40a57 100644 --- a/crates/ml/src/cuda_pipeline/gpu_dqn_trainer.rs +++ b/crates/ml/src/cuda_pipeline/gpu_dqn_trainer.rs @@ -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::(624) + .map_err(|e| MLError::ModelError(format!("alloc q_attn_params: {e}")))?; let q_attn_adam_m = stream.alloc_zeros::(624) .map_err(|e| MLError::ModelError(format!("alloc q_attn_adam_m: {e}")))?; let q_attn_adam_v = stream.alloc_zeros::(624)