Commit Graph

61 Commits

Author SHA1 Message Date
jgrusewski
9b85b9efd5 feat(ml): add Pushgateway metrics client for training jobs
Training jobs are short-lived K8s Jobs that can't be reliably scraped
by Prometheus. This adds a TrainingMetricsPusher that pushes epoch-level
metrics (loss, accuracy, throughput, gradient health, checkpoints) to
the Pushgateway so they persist for Prometheus to scrape.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 02:36:05 +01:00
jgrusewski
561e2bd299 fix: repair broken use statement in ml/deployment/endpoints.rs
The #[instrument] import was incorrectly inserted inside a `use super {}`
block by the previous commit, causing syntax errors.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 00:55:51 +01:00
jgrusewski
1aef51f99b fix(stubs): implement 15 production stubs, fix routing, delete placeholders
Web-gateway routing:
- Point TRADING_SERVICE_URL at api-gateway (proto mismatch fix)
  Web-gateway uses foxhunt.tli.TradingService proto but was connecting
  directly to trading-service which implements trading.TradingService.
  api-gateway already proxies Subscribe* → Stream* correctly.

GitLab KAS:
- Disable gitlab_kas in appConfig to stop sidekiq NotifyGitPushWorker
  errors (KAS pod was already disabled but Rails still tried to connect)

Trading service monitoring (3 stubs → real):
- AcknowledgeAlert: real alert lookup + state mutation in shared store
- GetActiveAlerts: returns actual active alerts from in-memory store
- StreamAlerts: now persists generated alerts (capped at 1000 entries)

Trading service ML streams (2 stubs → real):
- StreamModelMetrics: emits real inference_count, error_count, latency
  per model every N seconds from the RuntimeModelInfo registry
- StreamSignalStrength: emits per-symbol signal aggregation from model
  ensemble weights and latency confidence

Backtesting service:
- stop_backtest: real CancellationToken cancellation (was no-op)
  Tokens stored per-backtest, execute_backtest wraps strategy call
  in tokio::select! for immediate cancellation

Deleted 7 empty placeholder files:
- 4 Wave D regime stubs (dynamic_stops, ensemble, performance_tracker,
  position_sizer) — comment-only files, never wired
- 2 Wave 3 feature stubs (microstructure, statistical)
- 1 PPO stub (unified_ppo.rs — empty struct definitions)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 23:47:31 +01:00
jgrusewski
5d3efbd2cc feat(hyperopt): auto-scale PSO particles to GPU capacity
Remove artificial swarm_size cap from plan_hyperopt() that limited
concurrent trials to n_particles (default 20). Now concurrency is
purely VRAM-driven with a hardware cap of 128 threads.

optimize_parallel() auto-scales n_particles to match GPU budget:
- L4 24GB: ~65 concurrent DQN trials (was 20)
- H100 80GB: 128 concurrent DQN trials (was 20)
- CPU/small GPU: falls back to configured n_particles

