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.
| |
|---|
| 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:
1git clone https://github.com/uixova/vexira && cd vexira
2pip install torch sentencepiece
3huggingface-cli download uixova/vexira vexira_sft.pt vexira_spm.model --local-dir models/
4
5python translate.py --text "Hello world" --to tr
6# -> Merhaba dünya
1from translate import Translator
2
3tr = Translator()
4print(tr.translate(["Save", "Are you sure you want to quit?"],
5 tgt_lang="tr", domain="ui"))
6# ['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_pos is 512 but positions 128–511 were
never trained (pretraining used max_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
1@misc{vexira2026,
2 title = {Vexira: an 80M-parameter Turkish-English translation model},
3 author = {uixova},
4 year = {2026},
5 url = {https://github.com/uixova/vexira}
6}