Zum Hauptinhalt springen

Evolutionäre / suchbasierte Übersetzung

Die Grundidee: Mehrere Übersetzungskandidaten erzeugen, sie anhand einer Fitnessfunktion bewerten (chrF++, FST-Akzeptanz, Round-Trip-Konsistenz), die besten Kandidaten mutieren und wiederholen. Natürliche Selektion für Übersetzungen — die am besten geeigneten überleben.

:::info Dies ist ein Kochbuch, keine fertige Implementierung Dies ist der experimentellste Ansatz in der Kochbuch-Reihe. Er hat sich für MT in großem Maßstab noch nicht bewährt, aber die Architektur ist solide, und das Harness bewertet bereitwillig, was auch immer es produziert. :::

Wann sollten Sie diesen Ansatz verwenden

  • Sie verfügen über eine gute Bewertungsfunktion, aber kein einzelnes Modell liefert konsistente Ergebnisse
  • Sie möchten den Lösungsraum breiter erkunden als bei einer einzelnen Greedy-Generierung
  • Sie verfügen über Rechenbudget für viele parallele Generierungen (Dutzende Kandidaten pro Eingabe)
  • Sie interessieren sich für neuartige Forschung — dieser Ansatz ist für ressourcenarme MT noch wenig erforscht

Funktionsweise

[Generation 0] Generate N candidates (different models, temperatures, prompts)


[Score] Evaluate each candidate: chrF++, FST acceptance, fluency


[Select] Keep top K performers


[Mutate] Prompt an LLM: "improve this translation, fix these issues"


[Generation 1] Score again. Repeat for G generations.


[Output] Best-scoring candidate from final generation

Grundgerüst

async def evolutionary_translate(source, reference=None, generations=3, pop_size=8):
# Generation 0: diverse candidates
population = []
for model in ["gemini-2.5-pro", "gpt-4o", "claude-sonnet-4-6"]:
for temp in [0.3, 0.7, 1.0]:
candidate = await translate(source, model=model, temperature=temp)
population.append(candidate)

for gen in range(generations):
# Score each candidate
scored = [(c, score(c, reference)) for c in population]
scored.sort(key=lambda x: x[1], reverse=True)

# Select top K
survivors = [c for c, s in scored[:pop_size // 2]]

# Mutate: ask LLM to improve each survivor
mutants = []
for survivor in survivors:
mutant = await improve(source, survivor, feedback=scored[0])
mutants.append(mutant)

population = survivors + mutants

return max(population, key=lambda c: score(c, reference))

Gestaltung der Fitnessfunktion

Die Fitnessfunktion ist alles entscheidend. Optionen:

MetrikWas sie misstAutomatisiert?
chrF++ gegen ReferenzZeichenebene-Ähnlichkeit zum Goldstandard✅ Ja
FST-AkzeptanzrateMorphologische Validität✅ Ja (sofern FST verfügbar)
Round-Trip-KonsistenzStellt die Rückübersetzung die Quelle wieder her?✅ Ja
LLM-as-judgeEin weiteres LLM bewertet Sprachfluss/Genauigkeit✅ Ja (aber verrauscht)
Vorhandensein von WörterbuchbegriffenErscheinen bekannte Begriffe korrekt?✅ Ja

:::tip Kombinieren Sie mehrere Signale Eine gewichtete Kombination von Metriken ergibt eine robustere Fitnessfunktion als jede einzelne Metrik. Dies spiegelt den composite score des Harness selbst wider. :::

Vor- und Nachteile

✅ Erkundet vielfältige Lösungen❌ Rechenintensiv (N × G API-Aufrufe)
✅ Kann Ansätze entdecken, die kein einzelnes Modell findet❌ Erfordert eine gute Fitnessfunktion
✅ Parallelisierbar❌ Langsam — mehrere Generierungen pro Übersetzung
✅ Modellagnostisch❌ Abnehmender Ertrag nach einigen Generierungen

Lässt sich gut kombinieren mit

Siehe auch