From a5eeeaa47704bbd97c78efcafc775e5fdd4bb4c1 Mon Sep 17 00:00:00 2001 From: jgrusewski Date: Sun, 5 Apr 2026 14:51:21 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20smoketest=20max=5Fbars=2060K=E2=86=925K?= =?UTF-8?q?=20+=20counterfactual=20test=20threshold?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Reduce max_bars from 60000 to 5000 (smoketests ran 16min, now ~1min) - Fix test_counterfactual_experiences_in_buffer: compute threshold from actual config instead of hardcoded 4000, enlarge buffer to avoid wrap Co-Authored-By: Claude Opus 4.6 (1M context) --- config/training/dqn-smoketest.toml | 2 +- .../trainers/dqn/smoke_tests/regression.rs | 31 ++++++++++--------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/config/training/dqn-smoketest.toml b/config/training/dqn-smoketest.toml index 3e5705ed5..1617eb307 100644 --- a/config/training/dqn-smoketest.toml +++ b/config/training/dqn-smoketest.toml @@ -21,7 +21,7 @@ hidden_dim_base = 64 reward_scale = 1.0 huber_delta = 1.0 symbol = "ES.FUT" -max_bars = 60000 +max_bars = 5000 imbalance_bar_threshold = 1.0 imbalance_bar_ewma_alpha = 0.1 diff --git a/crates/ml/src/trainers/dqn/smoke_tests/regression.rs b/crates/ml/src/trainers/dqn/smoke_tests/regression.rs index cd9d2a21d..70c5261b5 100644 --- a/crates/ml/src/trainers/dqn/smoke_tests/regression.rs +++ b/crates/ml/src/trainers/dqn/smoke_tests/regression.rs @@ -161,9 +161,15 @@ fn test_counterfactual_experiences_in_buffer() -> anyhow::Result<()> { let mut p = smoke_params(); p.epochs = 1; p.early_stopping_enabled = false; - // Ensure we can distinguish 1x from 2x: buffer must be large enough to hold 2x - // smoketest defaults: gpu_n_episodes=32, gpu_timesteps=100, buffer_size=10000 - // base = 32 * 100 = 3200, counterfactual = 6400, fits in 10000 + + // Compute expected counts from the actual config + let n_ep = p.gpu_n_episodes; + let ts = p.gpu_timesteps_per_episode; + let base = n_ep * ts; + let with_cf = base * 2; // counterfactual doubles + // Buffer must be large enough to hold 2x WITHOUT wrapping, so we can + // distinguish 1x from 2x by counting entries. + p.buffer_size = with_cf + 100; let mut trainer = smoke_trainer_with(p)?; let rt = tokio::runtime::Builder::new_current_thread() @@ -173,27 +179,24 @@ fn test_counterfactual_experiences_in_buffer() -> anyhow::Result<()> { Ok("skip".to_owned()) }))?; - // Check replay buffer size via the agent let buffer_size = rt.block_on(async { let agent = trainer.get_agent().read().await; agent.get_replay_buffer_size().unwrap_or(0) }); - // With counterfactual: 32 * 100 * 2 = 6400 - // Without counterfactual (the old bug): 32 * 100 = 3200 - // Threshold at 4000 cleanly separates the two cases. - let min_expected = 4000; + // With counterfactual: buffer should have more entries than base (1x). + // Threshold: midpoint between 1x and 2x cleanly separates the cases. + let min_expected = (base + with_cf) / 2; assert!( buffer_size >= min_expected, - "PER buffer has {} entries (expected >= {min_expected}). \ - Counterfactual experiences may be silently dropped again. \ - With gpu_n_episodes=32, timesteps=100, expected 6400 (32*100*2).", - buffer_size + "PER buffer has {buffer_size} entries (expected >= {min_expected}). \ + base={base}, with_cf={with_cf}. \ + Counterfactual experiences may be silently dropped.", ); tracing::info!( - "Counterfactual regression: PER buffer has {} entries (expected ~6400)", - buffer_size + "Counterfactual regression: PER buffer has {buffer_size} entries \ + (expected ~{with_cf}, threshold={min_expected})", ); Ok(()) }