[Optimierungs-Review] Was hat das YouDub-Übersetzungsmodul an diesem ganzen Tag gemacht, welche Richtungen sind wirksam, welche bereits widerlegt
Das Hauptschlachtfeld dieses Tages war eigentlich nicht TTS, sondern das Übersetzungsmodul.
Der Grund ist sehr direkt: Beim Voiceover-Modul kann man später ohnehin auf eine Lösung wechseln, die näher an der Zielstimme liegt, aber im fertigen Video ist die offensichtlichste Schwachstelle weiterhin, dass die Untertitelübersetzung selbst nicht genug wie ein ausgereiftes Bilibili-Endprodukt wirkt, insbesondere:
- In Rolling-Caption-Szenen „klaut“ der vorherige Satz Informationen aus dem nächsten Satz.
- Die englischen Originaluntertitel sind fragmentiert; sobald man ins Chinesische starr zeilenweise übersetzt, wird es lang und holprig.
- Wenn man zu sehr darauf aus ist, „Sätze zu vervollständigen“, verrät man Punchline, Nomen oder Aktionen, die erst später kommen, zu früh.
- Wenn man zu sehr darauf aus ist, „Fragmentgrenzen beizubehalten“, wird das Chinesische wieder zu fragmentiert und sieht nicht wie echte Endprodukt-Untertitel aus.
Darum habe ich in dieser Optimierungsrunde den Fokus von „ein bestimmtes Video fixen“ auf „ein generalisierbares Framework für Übersetzungsbewertung und Iteration bauen“ verlagert.
Was wurde an diesem Tag konkret gemacht
1. Erst das Baselinesystem aufbauen, nicht mehr nach Gefühl tunen
Ich habe nicht weiter an einem einzelnen Video Zeile für Zeile herumgeschraubt, sondern direkt die über neunzig Bilibili/YouTube-Abgleich-Samples aus C:\\Users\\1\\bili_yt_export\\bili_youtube_first100.csv als Benchmark genommen.
Dazu habe ich zwei Dinge gemacht:
scripts/benchmark_translation.pyerweitertscripts/analyze_translation_artifact.pyneu hinzugefügt
Ersteres ist dafür da, die komplette Kette aus Übersetzen + Satzsegmentierung + Voiceover-Text-Umschreiben im Batch durchlaufen zu lassen und für jeden Case Metriken sowie Zwischenartefakte auszugeben.
Letzteres ist dafür da, jeden Case auseinanderzunehmen und anzuschauen, insbesondere diese Ebenen:
source_rowsprepared_source_rowstranslated_rows_pre_splitpredicted_rowsreference_rows
Dieser Schritt ist extrem wichtig, weil viele Probleme später nicht durch Post-Processing entstehen, sondern weil das LLM bereits in translated_rows_pre_split Inhalte aus späteren Zeilen „ausleiht“.
2. Das Kernproblem klar lokalisiert: Rolling-Caption leiht aus dem Folgekontext
Der größte Gewinn dieses Tages war nicht, dass irgendeine Metrik plötzlich explodiert ist, sondern dass das Hauptproblem präzise lokalisiert wurde:
In YouTube Auto-Untertiteln/offiziellen Untertiteln ist sehr viel Rolling-Caption-Struktur; viele Zeilen sind ursprünglich halbe Sätze, Restsätze oder über Zeilen hinweg fortgeführte Sätze.
Wenn man das Modell einfach „zeilenweise natürlich übersetzen“ lässt, tendiert es stark dazu, Informationen aus den nächsten ein bis zwei Zeilen in die aktuelle Zeile hineinzuziehen—dadurch wirkt das Chinesische flüssiger, aber auf der Timeline wird vorzeitig gespoilert.
Dieses Problem ist in den beiden Hard Cases zwIqbrD6JX4 und o2V-JJpJH_I am offensichtlichsten.
3. fragment_guard zur Default-Hauptlinie gemacht
Auf Basis der obigen Erkenntnisse habe ich fragment_guard standardmäßig eingeschaltet.
Die Kernidee ist nicht, „Chinesisch zwangsweise kaputt zu schreiben“, sondern dem Modell klare Limits zu setzen:
- Die aktuelle id darf nur die Semantik ausdrücken, die in der aktuellen Quellzeile bereits vorkommt.
- Wenn die Quellzeile offensichtlich ein unvollständiges Rolling-Caption-Fragment ist, ist es besser, das Chinesische minimal offener zu lassen, als zukünftigen Inhalt vorzeitig zu vervollständigen.
Das ist derzeit die einzige Änderung, die stabil als wirksam bewiesen ist und die ich bereit bin, als Default in die Hauptlinie zu übernehmen.
Aktuell bestätigte wirksame Ergebnisse
Hauptlinien-Konfiguration
Die aktuell stabile Hauptlinie ist grob:
- provider:
openai_context - api base:
http://192.168.10.88:8317/v1 - model:
gpt-5.4-mini - prompt profile:
auto_hybrid - temperature:
0 - fewshot:
8 fragment_guard=on- Alle übrigen Experiment-Schalter standardmäßig aus
Bestätigte Verbesserungen in Zahlen
fragment_guard ist von lokalen Experimenten bis hin zu mittleren Samples durchweg ein positiver Effekt:
- 4-Case-Vergleich:
52.432 -> 53.322 - 8-Case-Vergleich:
55.958 -> 56.058
Aktueller 8-Case-Hauptlinienreport:
- composite:
56.058 - chrF:
0.3707 - char F1:
0.7729 - density MAE ratio:
0.4272
Das zeigt, dass die aktuelle Hauptlinie zumindest weniger dazu neigt, Folgekontext vorzeitig „auszuleihen“, und der Gesamtrhythmus auch näher an der Verteilung von Bilibili-Endprodukt-Untertiteln liegt.
Welche Richtungen an diesem Tag im Wesentlichen widerlegt wurden
1. fragment_hints global einschalten
Es ist nicht völlig nutzlos—im Gegenteil, in manchen Cases ist es sehr stark.
Zum Beispiel:
zwIqbrD6JX4steigt in hard2 von54.439auf57.980VT6rLcVKhzghat ebenfalls eine deutliche Verbesserung
Aber das Problem ist die Instabilität.
Auf 8 Cases fällt das Gesamtergebnis stattdessen von 56.058 auf 55.296.
Das heißt: Es ist eher ein „starkes Medikament für bestimmte Strukturen“ und keine Strategie, die man aktuell standardmäßig einschalten kann.
2. auto_hybrid_v2
Ich habe eine aggressivere Profile-Autoselektionslogik gebaut, die verschiedene Videos automatisch zwischen literal_context / bilibili_dub / bilibili_pacing umschalten lassen soll.
Ergebnis: In 8 Cases fällt es direkt auf 54.375, schlechter als die aktuelle Hauptlinie 56.058.
Die Schlussfolgerung ist simpel: Die Gating-Logik ist noch nicht präzise genug, aktuell nicht reif für die Hauptlinie.
3. Den Umfang der Volltextübersetzung zwanghaft vergrößern
Ich habe zwei Richtungen probiert:
- Den Full-Context-Schwellenwert erhöhen, sodass mehr Videos in einem Rutsch komplett übersetzt werden
- Chunks von einem kleinen Fenster direkt deutlich vergrößern
Auf den ersten Blick wirkt es näher an „erst den ganzen Text verstehen, dann übersetzen“, aber in der Praxis gab es keinen stabilen Zugewinn.
Der Grund: Mit mehr Kontext wird es für das Modell auch leichter, über ids hinweg Inhalte zu leihen; die Timeline kann am Ende sogar unordentlicher werden.
4. Die Chunk-Granularität extrem fein machen
Zum Beispiel die Idee chunk_max_items=2: Intuitiv reduziert das Satzverkettungen, aber der reale Gewinn ist schlecht und es wird deutlich langsamer.
Die hard2-Ergebnisse brachten keine Qualitätsverbesserung, aber die Latenz stieg stark an—besonders o2V-JJpJH_I zieht es sehr.
5. Den „Bilibili-Stil-Prompt“ maximal aufdrehen
Ich habe getestet:
literal_contextbilibili_dubbilibili_pacingauto_hybrid
In mixed4 ist auto_hybrid am besten, literal_context danach; die beiden stärker „stilisierten“ Profile sind sogar schlechter.
Das zeigt: Es geht derzeit nicht darum, „je mehr es wie Bilibili klingt, desto besser“, sondern zuerst müssen Kontextgrenzen, Fragment-Sätze und Timing-Ausrichtung gelöst werden—Stil kommt danach.
Die wichtigste Erkenntnisänderung dieses Tages
Ich dachte ursprünglich, das größte Problem sei „die Sätze sind nicht idiomatisch genug übersetzt“, aber das stimmt nicht.
Das tieferliegende Problem ist eigentlich:
- Der Input ist a priori schon fragmentiert
- Zwischen den Fragmenten gibt es starke Überlappung
- Damit Chinesisch natürlich wirkt, muss man moderat Tonfall und Struktur ergänzen
- Aber sobald man zu viel ergänzt, verrät man zukünftige Inhalte vorzeitig
Darum ist die schwierigste Stelle im Übersetzungsmodul nicht „Chinesisch→Englisch“ oder „Englisch→Chinesisch“ an sich, sondern:
Unter der Prämisse, Zeitgrenzen nicht zu überschreiten, fragmentiertes Englisch zu einem chinesischen Rhythmus zu ordnen, der wie echte Endprodukt-Untertitel wirkt.
Das ist nicht dasselbe Problem wie gewöhnliche maschinelle Übersetzung.
Punkte, die noch nicht gelöst sind
Auch wenn die Hauptlinie stabiler ist als zuvor, ist sie noch weit von meinem Ziel entfernt—insbesondere hat sie noch nicht die Fertigungsqualität der Bilibili-Beispiele erreicht, die du gegeben hast.
Aktuell klar noch ungelöst:
- In manchen Hard Cases wird weiterhin Folgekontext „ausgeliehen“
- In manchen Cases klingt das Chinesische noch nach „Übersetzungston“
- Nach dem Split ist das Längen-Matching noch nicht stabil genug
- Für
fragment_hintswurde noch keine stabile Gating-Bedingung gefunden - Die Anzahl und Auswahl der Few-Shot-Beispiele ist noch nicht optimal eingestellt
Nächste Schritte, die sich aus meiner Sicht am meisten lohnen
Am sinnvollsten ist derzeit nicht, noch mehr „mystische“ Prompts draufzupacken, sondern diese drei Dinge:
1. Feature-Gating für fragment_hints bauen statt globaler Schalter
Man weiß bereits, dass es in manchen Cases stark wirkt.
Der nächste Schritt sollte sein, anhand dieser Features zu gaten:
- fragmentary source ratio
- overlap ratio
- punctuated source ratio
- short/tiny line ratio
Also nur bei Videos mit „hoher Fragmentierung, viel Rolling Caption“ aktivieren—nicht global mit dem Beil.
2. Weiter die Few-Shot-Anzahl verifizieren
Ein kleines Signal am Ende des Tages war: fewshot=4 zeigte in hard2 erstmals einen kleinen Netto-Zugewinn:
- baseline hard2:
50.454 - fewshot=4 hard2:
50.600
Der Zugewinn ist nicht groß, aber die Richtung ist positiv.
Wenn mixed4 und mid8 das ebenfalls halten, deutet das darauf hin, dass die aktuellen 8 Few-Shots möglicherweise eher zu viel Rauschen reinbringen.
3. Weiter an Chunk-Context arbeiten: „nur Kontext geben, aber keine Übersetzungsberechtigung“
Ich habe bereits eine Version mit Kontextfenstern vor/nach dem Chunk ergänzt, aber derzeit ist das noch experimentell.
Der Wert dieser Richtung ist:
- Dem Modell Verständnis für den Gesamtabschnitt geben
- Gleichzeitig dennoch verlangen, dass es nur die ids des Ziel-Chunks ausgibt
Das ist theoretisch besser geeignet als simples Chunk-Vergrößern, um „den ganzen Text zu verstehen, aber nicht über Grenzen zu gehen“.
Fazit dieses Tages
Wenn man es in einem Satz zusammenfasst:
Der größte Erfolg dieses Tages war nicht, das Übersetzungsmodul fertig zu bauen, sondern klar herauszuarbeiten, „warum dieses Problem schwer ist, wo der Hauptengpass liegt, welche Richtungen wirken und welche es nicht mehr wert sind, weiter Zeit zu verbrennen“.
Jetzt ist zumindest klar:
- Das Übersetzungsproblem dieses Projekts ist im Kern nicht gewöhnliches MT
- Rolling-Caption-Grenzen sind der Hauptwiderspruch
fragment_guardist aktuell der einzige stabile positive Hebelfragment_hintshat Potenzial, muss aber gegatet werden- Few-Shot- und Kontextstrategie lohnen sich weiter zu vertiefen
Wenn man diese Toolchain später wirklich in Richtung „beste fremdsprachige Videoübersetzung und -synchronisation der Welt“ schleifen will, kann das Übersetzungsmodul als Nächstes nicht mehr per Bauchgefühl über Prompt-Tuning laufen, sondern muss weiter entlang benchmark-getrieben, Case-Attribution, dann kleine A/B-Schritte vorwärtsgehen.
Heute wurde zumindest dieser Weg geebnet.