OpenEuroLLM
Abhash Jha · Taskboard #186 · 5 Aug 2026
The setup
Everything in this talk starts from OLMo‑3‑7B‑Instruct‑SFT, reproduced from Dolci‑Instruct‑SFT. It's a solid instruction-following model — just an overwhelmingly English one.
Every result in this deck is "on this checkpoint" — we haven't tried these recipes anywhere else yet.
The risk we're managing
We keep training that checkpoint — same instruction-tuning recipe, new mixtures of English + EU-language examples. The open question every run has to answer: does English survive?
Strong, natural answers in German, French, Polish and more — while English stays exactly as good as it was.
English quietly drops — sometimes sharply — the moment you continue training on anything else. Catastrophic forgetting.
The plan, in order
What the earlier data sources taught us
Full numbers for Phases 0 & 1 are in the appendix.
Synthetic Data
A first version already trained and graded, and a second version — grounded in real-world context — now in progress.
Synthetic Data, version 1 · Taskboard #345
Each prompt draws a topic (11 topics, weighted — creative writing, QA, translation, math, summarization, and more), then — with a per-run probability — a persona (8 of them, e.g. "a non-native speaker still learning the language") and a constraint (15 templates, e.g. "respond in exactly N sentences," "must include the word X"). One call turns that combination into an instruction, a second generates the response.
Generator: google/gemma-4-31b-it (bf16), vLLM, TP=2 on Leonardo A100s. Back-translation ran on a pilot subset only — roughly doubling the cost of every example it touches, so it wasn't repeated at full production scale. Full axis tables and the back-translation methodology are in the appendix.
Synthetic Data, version 1 · results (Taskboard #186)
10 SFT runs — 5 English/EU mixtures × 2 scales — graded the same way as the earlier phases. Reading the 1M-scale sweep against the baseline:
1M-scale runs, winrate vs. baseline (Qwen3-30B-A3B judge). Overall Elo peaks at 767 (50% English, 1M, Qwen3.5-27B judge) — higher than the English-only run (725). Full 10-run table, 3-judge robustness check, and training hyperparameters are in the appendix.
Synthetic Data, the turn
Winrates climbed, but reading the actual generated pairs, the recipe wasn't there yet — a topic, a persona and a constraint are each sampled independently, so nothing stops them from landing on a combination nobody would really write.
→ "As a working professional on a tight deadline, write a short story that uses the letter q at least 5 times." Every axis checks out, the mechanical verifier passes it — but no one actually rushing to a deadline would impose an arbitrary letter-count on a short story.
"We also observed that the generated samples were not really high quality data and we need to improve the generation pipeline further."
Let the persona and the request follow from one real context, instead of sampling every axis independently — ground the whole prompt in a single situation.
Synthetic Data, version 2 · the plan
Sampling becomes hierarchical: first a domain family (local — needs country-specific knowledge — or general), then a specific domain within it, then a role and an intent that belong together. One call writes the instruction and response as a pair; an LLM judge replaces the mechanical checker.
| Sampling | Quality control | |
|---|---|---|
| v1 | topic × persona × constraint, independent | rule-based: language-ID + constraint checker |
| v2 | domain → role → intent, hierarchical | LLM judge: Qwen3.6-27B, holistic 0–10 score |
Goal: a dataset and a technique — hierarchical topic sampling plus an LLM-judge quality filter — for training multilingual instruction models, not just one more mixture.
Synthetic Data, version 2 · the procedure
State lives on disk at every stage, so a killed run just resumes: unfinished generate/judge calls pick back up by id, and the filter/dedupe steps recompute cheaply over everything accumulated so far.
Synthetic data, version 2 · what the models are actually asked
You are a native speaker and expert writer of
{lang}. Create ONE instruction + response.
Domain: {domain}
Diversity seed: {salt}
Suggested role: {role}
Suggested intent: {intent}
Instruction: native-fluent, realistic & self-
contained, genuinely non-trivial; any constraint
must be NATURAL and motivated (a real user would
actually ask for it).
Response: factually correct, no fabricated
claims; clearly explained, no padding.
Silently re-check before answering: does role /
intent / domain fit together naturally? Fix
anything that doesn't hold.
Output JSON only:
{{"instruction":"...","response":"...",
"role_used":"...","intent_used":"..."}}
You are a strict quality filter. Give ONE
holistic score 0-10, weighing whether the
TASK is worth training on AND how well the
RESPONSE executes it -- the WEAKER decides.
DISQUALIFYING (score 0-2 regardless of the
response): trivial trivia, a pointless /
unmotivated constraint, not a genuine request.
Otherwise, score the response by its single
worst flaw, not the sum of every small one:
9-10 excellent 7-8 good 5-6 fair
3-4 weak 1-2 poor 0 unusable
Output JSON only:
{{"score": <0-10>, "reason": "..."}}
Domain sampled by weight (e.g. estimated from LMArena traffic), not uniformly at random. Abridged — both prompts are longer in full. Source: synthgen/localized/prompts.py. Open question: the "diversity seed" is just an integer in the prompt text, not a true sampling seed — an LLM call has no real notion of one. Whether it nudges the model toward a less-obvious angle or does nothing is untested, worth discussing.
Where this sits among known recipes
Several well-known open recipes share the "generate, then filter" shape ours does — but differ in what they filter with, and none target multilingual grounding as a first-class axis.
| Recipe | Verification signal | Diversity mechanism |
|---|---|---|
| Ours (v2) | holistic LLM judge, 0–10 | hierarchical: domain (by real-world weight) → role → intent |
| OpenThoughts | rule-based — exact-match (math), execution (code) | seed-dataset sampling, ablated across question-generation methods |
| Tülu 3 | RLVR (verifiable rewards) + reward-model rejection sampling | persona-driven prompt synthesis |
| Phi‑4 | curation heuristics / classifiers ("textbook quality") | textbook-style seeding, targeted synthetic generation |
As documented in each project's public papers/repos — not independently re-verified by us, so treat this as directional. The throughline: none of these use a holistic per-example LLM-judge score as the primary keep/discard signal the way our v2 does, and none is built around multilingual grounding.
How the data sources compare so far
Same judge (Qwen3.5-27B), same five English/EU ratios, both v1 scales — only the EU data source differs: a translated EU-language mix (paired with English replay) vs. v1's native synthetic data.
v1 matches translation data at 100% English (no EU data yet, as expected) and pulls ahead at every other ratio, at both scales — most dramatically at 0% English, where v1 holds at 750–759 and translation data collapses to 677. 1M sits at or above 500k almost everywhere, confirming more data helps rather than just adding noise. Source: appendix.
The fairest single comparison
The 0%-English point makes v1 look like an outright win. But translation data's own declared sweet spot was 75/25 — so that's the fairest single ratio to compare at, and the picture there is more honest: v1 buys a lot of EU winrate, at some cost to English winrate. Overall Elo comes out close to a wash.
| Metric (at 75% English) | v1 (500k / 1M) | Translation data |
|---|---|---|
| Overall Elo | 752 / 755 | 747 |
| English winrate vs. baseline | 51.3% / 51.9% | 59.7% |
| EU winrate vs. baseline | 70.6% / 73.7% | 51.4% |
Overall Elo: Qwen3.5-27B, LMArena Bradley-Terry. Winrate: Qwen3-30B-A3B, vs. each track's own baseline. The Overall-Elo edge (752–755 vs. 747) is within bootstrap noise (±9–12) — at matched ratio, call it a tie on the blended metric and a clear tradeoff on the split one, not a clean win for either source.
Synthetic Data, version 2 · the core experiment
v1 already beats the translation-data baseline, and — checked under three independent judges — beats the Dolci-Translated models too (next slide). v2's job is to beat v1 itself: the same grounded, judge-filtered idea, minus the axis-independence problem.
What we want in the end isn't just a higher judge score — it's language that reads fluent and localized to a native speaker, which is why the judge and an eventual human read-through both matter.
Checked under three judges
To make sure the ranking isn't one judge's quirk, we re-scored baseline, two v1 configs — the more balanced 50en-1M and the most-multilingual 0en-1M — and the Dolci-Translated models under three independent judges.
Labels shown at the rightmost judge only, for clarity — full numbers in the appendix. Gemma judges score everything ~40–50 points lower than Qwen3.5 in absolute terms (an offset, not a re-ranking); compare within a judge, not across. Not evaluated under Qwen3.5-27B: Dolci-Translated. On every judge where both exist, v1 beats Dolci-Translated — and both v1 configs beat baseline under all three.
Synthetic Data v2 · trusting the new judge
We handed the judge examples we know are good, and examples we deliberately made bad — wrong answers, mixed-up languages, nonsense constraints — across 11 EU languages, and checked whether its scores actually separate the two, language by language.
Overall: 9.06 good vs. 2.22 bad (n≈108 each). Czech (cs) separates least cleanly of the eleven; wrong-answer bad examples are the hardest defect type — both worth another look.
Beyond this one checkpoint
Everything so far starts from one checkpoint. Once v2's core experiment is settled, the next question is whether the same recipe — hierarchical sampling plus a judge filter — helps on a different base model too.
Our own base model, once it has an annealed and length-extended checkpoint available. Not ready yet — this is the preferred target once it is.
Start with a checkpoint that's already available — Qwen3-8B-base or Apertus-8B-base — to check the recipe isn't just an OLMo/Dolci artifact.
Where things stand
v1 already matches or beats the translation-data baseline at every English/EU ratio — and by a wide margin at 0% English (750 vs. 677 overall Elo). Checked under three independent judges, it beats the Dolci-Translated models too. The open question is whether v2's grounding beats v1 itself — and whether the whole recipe holds up on a checkpoint that isn't OLMo-3-7B.
Next steps
Summary
v1's from-scratch synthetic data is trained and graded — matching or beating translation data at every ratio, and pulling decisively ahead once English drops to zero. At that baseline's own matched "sweet spot" ratio it's a real tradeoff, not a clean win. v2 grounds the same idea in hierarchical sampling and an LLM judge, and its judge is already validated. The core experiment left is v2 vs. every baseline we have — then trying the whole recipe on a different base model.
Taskboard #186 · #345 · questions welcome
Appendix
Terms defined · full early-experiment tables · v1 recipe & results in full · v2 tool layout · judge validation numbers · LUMI training config · references
Appendix · glossary
Appendix · what "Track A–G" actually means
The main slides avoid these labels and just describe what each source actually is (real/existing data, translation data, or our own synthetic data), but the underlying lab notebook names each experiment a Track, A through G. For anyone cross-referencing the source docs:
| Track | Question | Design |
|---|---|---|
| A | Does the English/EU ratio matter? | 90/80/70% English, ~95k samples, fusion-synth only, EU split equally across 8 languages |
| B | Does more diverse data help? | Same ratios, ~490k samples, fusion-synth + WildChat, LMSYS-Chat, OASST2 |
| C | Is the English regression caused by EU data, or by continued SFT itself? | 100% English control (no EU data at all), same total samples |
| D | Does replaying the base checkpoint's own English data reduce forgetting? | Same ratios as A, but English sourced from Dolci‑Instruct‑SFT (replay) instead of fresh English |
| E | Does Dolci replay scale with more data? | Same as D, but ~490k samples instead of ~95k |
| F | How do extreme English/EU ratios behave, with replay? | 100/75/50/25/0% English, ~500k samples, 6 EU languages, Dolci replay, EU data from fusion-synth (translation-based) — this is called "translation data" everywhere else in this deck |
| G | What if the EU data is native synthetic (v1) instead of translated? | Same design as F, but EU data comes from the v1 recipe (Taskboard #345) instead of fusion-synth; two scales, 500k and 1M, 11 EU languages — this is called "v1" / "synthetic data" everywhere else in this deck |
Tracks A–F predate this work (team effort); Track G is v1's training sweep, described throughout the main slides simply as "v1."
Appendix · full early-experiment matrix
| Exp. | En/EU | N | Elo | Elo en | Elo w/o en |
|---|---|---|---|---|---|
| Baseline | — | — | 741±9 | 950±21 | 722±10 |
| A1‑90en | 90/10 | 94.7k | 702±10 | 771±32 | 692±10 |
| A2‑80en | 80/20 | 93.6k | 704±11 | 769±30 | 703±11 |
| A3‑70en | 70/30 | 91.7k | 713±10 | 766±29 | 689±11 |
| B1‑90en | 90/10 | 491k | 720±9 | 789±26 | 708±10 |
| B2‑80en | 80/20 | 473k | 722±9 | 797±26 | 722±10 |
| C0‑100en | 100/0 | 94.7k | 670±11 | 791±29 | 681±11 |
| D1‑90en | 90/10 | 94.7k | 751±8 | 942±20 | 716±11 |
| D2‑80en | 80/20 | 93.6k | 751±8 | 956±20 | 725±12 |
| D3‑70en | 70/30 | 91.7k | 753±9 | 963±21 | 731±11 |
| E1‑90en | 90/10 | 491k | 758±9 | 965±21 | 740±9 |
| E2‑80en | 80/20 | 474k | 759±8 | 931±24 | 725±9 |
| E3‑70en | 70/30 | 455k | 751±9 | 940±22 | 726±9 |
| F1‑100en | 100/0 | 500k | 728±9 | 954±22 | 695±11 |
| F2‑75en | 75/25 | 486k | 747±10 | 947±22 | 711±10 |
| F3‑50en | 50/50 | 453k | 726±9 | 935±21 | 700±12 |
| F4‑25en | 25/75 | 359k | 739±9 | 912±22 | 685±11 |
| F5‑0en | 0/100 | 234k | 677±11 | 762±31 | 680±11 |
Elo: Qwen3.5‑27B judge, LMArena Bradley‑Terry, 100 bootstraps, 200 battles/lang · internal labels A–F refer to the team's six Phase‑0 experiment tracks · source: multilingual_eu_results.md
Appendix · v1 meta-prompt axes (Taskboard #345)
| Topic | weight |
|---|---|
| creative_writing | 0.15 |
| qa | 0.12 |
| translation | 0.10 |
| math | 0.08 |
| summarization | 0.08 |
| trivia / brainstorming | 0.07 each |
| roleplay | 0.06 |
| coding / data_analysis | 0.05 each |
| other | 0.17 |
Personas applied with probability persona_p — e.g. "a university student preparing for an exam," "a non-native speaker still learning the language."
Constraints applied with probability constraint_p — format (bullets, numbered, JSON), length (word/sentence counts), structure (headings, paragraphs), keyword include/exclude, casing. Casing and letter-frequency constraints are flagged not script-safe for non-Latin alphabets.
Axes defined in synthgen/config.py; topics can also be sampled empirically from WildChat via synthgen topics.
Appendix · v1 verification (Taskboard #345)
Back-translation QC: a sample of non-English generations was translated back to English by five independent reader models — DeepSeek-V3.2 (222 samples), Claude Sonnet 4.6 (250), Qwen-2.5-72B-Instruct (250), GPT-OSS-120B (243), Gemma-4-26B-it (800) — and read for meaning, register, and whether the constraint survived the round trip. This qualitative pass was the bar for approving the scale-up.
| Lang | Language-id acc. | Constraint compliance |
|---|---|---|
| es | 95.1% | 95.8% |
| fr | 97.3% | 96.3% |
| de | 97.5% | 97.0% |
| it | 94.5% | 97.7% |
| pt | 94.1% | 96.4% |
| pl | 96.3% | 96.2% |
| nl | 95.7% | 98.1% |
| cs | 95.4% | 95.4% |
| ro | 98.0% | 97.3% |
| el | 97.7% | 94.3% |
| uk | 94.4% | 93.4% |
source: Taskboard #345 comments
Appendix · Track G full results (Taskboard #186)
| Model | Scale | Overall Elo | EN Elo | W/O EN Elo | EN WR | EU WR | Track F ref |
|---|---|---|---|---|---|---|---|
| baseline | — | 723±12 | 956±46 | 679±22 | 50 | 50 | 741±9 |
| G1 100en | 500k | 723±12 | 961±46 | 677±23 | 49.2 | 47.0 | F1: 728±9 |
| G1 100en | 1M | 725±12 | 950±43 | 685±19 | 51.2 | 50.4 | F1: 728±9 |
| G2 75en | 500k | 752±12 | 970±46 | 712±22 | 51.3 | 73.7 | F2: 747±10 |
| G2 75en | 1M | 755±12 | 951±42 | 716±26 | 51.9 | 70.6 | F2: 747±10 |
| G3 50en | 500k | 757±12 | 946±42 | 723±18 | 47.4 | 76.0 | F3: 726±9 |
| G3 50en | 1M | 767±12 | 975±46 | 724±23 | 49.5 | 73.7 | F3: 726±9 |
| G4 25en | 500k | 757±12 | 964±45 | 716±23 | 47.3 | 79.6 | F4: 739±9 |
| G4 25en | 1M | 766±12 | 947±42 | 702±47 | 46.5 | 76.2 | F4: 739±9 |
| G5 0en | 500k | 750±12 | 925±42 | 713±23 | 44.1 | 75.8 | F5: 677±11 |
| G5 0en | 1M | 759±12 | 915±41 | 722±21 | 44.1 | 77.1 | F5: 677±11 |
LMArena-140k, 2204 battles, Qwen3.5-27B judge (Elo) & Qwen3-30B-A3B judge (WR). "Track F ref" is the matching-ratio Track F number from multilingual_eu_results.md — same ratio, different EU data source, so it's the direct comparison. Track G matches or beats it at every ratio, most dramatically at 0% English.
source: trackg-eval/REPORT.md; Taskboard #186 comments, 2026-07-13 & 2026-07-21
Appendix · Track G training configuration
OLMo‑3‑7B (d_model 4096, 32 layers/heads, ffn 11008, reordered-norm, qk-norm RMS, YaRN rope θ=500000 factor=8), continued SFT on the reproduced Instruct-SFT. AdamW, lr 8e-5, betas (0.9, 0.95), eps 1e-8, weight_decay 0, max_grad_norm 1.0.
Warmup 3% of steps, cosine decay to 0, 2 epochs. Global batch 1,048,576 tokens, seq_len 32768, HSDP shard_degree 4, bf16 params / fp32 reduce, model compiled.
| Mixture | Final step, 500k | Final step, 1M |
|---|---|---|
| G1 — 100% English | 696 | 1390 |
| G2 — 75% English | 680 | 1362 |
| G3 — 50% English | 668 | 1334 |
| G4 — 25% English | 652 | 1304 |
| G5 — 0% English | 636 | 1272 |
Switched training hardware from Nvidia H200 (HoreKa) to AMD MI250X (LUMI) for this sweep.
Appendix · three-judge evaluation notes
source: trackg-eval/REPORT.md · scripts/collect_three_judge.py, scripts/make_plots_threejudge.py
Appendix · English vs. EU tradeoff, all three judges
Every panel shows the same shape: English (x) stays in a narrow band once the model has any multilingual training, while EU-mean (y) fans out as more multilingual data is added — the "free lunch" holds under all three judges. Dolci-Translated (diamonds, Gemma judges only) sits on a similar English level but noticeably lower on EU than the strongest Track G points. Not shown: Qwen3.5-27B never scored the Dolci models. Self-computed from raw per-language JSON (simple mean of the 11 EU languages, full-anchor method) for consistency across judges — a different convention from the "independent" numbers quoted elsewhere in this appendix.
source: trackg-eval/results_perlang/TABLE_with_errorbars.txt (Qwen3.5); trackg-eval/results_gemma31b/, results_gemma26a4b/ raw result JSON (elo_per_language)
Appendix · v2 tool (synthgen, this repo)
synthgen build-localized-prompts synthgen generate --backend vllm \ --mode localized synthgen generate --backend vllm \ --mode judge synthgen decide-thresholds synthgen quality-filter synthgen topup --target N \ --endpoints-dir endpoints/
$SYNTHGEN_ROOT/ ├── prompts/prompts.jsonl ├── outputs/ │ ├── loc_<model>.jsonl │ ├── judged_<model>.jsonl │ ├── loc_full.kept.jsonl │ └── loc_full.dedup.jsonl ├── review/ └── logs/
Grounding axes: 20 "local" domains that require country-specific knowledge (bureaucracy, healthcare, holidays, slang…) plus 10 general domains (work, creative writing), each crossed with a role and an intent. Generation runs against local models served on LUMI (vLLM) or a hosted API, through one shared backend.
Appendix · v2 judge validation, full breakdown
| Bad-example type | n | mean score | range |
|---|---|---|---|
| mixed language | 22 | 1.73 | 1–2 |
| nonsense constraint | 19 | 1.00 | 1–1 |
| trivial question | 22 | 1.00 | 1–1 |
| wrong answer | 22 | 3.95 | 0–10 |
| bad explanation | 22 | 3.27 | 1–5 |
| Medium/borderline type | n | mean score | range |
|---|---|---|---|
| slightly generic | 21 | 9.14 | 5–10 |
| somewhat shallow | 22 | 9.18 | 8–10 |
| minor imprecision | 22 | 8.59 | 1–10 |
| slightly unnatural | 22 | 9.00 | 5–10 |
| borderline basic | 22 | 9.45 | 8–10 |
11 EU languages tested, good mean 9.06 vs bad mean 2.22 overall. Wrong-answer examples are the one type that occasionally scored high — a concrete lead for tightening the judge prompt. Judge: Qwen/Qwen3.6-27B; generator: google/gemma-4-31b-it; both served via vLLM.
source: studies/localized_bootstrap/outputs/summary.json
Appendix · the LUMI training pipeline
Porting this from the original (Nvidia) supercomputer to LUMI's AMD chips needed genuine fixes — hardcoded paths, model-compatibility gaps, and a self-contained training image so every run reproduces the same environment. Validated end-to-end on real hardware before the full sweep launched.
| path | contents |
|---|---|
| oellm/pipelines/tokenization/ | tokenizes the data mixtures for LUMI and the original cluster |
| oellm/pipelines/preprocessing/ | converts the base model into the training format |
| oellm/pipelines/training/ | the training scripts and a fast smoke test |
| oellm/pipelines/container/ | the self-contained training image and its build steps |
| oellm/configs/ | the 10 mixture configs (5 ratios × 2 scales) |
| oellm/experiments/dolci_synthetic/ | orchestrates the full sweep and the results writeup |
| trackg-eval/ | the standalone evaluation campaign — 3-judge scoring, ComparIA, plots, REPORT.md |
Appendix · references
synthgen/localized/studies/localized_bootstrap/oellm/experiments/dolci_synthetic/, oellm/pipelines/ in fabio‑open‑instruct/open‑instructoellm/experiments/multilingual_eu/results/multilingual_eu_results.md