50M-MSA-Egyptian-v1 — Bidirectional MSA ↔ Egyptian Arabic

A 51.8M-parameter small language model that translates both ways between Modern Standard Arabic (الفصحى) and Egyptian colloquial Arabic (المصرية العامية). A single set of weights serves both directions; a direction-specific Arabic system prompt selects which way to translate.

Finetuned from oddadmix/50M-2048-Emhotob, a tiny Arabic base model trained from scratch.

Evaluation

Evaluated on a deterministic held-out set of 3,000 pairs (seed=42), decoded greedily (do_sample=False, no repetition penalty), scored with sacreBLEU:

Direction sacreBLEU chrF
MSA → Egyptian 24.00 52.45
Egyptian → MSA 26.28 52.22

Egyptian→MSA scores a bit higher, as expected — MSA is more standardized, so a single reference captures more of the valid output space. The saved weights are the best checkpoint by validation loss (eval_loss=1.249, epoch 2 of 3).

Decoding note: use plain greedy. A repetition penalty (1.2) was tested and lowered BLEU by ~12 points in both directions, because Arabic legitimately repeats short particles that the penalty suppresses.

Example translations

Real greedy-decoded outputs from the held-out set:

MSA → Egyptian

MSA input Model output (Egyptian)
شكرًا جزيلًا لك، أنت لطيف للغاية. متشكرة قوي، إنتي طيبة أوي.
عزيزتي، المقصد ليس أن لاعبًا واحدًا هو الذي يؤثر على المنتخب الوطني. يا حبيبي، الفكرة مش إن لاعب واحد هو اللي بيأثر على المنتخب.
ليكمل الله لك الخير مقابل ضيافتك الرائعة. ربنا يكرمك بالخير على ضيافتك الحلوة.

Egyptian → MSA

Egyptian input Model output (MSA)
شكراً جداً، إنت طيب قوي. شكرًا جزيلًا لك، أنت لطيف جدًا.
يا حبيبي الفكرة مش إن لعيب واحد هو اللي هيأثر على المنتخب. يا عزيزتي، الفكرة ليست أن لاعب واحد سيؤثر على الفريق الوطني.
ربنا يجازيك خير على كرمك وحسن ضيافتك. ليجلب الله لك الخير على كرمك، وحسن ضيافتك.

A larger set of 20 examples per direction (with references) is in eval_bidirectional_greedy.json.

Usage

ChatML format. Pick the system prompt for the direction you want:

import torch
from transformers import AutoModelForCausalLM, AutoTokenizer

model_id = "oddadmix/50M-MSA-Egyptian-v1"
tok = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(model_id, dtype=torch.bfloat16).to("cuda").eval()

SYS_TO_EGY = "أنت مترجم محترف. ترجم النص من اللغة العربية الفصحى إلى اللهجة المصرية العامية."
SYS_TO_MSA = "أنت مترجم محترف. ترجم النص من اللهجة المصرية العامية إلى اللغة العربية الفصحى."

def translate(text: str, system: str) -> str:
    prompt = (
        f"<|im_start|>system\n{system}<|im_end|>\n"
        f"<|im_start|>user\n{text.strip()}<|im_end|>\n"
        f"<|im_start|>assistant\n"
    )
    ids = tok(prompt, return_tensors="pt", add_special_tokens=False).to(model.device)
    if tok.bos_token_id is not None:  # training prepends BOS
        bos = torch.tensor([[tok.bos_token_id]], device=model.device)
        ids["input_ids"] = torch.cat([bos, ids["input_ids"]], dim=1)
        ids["attention_mask"] = torch.cat([torch.ones_like(bos), ids["attention_mask"]], dim=1)
    out = model.generate(**ids, max_new_tokens=256, do_sample=False,
                         eos_token_id=tok.eos_token_id, pad_token_id=tok.pad_token_id)
    return tok.decode(out[0, ids["input_ids"].size(1):], skip_special_tokens=True).strip()

print(translate("ليكمل الله لك الخير مقابل ضيافتك الرائعة.", SYS_TO_EGY))
# → ربنا يكرمك بالخير على ضيافتك الحلوة.
print(translate("ربنا يجازيك خير على كرمك وحسن ضيافتك.", SYS_TO_MSA))
# → ليجلب الله لك الخير على كرمك، وحسن ضيافتك.

Training

  • Base model: oddadmix/50M-2048-Emhotob (Llama arch, ~51.8M params)
  • Dataset: oddadmix/egyptian-msa-2.9-openai-bytedance-translations (132K rows, egyptian/msa columns)
  • Method: HuggingFace Trainer, ChatML, prompt-masked cross-entropy. Each row is exploded into two training examples (one per direction, ~258K total). Two ChatML special tokens (<|im_start|>, <|im_end|>) were added and embeddings resized.
  • Hyperparameters: 3 epochs · effective batch 64 · LR 3e-4 (cosine, 5% warmup) · bf16 · max length 1024 · load_best_model_at_end on eval_loss.
  • Split: 129,009 train / 3,000 deterministic held-out (seed=42), scored both directions.

Limitations

  • A 50M model: expect errors on rare / technical vocabulary and occasional drift on long inputs. Idioms and honorifics are mostly handled well.
  • Gender is disambiguated only from context; ambiguous inputs may default one way.
  • Trained on conversational Egyptian ↔ MSA; other dialects are out of scope.

License

Apache-2.0, inherited from the base model.

Downloads last month
20
Safetensors
Model size
51.8M params
Tensor type
BF16
·
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for oddadmix/50M-MSA-Egyptian-v1

Finetuned
(16)
this model

Collection including oddadmix/50M-MSA-Egyptian-v1

Article mentioning oddadmix/50M-MSA-Egyptian-v1