From 83b089928c0f3ba3c5ad6fa6dc1cf00ccc4281e2 Mon Sep 17 00:00:00 2001 From: jgrusewski Date: Wed, 25 Mar 2026 21:30:11 +0100 Subject: [PATCH] =?UTF-8?q?fix:=20recalibrate=20CI=20tests=20for=20wider?= =?UTF-8?q?=20v=5Frange=20(=C2=B1240)=20and=20larger=20gradients?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit dqn-smoke: Walk-forward validation DQN uses raw price returns (~0.001), not production reward_scale=10. Set v_min/v_max to ±10 for the small 16-dim 3-action test network (was inheriting ±240 from production default). dqn-early-stop: Gradient collapse threshold = lr × multiplier must exceed the actual gradient norm to trigger collapse. With v_range ±240, gradient norms reach 100-10000 (was ~0.5-2.0 with old ±2.0 range). Updated multiplier from 1e9 to 1e12 to guarantee threshold (10000) > grad norm. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../dqn_early_stopping_termination_test.rs | 17 ++++++++--------- crates/ml/tests/dqn_training_smoke_test.rs | 4 ++++ 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/crates/ml/tests/dqn_early_stopping_termination_test.rs b/crates/ml/tests/dqn_early_stopping_termination_test.rs index 757b68514..bbbaa557b 100644 --- a/crates/ml/tests/dqn_early_stopping_termination_test.rs +++ b/crates/ml/tests/dqn_early_stopping_termination_test.rs @@ -138,14 +138,12 @@ async fn test_early_stopping_terminates_with_error() { ml::training_profile::DqnTrainingProfile::load("dqn-smoketest").apply_to(&mut hyperparams); // Force gradient collapse detection by setting threshold above typical grad norm. - // Threshold = 1e-8 × 1e9 = 10.0 (always above typical grad norms ~0.5-2.0). - // RegimeConditionalDQN tracks collapse across epoch-boundary log_diagnostics() - // and per-step check_gradient_collapse() with a shared counter. - // With patience=3, collapse triggers during epoch 2 training steps - // (epoch 1 boundary increments to 1, per-step checks in epoch 2 reach 3). + // Threshold = lr × multiplier. With v_range ±240 (C51), gradient norms can reach + // 100-10000 depending on epoch/data. Set threshold = 1e-8 × 1e12 = 10000.0 to + // guarantee the norm stays below threshold → collapse triggers reliably. hyperparams.learning_rate = 1e-8; hyperparams.epochs = 10; - hyperparams.gradient_collapse_multiplier = 1e9; + hyperparams.gradient_collapse_multiplier = 1e12; hyperparams.gradient_collapse_patience = 3; hyperparams.min_epochs_before_stopping = 1; hyperparams.early_stopping_enabled = true; @@ -212,13 +210,14 @@ async fn test_gradient_collapse_propagates_error() { let mut hyperparams = DQNHyperparameters::conservative(); ml::training_profile::DqnTrainingProfile::load("dqn-smoketest").apply_to(&mut hyperparams); - // Force gradient collapse detection: threshold = lr × multiplier = 5e-9 × 1e9 = 5.0 - // Typical grad norms are ~0.5-2.0, so threshold 5.0 is always above → collapse triggers. + // Force gradient collapse detection: threshold = lr × multiplier = 5e-9 × 1e12 = 5000.0 + // With v_range ±240 (C51), grad norms can reach 100-10000. Threshold must be above + // the maximum expected norm to guarantee collapse detection fires. // GPU PER requires buffer_size >= 1024. Warmup = 1024 × 0.2 = 204 steps. // max_training_steps_per_epoch=300 clears warmup in epoch 1 (300 > 204). hyperparams.learning_rate = 5e-9; hyperparams.epochs = 10; - hyperparams.gradient_collapse_multiplier = 1e9; + hyperparams.gradient_collapse_multiplier = 1e12; hyperparams.gradient_collapse_patience = 3; hyperparams.min_epochs_before_stopping = 1; hyperparams.early_stopping_enabled = true; diff --git a/crates/ml/tests/dqn_training_smoke_test.rs b/crates/ml/tests/dqn_training_smoke_test.rs index 68a83d860..49dc63e28 100644 --- a/crates/ml/tests/dqn_training_smoke_test.rs +++ b/crates/ml/tests/dqn_training_smoke_test.rs @@ -355,6 +355,10 @@ async fn test_dqn_training_smoke() -> Result<()> { dqn_config.use_iqn = false; dqn_config.epsilon_start = 0.3; dqn_config.epsilon_end = 0.01; + // Walk-forward uses raw price returns (~0.001), NOT the production reward + // function (scale 10.0). Override v_range to match this simpler reward scale. + dqn_config.v_min = -10.0; + dqn_config.v_max = 10.0; let mut strategy = DqnStrategy::new(dqn_config)?; let report = harness.validate(&mut strategy, &ts_data)?;