max_trials scales proportionally to ensure 3+ PSO iterations
for convergence with larger swarms.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 22:12:11 +01:00
jgrusewski
4cc15d4496 feat(hyperopt): VRAM-aware parallel trial concurrency with OOM protection
optimize_parallel() now uses HardwareBudget::plan_hyperopt() to compute
max concurrent trials based on model VRAM footprint. Includes ramp-up
(start at half concurrency), VRAM watchdog (check free memory before
spawning), and graceful degradation to sequential.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 21:44:39 +01:00
jgrusewski
25141c4b90 feat(hyperopt): add HyperoptStrategy and HardwareBudget::plan_hyperopt()
Computes optimal (concurrency, batch_size_bounds) based on model memory
footprint vs detected GPU VRAM. Scales from CPU-only (sequential) through
H100 80GB (full swarm parallel). 20% safety margin for CUDA allocator.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 21:34:24 +01:00
jgrusewski
ad8ab79f5e fix(hyperopt): remove hardcoded batch_size=160 clamp from DQN adapter
PSO now controls batch_size within [64, 4096] range. HardwareBudget
adjusts upper bound based on detected VRAM. The .min(160.0) clamp was
silently overriding PSO's choices on any GPU larger than 3050 Ti.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 21:30:06 +01:00
jgrusewski
14d405f112 refactor(ml): remove legacy base_model_memory_mb from BatchSizeConfig
Single model_memory_mb field now serves as the sole source of truth for
base model memory. Removes the redundant base_model_memory_mb field,
legacy dual-path branches in calculate_optimal_batch_size() and
max_safe_batch_size(), and the associated legacy test.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 20:58:04 +01:00
jgrusewski
6804f0facf fix(dqn): let PSO control batch_size, use VRAM ceiling instead of AutoBatchSizer override
AutoBatchSizer was computing an "optimal" batch_size (128 on L4) and
overriding the PSO-chosen value. On an L4 24GB this meant 3.5% VRAM
utilization per trial. Now the trainer only clamps if the batch_size
would actually OOM, letting PSO explore the full [64, 4096] range.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 20:48:43 +01:00
jgrusewski
cd8a45d8a8 fix(gpu): wire PPO GPU experience collection, fix debug log levels, increase hyperopt deadline
- Wire GPU experience collection into PPO hyperopt adapter with CPU fallback
  (ensure_gpu_data, gpu_collect_trajectories, batch-to-trajectory converter)
- Downgrade 6 ERROR-level debug logs to debug!() in DQN hyperopt adapter
- Increase hyperopt activeDeadlineSeconds from 1h to 6h (job-template + train.sh)
- Mark 3 data-dependent real_data_loader tests as #[ignore]
- Fix 4 clippy map_or → is_none_or warnings in trading_service

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 19:58:16 +01:00
jgrusewski
195f880fb4 feat(hyperopt): add batch_size to PPO and Liquid parameter spaces
PPO: add batch_size as 6th param (index 5)
- Static bounds: 512–8192 (PPO needs large batches for variance reduction)
- Default: 2048 (was hardcoded)
- Dynamic: scales with VRAM (200MB overhead, 0.015 MB/sample)
- Wire into PPOConfig in train_with_params()

Liquid CfC: add batch_size as 8th param (index 7)
- Static bounds: 8–512
- Default: 32 (was hardcoded)
- Dynamic: scales with VRAM (100MB overhead, 0.06 MB/sample)
- Wire into CfCTrainConfig in train_with_params()
- NUM_PARAMS: 7 → 8

All 176 hyperopt tests pass, full workspace compiles clean.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 19:20:08 +01:00
jgrusewski
b4239e8c43 feat(hyperopt): add VRAM-aware batch_size scaling to 9 existing adapters
Override continuous_bounds_for() in all adapters that already have batch_size:
- TFT (idx 1): 150MB overhead, 0.05 MB/sample, cap 2048
- Mamba2 (idx 1): 200MB overhead, 0.03 MB/sample, cap 2048
- TGGN (idx 7): 100MB overhead, 0.08 MB/sample, cap 1024
- TLOB (idx 6): 120MB overhead, 0.10 MB/sample, cap 1024
- KAN (idx 7): 80MB overhead, 0.04 MB/sample, cap 1024
- xLSTM (idx 6): 180MB overhead, 0.06 MB/sample, cap 1024
- Diffusion (idx 6): 250MB overhead, 0.12 MB/sample, cap 512
- DQN (idx 1): 300MB overhead, 0.02 MB/sample, cap 4096
- ContinuousPPO (idx 9): 250MB overhead, 0.03 MB/sample, cap 4096

