youtube_abschrift_korrigieren/README.md
2026-10-10 19:23:28 +02:00

206 lines
8.8 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.

# youtube_rede_korrigieren
Korrigiert automatische Abschriften deutscher Reden (z. B. YouTube-Untertitel als
Text) mit einem lokalen Sprachmodell über Ollama: Rechtschreibung, Satzzeichen,
Hörfehler, Absätze – möglichst wortgetreu, ohne Zusammenfassung oder Glättung.
Drei Werkzeuge, einzeln oder hintereinander nutzbar:
| Skript | Aufgabe |
|---|---|
| `yt_untertitel.py` | Untertitel eines YouTube-Videos als VTT herunterladen |
| `vtt2txt.py` | VTT in eine Rohabschrift (Text) umwandeln |
| `rede_korrigieren.py` | Rohabschrift (oder VTT direkt) mit dem Sprachmodell korrigieren |
## Voraussetzungen
- Python 3.9+ (nur Standardbibliothek)
- für den Download: [yt-dlp](https://github.com/yt-dlp/yt-dlp) (`pip install yt-dlp`)
- Ollama auf `127.0.0.1:11434` mit dem Modell `qwen3:32b`
(`ollama pull qwen3:32b`)
Für gute Geschwindigkeit muss das Modell komplett in den Grafikspeicher passen.
Mit `OLLAMA_NUM_PARALLEL=1` braucht `qwen3:32b` bei 16k Kontext rund 24 GB
(eine RTX 3090). Bei `OLLAMA_NUM_PARALLEL=4` landet ein Drittel auf der CPU und
der Lauf wird etwa 12-mal langsamer.
## Aufruf
Ablauf von der YouTube-URL zum korrigierten Text:
```bash
./yt_untertitel.py -u 'https://www.youtube.com/watch?v=rm6lADgf6GQ' -n Lahnstein -d testdaten
./vtt2txt.py -i testdaten/Lahnstein.de-orig.vtt
./rede_korrigieren.py -i testdaten/Lahnstein.de-orig.txt
```
Der mittlere Schritt ist optional: `rede_korrigieren.py -i testdaten/Lahnstein.de-orig.vtt`
wandelt die Untertitel selbst um. Die `.txt` lohnt sich, um den Rohtext anzusehen
oder ein Glossar daraus zu erstellen.
### Untertitel herunterladen: `yt_untertitel.py`
Lädt die Untertitel eines YouTube-Videos über `yt-dlp` als VTT-Datei, ohne das
Video selbst. Gewählt wird:
1. manuelle Untertitel in der gewünschten Sprache, sonst
2. automatische Untertitel in der Originalsprache des Videos (`de-orig`).
Automatische Untertitel ohne `-orig` sind Maschinenübersetzungen aus einer anderen
Sprache und werden nie genommen. Gibt es keine passende Spur, nennt das Skript die
vorhandenen Sprachen.
```bash
./yt_untertitel.py -u URL # → <Video-ID>.de-orig.vtt
./yt_untertitel.py -u URL -n Lahnstein -d testdaten # → testdaten/Lahnstein.de-orig.vtt
```
| Option | Bedeutung |
|---|---|
| `-u`, `--url` | YouTube-URL, Pflicht |
| `-n`, `--name` | Dateiname ohne Endung; Standard: Video-ID |
| `-l`, `--lang` | Sprache; Standard: `de` |
| `-d`, `--dir` | Zielverzeichnis (wird angelegt); Standard: aktuelles Verzeichnis |
Eine vorhandene Datei gleichen Namens wird überschrieben.
### Untertitel umwandeln: `vtt2txt.py`
Macht aus VTT-Untertiteln (z. B. von `yt-dlp --write-auto-subs`) die Rohabschrift
für `rede_korrigieren.py`: Zeitstempel und Tags werden entfernt. YouTube-Auto-Untertitel
zeigen ein rollendes Fenster, jeder Block wiederholt das Ende des vorigen. Übernommen
wird nur, was nach dieser Überlappung neu ist; sagt der Redner eine Zeile wirklich
zweimal, bleibt sie zweimal erhalten.
```bash
./vtt2txt.py -i rede.de.vtt # → rede.de.txt
./vtt2txt.py -i ramstein.de*.vtt # mehrere Dateien, je → *.txt
./vtt2txt.py -i "ramstein.de*.vtt" # Muster löst das Programm auf (Windows)
./vtt2txt.py -i rede.de.vtt -o out/rede.txt # eigene Ausgabedatei
./vtt2txt.py -i *.vtt -o out/ # alle in ein Verzeichnis
```
| Option | Bedeutung |
|---|---|
| `-i`, `--input` | eine oder mehrere VTT-Dateien oder Muster, Pflicht |
| `-o`, `--output` | Ausgabedatei (nur bei einer Eingabedatei) oder Verzeichnis (vorhanden oder mit `/` am Ende); Standard: `<Eingabe ohne Endung>.txt` neben der Eingabe |
Eine fehlerhafte Datei (keine Untertitel, nicht UTF-8) wird gemeldet, die übrigen
werden trotzdem umgewandelt; der Exit-Code ist dann 1.
### Abschrift korrigieren: `rede_korrigieren.py`
```bash
./rede_korrigieren.py -i rede.txt # → rede.korrigiert.txt
./rede_korrigieren.py -i rede.txt -o out/rede.txt # eigene Ausgabedatei
./rede_korrigieren.py -i rede.txt -g rede.glossar.txt # mit Glossar
./rede_korrigieren.py -i rede.de.vtt # VTT direkt → rede.de.korrigiert.txt
```
| Option | Bedeutung |
|---|---|
| `-i`, `--input` | Eingabedatei: Rohabschrift (`.txt`) oder Untertitel (`.vtt`, wird wie mit `vtt2txt.py` umgewandelt), Pflicht |
| `-o`, `--output` | Ausgabedatei; Standard: `<Eingabe ohne Endung>.korrigiert.txt` neben der Eingabe |
| `-g`, `--glossar` | Glossar mit festen Ersetzungen und Schreibweisen |
## Ablauf
1. **Fließtext:** Untertitel-Zeilenumbrüche werden entfernt.
2. **Feste Ersetzungen** aus dem Glossar (`falsch => richtig`) werden im Rohtext
angewendet, bevor das Modell ihn sieht.
3. **Korrektur:** Der Text wird in Abschnitte von ca. 1200 Wörtern geteilt (immer
am Satzende) und abschnittsweise vom Modell korrigiert. Fortschritt wird live
angezeigt.
4. **Wortzahl-Prüfung:** Weicht die Wortzahl eines Abschnitts um mehr als 5 % ab,
gibt es eine Warnung (mögliche Auslassungen oder Ergänzungen).
5. **Absätze:** Das Modell nennt nur Satznummern, an denen ein Absatz beginnt; der
Text selbst wird dabei nicht verändert. Absätze über 10 Sätze werden nochmals
geteilt, Absätze unter 3 Sätzen mit dem Nachbarn verbunden.
Zweifelhafte Stellen markiert das Modell als `Lesart [prüfen: Originalwortlaut]`.
## Glossar
Eine Zeile pro Eintrag, `#` leitet Kommentare ein:
```text
# feste Ersetzung (ganze Wörter, Groß-/Kleinschreibung zählt, Reihenfolge = Datei)
Willly Brand => Willy Brandt
Kremmel => Kreml
# Hinweis fürs Modell (korrekte Schreibweise, optional mit Erläuterung)
Multi-Domain Task Force
Michael Gorbatschow (Vorname so belassen)
```
Ersetzungen ohne Treffer werden gemeldet (Tippfehler im Glossar).
`ramstein.glossar.txt` und `magdeburg.glossar.txt` sind Beispiele zu den Testdaten.
## Testdaten
`testdaten/` enthält drei Reden, jeweils als automatische YouTube-Untertitel
(`.vtt`, Original) und daraus mit `vtt2txt.py` gewonnener Rohtext (`.txt`, Eingabe
für das Programm):
- `ramstein.de.*`: Rede über die US Air Base Ramstein (mit Glossar `ramstein.glossar.txt`)
- `magdeburg.de-orig.*`: Rede in Magdeburg (mit Glossar `magdeburg.glossar.txt`)
- `Lahnstein.de-orig.*`: Rede „Respekt geht anders“ in Lahnstein (noch ohne Glossar,
geladen mit `yt_untertitel.py`)
```bash
./vtt2txt.py -i "testdaten/*.vtt" # erzeugt alle .txt neu
./rede_korrigieren.py -i testdaten/ramstein.de.txt -g ramstein.glossar.txt
# → testdaten/ramstein.de.korrigiert.txt (nicht versioniert)
```
Ein Lauf dauert mit `qwen3:32b` vollständig auf einer RTX 3090 etwa 6 Minuten.
## Tests
```bash
python3 -m pytest
```
Die Tests brauchen kein Ollama: Modellaufrufe werden durch Fakes ersetzt. Geprüft
werden Abschnittsbildung, Glossar (inkl. „jede Ersetzung in den Beispiel-Glossaren
trifft ihre Testdaten“), Streaming-Auswertung, Absatzgliederung (Text bleibt
unverändert, 3–10 Sätze), Zwischenspeicher/Fortsetzen und die Kommandozeile.
`tests/test_yt_untertitel.py` prüft Spurauswahl, Aufruf von `yt-dlp` und
Fehlerfälle (ohne Netz, `yt-dlp` wird durch Fakes ersetzt).
`tests/test_vtt2txt.py` prüft die VTT-Umwandlung: jede `.vtt` in `testdaten/`
ergibt genau die zugehörige `.txt`, echte Wiederholungen bleiben erhalten,
dazu Muster, Ausgabeverzeichnis und Fehlerfälle.
## Zwischenstände
Jeder fertige Abschnitt und jede Absatzgliederung wird in `<Ausgabe>.parts/`
gespeichert. Ein erneuter Lauf überspringt alles, was schon berechnet ist.
Ändern sich Modell, Prompt, Glossar oder Text eines Abschnitts, wird genau dieser
Teil neu berechnet. Den Ordner kann man jederzeit löschen.
## Einstellungen
Oben in `rede_korrigieren.py`:
| Konstante | Standard | Bedeutung |
|---|---|---|
| `MODEL` | `qwen3:32b` | Ollama-Modell |
| `CHUNK_SIZE` | 1200 | Wörter pro Korrekturabschnitt |
| `MAX_WORD_DEVIATION` | 0.05 | Warnschwelle Wortzahl |
| `MAX_PARAGRAPH_SENTENCES` | 10 | längster erlaubter Absatz |
| `MIN_PARAGRAPH_SENTENCES` | 3 | kürzester gewünschter Absatz |
## Bekannte Grenzen
- Das Modell ändert gelegentlich Wörter eigenmächtig, auch sinnverändernd
(Magdeburg-Rede ohne Glossar: „Professor“ → „Professorin“, „gedeiliche“ →
„geregelte“ statt „gedeihliche“). Stichproben lohnen sich; gefundene Fälle
gehören ins Glossar.
- `qwen3:32b` ohne Denkmodus erkennt Hörfehler ohne Glossar nur teilweise und
setzt kaum `[prüfen: …]`-Marken. Bekannte Fehler gehören deshalb ins Glossar.
- Das Verbinden kurzer Absätze achtet nicht auf den Inhalt.
- `vtt2txt.py` erkennt Wiederholungen an der Überlappung aufeinanderfolgender
Untertitel-Blöcke. Bei Untertiteln ohne rollendes Fenster gehen deshalb zwei
direkt aufeinanderfolgende, identische Blöcke zu einem zusammen.
- Abkürzungen wie „z. B.“ oder „2. Weltkrieg“ können als Satzende gelten; das
beeinflusst nur mögliche Absatzgrenzen, nicht den Text.