hermes-erkenntnisse/2026-07-24-ticket84-video-laenge-dynamisch.md

88 lines
5.6 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.

# #84: Video-Länge dynamisch statt fest gedeckelt (~2 Min)
**Datum:** 2026-07-24
**Ort:** `B:\barby\orchestrator\main.py` (VM302, Dienst `BarbyOrchestrator`, Port 8197) + `/opt/gpu1-status/app.py` (VM201, Dienst `gpu1-portal`, Port 9090, öffentlich `cp.go-ki.eu`)
**Backups:** `B:\barby\orchestrator\main.py.bak-video-length-20260723-234947` (VM302), `/opt/gpu1-status/app.py.bak-video-length-84-20260724-002728` (VM201)
## Wo saß der Cap
In `main.py`, Konstante `MAX_VIDEO_SEGMENTS = 12` (Zeile ~338, alt) und in `build_plan()`
(Video-Zweig, ~Zeile 517-536, alt): egal wie lang der Prompt/das Drehbuch die Dauer
vorgab, wurde die Segmentzahl **hart** auf 12 Segmente gekürzt (12 × ~3,06s/Segment
≈ 37s effektive Kappungsgrenze — der praktisch erlebte "~2 Min Deckel"). Es gab
dafür **kein echtes technisches Limit** — Segmente werden sequenziell gerendert
(`render_video_segments`), es gibt kein VRAM-/Parallelitäts-Limit, das die Anzahl
deckelt, nur Wall-Clock-Zeit auf der A40.
## Was geändert wurde (additiv, reversibel)
**Backend (`main.py`):**
1. `MAX_VIDEO_SEGMENTS` bleibt als reiner *Referenzwert* für Renderzeit-Hinweise
erhalten, deckelt aber die Länge nicht mehr.
2. Neu: `HARD_SAFETY_SEGMENT_LIMIT` (ENV-konfigurierbar, Default 600 Segmente ≈ 30 Min) —
eine echte Sicherheitsgrenze gegen Tippfehler/DoS ("9999 Minuten"), **kein**
Qualitäts-/Inhalts-Cap. Nur wenn diese Grenze überschritten wird, greift ein Cap
(mit klarer Hinweis-Meldung, warum).
3. `build_plan()`: Segmentzahl = `ceil(gewünschte_sekunden / SEGMENT_LEN_SEC)`, ohne
Deckelung auf 12. Neues Feld im Plan: `geschaetzte_rohdiffusions_minuten_a40`
(reine A40-Diffusionszeit, informativ).
4. Neues Request-Feld `laenge_modus: "auto" | "fest"` (GenerateRequest, `/generate`
und `/api/orchestrate`+`/orchestrate` via `_orchestrate_handler`). Bei `"auto"`
entscheidet der Inhalt (Wortzahl im Drehbuch, ~2,3 Wörter/Sekunde geschätzt) —
unabhängig von der bereits vorhandenen Prompt-Phrasenerkennung
(`CONTENT_DECIDES_RE`, z.B. "Inhalt entscheidet"), die weiterhin zusätzlich greift.
5. `video_dauer_sekunden` (Parameter-Override, war schon vorhanden) hat weiterhin
Vorrang vor `laenge_modus=auto`.
**Frontend (`app.py`, VM201, Video-Erstellen-Tab):**
1. Dropdown `#ve-laenge`: neue Option `🤖 Auto (Inhalt entscheidet)` (Value `auto`)
ganz oben ergänzt, zusätzlich `5 Minuten` (300s) als weitere feste Option. Default
bleibt unverändert bei 60 Sekunden (additiv, kein Verhaltensbruch für bestehende
Nutzung).
2. `vePipelineStart()`: bei `laenge==='auto'` wird `laenge_sekunden:null` und
`laenge_modus:'auto'` gesendet statt `laenge_sekunden:parseInt('auto')` (NaN).
Der Portal-Endpunkt `/api/studio/orchestrate` ist ein reiner Passthrough zum
Orchestrator (`/api/orchestrate`), daher kein weiterer Code auf VM201 nötig.
## Beleg (Testinstanz Port 8199, main.py unverändert vom Prod-main.py, GPU-Job sofort
nach Plan-Auslesen gestoppt, um die A40 nicht unnötig zu belasten)
| Test | Eingabe | Ergebnis vorher (Cap) | Ergebnis nachher |
|---|---|---|---|
| Explizite Dauer | "... 90 Sekunden Video." | 12 Segmente (~37s, hart gekappt) | **30 Segmente**, `geplante_segmente=30`, Hinweis: "30 Segmente geplant (~1.5 Min reine A40-Diffusionszeit ...) - läuft vollständig durch, kein Cap mehr (siehe #84)." |
| Explizite Dauer (Prod, nach Restart) | "... 75 Sekunden Video." | 12 Segmente | **25 Segmente**, `geschaetzte_rohdiffusions_minuten_a40=1.3` |
| Inhalt entscheidet (Prompt-Phrase) | Mehrszenen-Text + "Inhalt entscheidet die Laenge." | n/a | `modus=inhalt_entscheidet`, 6 Segmente, Quelle "39 Woerter im Drehbuch" |
| `laenge_modus=auto` (API-Feld) | Mehrszenen-Text, `laenge_modus:"auto"` | n/a | `modus=inhalt_entscheidet`, Quelle "... Woerter im Drehbuch (laenge_modus=auto)" — funktioniert unabhängig von Prompt-Phrasen |
| Sicherheitsgrenze | (nicht produktiv getestet, nur Codepfad geprüft) | n/a | greift nur ab >600 Segmenten (~30 Min), mit expliziter Hinweis-Meldung "Tippfehler-/DoS-Schutz, kein Qualitäts-Cap" |
`python -m py_compile B:\barby\orchestrator\main.py` → exit 0 (VM302).
`python3 -m py_compile /opt/gpu1-status/app.py` → COMPILE_OK (VM201).
`https://cp.go-ki.eu/` → HTTP 200, ausgeliefertes HTML enthält
`Auto (Inhalt entscheidet)` und `laenge_modus:(laenge==='auto'?'auto':null)`.
## Echtes technisches Limit (ehrlich benannt, keine Cap-Tarnung)
- **A40 VRAM** ist während EINES Segments knapp (`vram_free_gb` im `/health`-Endpunkt
lag beim Testlauf bei 0.3 GB frei von 45 GB) — das begrenzt aber nicht die
*Anzahl* der Segmente, weil sie sequenziell laufen, sondern nur, wie viel
parallel dazu (Postprocessing des Vorsegments) gleichzeitig laufen kann. Das ist
bereits in `postprocess_segment` als überlappende Async-Task gelöst (#20).
- **Wall-Clock-Zeit** ist die echte Grenze: laut Code-Kommentar ~4,3 Min/Clip im
Fastpath (512×896, 4-Step-Lightning-LoRA) — ein 25-Minuten-Video (500 Segmente)
würde real mehrere Stunden A40-Zeit brauchen. Das steht jetzt als
`geschaetzte_rohdiffusions_minuten_a40` im Plan, damit das vor dem Start sichtbar
ist, statt überrascht zu werden.
- Die neue `HARD_SAFETY_SEGMENT_LIMIT` (600 Segmente ≈ 30 Min) ist bewusst so hoch
gewählt, dass sie in der Praxis nie ein normales Drehbuch trifft, sondern nur
echte Fehleingaben abfängt.
## Rollback
```powershell
Copy-Item B:\barby\orchestrator\main.py.bak-video-length-20260723-234947 B:\barby\orchestrator\main.py -Force
schtasks /Run /TN "BarbyOrchestrator"
```
```bash
ssh root@100.114.24.89 "cp -a /opt/gpu1-status/app.py.bak-video-length-84-20260724-002728 /opt/gpu1-status/app.py && systemctl restart gpu1-portal.service"
```