hermes-erkenntnisse/burst-compute/w44-cpu-offload-step3-2026-07-23.md

3.2 KiB

W44 Burst-Compute: CPU-Offload, Schritt 3 (2026-07-23)

Design-Entscheidung des Koordinators: CPU-Offload-Ziel ist VM302 selbst (100.104.5.57), NICHT der GPU1-Hypervisor. Grund (von mir eskaliert, von Bär/Koordinator bestaetigt): GPU1-Host ist geteilte Prod-Hardware mit nur 22GB freiem RAM (231/251GB belegt) und hat weder ffmpeg noch piper installiert -- ein Hypervisor-Paket-Eingriff waere riskant und unnoetig. VM302 hat waehrend eines A40-Renders viele CPU-Kerne + RAM frei, waehrend nur die GPU/VRAM belegt ist -- genau die richtige freie Kapazitaet.

Realitaets-Check vor dem Bauen

  • ffmpeg ist auf VM302 vorhanden (D:\Python311\ffmpeg.exe), piper ist NICHT vorhanden (weder auf VM302 noch auf GPU1).
  • Das bestehende Compositing-Endpoint (:8196 /api/compose, in app.py per _px_forward_nacht durchgereicht) nutzt ffmpeg bereits rein CPU-basiert (kein -hwaccel/NVENC) -- es gab de facto nichts umzuleiten, weil es nie GPU-gebunden war.

Echter CPU-Lauf als Beleg (waehrend aktivem A40-Render!)

Auf VM302 per WinRM ausgefuehrt:

VOR:  nvidia-smi --query-gpu=memory.used -> 45378 MiB (Render laeuft, GPU fast voll)
ffmpeg -f lavfi -i "sine=frequency=440:duration=3" test.wav   (CPU-Synthese)
ffmpeg -i test.wav -codec:a libmp3lame test.mp3                (CPU-Encode)
NACH: nvidia-smi --query-gpu=memory.used -> 45378 MiB (UNVERAENDERT), GPU-Util 0% durchgehend
Dateien erzeugt: test.wav (264678 bytes), test.mp3 (12942 bytes)

→ Beweis: ein realer CPU-Job lief parallel zum aktiven A40-Video-Render, ohne die GPU zu beruehren (0 MiB VRAM-Delta).

Was in app.py gebaut wurde

  • _CPU_OFFLOAD_CAPABLE-Dict: dokumentiert je Kandidat ob eine echte CPU-Route existiert:
    • compose_ffmpeg: verfuegbar (bereits CPU-only, kein Code-Reroute noetig -- nur verifiziert+dokumentiert)
    • tts_piper: NICHT verfuegbar (Piper fehlt) -- bewusst kein Fake-Endpoint gebaut
    • vae_cpu: NICHT verfuegbar (ComfyUI hat keinen eingerichteten CPU-VAE-Modus)
  • Neuer Endpoint GET /api/burst/cpu-status (auth-gated) liefert dieses Dict -- Grundlage fuer den Dispatcher in Schritt 4 (der bei Bedarf leichte CPU-Tasks NICHT nach Monster/GPU-Shadow schickt, sondern lokal auf VM302-CPU belaesst, wenn available=True).

Warum kein Piper-Install in diesem Schritt

Bewusste Entscheidung gegen Scope-Creep: Piper waere ein echter Software-Install (neues Binary + ONNX-Modelle) auf VM302 -- additiv/reversibel grundsaetzlich moeglich, aber ein separater, review-wuerdiger Schritt (Speicherplatz, Stimmqualitaet, Modell-Ablage nach M:\ gemaess goldener Regel). Als offener Folgeschritt vermerkt, kein stiller Verzicht.

Ablauf (Portal-Skill)

  1. Fresh-Read+Backup: app.py.bak-w44-step3-20260723_182251, md5 identisch mit Live-Stand vor Edit
  2. Unique-String-Replace (1 Anker, assert count==1 erfuellt)
  3. py_compile OK
  4. Testinstanz :9092: /=200, /api/burst/cpu-status=401, /api/burst/a40-guard/status=401 (beide Routen sauber koexistierend) -- gestoppt
  5. systemctl restart -- PID-Gegenprobe: alte PID 202126 (Start 18:22:17, vor Edit) -> neue PID 203542 (Start 18:24:53, nach Edit) -- Restart diesmal ohne Gateway-Fehler bestaetigt UND per PID verifiziert
  6. Live: :9090/=200, :9090/api/burst/cpu-status=401, cp.go-ki.eu=200