On CPU-only, all adapters fall back to existing static bounds.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 19:19:25 +01:00
jgrusewski
de2169fbe4 feat(hyperopt): add HardwareBudget + continuous_bounds_for() to ParameterSpace trait
Add VRAM-aware batch size bounds infrastructure:
- HardwareBudget struct with detect(), cpu_only(), with_memory_mb() constructors
- max_batch_size() helper for per-model memory profile scaling
- continuous_bounds_for(budget) default method on ParameterSpace trait
- Default impl delegates to static continuous_bounds() (non-breaking)
- Updated 2 optimizer call sites to detect hardware and use dynamic bounds
- 6 new unit tests for HardwareBudget behavior

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 19:03:56 +01:00
jgrusewski
40febb0061 fix(cuda): enable GPU experience collection for regime-conditional DQN
The GPU experience collector only supported DQNAgentType::Standard, but
enable_regime_qnetwork defaults to true, creating RegimeConditional
agents. This silently fell back to CPU with a debug! message invisible
at INFO log level.

- Add primary_head() accessor to RegimeConditionalDQN (returns trending head)
- Extract weights from primary head for both collector init and weight sync
- Upgrade debug! to warn! for missing GPU collection prerequisites
- Add warn! to PPO for silent GPU skip when raw market data not uploaded

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 17:01:01 +01:00
jgrusewski
fa74f9afcf fix(cuda): add missing gpu_portfolio.rs and experience_kernels.cu files
These files were part of the Phase 2 cuda_pipeline but were untracked
and not included in previous commits. Required for compilation with
--features ml/cuda.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 14:41:54 +01:00
jgrusewski
9b2804f9ec feat(cuda): wire GPU experience collection into DQN & PPO training loops
Phase 3 of the CUDA pipeline: both trainers now take a GPU-first path
for experience collection (128×500 = 64K experiences per kernel launch,
zero CPU-GPU roundtrips per timestep) with automatic CPU fallback.

- DQN: upload features alongside targets, GPU collection branch before
  CPU loop, gpu_batch_to_experiences() conversion into replay buffer
- PPO: set_raw_market_data() for CudaSlice upload, GPU collection
  branch bypasses collect_rollouts + prepare_training_batch entirely,
  gpu_batch_to_trajectory_batch() conversion with in-kernel GAE
- Configurable GPU batch sizes (gpu_n_episodes, gpu_timesteps_per_episode)
  and trading params (initial_capital, avg_spread) via hyperparameters
- SAFETY training diagnostics downgraded from warn! to debug!
- 4 new batch index-math validation tests in cuda_pipeline

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 14:14:48 +01:00
jgrusewski
d4b22910d7 fix(ppo): replace wildcard match with explicit Device variants for clippy
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 13:38:42 +01:00
jgrusewski
341514a4b0 feat(ppo): integrate GPU experience collector with weight sync
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 13:32:57 +01:00
jgrusewski
50b360c23c test(cuda): add PPO collector config defaults and source concatenation tests
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 13:30:58 +01:00
jgrusewski
6b4c309760 feat(cuda): add GpuPpoExperienceCollector with zero-roundtrip kernel launch
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 13:29:24 +01:00
jgrusewski
141aa46848 feat(cuda): add PPO actor/critic weight extraction and GPU upload
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 13:25:20 +01:00
jgrusewski
4c22b15ca4 feat(cuda): add PPO experience kernel — actor, critic, GAE, full rollout
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 13:20:45 +01:00
jgrusewski
dfcc19538a refactor(cuda): extract shared device functions to common_device_functions.cuh
Move 10 shared device functions (gpu_random, leaky_relu, matvec_leaky_relu,
action_to_exposure, action_to_tx_cost, barrier_init/check/reset,
diversity_entropy, curiosity_inference) and shared constants from
dqn_experience_kernel.cu into a new common_device_functions.cuh header.

