OpenEuroLLM

Adding Multilingual
Capabilities with SFT

Abhash Jha · Taskboard #186 · 5 Aug 2026

The setup

Our starting point: one checkpoint, mostly English

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.

93%
of its training examples are English
~160
other languages share what's left — each under 0.4%
2.15M
training examples in total

Every result in this deck is "on this checkpoint" — we haven't tried these recipes anywhere else yet.

The risk we're managing

Continued training can quietly erase English

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?

What we want

Strong, natural answers in German, French, Polish and more — while English stays exactly as good as it was.

What tends to happen instead

English quietly drops — sometimes sharply — the moment you continue training on anything else. Catastrophic forgetting.

The plan, in order

Three EU-language data sources, each building on the last

Real Data Source
Existing sources, at scale
  • Mix in EU-language text already sitting around: WildChat, LMSYS-Chat, OASST2, fusion-synth
  • Sweep the English/EU ratio and the dataset size
  • Also replay the checkpoint's own original English data
Translation Data
Translate Dolci itself
  • Take Dolci‑Instruct‑SFT's own English examples
  • Translate them into 7 EU languages with a strong translation model
  • Paired with the same English replay
Synthetic Data
Generate our own synthetic data
  • v1: generated from scratch, trained and graded on LUMI
  • v2: redo it, grounded in real-world context per language

What the earlier data sources taught us

What real data and translation established

  • 01Replaying the checkpoint's own English data protects English. Skip that, and English Elo falls sharply (950 → 771) as soon as EU languages are added.
  • 02The ratio matters less than where the data comes from — but pushed too far past a 3:1 English:EU split, overall quality still turns over, shown right.
  • 03Translating Dolci itself (translation data) worked well — both a 75/25 and a 25/75 split improved non-English scores without giving up English.
  • 04But translation only goes so far — same questions, new languages, nothing culturally new. That gap is what Synthetic Data is for.
Overall Elo vs. English share of the mix
750 700 75% EN → Elo 747, best overall 728 726 739 677 100% EN 75% EN 50% EN 25% EN 0% EN

Full numbers for Phases 0 & 1 are in the appendix.

Synthetic Data

Generate our own EU-language 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

v1: hierarchical topic sampling, checked mechanically

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.

sample topic × persona × constraint generate instruction, then response back-translation QC (pilot) verify at scale
1.5M
unique pairs shipped, across 11 EU languages
94–98%
language-id accuracy, per language
93–98%
constraint-compliance rate, per language

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)

v1 is trained and graded: EU winrate climbs, English gives a little back

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:

Winrate vs. baseline — English-only battles vs. non-English (EU) battles, not Elo
50% 75% 44.1% 77.1% already 70.6% by 75% EN Baseline 100% EN 75% EN 50% EN 25% EN 0% EN
English winrate vs. baseline
EU winrate vs. baseline (11-lang avg)

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

Good numbers, but we flagged the data itself

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.

A real combination v1's axes can produce

topic: creative_writing persona: a working professional on a tight deadline constraint: the letter "q" must appear ≥5 times

→ "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.

What we noticed

"We also observed that the generated samples were not really high quality data and we need to improve the generation pipeline further."

The fix for v2

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

v2: hierarchical sampling, judged instead of checked

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.

SamplingQuality control
v1topic × persona × constraint, independentrule-based: language-ID + constraint checker
v2domain → role → intent, hierarchicalLLM 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

One example, start to finish

Sample domain → role → intent Generation call one model, JSON out Judge call holistic 0–10 score Threshold filter per language ≥ threshold Keep survivor pool below it Discard language still short of its target → generate another round (top‑up)

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

The two prompts, abridged

Generation prompt

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":"..."}}

Judge prompt

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

What other post-training data recipes verify on

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.

RecipeVerification signalDiversity mechanism
Ours (v2)holistic LLM judge, 0–10hierarchical: domain (by real-world weight) → role → intent
OpenThoughtsrule-based — exact-match (math), execution (code)seed-dataset sampling, ablated across question-generation methods
Tülu 3RLVR (verifiable rewards) + reward-model rejection samplingpersona-driven prompt synthesis
Phi‑4curation 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

Our synthetic data (v1) already beats translation data, ratio for ratio

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.

Overall Elo (all 12 languages, Bradley-Terry) — not English-only or non-English-only
700 750 peak (50% EN): 500k 757 / 1M 767 · at 0% EN: 500k 750 / 1M 759 728 747 726 739 677 100% EN 75% EN 50% EN 25% EN 0% EN
v1, 500k (hollow circle)
v1, 1M (filled square)
Translation data (with English replay)

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

At translation data's own "sweet spot" ratio, it's a real tradeoff

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 Elo752 / 755747
English winrate vs. baseline51.3% / 51.9%59.7%
EU winrate vs. baseline70.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

Show the final mix beats every baseline at once

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

v1's lead holds under every judge we tried

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.

Overall Elo (all 12 languages, global Bradley-Terry fit) — not English-only or non-English-only
700 750 678 731 751 703 Qwen3.5-27B Gemma-4-31B Gemma-4-26B-A4B
Baseline
v1, balanced (50en‑1M)
v1, most-multilingual (0en‑1M)
Dolci-Translated (A-75en)

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

