Latimal Menu Intelligence

A model fluent in food

Food-domain AI for search, classification, cart upsell, matching, and dedup. The model reads dish names the same way across spellings, transliterations, and 100+ languages, treating “Margherita Pizza”, “Pizza Margherita”, “마르게리타 피자”, and “マルゲリータピザ” as one dish. The dedup demo below runs live; the rest of the toolkit is in the gallery further down.

Trained for food. Here is the proof.

Full benchmarks

Dedup F1 on the food benchmark suite. Latimal vs an off-the-shelf open-source stack (bge-m3 + bge-reranker-v2-m3).

Cross-lingual dedupSame dish across writing systems · F1
Latimal
0.83
bge-m3 + bge-reranker-v2-m3
0.26
Indian menu dedupCross-restaurant duplicate detection · F1
Latimal
0.92
bge-m3 + bge-reranker-v2-m3
0.75
Global cross-restaurant dedupDuplicate detection across world cuisines · F1
Latimal
0.82
bge-m3 + bge-reranker-v2-m3
0.80

Latimal: current production stack, benchmarked on 2026-05-22. Competitor: bge-m3 + off-the-shelf bge-reranker-v2-m3. Both run on the identical 26-benchmark snapshot.

Cross-script deduplication

Cluster duplicate menu items across spellings, transliterations, languages, and writing systems.

3601 msAPI
Example menus
15 items / 30 max

Paste your own menu above. The playground runs the first 30 items; the API itself handles up to 2,000 per call.

Nothing you paste in the playground is stored.

15 items
Cloudflare Turnstile verification
Loading verification…
15 items→4 dishes→11 duplicates removed
Seven scripts, one dish
Margherita Pizza written in Latin, Japanese, Korean, Arabic, Cyrillic, Chinese, and Thai, plus a typo, a promo tag, a portion tag, and a discount tag, all collapse into one cluster. Greek Salad, Buffalo Chicken Wings, and Chocolate Brownie stay separate. Keyword matching catches only the Latin variants and never crosses a writing system.
  • Canonical
    ENMargherita Pizza
    6 scripts
    • ENPizza Margherita
      0.969
    • ENMargherita Pizza (Large)
      1.000portion tag
    • EN**NEW** Margherita Pizza
      1.000promo stripped
    • ENMargerita Pizza
      0.838typo / spelling
    • ENMargherita Pizza 50% OFF
      0.916promo stripped
    • 日マルゲリータピザ
      0.565transliteration
    • 한마르게리타 피자
      0.567transliteration
    • عبيتزا مارغريتا
      0.620transliteration
    • ??Пицца Маргарита
      0.597
    • 中玛格丽特披萨
      0.536transliteration
    • ไทพิซซ่ามาร์เกอริต้า
      0.568transliteration
server 3601 ms

How other tools cluster the same menu

The exact items you just ran, clustered three ways. Latimal pulls the variants into one dish; the others do not.

Latimal
15 → 4 dishes, 11 duplicates found
ENMargherita Pizza
  • ENPizza Margherita
  • ENMargherita Pizza (Large)
  • EN**NEW** Margherita Pizza
  • ENMargerita Pizza
  • ENMargherita Pizza 50% OFF
  • 日マルゲリータピザ
  • 한마르게리타 피자
  • عبيتزا مارغريتا
  • ??Пицца Маргарита
  • 中玛格丽特披萨
  • ไทพิซซ่ามาร์เกอริต้า

3 items left unmerged

bge-m3 + bge-reranker-v2-m3
15 → 13 dishes, 2 duplicates found
ENMargherita Pizza
  • ENPizza Margherita
  • ENMargerita Pizza

12 items left unmerged

Keyword search (SQL ILIKE)
15 → 12 dishes, 3 duplicates found
ENMargherita Pizza
  • ENMargherita Pizza (Large)
  • EN**NEW** Margherita Pizza
  • ENMargherita Pizza 50% OFF

11 items left unmerged

Methodology

  • Latimal. The live result from this playground run: Latimal's food-domain dedup, union-find clustering at cosine 0.85.
  • bge-m3 + bge-reranker-v2-m3. Off-the-shelf open-source stack: bge-m3 embeddings re-scored by bge-reranker-v2-m3, then union-find clustering at cosine 0.85 (the same threshold Latimal uses). Computed offline on these exact items.
  • Keyword search (SQL ILIKE). Two items group only when one is a case-insensitive substring of the other, the SQL `ILIKE '%term%'` pattern. No model, no embeddings. This is what menu deduplication looks like without semantic understanding.
  • The comparison is shown on curated examples only. The baseline columns are pre-computed; the Latimal column is the live result from your run above.

Precision check

Merging duplicates is only half the job. The model also has to refuse to merge dishes that merely look alike. These three pairs run live against the match endpoint.

  • Cross-lingual merge
    ENButter ChickenENMurgh Makhani
    Same dishas expected
    cosine
    0.885
    reranker
    0.985

    Merged: the same North Indian curry known by its English name and its Hindi name.

  • Protein conflict
    ENChicken BiryaniENVeg Biryani
    Differentas expected
    cosine
    0.364
    reranker
    n/a

    Kept apart: same rice dish, but chicken and vegetable versions are distinct menu items.

  • Same style, different protein
    ENChicken Tikka MasalaENPaneer Tikka Masala
    Differentas expected
    cosine
    0.601
    reranker
    0.004

    Kept apart: identical preparation style, but chicken and paneer are different proteins.

Compare your own two items
vs

Use this in your app

The snippet below carries the exact menu you just ran. Public Latimal API, swap in your key.

curl -X POST https://dish-embed.latimal.com/dedup \
  -H "X-API-Key: $LATIMAL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "items": [
    "Margherita Pizza",
    "Pizza Margherita",
    "Margherita Pizza (Large)",
    "**NEW** Margherita Pizza",
    "Margerita Pizza",
    "Margherita Pizza 50% OFF",
    "マルゲリータピザ",
    "마르게리타 피자",
    "بيتزا مارغريتا",
    "Пицца Маргарита",
    "玛格丽特披萨",
    "พิซซ่ามาร์เกอริต้า",
    "Greek Salad",
    "Buffalo Chicken Wings",
    "Chocolate Brownie"
  ],
  "cosine_threshold": 0.85
}'

Run this on your full catalog

What you saw is a 15-item demo. The API clusters 2,000 items per call. Start a free trial, or send the founder your messiest menu.

The full menu intelligence toolkit

Semantic search, cuisine classification, cart upsell, and menu health, all powered by the same food-domain intelligence behind the dedup demo above. Open any tool to run it live.