teaching a small model to write and think in real romanian

Community Article
Published July 4, 2026

most labs won't bother teaching a small model to write good romanian. it's a small language, the leaderboards don't reward it, and "sounds roughly fluent" is usually good enough to ship.

it isn't good enough. a model can be fluent-ish and still invent word-forms that don't exist, slip into english mid-sentence, and drop diacritics like they're optional. if you actually read romanian, you notice immediately.

so we spent a training run fixing exactly that. today we're releasing surogate 3.5, two romanian-first bilingual (RO/EN) models, 2B and 4B, both apache 2.0.

what they are

surogate 3.5 is a dual-mode reasoner built on the qwen3.5 family:

  • thinking on: it reasons step by step in the language of the prompt. romanian prompt, romanian chain-of-thought, math included. english prompt, english chain-of-thought.
  • thinking off: it answers directly, no reasoning trace.

the models were trained with our open-source surogate training framework.

the thing we actually cared about

the goal was never a leaderboard number. it was romanian text that a native speaker wouldn't flinch at. three failure modes, measured on a 13,963-prompt romanian generation benchmark scored against a dexonline-authoritative dictionary:

invented word-forms (made-up words that don't exist), per 1k tokens, lower is better:

invented word-forms / 1k ↓
qwen3.5-4B (base) 4.07
surogate 3.5-2B 1.49
surogate 3.5-4B 1.56

that's the headline: roughly a 2.6x cut in made-up words, and the 2B holds it just as well as the 4B.

english leakage (english creeping into romanian output), per 1k, lower is better:

english-leak / 1k ↓
qwen3.5-4B 1.38
surogate 3.5-2B 0.88
surogate 3.5-4B 1.00

reasoning language match: when the chain-of-thought is on, does it actually think in the prompt's language, or quietly switch to english to do the real work?

RO prompts EN prompts <think> leak (no-think mode)
surogate 3.5-2B 100% 100% 0% (1/1392)
surogate 3.5-4B 100% 100% 0% (1/1392)

a reasoning model that switches to english to think isn't reasoning in your language, it's translating. keeping the chain-of-thought in the prompt language is the harder version, and the honest one.

the full table

greedy decoding unless noted. IFEval is strict metrics. translation is chrF2 on a held-out RO↔EN set.

benchmark qwen3.5-4B surogate 3.5-2B surogate 3.5-4B
RO invented word-forms / 1k ↓ 4.07 1.49 1.56
RO english-leak / 1k ↓ 1.38 0.88 1.00
RO missing diacritics / 1k ↓ 0.68 1.93 0.30
RO IFEval (prompt / instr strict) ↑ 0.272 / 0.541 0.116 / 0.350 0.294 / 0.545
RO GSM8K (strict) ↑ 0.706 0.459 0.722
EN IFEval (prompt strict) ↑ 0.823 0.522 0.691
EN GSM8K (strict) ↑ 0.890 0.665 0.882
translation EN→RO (chrF2) ↑ 54.8 46.9 53.9
translation RO→EN (chrF2) ↑ 62.5 53.1 63.0

the 4B beats base qwen3.5-4B on romanian orthography, romanian ifeval, romanian gsm8k, and ro→en translation, while cutting invented words by more than half. it also has the best diacritics in the table by a wide margin (0.30 vs 0.68).

where it still trails (we're not hiding it)

  • english ifeval and english gsm8k are behind base qwen. the romanian-first training costs some english instruction-following.
  • en→ro translation trails base qwen slightly on the 4B.
  • the 2B trades diacritic accuracy (1.93 vs base 1.05) and instruction-following for its low invented-word rate. it's a specialist: reach for the 4B if you need diacritics and ifeval.

we left the whole table up on purpose. judge it yourself.

which one to use

  • surogate 3.5-2B: one job, done well. romanian text that doesn't make up words, on hardware you already own. a specialist for generation quality at small scale.
  • surogate 3.5-4B: the all-rounder. best romanian orthography in the set, strong reasoning, keeps the low invented-word rate.

usage

vLLM, 4B:

vllm serve surogate/Surogate-3.5-4B --reasoning-parser qwen3 \
  --enable-auto-tool-choice --tool-call-parser hermes

vLLM, 2B:

vllm serve surogate/Surogate-3.5-2B --reasoning-parser qwen3

thinking control via the chat template:

tok.apply_chat_template(
    messages,
    add_generation_prompt=True,
    enable_thinking=True,   # step-by-step reasoning in the prompt's language
    # enable_thinking=False -> direct answer
)

one sampling note: the repo ships a generation_config.json (temperature 0.6, top_p 0.95, top_k 20). don't sample with top_p=1.0, the unfiltered tail degrades output. for orthography-critical work, prefer greedy (temperature=0).

links

built by the team at invergent in bucharest. apache 2.0.

intelligence should speak your language too.

Community

Sign up or log in to comment