Das Modell steckt in den Cache-Schlüsseln; ein anderes Modell rechnet neu. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
10 KiB
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.
Die Werkzeuge sind einzeln oder hintereinander nutzbar:
| Skript | Aufgabe |
|---|---|
extract_text.py |
YouTube-URL → Textdatei in einem Schritt (die beiden folgenden zusammen) |
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 (
pip install yt-dlp) - Ollama auf
127.0.0.1:11434mit dem Modellqwen3: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
Von der YouTube-URL zum korrigierten Text:
./extract_text.py -u 'https://www.youtube.com/watch?v=rm6lADgf6GQ' -o lahnstein.txt
./rede_korrigieren.py -i lahnstein.txt # → lahnstein.korrigiert.txt
Dasselbe in Einzelschritten, wenn die VTT-Datei erhalten bleiben soll:
./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 Schritt über vtt2txt.py ist optional: rede_korrigieren.py nimmt auch die
.vtt direkt. Die .txt lohnt sich, um den Rohtext anzusehen oder ein Glossar
daraus zu erstellen.
URL → Text in einem Schritt: extract_text.py
Lädt die Untertitel und speichert nur den Text; die VTT-Datei bleibt ein
Zwischenschritt im temporären Verzeichnis. Die Spurwahl ist dieselbe wie bei
yt_untertitel.py, nur ist die Standardsprache die des Original-Audios.
./extract_text.py -u 'https://www.youtube.com/watch?v=rm6lADgf6GQ' # → output.txt
./extract_text.py -u URL -l de -o testdaten/rede.txt # Sprache und Ziel
./extract_text.py -u URL -f -o rede.txt # lesbarer Fließtext
./rede_korrigieren.py -i output.txt # → output.korrigiert.txt
| Option | Bedeutung |
|---|---|
-u, --url |
YouTube-URL, Pflicht |
-l, --lang |
Sprache; Standard: Sprache des Original-Audios (<sprache>-orig) |
-o, --output |
Ausgabedatei (Verzeichnisse werden angelegt, vorhandene Datei überschrieben); Standard: output.txt |
-f, --fliesstext |
Fließtext, auf 80 Zeichen umbrochen (Wörter werden nie getrennt), statt der kurzen Untertitelzeilen; beides versteht rede_korrigieren.py |
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:
- manuelle Untertitel in der gewünschten Sprache, sonst
- 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.
./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.
./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
./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 |
-m, --model |
Ollama-Modell; Standard: qwen3:32b (Konstante MODEL) |
Ablauf
- Fließtext: Untertitel-Zeilenumbrüche werden entfernt.
- Feste Ersetzungen aus dem Glossar (
falsch => richtig) werden im Rohtext angewendet, bevor das Modell ihn sieht. - Korrektur: Der Text wird in Abschnitte von ca. 1200 Wörtern geteilt (immer am Satzende) und abschnittsweise vom Modell korrigiert. Fortschritt wird live angezeigt.
- Wortzahl-Prüfung: Weicht die Wortzahl eines Abschnitts um mehr als 5 % ab, gibt es eine Warnung (mögliche Auslassungen oder Ergänzungen).
- 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:
# 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 Glossarramstein.glossar.txt)magdeburg.de-orig.*: Rede in Magdeburg (mit Glossarmagdeburg.glossar.txt)Lahnstein.de-orig.*: Rede „Respekt geht anders“ in Lahnstein (noch ohne Glossar, geladen mityt_untertitel.py)
./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
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_extract_text.py prüft den Gesamtablauf URL → Text, Sprachwahl
(Original-Audio, manuell vor automatisch) und Fehlerfälle.
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 (auch per -m), 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 (Standard für -m) |
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:32bohne 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.pyerkennt 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.