Emhotob-50M-Tashkil-v2

A 51.8M-parameter Llama model fine-tuned to add tashkil (diacritics / harakat) to undiacritized Arabic text. Fine-tuned from oddadmix/50M-2048-Emhotob on the full freococo/arabic_tashkil_dataset (~1.5M gold-standard vocalized pages of classical Arabic / Islamic texts).

This is v2 of the series โ€” trained on ~20ร— more data than oddadmix/Emhotob-50M-Tashkil-v1 and substantially better at word preservation.

License note: the training data is licensed CC BY-NC-ND 4.0 (non-commercial, no-derivatives). This model is released under the same license to respect the upstream terms. Use accordingly.

Task framing

Prompt-masked supervised fine-tuning (causal LM). Loss is computed only on the diacritized output span:

ุดูƒูู‘ู„ ุงู„ู†ุต ุงู„ุนุฑุจูŠ ุงู„ุชุงู„ูŠ:
{undiacritized text}
### ุงู„ุฑุฏ:
{diacritized text}</s>      โ† loss only here

Usage

from transformers import AutoTokenizer, AutoModelForCausalLM
import torch

model_id = "oddadmix/Emhotob-50M-Tashkil-v2"
tok = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(model_id, dtype=torch.bfloat16).cuda().eval()

text = "ุฐู‡ุจ ุงู„ุทุงู„ุจ ุงู„ู‰ ุงู„ู…ุฏุฑุณุฉ"
prompt = f"ุดูƒูู‘ู„ ุงู„ู†ุต ุงู„ุนุฑุจูŠ ุงู„ุชุงู„ูŠ:\n{text}\n### ุงู„ุฑุฏ:\n"
ids = [tok.bos_token_id] + tok.encode(prompt, add_special_tokens=False)
out = model.generate(
    torch.tensor([ids]).cuda(),
    max_new_tokens=512, do_sample=False,
    eos_token_id=tok.eos_token_id, pad_token_id=tok.pad_token_id,
)
print(tok.decode(out[0][len(ids):], skip_special_tokens=True))

Training

  • Data: full freococo set, restricted to the 1,012,933 pages whose diacritized target fits the model's 2048-token context (a max-chars 2500 pre-filter; ~32% of pages that would require truncation were dropped rather than corrupt the add-only training signal). A disjoint 4,000-row validation set was carved with a fixed seed.
  • Config: 1 epoch, batch 16 ร— grad-accum 2 (effective 32), LR 3e-4 cosine, bf16, max_length 2048.
  • Hardware: single RTX 5090, ~2 h, 31,655 steps.
  • Final eval_loss: 0.0226.

Evaluation

300 held-out rows, greedy decoding.

In-domain (freococo clean held-out):

Metric Value
Diacritic Error Rate (DER) โ†“ 1.32%
Character accuracy โ†‘ 98.68%
Exact sentence match โ†‘ 32.67%
Word preservation โ€” skeleton exact โ†‘ 97.33%
Word preservation โ€” word-count match โ†‘ 98.33%
Word preservation โ€” mean word survival โ†‘ 98.60%

Zero-shot on the arbml test split (never seen during training):

Metric Value
DER โ†“ 2.03%
Word preservation โ€” skeleton exact โ†‘ 95.33%
Word preservation โ€” mean word survival โ†‘ 97.98%

vs v1: in-domain DER improves 1.88% โ†’ 1.32%, and the "add-only" word-preservation weak spot is largely fixed (skeleton-exact 89.7% โ†’ 97.3%). Even zero-shot on arbml, v2 preserves words far better than v1; its slightly higher DER there reflects domain shift, not a regression.

skeleton exact = strip all diacritics from the output and check it equals the input character-for-character โ€” the strongest guarantee the model only added marks.

Limitations

  • Small model (52M params); tuned on classical Arabic / Islamic prose (with ยง and -[NN]- structural markers preserved). Domain-shifted text may see higher DER.
  • Context limited to 2048 tokens; pages longer than that were excluded from training and should be split at inference.
  • Non-commercial, no-derivatives license inherited from the training data.
Downloads last month
4
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/Emhotob-50M-Tashkil-v2

Finetuned
(11)
this model

Dataset used to train oddadmix/Emhotob-50M-Tashkil-v2