homelab-brain/ki-video/PLAN.md

516 lines
20 KiB
Markdown
Raw 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.

# KI-Video — Lokale Produktionspipeline
**Stand: 16.03.2026**
## Ziel
Lokale, produktiv nutzbare Pipeline fuer YouTube-Videos im Commentary-/Erklaerstil.
Thema rein → fertiges Video raus. Kein Forschungsprojekt, kein Proof-of-Concept.
## Videoformat
Referenz-Stil: **"Geld & Imperien"** / **"Money & People"** (YouTube)
- https://youtu.be/4XfhrrbklbM (24 Min, Geld & Imperien)
- https://youtu.be/MIkAOwJYaP0 (19 Min, Money & People)
| Eigenschaft | v1 |
|---|---|
| **Typ** | Commentary, Erklaervideo, Analyse |
| **Laenge** | 10-30 Minuten |
| **Visuell** | Bilder + Karten + Infografiken + Text-Overlays + Ken-Burns |
| **Stimme** | XTTS v2, natuerliche deutsche Maennerstimme, Voice-Cloning |
| **Untertitel** | Automatisch (faster-whisper → SRT) |
| **Avatar** | **Nein.** Erst ab v1.5 als optionaler PiP-Test. |
| **Kein** | Face-Cam, Realfilm, Vollbild-Avatar, Piper TTS |
Das fertige Video besteht aus: Bilder mit Ken-Burns-Effekten + Voiceover + Hintergrundmusik
+ Text-Overlays + eingebrannte Untertitel. Das reicht. Die Referenz-Kanaele machen es genauso.
### Anatomie eines 20-Min-Videos
| Element | Menge | Quelle |
|---|---|---|
| **Skript** | ~3500-5000 Woerter | GPT-5.4 (Cloud) + menschliches Review |
| **Szenenplan** | ~100 Szenen (JSON) | Qwen 14B (lokal) |
| **Hero-Bilder** | 10-15 Stueck | FLUX.1-dev (3090) |
| **Standard-Bilder** | 70-100 Stueck | SDXL (3x 3080) |
| **Voiceover** | 20 Min WAV | XTTS v2 (3080) |
| **Untertitel** | SRT-Datei | faster-whisper (3080) |
| **Hintergrundmusik** | 1-2 Tracks | Lizenzfrei, manuell gewaehlt |
| **Text-Overlays** | 20-40 Stueck | FFmpeg (aus Szenenplan) |
## v1 — Produktions-Pipeline
### Prinzip
```
GPT-5.4 (Cloud) → Qwen 14B (lokal) → 5 GPUs parallel → FFmpeg → MP4
Skript Szenenplan Bilder + Voice Assembly
```
Kein Avatar. Kein dynamisches Scheduling. Kein Service-Mesh.
5 GPUs, feste Zuordnung, SQLite als Zustand, Python als Orchestrator.
### Pipeline-Schritte
```
PHASE 1 — SKRIPT + SZENENPLAN (~30 Min, Cloud + lokal + Mensch)
═══════════════════════════════════════════════════════════════
Thema + Recherche-Notizen (manuell)
GPT-5.4 (OpenAI API) → Skript (~4000 Woerter)
│ Kosten: ~0.10-0.50 EUR
Mensch reviewt, korrigiert, gibt frei (~20 Min)
Qwen 14B (vLLM, :8401) → Szenenplan (JSON):
100 Szenen mit je:
- Bildprompt (EN, fuer FLUX oder SDXL)
- Szenentyp: hero | standard | karte | infografik
- Text-Overlay (oder null)
- Dauer in Sekunden
Orchestrator uebernimmt
PHASE 2 — PARALLEL-PRODUKTION (alle 5 GPUs, ~20 Min)
═════════════════════════════════════════════════════
┌──────────────────────────────────────────────────────────┐
│ ORCHESTRATOR (ki-tower, Python) │
│ Verteilt Jobs, pollt Status, sammelt Ergebnisse │
└──────┬──────────┬──────────┬──────────┬──────────────────┘
│ │ │ │
▼ ▼ ▼ ▼
┌──────────┐┌──────────┐┌──────────┐┌──────────────────────┐
│ 3090 ││ 3080 #0 ││ 3080 #1 ││ 3080 #2 + #3 │
│ ki-tower ││ Worker ││ Worker ││ Worker │
│ ││ ││ ││ │
│ FLUX.1 ││ XTTS v2 ││ SDXL ││ SDXL │ Whisper │
│ Hero- ││ Voice ││ Standard ││ Standard│ + ESRGAN │
│ Bilder ││ → SDXL ││ Bilder ││ Bilder │ Untertit. │
│ 10-15 St ││ → Rest ││ ~40 Stk ││ ~40 Stk │ + Upscale │
│ ~10 Min ││ ~20 Min ││ ~20 Min ││ ~20 Min │ ~5 Min │
└──────────┘└──────────┘└──────────┘└──────────────────────┘
Alle GPUs starten SOFORT. Keine Abhaengigkeitskette.
3080 #0: XTTS v2 Voiceover (~15 Min), danach SDXL Restbilder (~5 Min).
3080 #3: Whisper (braucht Audio, wartet auf #0) + ESRGAN parallel.
Engpass = Bildgenerierung (~20 Min fuer ~100 Bilder auf 3+1 GPUs).
PHASE 3 — ASSEMBLY (ki-tower, ~10-15 Min)
══════════════════════════════════════════
FFmpeg: Bilder + Ken-Burns + Zoom + Ueberblendungen → Videospur
FFmpeg: Audio-Mix (Voiceover + Hintergrundmusik)
FFmpeg: Text-Overlays einbrennen
FFmpeg: Untertitel (SRT) einbetten
NVENC: H.265 Encoding → fertiges MP4 (1080p)
Export: Thumbnail (FLUX hero-Bild) + Titel + Description + Tags
```
### Zeitschaetzung: 20-Min-Video (ohne Avatar)
| Phase | Dauer | GPUs | Engpass |
|---|---|---|---|
| 1. Skript + Szenenplan | ~30 Min | 1 (3090) + Cloud | Mensch (Review) |
| 2. Parallel-Produktion | ~20 Min | 5 (alle) | Bildgenerierung |
| 3. Assembly | ~10 Min | 1 (3090 NVENC) | FFmpeg Compositing |
| **Gesamt (Maschine)** | **~30 Min** | | |
| **Gesamt (inkl. Mensch)** | **~60 Min** | | |
Ohne Avatar: kein SadTalker-Engpass, keine TTS→Avatar-Abhaengigkeit.
Bildgenerierung ist der Engpass, aber auf 4 GPUs verteilt (3x SDXL + 1x FLUX).
### GPU-Zuordnung v1
| GPU | Aufgabe | VRAM | Dauer | Output |
|---|---|---|---|---|
| **3090** | Qwen 14B (Szenenplan) → FLUX.1-dev (Hero-Bilder) | 12 GB | ~10 Min | 10-15 hochwertige Key-Visuals |
| **3080 #0** | XTTS v2 (Voiceover) → SDXL (Restbilder) | 4→7 GB | ~20 Min | 20 Min Audio + ~15 Bilder |
| **3080 #1** | SDXL (Standard-Szenen, durchgehend) | 7 GB | ~20 Min | ~40 Bilder |
| **3080 #2** | SDXL (Standard-Szenen, durchgehend) | 7 GB | ~20 Min | ~40 Bilder |
| **3080 #3** | faster-whisper (Untertitel) + Real-ESRGAN (Upscaling) | 3 GB | ~5 Min | SRT + upscaled Thumbnails |
Alle 4 Bild-GPUs zusammen: **~100 Bilder in ~20 Minuten.**
3080 #3 ist nach ~5 Min fertig und idle — kann bei Bedarf auch SDXL uebernehmen.
## Hardware
### ki-tower (RTX 3090, 24 GB)
| Eigenschaft | Wert |
|---|---|
| CPU | AMD Ryzen 7 7700 (8C/16T) |
| RAM | 64 GB DDR5 |
| GPU | NVIDIA RTX 3090 (24 GB VRAM) |
| Storage | 1 TB NVMe |
| OS | Debian 12 + Docker + CUDA |
| Rolle | Chef: Szenenplan (Qwen), Hero-Bilder (FLUX), Assembly (FFmpeg), Orchestrator |
### gpu-worker (4x RTX 3080, je 10 GB)
| Eigenschaft | Wert |
|---|---|
| GPUs | 4x NVIDIA RTX 3080 (je 10 GB GDDR6X) |
| OS | Debian 12 + Docker + CUDA (identisch mit ki-tower) |
| Rolle | Worker: XTTS v2, SDXL-Batch, Whisper, ESRGAN |
| Vorteil | Selber CUDA-Stack — Code einmal schreiben, ueberall deployen |
### gpu-reserve (8x RX 6600 XT) — NICHT in v1
Zurueckgestellt. Kein Aufbau, keine Planung, keine Ressourcen.
Entscheidung nach 3 Monaten produktiver v1: behalten oder verkaufen.
## Rollenverteilung
### Cloud: GPT-5.4 → Skripte
Skriptqualitaet ist der Flaschenhals. Kein lokales Modell liefert
Persoenlichkeit, Meinung und natuerliches deutsches Storytelling auf diesem Niveau.
Kosten: ~0.10-0.50 EUR/Skript. Irrelevant vs. Stromkosten.
### ki-tower (3090): Szenenplan + Hero-Bilder + Assembly
| Dienst | Tool | Port | VRAM |
|---|---|---|---|
| Szenenplan-LLM | Qwen 2.5 14B (vLLM) | :8401 | ~12 GB |
| Hero-Bilder | FLUX.1-dev (ComfyUI) | :8402 | ~12 GB |
| Assembly | FFmpeg + NVENC | — | ~1 GB |
| Orchestrator | Python | — | CPU |
Schritte laufen sequentiell auf der 3090. Erst Qwen (Szenenplan), dann FLUX (Bilder),
dann FFmpeg (Assembly). Kein VRAM-Flush noetig (14B = 12 GB, FLUX = 12 GB).
### gpu-worker (3080): Voice + Bilder + Untertitel
| GPU | Dienst | Tool | Port | VRAM |
|---|---|---|---|---|
| #0 | TTS → Bilder | XTTS v2 → SDXL | :8501 | 4 → 7 GB |
| #1 | Bilder | SDXL | :8502 | 7 GB |
| #2 | Bilder | SDXL | :8503 | 7 GB |
| #3 | Untertitel + Upscaling | faster-whisper + Real-ESRGAN | :8504 | 3 GB |
1 Container pro GPU. HTTP-API pro Worker. Orchestrator auf ki-tower pollt Status.
Tailscale verbindet ki-tower und gpu-worker.
## Produktions-Datenbank
Zentrale Steuerung: **`production.db`** (SQLite) auf ki-tower.
### Schema
```sql
CREATE TABLE channels (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
slug TEXT UNIQUE NOT NULL,
voice_path TEXT NOT NULL, -- XTTS Voice-Cloning Referenz
prompt_template TEXT, -- GPT-5.4 System-Prompt (Persoenlichkeit)
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE videos (
id INTEGER PRIMARY KEY,
channel_id INTEGER REFERENCES channels(id),
title TEXT NOT NULL,
topic TEXT,
status TEXT DEFAULT 'draft', -- draft→script→scenes→producing→assembly→review→published
script TEXT,
scene_plan TEXT, -- JSON
voiceover_path TEXT,
subtitle_path TEXT,
final_path TEXT,
thumbnail_path TEXT,
yt_title TEXT,
yt_description TEXT,
yt_tags TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
published_at DATETIME
);
CREATE TABLE scenes (
id INTEGER PRIMARY KEY,
video_id INTEGER REFERENCES videos(id),
scene_nr INTEGER NOT NULL,
scene_type TEXT NOT NULL, -- hero | standard | karte | infografik
prompt TEXT NOT NULL,
overlay TEXT,
duration_s REAL NOT NULL,
image_path TEXT,
status TEXT DEFAULT 'pending' -- pending→generating→done→failed
);
CREATE TABLE jobs (
id INTEGER PRIMARY KEY,
video_id INTEGER REFERENCES videos(id),
job_type TEXT NOT NULL, -- tts | sdxl | flux | whisper | esrgan | assembly
gpu TEXT,
status TEXT DEFAULT 'queued', -- queued→running→done→failed
input_data TEXT,
output_path TEXT,
error TEXT,
queued_at DATETIME DEFAULT CURRENT_TIMESTAMP,
started_at DATETIME,
finished_at DATETIME
);
```
### Verzeichnisstruktur
```
/data/ki-video/
├── production.db
├── channels/
│ └── kanal-a/
│ ├── voice-sample.wav # XTTS Referenz (~30s)
│ └── prompt.md # GPT-5.4 Persoenlichkeits-Prompt
├── videos/
│ └── 2026-03-16-iran-hyperschall/
│ ├── script.md
│ ├── scenes.json
│ ├── images/ # 80-120 generierte Bilder
│ ├── audio/
│ │ ├── voiceover.wav
│ │ └── music.mp3
│ ├── subtitles.srt
│ ├── thumbnail.png
│ └── final.mp4
└── templates/
├── ffmpeg-kenburns.sh
└── music/
```
### Statusmaschine
```
draft → script → scenes → producing → assembly → review → published
draft : Thema angelegt
script : GPT-5.4 Skript + menschliches Review
scenes : Qwen generiert Szenenplan
producing : 5 GPUs arbeiten parallel (Bilder + Voice + Untertitel)
assembly : FFmpeg baut Video zusammen
review : Mensch schaut fertiges Video
published : YouTube-Upload
```
### Orchestrator (Python, ki-tower)
```
Alle 10 Sekunden:
1. videos WHERE status = 'scenes'
→ Jobs erstellen: 1x TTS, Nx SDXL, Mx FLUX, 1x Whisper, 1x ESRGAN
2. jobs WHERE status = 'queued'
→ Abhaengigkeiten pruefen (Whisper wartet auf TTS)
→ An Worker senden (HTTP REST)
3. jobs WHERE status = 'running'
→ Worker pollen, Status updaten
4. Alle Jobs eines Videos done?
→ Assembly-Job starten (FFmpeg)
5. Assembly done?
→ Status → 'review'
→ Telegram-Benachrichtigung (Hausmeister-Bot)
```
### CLI
```bash
./produce.py new --channel kanal-a --topic "Oelpreis-Krise 2026"
./produce.py status
./produce.py approve-script 42
./produce.py publish 42
./produce.py gpus
```
## Worker-Architektur
```
ki-tower (3090) gpu-worker (4x 3080)
┌─────────────────────────┐ ┌──────────────────────────────┐
│ Orchestrator (Python) │ │ Debian 12 + Docker + CUDA │
│ ├── production.db │ Tailscale │ │
│ ├── /api/submit-job │◄────────────►│ #0: xtts+sdxl :8501 │
│ ├── /api/job-status │ │ #1: sdxl :8502 │
│ └── /api/get-result │ │ #2: sdxl :8503 │
│ │ │ #3: whisper+esrgan :8504 │
│ Qwen 14B (vLLM) :8401 │ │ │
│ FLUX.1 (ComfyUI):8402 │ │ 10 GB VRAM pro Karte │
│ FFmpeg (lokal) │ │ CUDA-nativ │
└─────────────────────────┘ └──────────────────────────────┘
```
## Konkretes Beispiel: "Irans Hyperschall-Schlag" (24 Min)
```
INPUT:
Thema: "Irans Hyperschallrakete — geopolitische Folgen"
Recherche: 3-4 Quellenlinks
PHASE 1 (~30 Min):
GPT-5.4 → Skript (4500 Woerter)
Mensch reviewt (~20 Min)
Qwen 14B → Szenenplan: 105 Szenen (JSON)
PHASE 2 (~20 Min, alle 5 GPUs parallel):
3090: 12 Hero-Bilder (FLUX.1-dev)
3080 #0: XTTS v2 → 24 Min Voiceover → danach 15 SDXL-Bilder
3080 #1: 40 Standardbilder (SDXL)
3080 #2: 40 Standardbilder (SDXL)
3080 #3: Whisper → Untertitel-SRT + ESRGAN Upscaling
PHASE 3 (~10 Min):
FFmpeg: 105 Szenen × Ken-Burns → Videospur
FFmpeg: Audio-Mix (Voiceover + Ambient-Musik)
FFmpeg: Text-Overlays + Untertitel
NVENC: H.265 → final.mp4 (1080p)
Gesamtzeit Maschine: ~30 Min
Gesamtzeit inkl. Mensch: ~60 Min
```
## Nicht-Ziele (v1)
- Kein Avatar (kommt spaeter als Test)
- Kein Vollbild-Avatar
- Kein Piper TTS (zu robotisch, XTTS v2 direkt)
- Kein AMD-Rig
- Kein Multi-Kanal (erst ein Kanal stabil betreiben)
- Keine YouTube-Upload-Automation
- Keine Batch-Produktion (ein Video nach dem anderen)
- Kein Kubernetes, kein Service-Mesh, kein Proxmox
## Umsetzungsreihenfolge
```
PHASE 1 — ki-tower Grundinstallation (Woche 1-2)
├── Debian 12 + NVIDIA 550+ Treiber + CUDA 12.x + Docker
├── vLLM + Qwen 2.5 14B → Szenenplan-Test
├── GPT-5.4 API anbinden → erster Skript-Test
└── Ergebnis: "Skript + Szenenplan funktionieren"
PHASE 2 — Bildgenerierung (Woche 3-4)
├── ComfyUI + FLUX.1-dev in Docker → Hero-Bilder testen
├── SDXL in Docker (gleicher ComfyUI oder A1111)
├── Workflow: Szenenplan-JSON → Bildprompts → Bilder
└── Ergebnis: "100 Bilder in <30 Min generiert"
PHASE 3 — 3080-Rig parallel aufbauen (Woche 3-5)
├── Debian 12 + CUDA + Docker (identischer Stack)
├── SDXL-Worker auf #1, #2 (sofort produktiv)
├── Tailscale + Worker-API anbinden
└── Ergebnis: "3 SDXL-Worker generieren Bilder parallel"
PHASE 4 — Voice + Untertitel (Woche 5-6)
├── XTTS v2 auf 3080 #0 → Voice-Cloning mit eigener Referenz testen
├── Deutsche Stimme tunen (Sprechstil, Tempo, Betonung)
├── faster-whisper auf 3080 #3 → SRT-Untertitel
└── Ergebnis: "Natuerliches deutsches Voiceover + Untertitel"
PHASE 5 — FFmpeg Assembly + erstes Video (Woche 6-7)
├── Ken-Burns-Presets (Schwenk, Zoom, statisch je Szenentyp)
├── Audio-Mix (Voiceover + Musik, Lautstaerke-Normalisierung)
├── Text-Overlay-Pipeline (aus Szenenplan-JSON)
├── Untertitel einbetten
├── Thumbnail-Generierung (FLUX hero-Bild)
├── NVENC Encoding
└── Ergebnis: "Erstes komplettes 10-Min-Video"
PHASE 6 — Orchestrator + Produktionsbetrieb (Woche 7-8)
├── Python-Orchestrator: production.db + Job-Verteilung
├── CLI (produce.py)
├── Telegram-Benachrichtigung bei fertigem Video
├── Erstes Video auf YouTube hochladen
└── Ergebnis: "v1 laeuft produktiv"
PHASE 7 — Stabilisierung + Tempo (Woche 9-10)
├── Prompt-Templates fuer Skripte verfeinern
├── FFmpeg-Presets fuer verschiedene Szenentypen
├── XTTS-Stimme weiter tunen
├── 3-5 Videos produzieren und Workflow optimieren
└── Ergebnis: "v1 ist stabil, 2-3 Videos/Woche moeglich"
```
## Spaeter (v1.5+)
Erst nach mindestens 10 produzierten Videos und stabilem Workflow.
### v1.5 — Avatar-Test (optional)
| Feature | Beschreibung |
|---|---|
| SadTalker PiP (~20%) | Sprechender Avatar unten rechts, 384x384 |
| Laeuft auf 3080 #2 | SDXL wird auf #1 und #0 (nach TTS) konzentriert |
| Abhaengigkeit | TTS muss vorher fertig sein (Audio → Lip-Sync) |
| Risiko | Qualitaet moeglicherweise nicht ausreichend. Alternativen: LivePortrait, MuseTalk |
| Entscheidung | Erst testen, dann entscheiden ob es im Kanal bleibt |
```
Avatar-Layout (nur v1.5):
┌─────────────────────────────────────────────┐
│ │
│ HAUPTBILD (Bilder, Karten) │
│ │
│ ┌─────────┐ │
│ │ Avatar │ │
│ │ ~20% │ │
│ └─────────┘ │
└─────────────────────────────────────────────┘
```
### v2 — Erweiterungen
| Feature | Voraussetzung |
|---|---|
| Multi-Kanal | v1 stabil, erster Kanal hat >20 Videos |
| Avatar-Varianten | SadTalker/LivePortrait qualitativ validiert |
| Batch-Produktion | Mehrere Videos in Queue |
| YouTube-Upload-API | Manueller Upload nervt (>3 Videos/Woche) |
| Vollbild-Avatar | Nur wenn Qualitaet stimmt. Aktuell unrealistisch mit SadTalker. |
### AMD-Rig
Nicht in der Planung. Entscheidung nach 3 Monaten v1:
- Wenn 3080-Rig Kapazitaetsgrenze erreicht: 1-Karten-Test (Whisper)
- Sonst: verkaufen, Erloese in Storage investieren
## Entscheidungen
| Frage | Entscheidung | Begruendung |
|---|---|---|
| Skript-LLM | **GPT-5.4** (Cloud) | Kreativitaet > lokale Inferenz. ~0.50 EUR/Skript. |
| Szenenplan-LLM | **Qwen 14B** (lokal) | Strukturiertes JSON, keine Kreativitaet noetig |
| Hero-Bilder | **FLUX.1-dev** (3090) | Beste Qualitaet fuer Thumbnails, Titel, Kapitelwechsel |
| Standard-Bilder | **SDXL** (3x 3080) | Schnell, gut genug, massiv parallelisierbar |
| Stimme (v1) | **XTTS v2** (3080 #0) | Voice-Cloning, natuerlich, deutsch. Keine Uebergangsloesung. |
| Untertitel | **faster-whisper** (3080 #3) | CUDA-nativ, schnell |
| Avatar (v1) | **Nein** | Fragil, Qualitaetsrisiko, unnoetige Komplexitaet |
| Assembly | **FFmpeg + NVENC** | Stabil, flexibel, hardware-beschleunigt |
| DB | **SQLite** | Ein User, eine Datei. |
| Netzwerk | **Tailscale** | ki-tower ↔ gpu-worker, fertig |
| OS | **Debian 12** | Beide Maschinen identisch. Docker + CUDA. |
| AMD-Rig | **Nicht in v1** | Kein Aufwand, keine Planung |
## Risiken
| # | Risiko | Impact | Mitigation |
|---|---|---|---|
| 1 | **XTTS v2 deutsche Stimme klingt unnatuerlich** | Hoch | Voice-Cloning mit guter Referenz. Fallback: OpenAI TTS als Bruecke (~0.50 EUR/Video). |
| 2 | **VRAM-Tetris auf 3090** (Qwen + FLUX) | Mittel | Sequentiell, nicht parallel. vLLM Model-Unloading. 14B statt 32B. |
| 3 | **Pipeline wird zu komplex vor erstem Video** | Hoch | Erste 3 Videos manuell (Bash-Scripts). Orchestrator erst in Phase 6. |
| 4 | **SDXL-Bilder stilistisch inkonsistent** | Mittel | Feste Negativprompts + Style-Presets pro Kanal. Seed-Listen. |
| 5 | **FFmpeg-Assembly hat Artefakte** | Mittel | Ken-Burns-Presets manuell testen. Ueberblendungen standardisieren. |
## Kosten
| Posten | Monatlich |
|---|---|
| Strom ki-tower (24/7) | ~30-40 EUR |
| Strom gpu-worker (bei Bedarf) | ~10-30 EUR |
| GPT-5.4 API (Skripte) | ~3-15 EUR |
| Cloud-TTS Fallback | ~0-10 EUR |
| **Gesamt** | **~45-85 EUR** |