The DQN kernel now expects the common header to be prepended via NVRTC
source concatenation at compile time. DQN-specific functions
(q_forward_dueling, argmax_q) remain in the kernel file. This enables
the upcoming PPO kernel to reuse the same shared functions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 13:14:55 +01:00
jgrusewski
e7a6814045 feat(dqn): integrate GPU experience collector with weight sync
Adds GpuExperienceCollector field to DQNTrainer, initializes it when
dueling networks and curiosity module are present on CUDA device, and
syncs GPU weight copies after each training epoch.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 12:34:23 +01:00
jgrusewski
b43070ee6c test(cuda): add unit tests for weight extraction, kernel source, and experience config
Adds 4 tests:
- gpu_weights: verify all 12 VarMap key paths exist with correct shapes
- gpu_weights: verify total parameter count matches spec (151,598)
- mod: verify kernel source contains entry-point function name
- mod: verify ExperienceCollectorConfig defaults and total_experiences()

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 12:25:08 +01:00
jgrusewski
260981b20a feat(cuda): add GpuExperienceCollector with zero-roundtrip kernel launch
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 12:20:28 +01:00
jgrusewski
86c81f21d4 feat(cuda): add weight extraction module for Q-network and curiosity GPU upload
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 12:15:43 +01:00
jgrusewski
39158ecab2 fix(cuda): spec compliance — barrier_done, step_in_episode, diversity penalty
Three fixes from spec review:
1. diversity_entropy returns -0.1 penalty (threshold < 1.0) instead of raw entropy
2. barrier_done included in episode termination (barrier hit ends episode)
3. step_in_episode counter resets properly on mid-loop episode reset

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 12:10:36 +01:00
jgrusewski
adf248f383 feat(cuda): add zero-roundtrip DQN experience collection kernel
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 12:03:27 +01:00
jgrusewski
388f54dd06 feat(dqn): pre-upload training data to GPU, use cached targets in hot loop
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 02:49:10 +01:00
jgrusewski
10b139c029 feat(cuda_pipeline): add VRAM estimation and safety guards
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 02:48:58 +01:00
jgrusewski
3cfa99de3f feat(ppo): pre-upload rollout states to GPU, eliminate per-step tensor allocs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 02:48:33 +01:00
jgrusewski
3883284219 feat(ml): add cuda_pipeline module with GPU data pre-upload for DQN/PPO
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 02:45:48 +01:00
jgrusewski
52630a77d3 perf: eliminate heap-alloc Decimal→float casts across 19 files (36 instances)
Replace all `.to_string().parse::<f32/f64>()` patterns with
`num_traits::ToPrimitive` methods (`.to_f32()`, `.to_f64()`).
Each string roundtrip heap-allocated per conversion — fatal in
DQN hot loop (300K+ bars × epochs). Decimal stays as canonical
financial type; conversions happen at GPU/float boundaries only.

Also fixes blocking_read() in async context (risk_integration.rs).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 02:29:04 +01:00
jgrusewski
35ac61b68d chore(ml): downgrade P2-C reversal warns to debug, delete stale patch
P2-C reversal/cash warns fire thousands of times per hyperopt trial
during backtest simulation. Also removes stale Kelly patch file (already
applied).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 01:13:37 +01:00
jgrusewski
5579efe7b1 chore(ml): downgrade portfolio-feature warns to debug
These fire every training step when portfolio isn't populated yet —
extremely noisy during hyperopt with parallel trials.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 01:10:36 +01:00
jgrusewski
21a8e3410f fix(hyperopt): require GPU for RL hyperopt, propagate device to trainers
The previous "auto-detect" logic forced CPU which was wrong — GPU is
faster for forward/backward even with parallel trials (DQN/PPO use
<350MB of 24GB VRAM across 7 threads).

Changes:
- Remove --device flag, always require CUDA GPU
- Add DQNTrainer::new_with_device() to share CUDA context across trials
- Propagate hyperopt device to internal DQN trainer (was ignoring it)
- PPO/DQN adapters error on missing GPU instead of silent CPU fallback
- Downgrade batch-size clamping from warn to debug

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 01:08:46 +01:00
jgrusewski
590883408a feat(hyperopt): auto-detect CPU for parallel RL hyperopt, use all cores
DQN/PPO networks are tiny (3 layers × 128 neurons). Running parallel
hyperopt on GPU wastes cores because CUDA context serializes across
threads — 5 trials on L4 only used 2000m of 6000m requested CPU.

