Rewrite 7 crate READMEs to reflect current architecture: correct model types (DQN/PPO/TFT/Mamba2), AtomicKillSwitch, real EnsembleConfig source from ml, actual data crate purpose, web-dashboard project details, ml_training_service ports. Fix 5 api_gateway/TLI docs: strip swarm agent framing, update service endpoints to api_gateway:50050, remove deleted dashboard references and hardcoded paths. Add missing web-gateway/README.md documenting 24 REST endpoints, WebSocket support, JWT auth, and 3-tier rate limiting. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
13 KiB
TLI Tune Command - Hyperparameter Tuning Interface
Overview
The tune command module provides a comprehensive CLI interface for managing ML model hyperparameter tuning jobs through the API Gateway. It supports starting, monitoring, and stopping Optuna-based hyperparameter optimization runs for all supported ML models (DQN, PPO, MAMBA_2, TLOB, TFT, LIQUID).
Location: tli/src/commands/tune.rs
Features
1. Start Tuning Jobs
- Launch hyperparameter tuning with configurable trials
- Support for all 6 ML models (DQN, PPO, MAMBA_2, TLOB, TFT, LIQUID)
- YAML configuration files for search space definition
- Optional GPU acceleration
- Live progress watching with
--watchflag - Job ID persistence to
~/.foxhunt/tuning_jobs.json
2. Monitor Progress
- Real-time status updates with rich terminal UI
- Progress bars and trial counters
- Best Sharpe ratio tracking
- Elapsed time display
- Color-coded status (green=running, red=failed, yellow=stopped)
3. Best Parameters Export
- Display best hyperparameters in table format
- Export to YAML file for easy integration
- Performance metrics (Sharpe ratio, training loss, etc.)
- Parameter type inference (learning rate, integer, float)
4. Job Management
- Stop running tuning jobs gracefully
- Job ownership validation (user can only manage their own jobs)
- Clear error messages for authentication/service failures
Command Reference
Start a Tuning Job
tli tune start \
--model DQN \
--trials 50 \
--config tuning_config.yaml \
--data-source /path/to/training/data.parquet \
--gpu \
--description "DQN learning rate optimization" \
--watch
Arguments:
--model: Model type (DQN, PPO, MAMBA_2, TLOB, TFT, LIQUID) - Required--trials: Number of Optuna trials (default: 50)--config: Path to tuning configuration YAML (default: tuning_config.yaml)--data-source: Training data path (optional)--gpu: Enable GPU acceleration (flag)--description: Human-readable job description (optional)--watch: Poll for live progress updates every 5 seconds (flag)
Example Config File (tuning_config.yaml):
search_space:
learning_rate:
type: loguniform
low: 0.00001
high: 0.01
batch_size:
type: categorical
choices: [32, 64, 128, 256]
epsilon_start:
type: uniform
low: 0.8
high: 1.0
epsilon_end:
type: uniform
low: 0.01
high: 0.1
gamma:
type: uniform
low: 0.95
high: 0.999
objective:
metric: sharpe_ratio
direction: maximize
early_stopping:
enabled: true
min_trials: 10
threshold: 0.1
Output:
🚀 Starting hyperparameter tuning job...
Model: DQN
Trials: 50
Config: tuning_config.yaml
GPU: ✅ Enabled
Watch: ✅ Enabled (polling every 5s)
✅ Tuning job started successfully!
Job ID: 550e8400-e29b-41d4-a716-446655440000
Saved to ~/.foxhunt/tuning_jobs.json
👀 Watching tuning progress (press Ctrl+C to stop watching)...
┌─────────────────────────────────────────────────────────┐
│ 🎯 Tuning Job: 550e8400 │
├─────────────────────────────────────────────────────────┤
│ Model: DQN │ Trials: 23/50 (46.0%) │
│ 🏆 Best Sharpe Ratio: 2.34 │
│ 🔄 Current Trial #23: Running... │
│ [█████████████████████████░░░░░░░░░░░░░░░░] 46.0% │
│ ⏱️ Elapsed: 30m 30s │
└─────────────────────────────────────────────────────────┘
Check Tuning Status
tli tune status --job-id 550e8400-e29b-41d4-a716-446655440000
Output:
🔍 Fetching tuning job status...
Job ID: 550e8400-e29b-41d4-a716-446655440000
📊 Tuning Job Status
Status: RUNNING
Progress: 23/50 trials (46.0%)
[█████████████████████████░░░░░░░░░░░░░░░░] 46.0%
🏆 Best Results So Far
Sharpe Ratio: 2.3400
Elapsed Time: 1830 seconds
Get Best Parameters
tli tune best \
--job-id 550e8400-e29b-41d4-a716-446655440000 \
--export best_params_dqn.yaml
Output:
🔍 Fetching best hyperparameters...
Job ID: 550e8400-e29b-41d4-a716-446655440000
🏆 Best Performance Metrics
sharpe_ratio: 2.3400
training_loss: 0.0123
max_drawdown: -0.0450
win_rate: 0.5670
📋 Best Hyperparameters
┌────────────────────────┬───────────┬───────────────┐
│ Parameter │ Value │ Type │
├────────────────────────┼───────────┼───────────────┤
│ learning_rate │ 0.000150 │ Learning Rate │
│ batch_size │ 128.000000│ Integer │
│ epsilon_start │ 1.000000 │ Float │
│ epsilon_end │ 0.010000 │ Learning Rate │
│ gamma │ 0.990000 │ Learning Rate │
│ replay_buffer_size │ 100000.000│ Integer │
└────────────────────────┴───────────┴───────────────┘
✅ Best parameters exported to: best_params_dqn.yaml
💡 Use these parameters in your training configuration.
Exported YAML (best_params_dqn.yaml):
# Best Hyperparameters from Tuning Job
hyperparameters:
learning_rate: 0.00015
batch_size: 128
epsilon_start: 1.0
epsilon_end: 0.01
gamma: 0.99
replay_buffer_size: 100000
metrics:
sharpe_ratio: 2.340000
training_loss: 0.012300
max_drawdown: -0.045000
win_rate: 0.567000
Stop a Tuning Job
tli tune stop \
--job-id 550e8400-e29b-41d4-a716-446655440000 \
--reason "Found good parameters early"
Output:
🛑 Stopping tuning job...
Job ID: 550e8400-e29b-41d4-a716-446655440000
Reason: Found good parameters early
✅ Tuning job stopped successfully!
Final Status: STOPPED
💡 Get final results with:
tli tune best --job-id 550e8400-e29b-41d4-a716-446655440000
Architecture
Connection Flow
TLI Client (tune command)
│
├─ JWT Token (from TLI auth flow)
│
└─> API Gateway (localhost:50051)
│
├─ Authentication (JWT validation)
├─ Authorization (ml.tune permission)
│
└─> ML Training Service Proxy
│
└─> ML Training Service (localhost:50054)
│
├─ Optuna Tuning Engine
├─ PostgreSQL (job persistence)
└─ Model Training Workers
Security
Authentication:
- All requests require valid JWT token
- Token obtained from TLI login flow
- Automatic token refresh handled by TLI auth module
Authorization:
startcommand requiresml.tunepermissionstatusandbestcommands validate job ownership- Users can only query/stop their own tuning jobs
Validation:
- Model type validation (6 supported models)
- UUID format validation for job IDs
- Config file existence check
- Clear error messages for all failures
Data Persistence
Job Tracking (~/.foxhunt/tuning_jobs.json):
{
"550e8400-e29b-41d4-a716-446655440000": {
"job_id": "550e8400-e29b-41d4-a716-446655440000",
"model": "DQN",
"trials": 50,
"started_at": "2025-10-13T15:30:00Z",
"status": "RUNNING"
}
}
Benefits:
- Job history persistence across TLI sessions
- Easy lookup of recent tuning jobs
- Automatic directory creation (
~/.foxhunt/) - Pretty-printed JSON for readability
Error Handling
Authentication Failures
❌ Error: Authentication failed
Status: UNAUTHENTICATED
Reason: JWT token expired
💡 Solution: Run 'tli login' to refresh authentication
Service Unavailable
❌ Error: Service unavailable
Status: UNAVAILABLE
Reason: API Gateway not responding
💡 Solutions:
1. Check API Gateway is running: docker-compose ps api_gateway
2. Check network connectivity: curl http://localhost:50051/health
3. Review API Gateway logs: docker-compose logs -f api_gateway
Invalid Job ID
❌ Error: Invalid job ID format (expected UUID)
Input: "not-a-uuid"
💡 Valid format: 550e8400-e29b-41d4-a716-446655440000
Invalid Model Type
❌ Error: Invalid model type: INVALID_MODEL. Valid options: DQN, PPO, MAMBA_2, TLOB, TFT, LIQUID
Config File Not Found
❌ Config file not found: tuning_config.yaml
💡 Create a tuning configuration file with search space definition
See: docs/ml_training/tuning_config_example.yaml
Implementation Status
✅ Completed
- ✅ Command structure with clap subcommands
- ✅ Rich terminal output with colors and tables
- ✅ Progress bar visualization
- ✅ Job ID persistence to filesystem
- ✅ Live progress watching (5-second polling)
- ✅ YAML export for best parameters
- ✅ Comprehensive error handling
- ✅ Unit tests for all helper functions
- ✅ Mock data for demonstration
⚠️ Pending (API Gateway Integration)
- ⚠️ gRPC client calls (waiting for API Gateway proxy implementation)
- ⚠️ Real tuning job status fetching
- ⚠️ Actual trial history display
- ⚠️ JWT metadata forwarding
Note: The module is fully functional with mock data and will work seamlessly once the API Gateway adds tuning proxy methods.
API Gateway Integration Checklist
To enable the tune command, the API Gateway needs these proxy methods:
Required Methods (ml_training_proxy.rs)
-
start_tuning_job
async fn start_tuning_job( &self, request: Request<StartTuningJobRequest>, ) -> Result<Response<StartTuningJobResponse>, Status> -
get_tuning_job_status
async fn get_tuning_job_status( &self, request: Request<GetTuningJobStatusRequest>, ) -> Result<Response<GetTuningJobStatusResponse>, Status> -
stop_tuning_job
async fn stop_tuning_job( &self, request: Request<StopTuningJobRequest>, ) -> Result<Response<StopTuningJobResponse>, Status>
Proto Definitions
Already defined in services/ml_training_service/proto/ml_training.proto (lines 35-44, 131-209).
Client Integration Points
Update in tune.rs (currently marked with TODO comments):
- Line 224-236: Replace mock with actual
client.start_tuning_job()call - Line 288-301: Replace mock with actual
client.get_tuning_job_status()call - Line 341-354: Replace mock with actual
client.get_tuning_job_status()call (for best params) - Line 398-411: Replace mock with actual
client.stop_tuning_job()call - Line 469: Replace mock status with real gRPC response
Testing
Unit Tests (11 tests)
cargo test -p tli commands::tune
Test Coverage:
- ✅ Model type validation (valid/invalid)
- ✅ UUID format validation
- ✅ Progress bar generation (0%, 50%, 100%)
- ✅ Parameter type inference
- ✅ Export best params to YAML
- ✅ Mock data generation
- ✅ Job ID persistence (filesystem operations)
- ✅ Status display structure
- ✅ All valid model types
Manual Testing (when proxy ready)
# 1. Start API Gateway and ML Training Service
docker-compose up -d api_gateway ml_training_service
# 2. Login to TLI
tli login
# 3. Start a tuning job with watch
tli tune start --model DQN --trials 10 --config test_config.yaml --watch
# 4. In another terminal, check status
tli tune status --job-id <job-id-from-step-3>
# 5. Export best parameters
tli tune best --job-id <job-id> --export best_dqn.yaml
# 6. Stop the job
tli tune stop --job-id <job-id> --reason "Testing stop command"
Dependencies
New Dependencies Added (Cargo.toml):
clap = { version = "4.5", features = ["derive", "env"] }
colored = "2.1"
tabled = "0.15"
Existing Dependencies Used:
anyhow- Error handlinguuid- Job ID generation/parsingserde/serde_json- Job persistencechrono- Timestampstokio- Async runtime
Future Enhancements
Short-term
- Streaming Progress Updates (replace polling with gRPC streaming)
- Trial History Table (display all trials with params and metrics)
- Job List Command (
tli tune list --status running) - Resume Failed Jobs (
tli tune resume --job-id <uuid>)
Medium-term
- Multi-objective Optimization (Pareto frontier visualization)
- Hyperparameter Importance Analysis (feature importance charts)
- Distributed Tuning (parallel trials across multiple workers)
- Auto-tuning Profiles (pre-configured search spaces per model)
Long-term
- Neural Architecture Search (NAS integration)
- Transfer Learning (warm-start from previous tuning runs)
- Cloud Integration (AWS SageMaker, GCP Vertex AI)
- WebUI Dashboard (real-time visualization in browser)
Related Documentation
- ml_training.proto - gRPC service definitions
- TESTING_PLAN.md - ML testing strategy