hermes-erkenntnisse/2026-07-24-ticket96-a40-lastguard-erweiterung.md

64 lines
4.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# A40-Last-Guard fuer Video-Overflow (#96 erweitert) — 2026-07-24
**Auftrag:** Bär-Vorgabe 2026-07-24 — der MiniMax/Kling-Video-Failover (#96) griff bisher NUR
wenn ComfyUI/A40 komplett unerreichbar war. Die A40 darf laut Bär nicht überlastet werden —
der Überlauf muss schon bei AUSLASTUNG greifen, nicht erst wenn die Karte tot ist.
## Was gebaut wurde (additiv, reversibel)
Datei: `B:\barby\orchestrator\main.py` (VM302:8197), `B:\barby\orchestrator\routing_tiers.json`
Backups vor Änderung: `main.py.bak-a40loadguard-20260724-113445`, `routing_tiers.json.bak-a40loadguard-20260724-113445`
### 1. Neues Last-Signal: `a40_load_status()`
Prüft VOR jedem Video-Schritt (`run_video_job`) drei unabhängige, additive Quellen (ODER-verknüpft):
| Quelle | Schwelle | Bedeutung |
|---|---|---|
| ComfyUI `/system_stats` VRAM | `A40_VRAM_BUSY_PCT` (Default **85%**) | Karte fast voll |
| nvidia-smi GPU-Util + ComfyUI-`/queue`-Stau | `A40_UTIL_BUSY_PCT` (Default **95%**) UND `queue_pending>=1` | Karte dauerhaft am Limit mit Rückstau |
| A40-Guard-Semaphore #54 (VM201 `/api/burst/a40-guard/status`) | `busy: true` | Karte hält schon 1 Job fest — laut Bär darf sie nie überbucht werden, das reicht allein |
Fail-open: jeder Messfehler → `overloaded=False` (ein kaputtes Signal leitet nie fälschlich extern um).
### 2. Überlauf-Entscheidung in `run_video_job`
- Nicht erreichbar → wie bisher (#96 Basisfall), jetzt über gemeinsamen Helper `_run_minimax_overflow()`.
- **NEU:** erreichbar aber `overloaded=True` → Job wird NICHT lokal nachgelegt (kein Thrashing/Überbuchung).
- Wenn Bär den MiniMax-Failover scharf geschaltet hat (`CLOUD_VIDEO_FALLBACK_ENABLED=1` + `MINIMAX_API_KEY`): Überlauf auf Video-Tier 5 (routing_tiers.json).
- Ohne Freigabe (aktueller Live-Zustand): Job bleibt lokal in der ComfyUI-Queue, das Last-Signal wird trotzdem in `job.plan.overflow.last_signal` dokumentiert — kein Geld ausgegeben ohne Bär-GO.
- `/health`-Endpoint zeigt jetzt die vollständige Trigger-Logik + den Last-Signal-Endpunkt.
### 3. routing_tiers.json
Neuer Meta-Eintrag `a40_last_signal_baer_2026-07-24` dokumentiert die Schwellen, Quellen und den Verify-Beleg.
`a40_guard_endpoint` korrigiert auf den echten Pfad `/api/burst/a40-guard/status`.
## Verify (Beleg, ohne echten Cloud-Call)
Testinstanz: `main.py` als Modul importiert (kein Server-Neustart nötig für den Funktionstest), `a40_load_status()` isoliert aufgerufen.
**Test 1 — A40 frei (Live-Zustand, VRAM 25.9/45GB frei = 42.4% belegt):**
```json
{"reachable": true, "overloaded": false, "vram_pct": 42.4, "guard_busy": false}
```
→ Job würde lokal eingereiht (Headroom vorhanden). **Bestätigt: lokal bleibt Priorität 1 bei Headroom.**
**Test 2 — künstlich scharfe VRAM-Schwelle (`A40_VRAM_BUSY_PCT=1`), reale Messwerte unverändert:**
```json
{"reachable": true, "overloaded": true, "gruende": ["vram_belegt_42.4pct_ab_1.0pct"]}
```
→ Plan-Entscheidung: Job bleibt lokal (kein Bär-GO für MiniMax), Last wird dokumentiert. Mit aktivem Failover wäre der Grund `a40_ueberlastet:vram_belegt_...` an `_run_minimax_overflow()` gegangen.
**Test 3 — A40-Guard-Semaphore (#54) isoliert getestet (Mock-Server liefert `{"busy":true,"job":"sim_video_job_123"}`):**
```json
{"reachable": true, "overloaded": true, "guard_busy": true, "gruende": ["a40_guard_belegt_job=sim_video_job_123"]}
```
**Bestätigt: die Guard-Semaphore allein (unabhängig von VRAM/Util) löst das Überlauf-Signal aus.**
## Deployment
- `python -m py_compile main.py` → OK (2×, vor und nach Doku-Ergänzung)
- Queue vor Neustart geprüft: `laufend=0, warteschlange=0` → kein Job unterbrochen
- Scheduled Task `BarbyOrchestrator` neu gestartet (Stop/Start), `/health` danach OK, `jobs.gesamt` unverändert (39) → State erhalten
- Kein echter Cloud-Call ausgelöst, kein Guthaben verbraucht (MiniMax bleibt Default AUS, Bär-GO weiterhin nötig für den ersten echten Testclip)
## Rollback
`Copy-Item main.py.bak-a40loadguard-20260724-113445 main.py -Force` + `Copy-Item routing_tiers.json.bak-a40loadguard-20260724-113445 routing_tiers.json -Force`, dann Scheduled Task `BarbyOrchestrator` neu starten.