From 079f3192ebe4eafaacc8bf7b213442d9505a1119 Mon Sep 17 00:00:00 2001 From: jgrusewski Date: Fri, 20 Feb 2026 20:49:41 +0100 Subject: [PATCH] docs: add DQN pipeline production readiness design 4-phase plan: fix tests + OOM safety, inference path, longer training, hyperopt end-to-end. Co-Authored-By: Claude Opus 4.6 --- ...6-02-20-dqn-production-readiness-design.md | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 docs/plans/2026-02-20-dqn-production-readiness-design.md diff --git a/docs/plans/2026-02-20-dqn-production-readiness-design.md b/docs/plans/2026-02-20-dqn-production-readiness-design.md new file mode 100644 index 000000000..b0cb4dbd1 --- /dev/null +++ b/docs/plans/2026-02-20-dqn-production-readiness-design.md @@ -0,0 +1,80 @@ +# DQN Pipeline Production Readiness — Design + +**Date**: 2026-02-20 +**Goal**: Prove the DQN training pipeline works end-to-end at production scale — from safe GPU training through hyperparameter optimization to model inference. + +## Context + +The DQN smoke test (7/7 assertions) proves the basic train -> checkpoint -> validate path works. But several gaps remain before the pipeline is production-ready: + +- One pre-existing test failure (`test_dqn_loss_decreases`) +- OOM protection exists in code but is not wired into the training loop +- No verified checkpoint -> inference -> trade signals path +- No proof that longer training produces meaningful convergence +- No proof that hyperopt actually improves over default hyperparameters + +## Milestone: 4 Phases + +### Phase 1: Fix Foundation (Tests + OOM Safety) + +**Fix broken tests:** +- `dqn_training_pipeline_test::test_dqn_loss_decreases` asserts `convergence_achieved` (loss < 1.0) but loss is ~3.75 after 20 epochs. Adjust the test to match realistic convergence behavior. + +**Wire OOM safety into training:** + +Three changes: + +1. **Dynamic batch size on startup** — Call `AutoBatchSizer` in `DQNTrainer::new()` to validate the configured batch size fits in GPU memory. Replace the static `MAX_BATCH_SIZE=230` with a real nvidia-smi memory query. Fall back to the static cap if nvidia-smi is unavailable (CI). + +2. **OOM recovery loop** — Wrap `train_step()` in an error handler that detects OOM via `is_oom_error()`, halves the batch size, clears CUDA cache, and retries. Max 3 retries before propagating the error. + +3. **Fix gradient accumulation** — Current implementation calls `optimizer.step()` per mini-batch (fake accumulation). Change to accumulate gradients across mini-batches and step once at the end. This means batch_size=64 with accumulation_steps=4 gives effective_batch=256 at only 64-sample peak memory. + +**Success criteria:** +- All DQN pipeline tests green +- Training with batch_size=64 completes 20 epochs on 4GB GPU +- OOM recovery fires and recovers when tested with an oversized batch + +### Phase 2: Production Inference Path + +**Integration test:** Train 5 epochs -> save checkpoint -> load into fresh DQN -> run inference on 100 real bars -> assert actions are valid, Q-values non-zero, loaded model matches original. + +**CLI example:** Update or create an example binary that loads a checkpoint from disk and runs inference on a data file, printing trade signals. Practical "use the model" entry point. + +**Success criteria:** +- Test passes: checkpoint -> load -> inference round-trip verified +- Example binary runs and produces trade signals from a checkpoint + +### Phase 3: Longer Training Run + +**Config:** 50 epochs on the small dataset (4 days, ~15k bars), batch_size=64, conservative defaults, early stopping patience=20. + +**Delivery:** `#[ignore]` integration test (not in CI) + updated `train_dqn_production.rs` example. + +**Success criteria:** +- Training completes without OOM +- Loss decreases >50% from epoch 1 +- Final loss < 2.0 +- Epsilon decays to near-zero + +### Phase 4: Hyperopt End-to-End + +**Config:** 10 trials of Nelder-Mead on the small dataset, 10-20 epochs per trial. + +**Delivery:** `#[ignore]` integration test proving the optimizer works. + +**Success criteria:** +- Hyperopt completes 10 trials without crashes or OOM +- Best trial Sharpe > first trial Sharpe (optimizer improves) +- Best model checkpoint saved and loadable + +## Non-goals + +- Full-scale training on year-long datasets (separate milestone) +- Multi-asset or cross-market validation +- Deploying a trading system +- Modifying the DQN architecture or reward function + +## Key Risk: OOM on 4GB GPU + +The RTX 3050 Ti has 4GB VRAM. With 51-dim state, 45 actions, and a [64,32] hidden network, a batch of 64 samples uses ~50MB for forward+backward pass. The replay buffer (500K experiences at ~400 bytes each = ~200MB) is the bigger concern. Mitigation: dynamic batch sizing, OOM recovery, and gradient accumulation let us train safely within the memory envelope.