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

4.1 KiB
Raw Blame History

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):

{"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:

{"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"}):

{"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.