An English → Persian (Farsi) neural machine translation (ترجمهٔ ماشینی)
model, based on the
MarianMT
architecture and trained from scratch (آموزش از صفر) on the OpenSubtitles
en-fa parallel corpus. Built specifically to be small and fast enough for
real-time, fully offline translation on Android (ترجمهٔ آفلاین و بلادرنگ
روی اندروید — بدون نیاز به اینترنت؛ see onnx-int8/ below).
d_model=512, FFN dim 2048share_encoder_decoder_embeddings=Truemarian-en-fa-epoch4 in the training pipeline). Batch size 64
(gradient accumulation 2 → effective batch 128), learning rate 5e-4, 4000
warmup steps, fp16, on a single Colab T4 GPUTrained on the OPUS OpenSubtitles en-fa corpus . Cleaning steps applied before training:
from transformers import MarianTokenizer, MarianMTModel
tokenizer = MarianTokenizer.from_pretrained("omid1989ahmadi/marian-en-fa")
model = MarianMTModel.from_pretrained("omid1989ahmadi/marian-en-fa")
inputs = tokenizer("Hello, how are you?", return_tensors="pt")
output = model.generate(**inputs, max_length=128, num_beams=4)
print(tokenizer.decode(output[0], skip_special_tokens=True))
# سلام، حالت چطوره؟
A few more example translations from this model:
| English | Persian |
|---|---|
| I don't think that's a good idea. | فکر نکنم ايده ي خوبي باشه |
| The meeting has been postponed until tomorrow. | جلسه تا فردا تعويق افتاده |
| The model is running directly on the device. | مدل داره مستقیما روی دستگاه کار میکنه |
| The system is processing the audio in real time. | سيستم صوتي رو در زمان واقعي پردازش مي کنه. |
| There's no reason to worry about it. | دليلي نداره که نگرانش باشي. |
| Could you explain what happened? | ميتوني توضيح بدي چه اتفاقي افتاد؟ |
test_100_result.txt is included in the repo — a sample of 100 translation
outputs from the model's test split, for a quick look at output quality
without having to run inference yourself.
The onnx-int8/ subfolder contains a quantized, mobile-ready export:
| File | Description |
|---|---|
encoder_model_quantized.onnx |
Encoder, int8 dynamic-quantized |
decoder_model_quantized.onnx |
Decoder (no KV cache) — first generation step |
decoder_with_past_model_quantized.onnx |
Decoder with KV cache — subsequent steps |
tokenizer_source.json |
Fast tokenizer (HF tokenizers format) for encoding English input |
tokenizer_target.json |
Fast tokenizer for decoding Persian output |
source.spm / target.spm |
Underlying SentencePiece models |
vocab.json |
Shared vocabulary |
Sizes: fp32 ONNX ~630 MB total → int8 ~117 MB total.
CPU benchmark (10 short sentences, ONNX Runtime, CPUExecutionProvider,
beam search width 4): average 318 ms, fastest 206 ms, slowest 472 ms.
These files were exported with optimum-cli export onnx --task text2text-generation-with-past and quantized with
onnxruntime.quantization.quantize_dynamic. tokenizer_source.json /
tokenizer_target.json were built with transformers' internal
MarianConverter (Marian has no official *Fast tokenizer, so these are
generated directly from the SentencePiece + vocab files rather than saved
automatically).
Load with ai.djl.huggingface.tokenizers.HuggingFaceTokenizer (encode with
tokenizer_source.json, decode with tokenizer_target.json) and
ai.onnxruntime (onnxruntime-android) for the three ONNX graphs, using a
two-session KV-cache decoding loop (first step: decoder_model_quantized.onnx;
subsequent steps: decoder_with_past_model_quantized.onnx, which does not
take encoder_hidden_states as input, only input_ids +
encoder_attention_mask + the cached past_key_values.*).
Note: the fast tokenizer does not append the end-of-sequence token
automatically — append eos_token_id (see config.json) to the encoded
input ids yourself.
Training checkpoints (checkpoint-<step>/) are included in the repo
alongside the final model, for anyone who wants to continue fine-tuning
rather than starting from the fully-trained weights. Checkpoints were saved
every 5,000 steps (save_steps=5000), with only the 3 most recent kept at
any time (save_total_limit=3) — so the checkpoints present are the last
few saved during training, not the full training history.
MIT. Note that the OpenSubtitles training data itself carries its own OPUS license terms, worth checking before wide redistribution.
checkpoint-160000/optimizer.pt 484 MBcheckpoint-165000/optimizer.pt 484 MBcheckpoint-165372/optimizer.pt 484 MBcheckpoint-160000/model.safetensors 242 MBcheckpoint-165000/model.safetensors 242 MBcheckpoint-165372/model.safetensors 242 MBmodel.safetensors 242 MBonnx-int8/decoder_model_quantized.onnx 42 MBonnx-int8/decoder_with_past_model_quantized.onnx 39 MBonnx-int8/encoder_model_quantized.onnx 36 MBcheckpoint-160000/rng_state.pth 14.6 kBcheckpoint-165000/rng_state.pth 14.6 kBcheckpoint-165372/rng_state.pth 14.6 kBcheckpoint-160000/training_args.bin 5.4 kBcheckpoint-165000/training_args.bin 5.4 kBcheckpoint-165372/training_args.bin 5.4 kBtraining_args.bin 5.4 kBcheckpoint-160000/scheduler.pt 1.5 kBcheckpoint-165000/scheduler.pt 1.5 kBcheckpoint-165372/scheduler.pt 1.5 kBcheckpoint-160000/scaler.pt 1.4 kBcheckpoint-165000/scaler.pt 1.4 kBcheckpoint-165372/scaler.pt 1.4 kB