Emhotob-25M-MSA-Egyptian-v2 โ€” Bidirectional MSA โ†” Egyptian Arabic (~25.3M params)

A 25.3M-parameter model that translates both ways between Modern Standard Arabic (ุงู„ูุตุญู‰) and Egyptian colloquial Arabic (ุงู„ู…ุตุฑูŠุฉ ุงู„ุนุงู…ูŠุฉ). A single set of weights serves both directions; a direction-specific system prompt selects which way to translate.

Finetuned from oddadmix/Emhotob-25M-v2, a tiny Llama-architecture base (hidden 384, 8 layers, 6 heads, vocab 32000, tied embeddings).

Scaling study. This is one rung of a from-scratch Arabic scaling study that runs an identical SFT + eval recipe across bases from 0.5M to 50M parameters to locate where translation emerges. On the headline MSAโ†”Egyptian pair, output is degenerate at โ‰ค1M, becomes real-but-rough at 5M, and usable at 10M+. See the sibling oddadmix/50M-MSA-Egyptian-v1 for the fluent reference.

Evaluation

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 21.55 50.06
Egyptian โ†’ MSA 23.01 49.09

Saved weights are the best checkpoint by validation loss (eval_loss = 1.491). 20 samples per direction with references are in eval_bidirectional.json.

Example translations

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

MSA โ†’ Egyptian

Source Model output Reference
ุฃู†ุง ูู‚ุท ุฃุญุงูˆู„ ุฃู† ุฃุทู…ุฆู† ู†ูุณูŠ. ู…ุง ู‡ูˆ ุงู„ุฃุณูˆุฃ ุงู„ุฐูŠ ูŠู…ูƒู† ุฃู† ูŠุญุฏุซุŸ ุฅู†ู‡ ู…ุฑู‡ู‚ ุนู‚ู„ูŠู‹ุง ูู‚ุทุŒ ู„ูƒู†ู‡ู… ูŠู‚ููˆู† ุจุญุฒู…. ุญู‚ู‹ุงุŒ ุฅู†ู‡ู… ูŠู‚ููˆู† ุจุญุฒ ุฃู†ุง ุจุณ ุจุญุงูˆู„ ุฃุทู…ู† ู†ูุณูŠ. ุฅูŠู‡ ุงู„ุฃุณูˆุฃ ุงู„ู„ูŠ ู…ู…ูƒู† ูŠุญุตู„ุŸ ู‡ูˆ ู…ุฑู‡ู‚ ุนู‚ู„ูŠู‹ุง ุจุณุŒ ุจุณ ู‡ู…ุง ูˆุงู‚ููŠู† ุจุญุฒู…. ุจุฌุฏ ู‡ู…ุง ูˆุงู‚ููŠู† ุจุญุฒู…. ุงู†ุง ุจุณ ุจุญุงูˆู„ ุงุทู…ู† ู†ูุณูŠ. ุงูŠู‡ ุฃุณูˆุฃ ุญุงุฌุฉ ู…ู…ูƒู† ุชุญุตู„ุŸ ุงู„ู…ูˆุถูˆุน ู…ุชุนุจ ู†ูุณูŠู‹ุงุŒ ุจุณ ู‡ู… ูˆุงู‚ููŠู† ุซุงุจุชูŠู† ูุนู„ุงู‹.
ุดูƒุฑู‹ุง ุฌุฒูŠู„ู‹ุง ู„ูƒุŒ ุฃู†ุช ู„ุทูŠู ู„ู„ุบุงูŠุฉ. ุดูƒุฑุงู‹ ุฌุฏุงู‹ุŒ ุฅู†ุช ุทูŠุจ ุฌุฏุงู‹. ุดูƒุฑุงู‹ ุฌุฏุงู‹ุŒ ุฅู†ุช ุทูŠุจ ู‚ูˆูŠ.

Egyptian โ†’ MSA

