jgrusewski 61ab27ff34 gem(G6+G10): graph-safe forward + HEALTH_DIAG readback (measurement-first)
Following the V7-gem methodology you flagged: instead of blindly wiring
backward gradients for two possibly-redundant features (G10 redundant
with spectral_norm, G6 redundant with NoisyNets/ensemble-KL), this commit
makes both forward-only and exposes their values via HEALTH_DIAG so we
can MEASURE whether they're producing meaningful signal before committing
to the full backward integration.

Three coordinated changes:

1) G10 temporal_consistency_penalty rewritten graph-safe
   (experience_kernels.cu)

   Was: multi-block kernel with cross-block atomicAdd into a single scalar,
   and a Rust wrapper that called cuMemsetD32Async to zero it before each
   launch. cuMemsetD32Async is NOT capturable in CUDA Graph, so wiring
   into submit_aux_ops would break graph capture.

   Now: per-sample loss buffer [B], one thread per sample, no atomic, no
   memset. Caller reduces with the existing c51_loss_reduce_kernel
   (single-thread sequential sum) for the scalar. Same pattern as G12
   predictive_coding_loss + reduce. Fully graph-safe, fully deterministic.

2) Rust wrappers updated (gpu_dqn_trainer.rs)

   - compute_branch_independence: drop the cuMemsetD32Async (G6 was
     already graph-safe — single-block kernel writes scalar via
     overwrite, not accumulation; the memset was unnecessary)
   - compute_temporal_consistency: switch to two-step (per-sample +
     reduce) to match the new kernel signature; drop cuMemsetD32Async
   - New temporal_per_sample_buf field [B] alongside the existing
     temporal_penalty_buf scalar
   - Three new readback methods (sync DtoH, epoch-boundary only):
       branch_indep_loss_value()  — G6
       temporal_loss_value()      — G10
       predictive_loss_value()    — G12 (was unread previously)

3) Wired into the training loop

   - submit_aux_ops calls compute_branch_independence + compute_temporal_consistency
     right after compute_predictive_coding_loss (G12). Forward-only — no
     backward gradient flows yet.
   - FusedTrainingCtx::read_gem_losses() — pass-through accessor that
     calls all three trainer-level readbacks at once.
   - HEALTH_DIAG line gained a `gems [g6_branch_indep=X g10_temporal=Y
     g12_predictive=Z]` suffix so each epoch's penalty magnitudes are
     visible. Sync DtoH happens once per epoch (batch boundary), so the
     overhead is negligible (~3 × ~1µs).

What this gives us:

  - Empirical evidence of whether G6/G10 gem signals are nonzero
  - A clean baseline for deciding whether to wire backward (V7
    methodology: measure, then commit)
  - G12 predictive loss is now also visible (was wired backward in
    earlier commit but the loss scalar itself was never logged)

Smoke test:
  - 6 trials passed
  - Best Sharpe variance: [15.72, 31.94] (wider than G12-only [17.99,
    19.56]) — likely cuBLAS algorithm reselection from the new kernel
    launches changing graph timing; not a correctness issue
  - Tests pass; HEALTH_DIAG now logs gem values per epoch

Next session can run a 5-trial multi-trial test, look at the HEALTH_DIAG
gems line, and decide:
  - If g10_temporal ≈ 0 → G10 redundant with spectral_norm; delete
  - If g10_temporal nonzero → wire backward
  - Same logic for g6_branch_indep

Files touched:
  crates/ml/src/cuda_pipeline/experience_kernels.cu      (-30 / +48)
  crates/ml/src/cuda_pipeline/gpu_dqn_trainer.rs         (+87 / -31)
  crates/ml/src/trainers/dqn/fused_training.rs           (+25)
  crates/ml/src/trainers/dqn/trainer/training_loop.rs    (+10 / +3)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 09:51:19 +02:00

Foxhunt

Production HFT trading system in Rust.

Architecture

The workspace contains 32 crates organized as follows:

Core Libraries (16)

Crate Purpose
trading_engine Order processing, FIX 4.4, IB TWS, SIMD, RDTSC timing
risk VaR, Kelly, circuit breakers, kill switches, compliance
risk-data Risk data types and shared structures
trading-data Trading data types
ml DQN Rainbow, PPO, TFT, Mamba2, ensemble inference
ml-data ML data types and feature definitions
data Market data ingestion and storage
backtesting Replay engine, strategy tester
adaptive-strategy Ensemble execution, microstructure analysis
common Shared types, resilience, error handling
storage S3 and local model storage
model_loader Model serialization and loading
market-data Market data feed handlers
database PostgreSQL access layer (SQLx)
config Configuration management
tli CLI commands and tooling

Services (8)

Service Purpose
backtesting_service gRPC backtesting service
broker_gateway_service FIX routing, broker connectivity
trading_service Core trading operations
ml_training_service Model training orchestration
data_acquisition_service Market data acquisition
trading_agent_service Autonomous trading agents
api_gateway gRPC API gateway with auth
web-gateway Axum REST + WebSocket gateway

Frontend

web-dashboard/ -- React 19 + TypeScript + Vite + TradingView charts.

Building

# Check compilation (no PostgreSQL required)
SQLX_OFFLINE=true cargo check --workspace

# Run tests for a specific crate
SQLX_OFFLINE=true cargo test -p <crate> --lib

# Clippy
SQLX_OFFLINE=true cargo clippy --workspace

ML Models

Four production model architectures on Candle v0.9.1 with CUDA:

  • DQN Rainbow -- Deep Q-Network with prioritized replay, dueling heads, noisy nets
  • PPO -- Proximal Policy Optimization with GAE and LSTM policies
  • TFT -- Temporal Fusion Transformer for multi-horizon forecasting
  • Mamba2 -- State space model for sequence prediction

Each model has a standalone trainer and a UnifiedTrainable adapter for the hyperopt pipeline.

Infrastructure

  • Git: Gitea at git.fxhnt.ai (Tailscale-only), Scaleway DEV1-S
  • Observability: OpenTelemetry OTLP (env OTEL_EXPORTER_OTLP_ENDPOINT)
  • Database: PostgreSQL with SQLx offline mode for CI

License

Proprietary. All rights reserved.

Description
No description provided
Readme 849 MiB
Languages
Rust 88.2%
Cuda 7.7%
Python 1.3%
Shell 1.1%
PLpgSQL 0.8%
Other 0.8%