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 <noreply@anthropic.com>
This commit is contained in:
80
docs/plans/2026-02-20-dqn-production-readiness-design.md
Normal file
80
docs/plans/2026-02-20-dqn-production-readiness-design.md
Normal file
@@ -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.
|
||||
Reference in New Issue
Block a user