Changes:
- Add --device flag to hyperopt_baseline_rl (auto/cpu/cuda)
- Auto mode forces CPU for parallel runs (no CUDA contention)
- CPU mode uses all available cores (no 2-core reserve)
- Add with_device() builder to DQN/PPO hyperopt trainers
- Downgrade "portfolio value <= 0" and GPU utilization warnings

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 00:11:58 +01:00
jgrusewski
979061c80c fix: downgrade remaining DQN training warn noise to debug/info
Portfolio value <= 0 during early exploration is expected behavior,
not a warning. GPU memory utilization advisory is informational.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 23:48:19 +01:00
jgrusewski
b762fecff8 fix: downgrade DQN warn noise to debug, fix clippy warnings, default dev-release
- DQN portfolio_tracker: Phase 1/2 complete logs warn→debug (noisy per-epoch)
- risk: lazy_static→LazyLock, .map→.inspect, midpoint overflow fixes
- risk: remove unused POSITION_PROCESSING_LATENCY, lazy_static dep
- CI: default DEV_RELEASE=true for fast iteration (thin LTO, 24% faster)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 23:04:37 +01:00
jgrusewski
8225950f06 feat(ml): parallel PSO hyperopt with IBKR cost defaults
Enable concurrent trial evaluation for DQN/PPO hyperparameter
optimization via clone-per-particle pattern — each PSO particle
clones the trainer and trains independently, replacing the previous
Arc<Mutex> serialization bottleneck. On L4 (8 vCPU) this yields
~4-5x throughput improvement.

Changes:
- DQNTrainer/PPOTrainer: Clone with Arc<AtomicUsize> trial counter
- DQNTrainer: replace unsafe mutable aliasing with Arc<Mutex> for
  best_trial tracking
- ArgminOptimizer: add optimize_parallel() with ParallelObjectiveFunction
  and scoped-thread LHS evaluation
- CLI: --parallel 0 (auto-detect CPUs-2), --initial-capital 35000,
  --tx-cost-bps 0.1 (IBKR ES all-in)
- CI: both hyperopt jobs use --parallel 0 + IBKR ES cost defaults

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 19:42:22 +01:00
jgrusewski
b4cfd88634 refactor(ml): drop dead TFT Parquet loader (-130 lines)
train_from_parquet and load_training_data_from_parquet had zero
callers — TFT hyperopt uses train_from_bars via DBN data.
Also removes unused NormalizationParams struct from this module.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 18:56:04 +01:00
jgrusewski
3564efe961 fix(ml): fix TFT OOB in historical features — 51 not 54 elements
Feature vectors are [f64; 51] after WAVE 10 (Proxy OFI removal):
  [0..5] static, [5..15] known, [15..51] unknown (36 features)

Old code used fv[15..54].min(fv.len()) which silently produced 36
features per step but expected 39 in Array2 shape → ShapeError.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 18:52:35 +01:00
jgrusewski
48aac3c601 fix(ml): implement actual gradient clipping in PPO (was warn-only)
Three critical stability fixes for PPO training:

1. Gradient clipping: Added clip_grads() that scales gradients by
   max_norm/norm when L2 norm exceeds max_grad_norm (0.5). Previously
   the code only logged a warning — gradient norms of 27-171x above
   the threshold were applied raw to weights, causing divergence.
   Fixed in all 8 locations across PpoTrainer (6) and ContinuousPPO (2).

2. Return normalization: Value loss now normalizes returns to N(0,1)
   before computing MSE. Raw cumulative returns (±1000s) caused enormous
   value gradients that destabilized the critic network.

