Instructions to use oddadmix/Emhotob-50M-Tashkil-v2 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use oddadmix/Emhotob-50M-Tashkil-v2 with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="oddadmix/Emhotob-50M-Tashkil-v2")# Load model directly from transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrained("oddadmix/Emhotob-50M-Tashkil-v2") model = AutoModelForCausalLM.from_pretrained("oddadmix/Emhotob-50M-Tashkil-v2", device_map="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use oddadmix/Emhotob-50M-Tashkil-v2 with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "oddadmix/Emhotob-50M-Tashkil-v2" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "oddadmix/Emhotob-50M-Tashkil-v2", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker
docker model run hf.co/oddadmix/Emhotob-50M-Tashkil-v2
- SGLang
How to use oddadmix/Emhotob-50M-Tashkil-v2 with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "oddadmix/Emhotob-50M-Tashkil-v2" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "oddadmix/Emhotob-50M-Tashkil-v2", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "oddadmix/Emhotob-50M-Tashkil-v2" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "oddadmix/Emhotob-50M-Tashkil-v2", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }' - Docker Model Runner
How to use oddadmix/Emhotob-50M-Tashkil-v2 with Docker Model Runner:
docker model run hf.co/oddadmix/Emhotob-50M-Tashkil-v2
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 2500pre-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
Model tree for oddadmix/Emhotob-50M-Tashkil-v2
Base model
oddadmix/50M-2048-Emhotob