Accéder au contenu principal

Traduction Évolutionnaire / Basée sur la Recherche

L'idée : Générer plusieurs traductions candidates, les évaluer par rapport à une fonction d'adaptation (chrF++, acceptation FST, cohérence aller-retour), muter les meilleurs performants, et répéter. Sélection naturelle pour les traductions — les plus aptes survivent.

:::info Ceci est un recueil de recettes, non une implémentation finalisée Ceci est l'approche la plus expérimentale de la série de recueils. Elle n'a pas été éprouvée pour la TA à grande échelle, mais l'architecture est solide et le harnais évaluera volontiers tout ce qu'elle produit. :::

Quand l'Utiliser

  • Vous disposez d'une bonne fonction d'évaluation mais aucun modèle unique ne produit des résultats cohérents
  • Vous souhaitez explorer l'espace des solutions plus largement qu'une génération gloutonne unique
  • Vous avez un budget de calcul pour de nombreuses générations parallèles (des dizaines de candidates par entrée)
  • Vous êtes intéressé par la recherche novatrice — cette approche est peu explorée pour la TA en ressources limitées

Comment Cela Fonctionne

[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

Squelette

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))

Conception de la Fonction d'Adaptation

La fonction d'adaptation est essentielle. Options :

MétriqueCe qu'elle MesureAutomatisée ?
chrF++ par rapport à la référenceSimilarité au niveau des caractères avec l'or✅ Oui
Taux d'acceptation FSTValidité morphologique✅ Oui (si FST disponible)
Cohérence aller-retourLa rétrotraduction récupère-t-elle la source ?✅ Oui
LLM-as-judgeUn autre LLM évalue la fluidité/exactitude✅ Oui (mais bruyant)
Présence de termes du dictionnaireLes termes connus apparaissent-ils correctement ?✅ Oui

:::tip Combinez plusieurs signaux Une combinaison pondérée de métriques crée une fonction d'adaptation plus robuste qu'une seule métrique. Cela reflète le score composite du harnais lui-même. :::

Avantages et Inconvénients

✅ Explore des solutions diverses❌ Coûteux en calcul (N × G appels API)
✅ Peut découvrir des approches qu'aucun modèle unique ne trouve❌ Nécessite une bonne fonction d'adaptation
✅ Parallélisable❌ Lent — plusieurs générations par traduction
✅ Agnostique au modèle❌ Rendements décroissants après quelques générations

S'Associe Bien Avec

Voir Aussi