Before trusting it, we tested whether it can tell good from bad

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.

Judge quality score, 0–10 — not Elo
0 2.5 5 7.5 10 8.5 es 10 fr 9.9 de 10 it 10 pt 9.2 pl 8.9 nl 6.3 cs 8.7 ro 8.2 el 10 uk
Known-good example, mean score
Known-bad example, mean score

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

Does the recipe generalize past OLMo-3-7B?

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.

Ideal candidate — Prelude

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.

In the meantime

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

What we've established, and what's still open

done
v1 recipe built (#345), 1.5M examples shipped, 10 models trained and graded (#186)
done
v2 designed around hierarchical sampling; its judge validated across 11 languages
pending
Scaling v2 · training + grading a v2 sweep against all three baselines · testing on another base model

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

Scale v2, run the core experiment, then generalize

  • 01Finish topping up v2 to production scale across all 11 languages.
  • 02Train and grade a v2 sweep, and compare it against all three baselines — sourced data, translated English, and v1 — at matched ratio and scale.
  • 03Check fluency and localization directly, not just the judge score, on the winning mix.
  • 04Repeat the recipe on another base model — Prelude once it's ready, or Qwen3-8B-base / Apertus-8B-base sooner — to see if it generalizes.
  • 05Scale language coverage from the current 11 EU languages up to the full 36 OpenEuroLLM target languages.

Summary

One recipe graded, a better one being tested against it

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

The technical detail

Terms defined · full early-experiment tables · v1 recipe & results in full · v2 tool layout · judge validation numbers · LUMI training config · references

Appendix · glossary

Terms used in these slides

Elo
Bradley‑Terry rating fit over pairwise LLM-judge battles. Win probability = 1 / (1 + 10^((Rb−Ra)/400)); a 100-point gap ≈ 64% expected win rate, 200 points ≈ 76%.
Winrate
The share of head-to-head battles a model wins against a fixed baseline. 50% = tied with baseline.
Judge model
A separate model used to grade outputs — either picking a winner between two answers, or scoring one answer on its own.
Checkpoint
A saved snapshot of a model at some point in training, that can be picked back up or evaluated.
LUMI
A European public supercomputer (in Finland) with AMD GPUs, used for the Track G training sweep.
Replay
Mixing a checkpoint's own original training data back in during continued training, to protect what it already knows.
Hierarchical sampling
Sampling a broad category first (e.g. a domain family), then a specific value within it, then dependent axes — rather than sampling every axis independently.
synthgen
The tool built for v2 that generates and quality-filters the grounded multilingual training examples.

Appendix · what "Track A–G" actually means

The internal track labels, defined

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:

TrackQuestionDesign
ADoes the English/EU ratio matter?90/80/70% English, ~95k samples, fusion-synth only, EU split equally across 8 languages
BDoes more diverse data help?Same ratios, ~490k samples, fusion-synth + WildChat, LMSYS-Chat, OASST2
CIs the English regression caused by EU data, or by continued SFT itself?100% English control (no EU data at all), same total samples
DDoes 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
EDoes Dolci replay scale with more data?Same as D, but ~490k samples instead of ~95k
FHow 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
GWhat 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

Every early experiment, in full

Exp.En/EUNEloElo enElo w/o en
Baseline741±9950±21722±10
A1‑90en90/1094.7k702±10771±32692±10
A2‑80en80/2093.6k704±11769±30703±11
A3‑70en70/3091.7k713±10766±29689±11
B1‑90en90/10491k720±9789±26708±10
B2‑80en80/20473k722±9797±26722±10
C0‑100en100/094.7k670±11791±29681±11
D1‑90en90/1094.7k751±8942±20716±11
D2‑80en80/2093.6k751±8956±20725±12
D3‑70en70/3091.7k753±9963±21731±11
E1‑90en90/10491k758±9965±21740±9
E2‑80en80/20474k759±8931±24725±9
E3‑70en70/30455k751±9940±22726±9
F1‑100en100/0500k728±9954±22695±11
F2‑75en75/25486k747±10947±22711±10
F3‑50en50/50453k726±9935±21700±12
F4‑25en25/75359k739±9912±22685±11
F5‑0en0/100234k677±11762±31680±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)

EU-Instruct-Synthetic: the sampling axes

Topicweight
creative_writing0.15
qa0.12
translation0.10
math0.08
summarization0.08
trivia / brainstorming0.07 each
roleplay0.06
coding / data_analysis0.05 each
other0.17

Personas (8) & constraints (15)

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)

How v1 was checked before scaling up

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.

LangLanguage-id acc.Constraint compliance
es95.1%95.8%
fr97.3%96.3%
de97.5%97.0%
it94.5%97.7%
pt94.1%96.4%
pl96.3%96.2%
nl95.7%98.1%
cs95.4%95.4%
ro98.0%97.3%
el97.7%94.3%
uk94.4%93.4%

source: Taskboard #345 comments

