chore: Pre-cleanup commit - save current state before major reorganization
This commit is contained in:
105
ml/python/README.md
Normal file
105
ml/python/README.md
Normal file
@@ -0,0 +1,105 @@
|
||||
# Foxhunt RunPod Integration
|
||||
|
||||
Python module for managing RunPod GPU pods with enhanced features:
|
||||
- Pod deployment with GPU selection
|
||||
- Real-time S3 log streaming
|
||||
- Auto-termination on completion
|
||||
- Health checks and status monitoring
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
cd ml/python
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Command-line (via runpod_deploy.py)
|
||||
|
||||
```bash
|
||||
# Basic deployment
|
||||
python3 scripts/runpod_deploy.py --gpu-type "RTX A4000"
|
||||
|
||||
# With monitoring
|
||||
python3 scripts/runpod_deploy.py --monitor --timeout 120m
|
||||
|
||||
# Full automation
|
||||
python3 scripts/runpod_deploy.py --monitor --auto-stop --timeout 2h
|
||||
```
|
||||
|
||||
### Python API
|
||||
|
||||
```python
|
||||
from foxhunt_runpod import RunPodClient, S3LogMonitor
|
||||
|
||||
# Deploy a pod
|
||||
client = RunPodClient(
|
||||
api_key="your_api_key",
|
||||
volume_id="your_volume_id"
|
||||
)
|
||||
|
||||
gpus = client.get_available_gpus(min_vram=16)
|
||||
pod_data = client.deploy_pod(
|
||||
gpu_id=gpus[0]['id'],
|
||||
image="jgrusewski/foxhunt:latest",
|
||||
command="--epochs 100"
|
||||
)
|
||||
|
||||
# Monitor logs
|
||||
monitor = S3LogMonitor(
|
||||
bucket_name="your_bucket",
|
||||
aws_access_key="your_key",
|
||||
aws_secret_key="your_secret"
|
||||
)
|
||||
|
||||
monitor.stream_logs(
|
||||
pod_id=pod_data['id'],
|
||||
interval=10,
|
||||
timeout=7200
|
||||
)
|
||||
|
||||
# Terminate when done
|
||||
client.terminate_pod(pod_data['id'])
|
||||
```
|
||||
|
||||
## Environment Variables
|
||||
|
||||
Required in `.env.runpod`:
|
||||
- `RUNPOD_API_KEY` - RunPod API key
|
||||
- `RUNPOD_VOLUME_ID` - Network volume ID
|
||||
- `RUNPOD_CONTAINER_REGISTRY_AUTH_ID` - Docker registry auth (optional)
|
||||
|
||||
Optional for S3 monitoring:
|
||||
- `RUNPOD_S3_BUCKET` - S3 bucket name
|
||||
- `RUNPOD_S3_ACCESS_KEY` - AWS access key
|
||||
- `RUNPOD_S3_SECRET_KEY` - AWS secret key
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
scripts/runpod_deploy.py (CLI)
|
||||
↓
|
||||
ml/python/foxhunt_runpod/
|
||||
├── client.py - RunPodClient (pod management)
|
||||
├── s3_monitor.py - S3LogMonitor (log streaming)
|
||||
└── __init__.py - Module exports
|
||||
```
|
||||
|
||||
## Features
|
||||
|
||||
### RunPodClient
|
||||
- Query available GPUs with pricing
|
||||
- Deploy pods with datacenter filtering
|
||||
- Stop/terminate pods
|
||||
- Get pod status
|
||||
|
||||
### S3LogMonitor
|
||||
- Stream logs in real-time from S3
|
||||
- Detect training completion
|
||||
- Configurable polling interval
|
||||
- Timeout support
|
||||
|
||||
## Backward Compatibility
|
||||
|
||||
The script automatically falls back to legacy implementation if the module cannot be imported. All existing command-line flags are preserved.
|
||||
4
ml/python/requirements.txt
Normal file
4
ml/python/requirements.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
# Foxhunt RunPod Integration Requirements
|
||||
boto3>=1.26.0 # S3 log monitoring
|
||||
python-dotenv>=0.19.0 # .env.runpod file loading
|
||||
requests>=2.28.0 # RunPod REST API
|
||||
84
ml/python/test_module_import.py
Executable file
84
ml/python/test_module_import.py
Executable file
@@ -0,0 +1,84 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Test imports for foxhunt_runpod module.
|
||||
"""
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
# Add module to path
|
||||
sys.path.insert(0, str(Path(__file__).parent))
|
||||
|
||||
def test_imports():
|
||||
"""Test all module imports."""
|
||||
print("Testing foxhunt_runpod module imports...\n")
|
||||
|
||||
# Test 1: Main module
|
||||
print("1. Importing main module...")
|
||||
try:
|
||||
import foxhunt_runpod
|
||||
print(f" ✓ Version: {foxhunt_runpod.__version__}")
|
||||
except Exception as e:
|
||||
print(f" ✗ Failed: {e}")
|
||||
return False
|
||||
|
||||
# Test 2: RunPodClient
|
||||
print("\n2. Importing RunPodClient...")
|
||||
try:
|
||||
from foxhunt_runpod import RunPodClient
|
||||
print(" ✓ RunPodClient imported")
|
||||
except Exception as e:
|
||||
print(f" ✗ Failed: {e}")
|
||||
return False
|
||||
|
||||
# Test 3: PodMonitor
|
||||
print("\n3. Importing PodMonitor...")
|
||||
try:
|
||||
from foxhunt_runpod import PodMonitor
|
||||
print(" ✓ PodMonitor imported")
|
||||
except Exception as e:
|
||||
print(f" ✗ Failed: {e}")
|
||||
return False
|
||||
|
||||
# Test 4: S3Client
|
||||
print("\n4. Importing S3Client...")
|
||||
try:
|
||||
from foxhunt_runpod import S3Client
|
||||
print(" ✓ S3Client imported")
|
||||
except Exception as e:
|
||||
print(f" ✗ Failed: {e}")
|
||||
return False
|
||||
|
||||
# Test 5: Config
|
||||
print("\n5. Importing RunPodConfig...")
|
||||
try:
|
||||
from foxhunt_runpod import RunPodConfig
|
||||
print(" ✓ RunPodConfig imported")
|
||||
except Exception as e:
|
||||
print(f" ✗ Failed: {e}")
|
||||
return False
|
||||
|
||||
# Test 6: Errors
|
||||
print("\n6. Importing exceptions...")
|
||||
try:
|
||||
from foxhunt_runpod import (
|
||||
RunPodError,
|
||||
PodDeploymentError,
|
||||
PodNotFoundError,
|
||||
S3Error,
|
||||
ConfigurationError,
|
||||
)
|
||||
print(" ✓ All exceptions imported")
|
||||
except Exception as e:
|
||||
print(f" ✗ Failed: {e}")
|
||||
return False
|
||||
|
||||
print("\n" + "=" * 70)
|
||||
print("✅ All imports successful!")
|
||||
print("=" * 70)
|
||||
return True
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
success = test_imports()
|
||||
sys.exit(0 if success else 1)
|
||||
Reference in New Issue
Block a user