3. Hyperopt search space: Tightened value LR upper bound from 1e-3 to
   1e-4 (1e-3 is documented unstable), policy LR from 1e-3 to 3e-4.

Also fixed LSTM path where optimizer.step() ran BEFORE gradient norm
check — now clip → step (not step → warn).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 10:03:42 +01:00
jgrusewski
c706102b93 refactor: delete adaptive-strategy crate, port ConfidenceAggregator to ml
The adaptive-strategy crate (~28K lines, 22 source files) was an orphaned
framework with zero external consumers. Its only valuable piece — ensemble
uncertainty quantification — has been ported to ml/src/ensemble/confidence.rs.

Ported: ConfidenceAggregator, UncertaintyQuantifier, ReliabilityScorer,
IntervalCombiner, DisagreementTracker + all config/output types. Removed
gratuitous async from pure-math methods. 6 tests (4 ported + 2 edge cases).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 02:00:24 +01:00
jgrusewski
afd85b2f8f chore: clean up examples, update ML binaries and risk tests
- Delete 14 unused example files (-3,543 lines): config, adaptive-strategy,
  data, storage, trading_engine, api_gateway, backtesting, trading_service, chaos
- Update ML training/eval binaries: improved CLI args, completion tracking,
  CUDA test cleanup, hyperopt enhancements
- Fix KAN network and TFT module adjustments
- Update risk test assertions for consistency
- Fix backtesting repositories and promotion manager
- Update .serena project config and Cargo dependencies

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 01:33:18 +01:00
jgrusewski
b09ebfc3cb feat(ml): add HyperparameterOptimizable trainers for all 8 supervised models
Extend hyperopt infrastructure to support all 10 ML models (DQN, PPO +
8 supervised). Previously only TFT and Mamba2 had hyperopt trainers.

- Add HyperparameterOptimizable impl for Liquid, TGGN, TLOB, KAN, xLSTM, Diffusion
- Create shared_data.rs with common data prep utilities (build_flat_pairs,
  build_sequence_pairs, write_trial_result_json)
- Extend hyperopt_baseline_supervised binary to dispatch all 8 models
  (individual, "both" for tft+mamba2, "all" for all 8)
- Add CI jobs: 7 train-validate + 10 hyperopt jobs for all models
- Fix DiffusionMetrics NaN default, XLSTMMetrics serde, safe indexing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 23:47:52 +01:00
jgrusewski
acff64b678 fix(ml): TFT validation loss dtype F32→F64 conversion
The validate() method called loss.to_scalar::<f64>() on an F32 tensor,
causing "unexpected dtype, expected: F64, got: F32" at runtime.
Add .to_dtype(F64) before scalar extraction, matching the pattern
used in all other TFT gradient/loss code paths.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 20:30:54 +01:00
jgrusewski
7554730fc1 fix(ml): ignore perf benchmark tests in debug builds
These tests assert sub-millisecond latency thresholds that only hold
with opt-level=3. Now that dev/test builds use opt-level=0 (correct),
mark them #[ignore] so they run only via `cargo test --release`.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 18:09:01 +01:00
jgrusewski
265bd2441c fix(ml,ci): zero-dim guards on all 10 models, eliminate warnings, unblock CI parallelism
- Add dimension validation in DQN, PPO, Mamba2, TGGN, TLOB, Liquid,
  KAN, xLSTM, Diffusion constructors (fail-fast on zero-dim inputs
  that would cause CUDA_ERROR_INVALID_VALUE at runtime)
- Add num_unknown_features > 0 guard to TFT (temporal input required)
- Fix 12 dead-code/unused warnings in test compilation
- Remove opt-level=3 and codegen-units=1 from target rustflags
  (was forcing O3 + single-thread codegen on dev/test builds)
- Remove hardcoded jobs=16 cap (cargo now auto-detects CPU count)
- Switch linker to clang+lld (2-5x faster linking)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 17:38:43 +01:00