Synthetic Generation for Multilingual Instruction Tuning
@abhash-er y travaille déjà.
Depuis le 12/10/2026.
Évaluation
Cette issue n'a pas encore été évaluée.
Description
Goal
Generate high-quality, multilingual synthetic instruction-tuning data for the OpenEuroLLM (OELLM) project, covering 35 languages at production scale (100k samples/language), grounded in real-world topic distributions. (we can still do hand-picked categories ?)
Description
Pipeline
All of the generations would be done by synthgen. This would be the pipeline that we could follow for the generation:
+--------------------------------------------+
| build-localized-prompts |
+--------------------------------------------+
|
v
+--------------------------------------------+
| generate (mode=localized) |
+--------------------------------------------+
| -> outputs/loc_<gen_model>.jsonl
v
+--------------------------------------------+
| generate (mode=judge) |
+--------------------------------------------+
| -> outputs/judged_<judge_model>.jsonl
v
+--------------------------------------------+
| quality-filter (per-lang score thresholds) |
+--------------------------------------------+
|
v
+--------------------------------------------+
| dedupe (exact-hash, optional embedding) |
+--------------------------------------------+
|
v
+--------------------------------------------+
| outputs/loc_full.dedup.jsonl (survivors) |
+--------------------------------------------+
Generation Prompt
| Component | What it represents |
|---|---|
domain |
Topic drawn from a single taxonomy, weighted by real WildChat-1M frequency |
| persona (10% of rows) | An optional role (e.g. "a nurse") the model may adopt if it plausibly fits the domain — dropped otherwise |
| general-capability layer | Optional: narrow to a more specific angle within the domain, if one fits naturally |
| local-culture layer | Optional: weave in a genuine {country}-specific fact/institution/custom |
| task-type layer | Optional: shape as edit/rewrite or extraction/classification instead of open-ended generation, if that fits better |
| difficulty layer | Optional: prefer a harder, more expert version of the task over the generic one, if it fits |
| intent | No longer suggested — the model decides freely and self-reports it |
Example rendering (lang=fr, domain=coding, no persona drawn):
You are a native speaker and expert writer of French as used in France.
Create ONE high-quality instruction-tuning example...
Domain: coding
Silently decide a realistic user intent that fits this domain...
No persona: write a direct, standalone request.
If a more specific, non-obvious general-capability angle fits naturally
with this domain, narrow to it...
If a genuine France-specific angle fits naturally with this domain...
If this domain would more naturally take the shape of editing/rewriting...
If a more specific, higher-difficulty version of this task fits naturally...
Output JSON only, no commentary, no code fences:
{"instruction":"...","response":"...","role_used":"...","intent_used":"..."}
Judge Prompt
| Component | What it represents |
|---|---|
| Holistic score (0-10) | ONE score weighing both whether the task is worth training on and how well the response executes it — the weaker of the two decides the score |
| Disqualifying-task checks | Score 0-2 regardless of response quality if the instruction is: trivial trivia, a pointless/unmotivated constraint, or not a genuine request (quiz-style) — edit/rewrite and extraction/classification are explicitly exempted as genuine tasks |
| Severity-based scoring (for worthwhile tasks) | Scored by the single WORST problem in the response, not by counting flaws — 9-10 excellent, 7-8 good, 5-6 fair, 3-4 weak, 1-2 poor, 0 unusable |
| Language-note | Per-language leniency guidance: individual loanwords/technical terms are fine, phonetic transliteration costs a small deduction, but a whole clause of the instruction in the wrong language is a disqualifying code-switching defect (0-3) |
Example rendering (lang=fr, country=France):
You are a strict quality filter for multilingual instruction-tuning data. You are
fluent in French and knowledgeable about France. Only the highest-quality
examples should be kept; low-quality data harms training.
Give ONE holistic quality score, 0 to 10, for the example as training data...
DISQUALIFYING TASKS — score 0-2 no matter how correct, fluent, or obedient the
response is, if the INSTRUCTION is any of these: ...
Otherwise the task is worthwhile — score by the SEVERITY of the single WORST
problem in the RESPONSE...
LANGUAGE NOTE for French: individual English loanwords or technical terms are
FINE where French speakers use them...
Example (French, France):
Instruction:
{instruction}
Response:
{response}
Output JSON only, no commentary, no code fences:
{"score": <integer 0-10>, "reason": "<one sentence>"}
Filtering and deduplication
The judge's score (0-10, from the holistic prompt above) is used in two separate stages:
-
Quality filtering.
quality_filter.pyjoins each generated row to its judge score by id and keeps only rows scoring at or above a per-language threshold. Unscored or errored rows are dropped, not kept-by-default. -
Deduplication. Only rows that survived the quality filter are deduped - exact-hash by default, plus embedding-based near-dup detection when
--embedding-dedupeis set (as it is in the current production run). The judge itself plays no role in dedup beyond having already removed the low-quality rows before dedup runs.
Deliverable scope
The synthgen.localized pipeline produces a final deduped, quality-filtered dataset of ≥100k survivors per language across all 35 target languages. We would ideally also want to test it on Prelude, Qwen-3 and Apertus.
Related to: Issue #345
- Langage dominant
- Aucune donnée de langage
- Étoiles
- 3
- Forks
- 0
- Métriques de merge des PR
- Aucune PR mergée en 30 j
Préparer son environnement
Ce projet ne fournit ni conteneur de développement, ni Dockerfile, ni guide de contribution : l'installation est à votre charge. Commencez par son README, et consultez notre guide de la première contribution pour les étapes générales.
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Autres issues de OpenEuroLLM/Taskboard
-
[nucleus sparse] Experiment setupPeut-être pris @aaronkl l’a pris il y a 11 jours. OuverteT4.1 - Optimization HPC T4.2 - model exploration
OpenEuroLLM/Taskboard#439 · 1 commentaire · 1 réaction · 1 personne assignée ·
-
Qwen3.5 35B-A3B hybrid MoE weak and strong scalingPeut-être pris @ibaucells l’a pris il y a 11 jours. OuverteT4.1 - Optimization HPC
OpenEuroLLM/Taskboard#438 · 2 commentaires · 1 personne assignée ·
-
Safety and alignment evaluationPeut-être pris @BirgerMoell l’a pris il y a 12 jours. Ouverte4.6 post-training
OpenEuroLLM/Taskboard#436 · 1 personne assignée ·
-
Finding optimal dataset mixtures for DPOPeut-être pris @geoalgo l’a pris il y a 13 jours. Ouverte4.6 post-training
OpenEuroLLM/Taskboard#435 · 3 personnes assignées ·
-
DPO checkpoint mergingPeut-être pris @HannanJaved l’a pris il y a 13 jours. Ouverte4.6 post-training
OpenEuroLLM/Taskboard#434 · 2 commentaires · 1 personne assignée ·