mirror of
https://github.com/Purple-Horizons/openclaw-voice.git
synced 2026-08-14 00:58:01 +00:00
Add deployment scripts and RunPod guide
- deploy/runpod/README.md - Full RunPod deployment guide - scripts/generate_master_key.py - Generate secure admin keys - scripts/download_models.py - Pre-download Whisper models Deployment options documented: - RunPod GPU (/bin/zsh.44/hr for RTX 4090) - Docker Compose (local GPU/CPU) - Cost optimization tips
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
# Deploy OpenClaw Voice on RunPod
|
||||
|
||||
Deploy OpenClaw Voice on RunPod for GPU-accelerated voice inference.
|
||||
|
||||
## Quick Deploy
|
||||
|
||||
### 1. Create a RunPod Account
|
||||
Sign up at [runpod.io](https://runpod.io)
|
||||
|
||||
### 2. Deploy from Template
|
||||
|
||||
Use our pre-built template:
|
||||
|
||||
```
|
||||
Template ID: openclaw-voice
|
||||
Docker Image: ghcr.io/purple-horizons/openclaw-voice:latest
|
||||
```
|
||||
|
||||
Or deploy manually:
|
||||
|
||||
### 3. Manual Deployment
|
||||
|
||||
**Create a new Pod:**
|
||||
- GPU: RTX 4090 recommended ($0.44/hr)
|
||||
- Docker Image: `ghcr.io/purple-horizons/openclaw-voice:latest`
|
||||
- Expose Port: 8765
|
||||
- Volume: 20GB (for model cache)
|
||||
|
||||
**Environment Variables:**
|
||||
```
|
||||
OPENCLAW_STT_MODEL=large-v3-turbo
|
||||
OPENCLAW_STT_DEVICE=cuda
|
||||
OPENCLAW_REQUIRE_AUTH=true
|
||||
OPENCLAW_MASTER_KEY=<generate-a-secure-key>
|
||||
OPENAI_API_KEY=<your-openai-key>
|
||||
```
|
||||
|
||||
### 4. Connect
|
||||
|
||||
Once deployed, get your Pod's public URL:
|
||||
```
|
||||
wss://<pod-id>-8765.proxy.runpod.net/ws?api_key=<your-key>
|
||||
```
|
||||
|
||||
## Cost Optimization
|
||||
|
||||
### On-Demand (Pay per hour)
|
||||
- RTX 4090: ~$0.44/hr
|
||||
- RTX 3090: ~$0.30/hr
|
||||
- A10: ~$0.50/hr
|
||||
|
||||
### Spot Instances (Up to 80% cheaper)
|
||||
- Use spot instances for non-critical workloads
|
||||
- May be interrupted with 30s notice
|
||||
|
||||
### Reserved (Best for production)
|
||||
- Reserve a GPU for consistent pricing
|
||||
- No interruptions
|
||||
|
||||
## Scaling
|
||||
|
||||
### Single Pod
|
||||
- Handles ~10-20 concurrent voice sessions
|
||||
- Good for testing and small deployments
|
||||
|
||||
### Multiple Pods with Load Balancer
|
||||
1. Deploy 2+ pods
|
||||
2. Use RunPod's serverless endpoints
|
||||
3. Or put behind Cloudflare Load Balancer
|
||||
|
||||
## Monitoring
|
||||
|
||||
### Health Check
|
||||
```bash
|
||||
curl https://<pod-url>/
|
||||
```
|
||||
|
||||
### Check Logs
|
||||
```bash
|
||||
runpodctl logs <pod-id>
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### GPU Not Detected
|
||||
- Ensure NVIDIA drivers are loaded
|
||||
- Check `nvidia-smi` in pod terminal
|
||||
|
||||
### Out of Memory
|
||||
- Reduce batch size
|
||||
- Use smaller Whisper model (base vs large)
|
||||
- Upgrade to GPU with more VRAM
|
||||
|
||||
### High Latency
|
||||
- Use larger GPU
|
||||
- Enable streaming responses
|
||||
- Check network latency to RunPod region
|
||||
@@ -0,0 +1,84 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Download Whisper models for offline use.
|
||||
|
||||
Usage:
|
||||
python scripts/download_models.py [model_name]
|
||||
|
||||
Models:
|
||||
tiny - 39M params, ~1GB VRAM (fastest)
|
||||
base - 74M params, ~1GB VRAM
|
||||
small - 244M params, ~2GB VRAM
|
||||
medium - 769M params, ~5GB VRAM
|
||||
large-v3-turbo - 809M params, ~6GB VRAM (best quality/speed)
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
|
||||
def download_model(model_name: str = "base"):
|
||||
"""Download a Whisper model."""
|
||||
print(f"Downloading Whisper model: {model_name}")
|
||||
print("This may take a few minutes...")
|
||||
|
||||
try:
|
||||
from faster_whisper import WhisperModel
|
||||
|
||||
# This will download the model if not cached
|
||||
model = WhisperModel(model_name, device="cpu", compute_type="int8")
|
||||
|
||||
print(f"✅ Model '{model_name}' downloaded successfully!")
|
||||
print(f" Cached at: ~/.cache/huggingface/")
|
||||
|
||||
# Test the model
|
||||
import numpy as np
|
||||
audio = np.zeros(16000, dtype=np.float32)
|
||||
segments, info = model.transcribe(audio)
|
||||
list(segments) # Consume generator
|
||||
|
||||
print(f"✅ Model tested successfully!")
|
||||
|
||||
except ImportError:
|
||||
print("❌ faster-whisper not installed. Run:")
|
||||
print(" pip install faster-whisper")
|
||||
sys.exit(1)
|
||||
except Exception as e:
|
||||
print(f"❌ Error: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def list_models():
|
||||
"""List available models."""
|
||||
models = {
|
||||
"tiny": "39M params, ~1GB VRAM, fastest",
|
||||
"base": "74M params, ~1GB VRAM, good balance",
|
||||
"small": "244M params, ~2GB VRAM",
|
||||
"medium": "769M params, ~5GB VRAM",
|
||||
"large-v3": "1.5B params, ~10GB VRAM, best quality",
|
||||
"large-v3-turbo": "809M params, ~6GB VRAM, best quality/speed ratio",
|
||||
}
|
||||
|
||||
print("Available Whisper models:")
|
||||
print()
|
||||
for name, desc in models.items():
|
||||
print(f" {name:20} - {desc}")
|
||||
print()
|
||||
print("Recommended: large-v3-turbo (GPU) or base (CPU)")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) < 2:
|
||||
list_models()
|
||||
print()
|
||||
model = input("Enter model name to download (or 'q' to quit): ").strip()
|
||||
if model.lower() == 'q':
|
||||
sys.exit(0)
|
||||
else:
|
||||
model = sys.argv[1]
|
||||
|
||||
if model in ["-h", "--help", "help"]:
|
||||
list_models()
|
||||
sys.exit(0)
|
||||
|
||||
download_model(model)
|
||||
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Generate a secure master API key for OpenClaw Voice.
|
||||
|
||||
Usage:
|
||||
python scripts/generate_master_key.py
|
||||
|
||||
Add the output to your .env file or deployment environment.
|
||||
"""
|
||||
|
||||
import secrets
|
||||
|
||||
|
||||
def generate_master_key() -> str:
|
||||
"""Generate a secure master key."""
|
||||
return f"ocv_master_{secrets.token_urlsafe(32)}"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
key = generate_master_key()
|
||||
|
||||
print("=" * 60)
|
||||
print("OpenClaw Voice Master Key")
|
||||
print("=" * 60)
|
||||
print()
|
||||
print(f"OPENCLAW_MASTER_KEY={key}")
|
||||
print()
|
||||
print("Add this to your .env file or deployment environment.")
|
||||
print("Keep this key SECRET - it has full admin access.")
|
||||
print("=" * 60)
|
||||
Reference in New Issue
Block a user