Nommer la nourriture dans six langues : ce que nous avons appris
Traduire des noms d'aliments n'est pas un problème de dictionnaire, mais culturel. Ce que nous avons appris en localisant 845+ aliments dans 6 langues pour le catalogue Vnutri.

Chaque nom d'aliment dans Vnutri est traduit en 6 langues : en, es, ca, fr, de, ru. Soit ~5 000 chaînes uniques (845 aliments × 6 langues). Quand on a commencé, ça ressemblait à un problème de dictionnaire — trouver un glossaire et passer le catalogue dans un traducteur. Trois mois plus tard, autre conclusion : traduire des noms d'aliments n'est pas un problème de dictionnaire.
Pourquoi la traduction directe échoue
Trois raisons.
1. Un nom n'est pas une description. « Pollock » en anglais est un poisson. En russe, « минтай ». Google Translate donne « поллок » (translittération phonétique), parce qu'il ne sait pas que le mot nomme un poisson. Savoir lequel demande de la connaissance de catégorie, pas une traduction littérale.
2. Les variétés sont régionales. La pomme Honeycrisp est courante aux US. En Europe, elle est rare. Granny Smith — l'inverse. Quand je dis « apple » en anglais, je pense implicitement à une variété américaine moyenne ; « pomme » en français, à une variété française moyenne. Des fruits physiquement différents avec des profils nutritionnels proches mais pas identiques.
3. Vocabulaire régional. « Eggplant » (US) = « aubergine » (UK) = « berenjena » (ES) = « albergínia » (CA) = « aubergine » (FR) = « Aubergine » (DE) = « баклажан » (RU). Déjà deux conventions à l'intérieur de l'anglais. Idem pour « zucchini » / « courgette ».
Et le pire — les noms scientifiques. « Salmo salar » désigne le saumon atlantique. La plupart des traducteurs gardent le latin (« Anguilliformes » au lieu de « anguille ») parce qu'ils ignorent ce qui est désigné.
Trois couches de localisation
Nous avons construit un pipeline en trois couches, chacune moins chère que la précédente, mais moins précise dans les cas rares.
Couche 1 : taxonomie d'ingrédients OFF
La taxonomie des ingrédients d'Open Food Facts est un dictionnaire multilingue curé d'aliments. 4 212 entrées sur 100+ langues chacune. Licence ODbL.
Taux d'appariement : ~70 % du catalogue. Première passe, la moins chère.
Match par niveaux :
- Direct (apple → apple) → traduction.
- Au singulier (apples → apple) → traduction.
- Sous-clé à 2 tokens triés (black beans → beans + black) → traduction.
- Sous-clé inversée (beans black → black beans) → traduction.
- Nom de tête (chocolate dark → chocolate) → traduction (avec prudence).
Sur un match — on prend les noms tout faits d'OFF sur les 6 langues. Qualité excellente : OFF est curé, les faux positifs sont quasi impossibles.
Couche 2 : Wikidata
Pour les ~30 % restants — Wikidata via l'API wbsearchentities. Sélecteur en niveaux avec filtres P31 (instance d'aliment).
- Match exact de label/alias + signal d'aliment dans description/P31.
- Chevauchement par substring + mot-clé d'aliment fort (
vegetable,fish,meat). P31dans liste blanche d'aliments (Q2095 food,Q3314483 cultivar,Q502163 fruit).- Description qui matche un regex large d'aliment.
À l'intérieur d'un niveau on trie par realTranslationCount — ça écarte les binômes scientifiques copiés sans changement dans chaque langue.
Taux d'appariement : ~25 % supplémentaires. Mis en cache. Nous nous sommes arrêtés autour de 476 aliments — les limites de rate non authentifiées de Wikidata coupent le crawling.
Couche 3 : Google Cloud Translation v3 (Translation LLM)
Passe finale. Modèle general/translation-llm en us-central1. Ce n'est pas du NMT (traduction automatique neuronale) classique — le Translation LLM est meilleur pour les noms d'aliments avec état.
Pourquoi le LLM bat le NMT :
- Accord en genre. « cooked adzuki beans » → espagnol : « judías adzuki cocidas » ✓ féminin pluriel. NMT met « cocido » par défaut, faux. Le LLM voit le nom dans la même chaîne et applique l'accord correct.
- Vocabulaire idiomatique. « pollock » → russe : NMT donne « поллок » ; LLM donne « минтай ». « cloudberry » → français : NMT renvoie « cloudberry » ; LLM donne « mûre des marais ».
Coût — 80 $/M chars (vs 20 $ NMT). Pour 5 000 × 30 caractères × 5 langues non-EN ≈ 60 $ par exécution complète. Mis en cache par (phrase, langue).
Après la passe LLM — table de fixes hardcoded pour 13 hallucinations attrapées en revue manuelle.
Pièges concrets
Ce qu'on a appris à la dure.
Marques. « Blackberry » en anglais est une baie. Le LLM le traduit parfois en « BlackBerry » (le téléphone) en espagnol. Fix : une liste de blocage de marques codée en dur.
Abréviations. « fig » (figue) — le LLM en allemand a donné « Abb. » et en russe « рис. » (pensant qu'il s'agissait de « figure » dans un tableau). Le mot était hors contexte, et le LLM a choisi la lecture statistiquement courante « fig. » (abréviation de figure).
Binômes passifs-agressifs. Wikidata stocke souvent les noms latins comme label principal (« Anguilliformes » pour « anguille »). Si ces binômes sont copiés comme « traductions », 100+ langues finissent avec la même chaîne latine — ça ressemble à « beaucoup de traductions » mais c'est une seule. Un filtre sur realTranslationCount (chaînes distinctes entre langues) supprime ces cas.
Inversions verbe/nom. « skate » en anglais est un poisson (raie). Le LLM en russe a donné « кататься на коньках » (patiner). Le contexte « 100 g skate » n'a pas aidé.
Effet sushi. Mots japonais empruntés par la plupart des langues européennes. « Tofu », « miso », « sushi », « edamame » — restent tels quels dans les 6 langues. On ne les traduit pas.
Suffixe d'état
Un problème à part — l'état. « apple cooked » → en français : « pomme cuite » (accord en genre féminin). Le LLM le gère, mais seulement si la virgule est transformée en préfixe adjectif avant envoi : « apple, cooked » → « cooked apple » → « pomme cuite ».
Sinon, le LLM traduit la forme avec virgule littéralement en « pomme, cuite », un calque de l'anglais grammaticalement bancal.
C'est une transformation hardcoded avant l'appel LLM. Forme avec virgule → groupe nominal naturel → LLM → groupe nominal naturel dans la langue cible.
Ordre des mots par langue
L'anglais place l'adjectif avant le nom : « red apple ». Le français après : « pomme rouge ». L'espagnol — généralement après (« manzana roja »), parfois avant (« buena manzana »). Le catalan — presque toujours après.
La traduction directe garde l'ordre de la langue source. Cela donne des résultats étranges sur des noms composés longs : « raw black beans » → « haricots noirs crus » (correct) vs « crus haricots noirs » (incorrect).
Une passe finale de reorder (Claude Sonnet, mise en cache) parcourt chaque langue et réécrit les noms en forme nom-d'abord. C'est une étape à part du pipeline.
On n'écrit pas halal/kasher
Ce sont des certifications de processus, pas du produit lui-même. « Fromage kasher » n'est pas le même fromage qu'un fromage ordinaire (exigences de production différentes). Vnutri n'étiquette pas les produits comme halal/kasher — ce n'est pas une propriété du produit, mais du processus de production. Voir les 9 régimes expliqués.
Couverture
Après les trois couches du pipeline :
- en — 100 % (canonique)
- es — 95 %
- ca — 90 %
- fr — 94 %
- de — 92 %
- ru — 89 %
Le reste — là où le nom n'existe ni dans OFF ni dans Wikidata, et où le LLM a sorti quelque chose d'incorrect. On corrige à la main dans name-overrides.json.
Ce qu'on ne fait pas
- Pas de traduction des marques. Si le nom contient une marque, il reste tel quel.
- Pas de liberté pour le LLM. Chaque traduction est confrontée à OFF/Wikidata quand on a un point de donnée.
- Pas de NMT. Seulement Translation LLM ou taxonomie curée.
Problèmes ouverts
Variétés régionales. « Apple » — au catalogue, c'est une pomme moyenne. L'utilisateur russe pense antonovka ou gala ; l'américain à Honeycrisp ou Red Delicious. Fruits physiquement différents avec une nutrition proche mais pas identique.
Plats locaux. Pelmeni, borscht, kasha — mots qui existent dans chaque langue mais désignent des plats physiquement légèrement différents. Vnutri utilise généralement le nom source avec une translittération anglaise comme ancre.
Translittérer vs traduire. « Sushi » en allemand est « Sushi ». « Sushi » en russe est « суши ». « Pizza » en allemand est « Pizza ». « Pizza » en russe est « пицца ». Quand translittérer vs traduire — pas de règle dure, on suit la convention.
En savoir plus
Architecture du catalogue — d'où viennent nos données. Détails d'implémentation — dans le dossier apps/scripts/ du dépôt.
Références
- Open Food Facts. Ingredients Taxonomy. https://github.com/openfoodfacts/openfoodfacts-server/tree/main/taxonomies/food
- Wikidata Foundation. Wikidata Query Service. https://query.wikidata.org/
- Google Cloud. Cloud Translation API v3 documentation. 2024.
- Wood AJ, Lengyel P, et al. Multilingual neural machine translation: research and product. Trans Assoc Comput Linguist. 2020.