Source Model output Reference
ุงู†ุง ุจุณ ุจุญุงูˆู„ ุงุทู…ู† ู†ูุณูŠ. ุงูŠู‡ ุฃุณูˆุฃ ุญุงุฌุฉ ู…ู…ูƒู† ุชุญุตู„ุŸ ุงู„ู…ูˆุถูˆุน ู…ุชุนุจ ู†ูุณูŠู‹ุงุŒ ุจุณ ู‡ู… ูˆุงู‚ููŠู† ุซุงุจุชูŠู† ูุนู„ุงู‹. ุฃู†ุง ูู‚ุท ุฃุญุงูˆู„ ุฃู† ุฃุชุฃูƒุฏ ู…ู† ุฃู†ู†ูŠ ุฃุณุชุทูŠุน. ู…ุง ู‡ูˆ ุฃุณูˆุฃ ุดูŠุก ูŠู…ูƒู† ุฃู† ูŠุญุฏุซุŸ ุฅู†ู‡ ู…ุชุนุจ ุนู‚ู„ูŠู‹ุงุŒ ู„ูƒู†ู‡ู… ูŠู‚ููˆู† ููŠ ุฏูˆุงุฆุฑ. ุฃู†ุง ูู‚ุท ุฃุญุงูˆู„ ุฃู† ุฃุทู…ุฆู† ู†ูุณูŠ. ู…ุง ู‡ูˆ ุงู„ุฃุณูˆุฃ ุงู„ุฐูŠ ูŠู…ูƒู† ุฃู† ูŠุญุฏุซุŸ ุฅู†ู‡ ู…ุฑู‡ู‚ ุนู‚ู„ูŠู‹ุง ูู‚ุทุŒ ู„ูƒู†ู‡ู… ูŠู‚ููˆู† ุจุญุฒู…. ุญู‚ู‹ุงุŒ ุฅู†ู‡ู… ูŠู‚ููˆู† ุจุญุฒ
ุดูƒุฑุงู‹ ุฌุฏุงู‹ุŒ ุฅู†ุช ุทูŠุจ ู‚ูˆูŠ. ุดูƒุฑู‹ุง ุฌุฒูŠู„ู‹ุง ู„ูƒุŒ ุฃู†ุช ู„ุทูŠู ุฌุฏู‹ุง. ุดูƒุฑู‹ุง ุฌุฒูŠู„ู‹ุง ู„ูƒุŒ ุฃู†ุช ู„ุทูŠู ู„ู„ุบุงูŠุฉ.

Usage

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

import torch
from transformers import AutoModelForCausalLM, AutoTokenizer

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

SYSTEM = "ุฃู†ุช ู…ุชุฑุฌู… ู…ุญุชุฑู. ุชุฑุฌู… ุงู„ู†ุต ู…ู† ุงู„ู„ุบุฉ ุงู„ุนุฑุจูŠุฉ ุงู„ูุตุญู‰ ุฅู„ู‰ ุงู„ู„ู‡ุฌุฉ ุงู„ู…ุตุฑูŠุฉ ุงู„ุนุงู…ูŠุฉ."

def translate(text, system=SYSTEM):
    prompt = (f"<|im_start|>system\n{system}<|im_end|>\n"
              f"<|im_start|>user\n{text.strip()}<|im_end|>\n<|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:
        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()

Training

  • Base model: oddadmix/Emhotob-25M-v2 (Llama arch, hidden 384, 8 layers, 6 heads, vocab 32000, tied embeddings; 25,271,424 params after resizing for 2 ChatML tokens)
  • Dataset: oddadmix/egyptian-msa-2.9-openai-bytedance-translations
  • Method: HuggingFace Trainer, ChatML, prompt-masked cross-entropy (loss only on the assistant turn). Each row is exploded into two training examples (one per direction).
  • Hyperparameters: 3 epochs ยท effective batch 64 ยท LR 3e-4 (cosine, 5% warmup) ยท bf16 ยท max length 1024 ยท load_best_model_at_end on eval_loss.
  • Eval split: 3,000 deterministic held-out pairs (seed=42), scored both directions.

Limitations

A ~25.3M model: reliable on short/common sentences, but drift, repetition, and errors appear on long or rare inputs. Gender is disambiguated only from context. For fluent translation use the 50M sibling.

License

Apache-2.0, inherited from the base model.

Downloads last month
16
Safetensors
Model size
25.3M params
Tensor type
BF16
ยท
Inference Providers NEW
This model isn't deployed by any Inference Provider. ๐Ÿ™‹ Ask for provider support

Model tree for oddadmix/Emhotob-25M-MSA-Egyptian-v2

Finetuned
(2)
this model

Collection including oddadmix/Emhotob-25M-MSA-Egyptian-v2

Article mentioning oddadmix/Emhotob-25M-MSA-Egyptian-v2