Metodologia6 min de lectura

Anomenar aliments en sis idiomes: el que vam aprendre

Traduir noms d'aliments no és un problema de diccionari, sinó cultural. El que vam aprendre localitzant 845+ aliments a 6 idiomes per al catàleg de Vnutri.

La paraula 'apple' en sis idiomes en una pàgina — apple, manzana, poma, pomme, Apfel, яблоко

Cada nom d'aliment a Vnutri està traduït a 6 idiomes: en, es, ca, fr, de, ru. Són ~5 000 cadenes úniques (845 aliments × 6 idiomes). Quan vam començar, semblava un problema de diccionari — trobar un glossari i passar el catàleg per un traductor. Tres mesos després, una altra conclusió: traduir noms d'aliments no és un problema de diccionari.

Per què la traducció directa falla

Tres motius.

1. Un nom no és una descripció. "Pollock" en anglès és un peix. En rus, "минтай". Google Translate dóna "поллок" (transliteració fonètica), perquè no sap que el terme nomena un peix. Saber de quin peix es tracta exigeix coneixement de categoria, no traducció literal.

2. Les varietats són regionals. La poma Honeycrisp és d'ús diari als EUA. A Europa és rara. Granny Smith — al revés. Quan dic "apple" en anglès penso implícitament en una varietat mitjana estatunidenca; "poma" en català, una varietat mitjana catalana. Fruits físics diferents amb nutricions properes però no idèntiques.

3. Vocabulari regional. "Eggplant" (US) = "aubergine" (UK) = "berenjena" (ES) = "albergínia" (CA) = "aubergine" (FR) = "Aubergine" (DE) = "баклажан" (RU). Ja dues convencions dins l'anglès. El mateix amb "zucchini" / "courgette".

