mirror of
https://github.com/allaunthefox/Research-Stack.git
synced 2026-07-31 03:05:21 +00:00
Lean: update Semantics modules, add new numerics/physics data files Hardware: update FPGA bitstreams (tangnano9k_uart_loopback) Infra: k3s-flake tests, netcup-vps configuration, VCN compute substrate Docs: ARCHITECTURE, specs, citation updates
373 lines
13 KiB
Markdown
373 lines
13 KiB
Markdown
# Plan: Ray Deployment on Research Stack k3s
|
|
|
|
**Date:** 2026-05-29
|
|
**Status:** Draft
|
|
**Estimated effort:** 2-3 days
|
|
|
|
---
|
|
|
|
## Goal
|
|
|
|
Deploy Ray on the Research Stack k3s cluster with:
|
|
1. Distributed compute across 5 nodes (2 Ready, 3 flaky)
|
|
2. H.264 transport via Ray Object Store
|
|
3. GPU acceleration on qfox (RTX 4070)
|
|
4. Thundering herd mitigations for node reconnection
|
|
5. Graceful degradation when nodes go offline
|
|
|
|
---
|
|
|
|
## Current State
|
|
|
|
| Node | Status | Role | Hardware |
|
|
|------|--------|------|----------|
|
|
| nixos | Ready | control-plane | NixOS, 6.18.32 kernel |
|
|
| qfox-1 | Ready | worker | CachyOS, RTX 4070 |
|
|
| 361395-1 | NotReady | worker | Debian, edge VPS |
|
|
| racknerd | NotReady | worker | Debian, VPS |
|
|
| steamdeck | NotReady | worker | NixOS |
|
|
|
|
**Namespaces:** ai-models (empty), services, media, mail, monitoring, research, edge
|
|
|
|
**Existing workloads:**
|
|
- VCN pipeline: `braid_vcn_encoder.py` (Delta+RLE + RS ECC + ChaCha20 + H.264)
|
|
- Fractal dimension: `fractal_dimension.py` (DBC algorithm, 29x vectorized)
|
|
- GPU node: `vcn_lupine_gpu_node.py` (MKV decode + GPU compute)
|
|
- AlphaProof: `alphaproof_loop.py` (Ollama → lake build → feedback)
|
|
- Lean: 3572 jobs, 0 errors
|
|
- Python: 68/68 tests pass
|
|
|
|
---
|
|
|
|
## Architecture
|
|
|
|
### Ray Topology
|
|
|
|
```
|
|
Neon-64GB (Ray Head + Worker)
|
|
├── GCS (Global Control Store) — PVC-backed
|
|
├── Dashboard (:8265) — via Traefik ingress
|
|
├── Object Store — 32GB allocated
|
|
├── Raylet — 18 ARM64 cores
|
|
└── VCN Encoder — Delta+RLE + RS ECC + ChaCha20
|
|
|
|
qfox-1 (Ray GPU Worker)
|
|
├── Raylet — RTX 4070
|
|
├── NVDEC — H.264 hardware decode (0.1ms)
|
|
├── CUDA — GPU compute (fractal dimension, Q16 LUT)
|
|
└── Object Store — 8GB allocated
|
|
|
|
nixos (Ray CPU Worker)
|
|
├── Raylet — CPU cores
|
|
├── Software decode — H.264 fallback
|
|
├── Lean builds — lake build via Ray tasks
|
|
└── Object Store — 4GB allocated
|
|
|
|
racknerd (Ray Edge Worker — standby)
|
|
├── Raylet — 2 vCPU EPYC
|
|
├── Edge relay — forward to external clients
|
|
└── Object Store — 2GB allocated
|
|
|
|
steamdeck (Ray Idle Worker — standby)
|
|
├── Raylet — idle until needed
|
|
└── Object Store — 2GB allocated
|
|
```
|
|
|
|
### Network Flow
|
|
|
|
```
|
|
Braid data (Python)
|
|
→ Delta+RLE (vectorized copy-if, 3.3x)
|
|
→ RS ECC
|
|
→ ChaCha20
|
|
→ H.264 frame (YUV420)
|
|
→ MKV container
|
|
→ ray.put() → ObjectRef
|
|
→ Ray Object Store (shared memory)
|
|
→ GPU hardware decode (NVDEC) or CPU fallback
|
|
→ GPU compute or CPU compute
|
|
→ Result → ray.put() → ObjectRef
|
|
→ Downstream consumer
|
|
```
|
|
|
|
### Port Map
|
|
|
|
| Port | Service | Access |
|
|
|------|---------|--------|
|
|
| 6379 | Ray GCS | Internal (Tailscale only) |
|
|
| 8265 | Ray Dashboard | Via Traefik ingress |
|
|
| 10001 | Ray Client | Tailscale only |
|
|
| 8000 | Ray Serve | Via Traefik ingress |
|
|
|
|
---
|
|
|
|
## Implementation Steps
|
|
|
|
### Phase 1: Ray Head Deployment (Day 1)
|
|
|
|
**Step 1.1: Create Ray namespace and RBAC**
|
|
- File: `4-Infrastructure/k3s/ray/namespace.yaml`
|
|
- Create `ai` namespace (already exists, use it)
|
|
- ServiceAccount, ClusterRole, ClusterRoleBinding for Ray
|
|
|
|
**Step 1.2: Deploy Ray Head on Neon-64GB**
|
|
- File: `4-Infrastructure/k3s/ray/head-deployment.yaml`
|
|
- Image: `rayproject/ray:2.43.0-py311-cu124`
|
|
- Command: `ray start --head --dashboard-host=0.0.0.0 --object-store-memory=34359738368`
|
|
- PVC: 10Gi for GCS persistence
|
|
- Resources: 4 CPU request, 16 CPU limit, 8Gi RAM request, 32Gi RAM limit
|
|
- NodeSelector: `kubernetes.io/hostname: neon-64gb`
|
|
- Liveness probe: `ray health-check`
|
|
- Readiness probe: `ray status`
|
|
|
|
**Step 1.3: Deploy Ray Dashboard Service**
|
|
- File: `4-Infrastructure/k3s/ray/dashboard-service.yaml`
|
|
- ClusterIP service on port 8265
|
|
- Traefik IngressRoute at `/ray/dashboard`
|
|
|
|
**Step 1.4: Verify Head is running**
|
|
- `kubectl get pods -n ai`
|
|
- `curl http://localhost:8265` (port-forward)
|
|
- `ray status` inside head pod
|
|
|
|
### Phase 2: Worker Deployment (Day 1)
|
|
|
|
**Step 2.1: Deploy Ray GPU Worker on qfox-1**
|
|
- File: `4-Infrastructure/k3s/ray/gpu-worker-deployment.yaml`
|
|
- Image: `rayproject/ray:2.43.0-py311-cu124`
|
|
- Command: `ray start --address=ray-head.ai.svc.cluster.local:6379`
|
|
- Resources: 2 CPU, 8Gi RAM, 1 nvidia.com/gpu
|
|
- NodeSelector: `kubernetes.io/hostname: qfox-1`
|
|
- Toleration: `nvidia.com/gpu:NoSchedule`
|
|
- Environment: `NVIDIA_VISIBLE_DEVICES=all`
|
|
|
|
**Step 2.2: Deploy Ray CPU Worker on nixos**
|
|
- File: `4-Infrastructure/k3s/ray/cpu-worker-deployment.yaml`
|
|
- Image: `rayproject/ray:2.43.0-py311-cu124`
|
|
- Command: `ray start --address=ray-head.ai.svc.cluster.local:6379`
|
|
- Resources: 4 CPU, 8Gi RAM
|
|
- No GPU resources
|
|
|
|
**Step 2.3: Deploy Standby Workers (racknerd, steamdeck)**
|
|
- File: `4-Infrastructure/k3s/ray/standby-worker-deployment.yaml`
|
|
- Same as CPU worker but with lower resources
|
|
- Toleration: `node.kubernetes.io/unreachable:NoSchedule`
|
|
- Priority: low (evicted first when nodes are under pressure)
|
|
|
|
**Step 2.4: Verify all workers connected**
|
|
- `ray status` inside head pod
|
|
- Check: 4 workers connected (Neon, qfox, nixos, racknerd/steamdeck if online)
|
|
|
|
### Phase 3: Thundering Herd Mitigations (Day 2)
|
|
|
|
**Step 3.1: Staggered reconnection**
|
|
- File: `4-Infrastructure/k3s/ray/worker-entrypoint.sh`
|
|
- Script: compute jitter from Tailscale IP hash, sleep before connecting
|
|
- `delay = hash(tailscale_ip) % 30`
|
|
- Mount as ConfigMap, use as worker command
|
|
|
|
**Step 3.2: Token bucket on Head**
|
|
- File: `4-Infrastructure/k3s/ray/head-entrypoint.sh`
|
|
- Configure Ray with `--max-worker-startup-concurrency=1`
|
|
- One worker connects per second, burst of 3
|
|
- Workers get 429 + Retry-After on rejection
|
|
|
|
**Step 3.3: Object Store watermarks**
|
|
- File: `4-Infrastructure/k3s/ray/object-store-config.yaml`
|
|
- Configure Ray with memory thresholds:
|
|
- 60%: throttle incoming syncs to 1/s
|
|
- 80%: reject new connections
|
|
- 95%: emergency GC
|
|
- Spill cold objects to PVC at 60%
|
|
|
|
**Step 3.4: Circuit breaker per worker**
|
|
- File: `4-Infrastructure/shim/ray_circuit_breaker.py`
|
|
- Python class wrapping Ray client calls
|
|
- States: CLOSED (normal), OPEN (head overwhelmed), HALF-OPEN (testing)
|
|
- Failure threshold: 5 failures in 30s → OPEN
|
|
- Recovery: 60s wait → HALF-OPEN → probe → CLOSED
|
|
|
|
**Step 3.5: Graduated task migration**
|
|
- File: `4-Infrastructure/shim/ray_task_migrator.py`
|
|
- When GPU node returns, migrate tasks in batches:
|
|
- t=0s: 10% of tasks
|
|
- t=30s: 20% more
|
|
- t=60s: remaining 70%
|
|
- Abort if any batch fails
|
|
|
|
**Step 3.6: Witness deduplication**
|
|
- Ray ObjectRefs are already content-addressed
|
|
- Verify: `ray.put(data)` returns same ObjectRef for same data
|
|
- No custom code needed — document the behavior
|
|
|
|
### Phase 4: VCN Pipeline Integration (Day 2)
|
|
|
|
**Step 4.1: Wire VCN encoder to Ray Object Store**
|
|
- File: `4-Infrastructure/shim/vcn_ray_transport.py`
|
|
- `encode_and_store(braid_data) → ObjectRef`
|
|
- `decode_on_gpu(ObjectRef) → np.ndarray`
|
|
- `decode_on_cpu(ObjectRef) → np.ndarray` (fallback)
|
|
|
|
**Step 4.2: Wire fractal dimension to Ray**
|
|
- File: `4-Infrastructure/shim/fractal_ray_task.py`
|
|
- `@ray.remote(num_gpus=1) def compute_fd_gpu(data)`
|
|
- `@ray.remote(num_cpus=4) def compute_fd_cpu(data)`
|
|
- Auto-select based on GPU availability
|
|
|
|
**Step 4.3: Wire AlphaProof to Ray**
|
|
- File: `4-Infrastructure/shim/alphaproof_ray.py`
|
|
- `@ray.remote def prove_theorem(problem)`
|
|
- Parallel proof search across workers
|
|
- Pre-filter: skip trivial theorems (copy-if pattern)
|
|
|
|
**Step 4.4: Test end-to-end**
|
|
- Encode 100 braid strands → Object Store → GPU decode → compute → verify
|
|
- Measure: encode time, transfer time, decode time, compute time
|
|
- Verify: 3.3x speedup on Delta+RLE, 100x on H.264 decode
|
|
|
|
### Phase 5: k3s Migration (Day 3)
|
|
|
|
**Step 5.1: Migrate control plane**
|
|
- Stop k3s-server on Neon-64GB
|
|
- Install k3s-server on cupfox
|
|
- Update kubeconfig to point to cupfox
|
|
- Update Tailscale Funnel target
|
|
|
|
**Step 5.2: Re-point workers**
|
|
- Update k3s-agent on all workers to point to cupfox
|
|
- Verify: all nodes join new control plane
|
|
|
|
**Step 5.3: Update DNS and ingress**
|
|
- Update researchstack.info A record → cupfox IP
|
|
- Update Caddy upstream on racknerd
|
|
- Verify: Traefik ingress works
|
|
|
|
**Step 5.4: Verify Ray survives migration**
|
|
- Ray Head should reschedule on Neon (worker node now)
|
|
- GCS persists on PVC (survives restart)
|
|
- Workers reconnect to new Head
|
|
|
|
### Phase 6: Monitoring and Observability (Day 3)
|
|
|
|
**Step 6.1: Ray Dashboard ingress**
|
|
- File: `4-Infrastructure/k3s/ray/dashboard-ingress.yaml`
|
|
- Traefik IngressRoute at `researchstack.info/ray/`
|
|
- SSO-gated via Authentik
|
|
|
|
**Step 6.2: Prometheus metrics**
|
|
- Ray exports Prometheus metrics at `:8080/metrics`
|
|
- Scrape config in monitoring namespace
|
|
- Grafana dashboard for Ray cluster health
|
|
|
|
**Step 6.3: Alerting**
|
|
- Alert on: worker disconnect, Object Store pressure, task failures
|
|
- Route to: Telegram/Discord via Alertmanager
|
|
|
|
---
|
|
|
|
## Files to Create
|
|
|
|
| File | Purpose |
|
|
|------|---------|
|
|
| `4-Infrastructure/k3s/ray/namespace.yaml` | Namespace + RBAC |
|
|
| `4-Infrastructure/k3s/ray/head-deployment.yaml` | Ray Head on Neon |
|
|
| `4-Infrastructure/k3s/ray/head-service.yaml` | ClusterIP + IngressRoute |
|
|
| `4-Infrastructure/k3s/ray/gpu-worker-deployment.yaml` | GPU worker on qfox |
|
|
| `4-Infrastructure/k3s/ray/cpu-worker-deployment.yaml` | CPU worker on nixos |
|
|
| `4-Infrastructure/k3s/ray/standby-worker-deployment.yaml` | Standby on racknerd/steamdeck |
|
|
| `4-Infrastructure/k3s/ray/worker-entrypoint.sh` | Staggered reconnection script |
|
|
| `4-Infrastructure/k3s/ray/head-entrypoint.sh` | Token bucket config |
|
|
| `4-Infrastructure/k3s/ray/object-store-config.yaml` | Watermark thresholds |
|
|
| `4-Infrastructure/k3s/ray/dashboard-ingress.yaml` | Dashboard Traefik route |
|
|
| `4-Infrastructure/shim/ray_circuit_breaker.py` | Circuit breaker per node |
|
|
| `4-Infrastructure/shim/ray_task_migrator.py` | Graduated migration |
|
|
| `4-Infrastructure/shim/vcn_ray_transport.py` | VCN → Ray Object Store |
|
|
| `4-Infrastructure/shim/fractal_ray_task.py` | Fractal dimension on Ray |
|
|
| `4-Infrastructure/shim/alphaproof_ray.py` | AlphaProof on Ray |
|
|
|
|
---
|
|
|
|
## Files to Modify
|
|
|
|
| File | Change |
|
|
|------|--------|
|
|
| `4-Infrastructure/k3s-flake/k3s-edge.nix` | Update Traefik for Ray ingress |
|
|
| `6-Documentation/INFRASTRUCTURE.md` | Add Ray section |
|
|
| `6-Documentation/RUNBOOK.md` | Add Ray troubleshooting |
|
|
| `AGENTS.md` | Add Ray deployment rules |
|
|
|
|
---
|
|
|
|
## Validation
|
|
|
|
### Phase 1 Validation
|
|
- [ ] Ray Head pod Running on Neon
|
|
- [ ] Dashboard accessible at localhost:8265 (port-forward)
|
|
- [ ] `ray status` shows 1 node (Head)
|
|
|
|
### Phase 2 Validation
|
|
- [ ] GPU worker connected (qfox)
|
|
- [ ] CPU worker connected (nixos)
|
|
- [ ] Standby workers connected (racknerd, steamdeck if online)
|
|
- [ ] `ray status` shows 4+ nodes
|
|
|
|
### Phase 3 Validation
|
|
- [ ] Simulate node disconnect: kill qfox pod
|
|
- [ ] Verify: GPU tasks queued, not failed
|
|
- [ ] Restart qfox pod
|
|
- [ ] Verify: staggered reconnection (watch logs)
|
|
- [ ] Verify: graduated migration (5→15→35→50 tasks)
|
|
- [ ] Verify: Object Store watermark triggers at 60%
|
|
|
|
### Phase 4 Validation
|
|
- [ ] `ray.put(braid_data)` returns ObjectRef
|
|
- [ ] `ray.get(ObjectRef)` returns original data
|
|
- [ ] GPU decode works on qfox
|
|
- [ ] CPU decode fallback works on nixos
|
|
- [ ] 100 braid strands: end-to-end < 10s
|
|
|
|
### Phase 5 Validation
|
|
- [ ] Control plane migrated to cupfox
|
|
- [ ] All workers join new control plane
|
|
- [ ] Ray Head reschedules on Neon
|
|
- [ ] GCS persists across restart
|
|
|
|
### Phase 6 Validation
|
|
- [ ] Dashboard accessible via Traefik
|
|
- [ ] Prometheus scraping Ray metrics
|
|
- [ ] Grafana dashboard shows cluster health
|
|
|
|
---
|
|
|
|
## Risks and Mitigations
|
|
|
|
| Risk | Impact | Mitigation |
|
|
|------|--------|-----------|
|
|
| Neon ARM64 image compatibility | Some services won't run | Test images before deploying |
|
|
| Ray Head on 4GB cupfox | OOM | Keep Head on Neon (64GB), cupfox is control-plane only |
|
|
| Tailscale DERP latency | Slow Ray RPC | Use direct connections when possible |
|
|
| Object Store memory pressure | OOM on workers | Watermarks + PVC spill |
|
|
| GPU driver mismatch | NVDEC fails | Fall back to CPU software decode |
|
|
| etcd on cupfox 128GB disk | Disk full | Monitor disk usage, set alerts |
|
|
|
|
---
|
|
|
|
## Open Questions
|
|
|
|
1. **ARM64 Ray image**: Does `rayproject/ray:2.43.0-py311-cu124` have ARM64 builds? If not, need to build custom image.
|
|
2. **NVDEC on qfox**: Is the NVIDIA driver new enough for NVDEC? Need to verify with `nvidia-smi`.
|
|
3. **PVC access from workers**: Can Ray workers on different nodes mount the same PVC? Need ReadWriteMany or NFS.
|
|
4. **Ray version**: 2.43.0 is latest stable. Check compatibility with k3s 1.35.4.
|
|
5. **Cost**: Ray Head on Neon uses 8-32GB RAM. Is that acceptable alongside other workloads?
|
|
|
|
---
|
|
|
|
## Success Criteria
|
|
|
|
- [ ] Ray cluster operational with 4+ nodes
|
|
- [ ] VCN pipeline runs on Ray (encode → transfer → decode → compute)
|
|
- [ ] GPU acceleration working (NVDEC + CUDA)
|
|
- [ ] Thundering herd mitigations tested (node disconnect/reconnect)
|
|
- [ ] Dashboard accessible via Traefik
|
|
- [ ] AlphaProof runs on Ray (parallel proof search)
|
|
- [ ] All existing workloads still functional (k3s services, Lean, Python)
|