Vexira
An 80.8M-parameter TR↔EN translation model. Runs fully offline on CPU — no internet, no API key, no GPU. Built for subtitles, game text, UI strings and file content.
Code and full documentation: https://github.com/uixova/vexira
| Parameters | 80.8M (fp16, ~490 MB) |
| Languages | Turkish ↔ English, bidirectional, single model |
| Speed | 78 ms/line (12.9 lines/s) — 4 CPU threads, no GPU |
| Effective context | 128 tokens (longer input is split and rejoined) |
| License | Apache-2.0 |
Benchmarks
FLORES-200 devtest (1012 sentences, beam 4, glossary off):
| model | en→tr BLEU | chrF++ | tr→en BLEU | chrF++ |
|---|---|---|---|---|
vexira.pt (pretrained) |
29.53 | 57.84 | 35.03 | 59.98 |
vexira_sft.pt (main) |
29.13 | 57.68 | 35.16 | 60.11 |
For reference on the same set: NLLB-200 distilled (600M) ≈ 26–28 en→tr, opus-mt-tc-big-en-tr (230M) ≈ 30. Vexira reaches that band with 80.8M parameters.
Term consistency — measured on a real 559-line Ren'Py game file, counting terms rendered differently across lines (a defect BLEU cannot see):
| model | inconsistent terms |
|---|---|
vexira.pt |
33 |
vexira_sft.pt |
19 (−42%) |
The built-in glossary additionally resolves 42% of those strings by exact match, where the model is never invoked at all.
Files
| file | what |
|---|---|
vexira_sft.pt |
main model — fine-tuned for UI/terminology consistency |
vexira.pt |
pretrained checkpoint, slightly higher en→tr BLEU, weaker consistency |
vexira_spm.model |
SentencePiece unigram tokenizer, 32k shared TR+EN |
Both checkpoints carry the tokenizer and a 1,234-term glossary embedded inside
the weights file, so a single .pt is self-contained.
Usage
This is a standalone PyTorch model, not a transformers architecture. Use the
repository code:
git clone https://github.com/uixova/vexira && cd vexira
pip install torch sentencepiece
huggingface-cli download uixova/vexira vexira_sft.pt vexira_spm.model --local-dir models/
python translate.py --text "Hello world" --to tr
# -> Merhaba dünya
from translate import Translator
tr = Translator()
print(tr.translate(["Save", "Are you sure you want to quit?"],
tgt_lang="tr", domain="ui"))
# ['Kaydet', 'Çıkmak istediğinizden emin misiniz?']
domain selects the register: sub subtitles · ui interface · doc prose ·
ocr screen text. With ui the glossary makes terminology deterministic.
Architecture
Encoder-decoder transformer, 12 encoder + 6 decoder layers, d_model 512,
d_ff 1408, 8 heads, RMSNorm (pre-LN), SwiGLU, learned absolute positions, tied
embeddings, 32k shared SentencePiece unigram vocabulary with byte_fallback.
No quantization: weights are fp16, computed in fp32 on CPU.
Limitations
- 128-token effective context.
max_posis 512 but positions 128–511 were never trained (pretraining usedmax_len=128); the code measures this and splits longer input at sentence boundaries, chaining parts with a context token. Measured: 16 sentences / 144 tokens preserved 16/16 concepts. - TR↔EN only.
- Not a knowledge or chat model. It translates; it does not answer questions or reason.
- Poetry, wordplay, heavy idiom and slang are weak.
- The reserved
<ocr>,<stt>,<tts>domain tokens exist but are untrained.
Training
Pretraining: 60.9M sentence pairs → 121.7M bidirectional examples, 7.56B tokens total (4.67× Chinchilla for this size), 4 sessions on 2×T4.
Fine-tuning: 133,753 examples, 3 epochs at LR 5e-5. The set is deliberately balanced — 51% UI / 49% general, with a length distribution matching pretraining — so that UI terminology is learned without losing general translation ability.
Data: 23 OPUS corpora (OpenSubtitles, CCMatrix, HPLT, CCAligned, WikiMatrix, TED, Tatoeba, KDE4, SETIMES and others) plus system locale catalogs for UI terminology. FLORES-200 devtest was never part of training.
Citation
@misc{vexira2026,
title = {Vexira: an 80M-parameter Turkish-English translation model},
author = {uixova},
year = {2026},
url = {https://github.com/uixova/vexira}
}
Evaluation results
- BLEU on FLORES-200 devtestself-reported29.130
- chrF++ on FLORES-200 devtestself-reported57.680
- BLEU on FLORES-200 devtestself-reported35.160
- chrF++ on FLORES-200 devtestself-reported60.110