Appendix · Track G full results (Taskboard #186)

Track G: all 10 runs, vs. the Track F reference

ModelScaleOverall EloEN EloW/O EN EloEN WREU WRTrack F ref
baseline723±12956±46679±225050741±9
G1 100en500k723±12961±46677±2349.247.0F1: 728±9
G1 100en1M725±12950±43685±1951.250.4F1: 728±9
G2 75en500k752±12970±46712±2251.373.7F2: 747±10
G2 75en1M755±12951±42716±2651.970.6F2: 747±10
G3 50en500k757±12946±42723±1847.476.0F3: 726±9
G3 50en1M767±12975±46724±2349.573.7F3: 726±9
G4 25en500k757±12964±45716±2347.379.6F4: 739±9
G4 25en1M766±12947±42702±4746.576.2F4: 739±9
G5 0en500k750±12925±42713±2344.175.8F5: 677±11
G5 0en1M759±12915±41722±2144.177.1F5: 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

How Track G's 10 runs were actually trained

Model & optimizer

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.

Schedule & scale

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.

MixtureFinal step, 500kFinal step, 1M
G1 — 100% English6961390
G2 — 75% English6801362
G3 — 50% English6681334
G4 — 25% English6521304
G5 — 0% English6361272

Switched training hardware from Nvidia H200 (HoreKa) to AMD MI250X (LUMI) for this sweep.

Appendix · three-judge evaluation notes

How the robustness check was actually run

  • ·Re-judged every cached generation with two more judges — google/gemma-4-31b-it and gemma-4-26B-A4B-it — on top of the original Qwen3.5-27B. Only the judge re-ran on GPU; generations were reused from cache.
  • ·Rank agreement is high: Spearman ρ on overall Elo — Gemma-31B↔Gemma-26B = 0.96, Qwen↔Gemma-31B = 0.86, Qwen↔Gemma-26B = 0.75 (the lower figure is dragged by a baseline/G1 cluster within ~4 Elo of each other — noise, not real disagreement).
  • ·Judge severity is an offset, not a re-ranking: both Gemma judges score every model ~40–50 Elo below Qwen3.5 in absolute terms, but preserve the same ordering.
  • ·Under the independent per-language method (Gemma judges only): English barely moves across the whole English-ratio sweep (~910–950), while the EU-language mean climbs +75 to +90 Elo — described in the source notes as "the multilingual data is ~free on the EU side," and it survives the judge swap.
  • ·The two Dolci-Translated models were LMArena-only runs (no separate English/EU winrate split was ever launched for them), so their winrate column is the single pooled crowd winrate, not a split.
  • ·Which v1 config is "best" depends on the judge. Under Qwen3.5-27B alone, 50en-1M scores highest (767) — just ahead of 0en-1M (759, within noise) — and keeps a closer-to-balanced English/EU winrate (49.5% EN vs. 0en-1M's 44.1%). Under both Gemma judges, 0en-1M scores highest instead. So the main slide plots both: 50en-1M as the more balanced pick, 0en-1M as the most-multilingual extreme.

source: trackg-eval/REPORT.md · scripts/collect_three_judge.py, scripts/make_plots_threejudge.py

Appendix · English vs. EU tradeoff, all three judges

The same tradeoff shape, under every judge

x = English Elo, y = EU-mean Elo (mean of 11 languages) — both full-anchor, same method in every panel; each panel scaled to its own judge
816 864 669 744 baseline Qwen3.5-27B
789 829 623 711 baseline Gemma-4-31B
816 839 620 724 baseline Gemma-4-26B-A4B
Baseline
Track G, 500k
Track G, 1M
Dolci-Translated (Gemma judges only)

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 — commands & output layout

The commands, in order

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/

What comes out

$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

Where the judge separated cleanly — and where it didn't

Bad-example typenmean scorerange
mixed language221.731–2
nonsense constraint191.001–1
trivial question221.001–1
wrong answer223.950–10
bad explanation223.271–5
Medium/borderline typenmean scorerange
slightly generic219.145–10
somewhat shallow229.188–10
minor imprecision228.591–10
slightly unnatural229.005–10
borderline basic229.458–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

How Track G's training runs actually work

assemble mixtures convert base model format tokenize train (10 runs) convert back for eval evaluate (done)

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.

pathcontents
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

Where to find everything

  • Taskboard #186 (this investigation, incl. Track G + 3-judge results) — github.com/OpenEuroLLM/Taskboard/issues/186
  • Taskboard #345 (v1 synthetic data recipe) — github.com/OpenEuroLLM/Taskboard/issues/345
  • v1 dataset — openeurollm/EU-Instruct-Synthetic on Hugging Face
  • Track G evaluation campaign — trackg-eval/REPORT.md (3-judge scoring, ComparIA, per-language plots)
  • v2 tool (synthgen, this repo) — synthgen/localized/
  • v2 judge validation study — studies/localized_bootstrap/
  • LUMI training pipeline — oellm/experiments/dolci_synthetic/, oellm/pipelines/ in fabio‑open‑instruct/open‑instruct
  • Full early-experiment results — oellm/experiments/multilingual_eu/results/multilingual_eu_results.md
1 / 36