I el pitjor cas — els noms científics. "Salmo salar" és salmó atlàntic. La majoria de traductors manté el llatí ("Anguilliformes" en lloc d'"anguila") perquè no sap a què es refereix.

Tres capes de localització

Vam muntar un pipeline de tres capes, cadascuna més barata que l'anterior, però menys precisa en casos rars.

Capa 1: taxonomia OFF d'ingredients

La taxonomia d'ingredients d'Open Food Facts és un diccionari multilingüe curat d'aliments. 4 212 entrades en 100+ idiomes cadascuna. Llicència ODbL.

Taxa de match: ~70 % del catàleg. Primera i més barata passada.

Match per nivells:

  1. Directe (apple → apple) → traducció.
  2. Singularitzat (apples → apple) → traducció.
  3. Subclau de 2 tokens ordenats (black beans → beans + black) → traducció.
  4. Subclau invertida (beans black → black beans) → traducció.
  5. Substantiu principal (chocolate dark → chocolate) → traducció (amb cautela).

Amb un match — traiem els noms ja fets d'OFF en els 6 idiomes. Qualitat excel·lent: OFF està curat, els falsos positius són gairebé impossibles.

Capa 2: Wikidata

Per al ~30 % restant — Wikidata via API wbsearchentities. Selector per nivells amb filtres P31 (instància d'aliment).

  1. Match exacte de label/àlies + senyal d'aliment a descripció/P31.
  2. Solapament per substring + paraula clau d'aliment (vegetable, fish, meat).
  3. P31 en llista blanca d'aliments (Q2095 food, Q3314483 cultivar, Q502163 fruit).
  4. Descripció que matcha regex àmplia d'aliment.

Dins de cada nivell ordenem per realTranslationCount — filtra binomis científics copiats sense canvi a cada idioma.

Taxa de match: ~25 % addicional. Cacheat. Es va aturar al voltant de 476 aliments — els límits de rate sense autenticació de Wikidata tallen el crawling.

Capa 3: Google Cloud Translation v3 (Translation LLM)

Passada final. Model general/translation-llm a us-central1. No és NMT (traducció automàtica neuronal) — el Translation LLM va millor per a noms d'aliments amb estat.

Per què l'LLM guanya al NMT:

  • Concordança de gènere. "cooked adzuki beans" → espanyol: "judías adzuki cocidas" ✓ femení plural. NMT posa "cocido" per defecte, malament. L'LLM veu el substantiu a la mateixa cadena i aplica el gènere correcte.
  • Vocabulari idiomàtic. "pollock" → rus: NMT dóna "поллок"; LLM dóna "минтай". "cloudberry" → francès: NMT retorna "cloudberry"; LLM dóna "mûre des marais".

Cost — $80/M chars (vs $20 NMT). Per a 5 000 × 30 caràcters × 5 idiomes no-EN ≈ $60 per passada completa. Cacheat per (frase, idioma).

Després de la passada de l'LLM — taula fixa de fixes per a 13 al·lucinacions detectades amb revisió manual.

Trampes concretes

El que vam aprendre pel camí.

Marques. "Blackberry" en anglès és una baia. L'LLM de vegades la tradueix a "BlackBerry" (el mòbil) en espanyol. Fix: llista de bloqueig de marques hardcoded.

Abreviatures. "fig" (figa) — l'LLM en alemany va donar "Abb." i en rus "рис." (pensant que era "figure" en una taula). La paraula estava fora de context i l'LLM va triar el significat estadísticament comú "fig." (abreviatura de figure).

Binomis passiu-agressius. Wikidata guarda sovint noms llatins com a label principal ("Anguilliformes" per a "anguila"). Si aquests binomis es copien com a "traduccions", 100+ idiomes acaben amb la mateixa cadena llatina — sembla "moltes traduccions" però és una sola. Un filtre per realTranslationCount (cadenes diferents entre idiomes) elimina aquests casos.

Canvis verb/substantiu. "skate" en anglès és un peix (rajada). L'LLM en rus va donar "кататься на коньках" (patinar). El context "100 g skate" no va ajudar.

Efecte sushi. Paraules japoneses agafades per la majoria d'idiomes europeus. "Tofu", "miso", "sushi", "edamame" — es queden tal qual en els 6 idiomes. No les traduïm.

Sufix d'estat

Un problema a part — l'estat. "apple cooked" → en català: "poma cuita" (concordança de gènere femení). L'LLM ho resol, però només si la coma es transforma en prefix adjectiu abans d'enviar: "apple, cooked" → "cooked apple" → "poma cuita".

Si no, l'LLM tradueix la forma amb coma literalment com "poma, cuita", calc de l'anglès i gramaticalment estrany.

És un transform hardcoded abans de la crida a l'LLM. Forma amb coma → frase nominal natural → LLM → frase nominal natural en l'idioma destí.

Ordre de paraules per idioma

L'anglès posa l'adjectiu abans del substantiu: "red apple". El francès després: "pomme rouge". L'espanyol — normalment després ("manzana roja"), a vegades abans ("buena manzana"). El català — gairebé sempre després.

La traducció directa manté l'ordre de l'idioma font. Això dóna resultats estranys amb noms compostos llargs: "raw black beans" → "fesols negres crus" (correcte) vs "crus fesols negres" (incorrecte).

Una passada final de reorder (Claude Sonnet, cacheada) recorre cada idioma i reescriu els noms en forma noun-first. És una etapa pròpia del pipeline.

No escrivim halal/kosher

Són sobre certificació de procés, no sobre l'aliment en si. "Formatge kosher" no és el mateix formatge que el normal (requisits de producció diferents). Vnutri no etiqueta productes com a halal/kosher — no és propietat de l'aliment, sinó del procés de producció. Veure 9 dietes explicades.

Cobertura

Després de les tres capes del pipeline:

  • en — 100 % (canònica)
  • es — 95 %
  • ca — 90 %
  • fr — 94 %
  • de — 92 %
  • ru — 89 %

La resta — on el nom simplement no està a OFF/Wikidata i l'LLM va donar quelcom incorrecte. S'arreglen a mà a name-overrides.json.

El que NO fem

  • No traduïm marques. Si el nom porta marca, es queda tal qual.
  • No donem llibertat a l'LLM. Cada traducció es verifica contra OFF/Wikidata on hi ha data point.
  • No fem servir NMT. Només Translation LLM o taxonomia curada.

Problemes oberts

Varietats regionals. "Apple" — al catàleg és una poma mitjana. L'usuari rus pensa en antonovka o gala; l'estatunidenc en Honeycrisp o Red Delicious. Fruits físics diferents amb nutrició propera però no idèntica.

Plats locals. Pelmeni, borscht, kasha — paraules que existeixen en cada idioma però referencien plats físics lleugerament diferents. Vnutri sol fer servir el nom d'origen amb transliteració anglesa com a àncora.

Transliterar vs traduir. "Sushi" en alemany és "Sushi". "Sushi" en rus és "суши". "Pizza" en alemany és "Pizza". "Pizza" en rus és "пицца". Quan transliterar vs traduir — sense regla dura, anem per convenció.

Més

Arquitectura del catàleg — d'on surten les nostres dades. Detalls d'implementació — al directori apps/scripts/ del repo.

Referències