ichkil — Arabic Tashkeel for Python
Vocalize bare Arabic text with a tiny, self-contained ONNX model (≈5 MB, CPU-only, no GPU, no tokenizer, no server). One call, fully offline after the first run.
ichkil downloads its model from Hugging Face
on first use, verifies its SHA-256, and runs inference with
ONNX Runtime. After that it is 100 % offline.
import ichkil
ichkil.diacritize("محمد قرأ الكتاب في المدرسة")
# -> 'مُحَمَّدٌ قَرَأَ الْكِتَابَ فِي الْمَدْرَسَةِ'
Install
pip install ichkil
Requires Python ≥ 3.9 (tested on 3.9 – 3.12). Dependencies: huggingface_hub,
onnxruntime (CPU).
Quickstart
import ichkil
# one-liner (lazy model download on first call, then cached)
ichkil.diacritize("العلم نور والجهل ظلمة")
# -> 'الْعِلْمِ نُورٌ وَالْجَهْلُ ظُلْمَةُ'
# explicit control
from ichkil import Diacritizer
d = Diacritizer() # downloads + verifies + caches the model
d.diacritize("القهوة جميلة في الصباح")
# -> 'الْقَهْوَةِ جَمِيلَةٌ فِي الصَّبَاحِ'
labels = d.predict_labels("كتاب") # [4, 2, 1, 4] (one label id per character, 0..12)
# fully offline: point at local files
d = Diacritizer.from_file("./model.onnx")
Command line
pip install ichkil
ichkil "محمد قرأ الكتاب"
# مُحَمَّدٌ قَرَأَ الْكِتَابَ
ichkil --json "العلم نور"
# {"input": "العلم نور", "output": "الْعِلْمِ نُورٌ"}
cat text.txt | ichkil # read from stdin
ichkil --model ./model.onnx "محمد" # offline mode
API
| Item | Description |
|---|---|
ichkil.diacritize(text: str) -> str |
Vocalize text (module-level convenience, lazy default model). |
ichkil.predict_labels(text: str) -> list[int] |
Label id (0–12) per character. |
Diacritizer |
Constructor: repo_id, revision, cache_dir, token, verify_checksum, num_threads. |
Diacritizer.from_file(model_path, config_path=None) |
Build from local model.onnx (+ config.json beside it). |
Diacritizer.diacritize(text) / .predict_labels(text) |
Instance methods (same behavior). |
ichkil.pipeline |
Pure text helpers: strip_diacritics, encode, decode, attach, label tables. |
| Errors | IchkilError ← ChecksumError, ModelLoadError, InferenceError. |
ichkil.reset_default() |
Drop the lazily-created default instance (useful in tests). |
Label contract
The model predicts exactly one label per input character:
| id | meaning | id | meaning |
|---|---|---|---|
| 0 | non-letter token / padding | 7 | shadda + fatha (ّـَ) |
| 1 | letter, no diacritic | 8 | shadda + damma (ّـُ) |
| 2 | fatha (ـَ) | 9 | shadda + kasra (ّـِ) |
| 3 | damma (ـُ) | 10 | tanwin fatha (ـً) |
| 4 | kasra (ـِ) | 11 | tanwin damma (ـٌ) |
| 5 | sukun (ـْ) | 12 | tanwin kasra (ـٍ) |
| 6 | shadda (ـّ) |
Already-vocalized input is stripped first, so diacritize is idempotent.
Non-Arabic characters (Latin letters, digits, punctuation, spaces) pass through
unchanged.
Model provenance
- Repository:
ichkil/ichkil(model.onnx,config.json,SHA256SUMS) - SHA-256 of
model.onnx:9055816b214346b0a8044a4a8deceb36e818dffd0b04699715ea23883bf54744 - Contract:
input_idsint64[batch, seq]→logitsfloat32[batch, seq, 13]; sequence length fully dynamic (up tomax_seq_len = 1024in the golden contract) - Quality: DER 2.80 % on the reference evaluation set; ONNX output is bit-identical to the PyTorch reference (equivalence verified)
- The cross-runtime golden vectors shipped in
tests/golden.jsonare a verbatim copy of the core repository'sgolden/vectors.json
Development
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest # pure pipeline tests (no network)
pytest -m integration # + model tests (downloads once, ~5 MB)
ruff check . && ruff format --check . # lint
Publishing
v* tags are built and published to PyPI via GitHub trusted publishing (OIDC) —
no API token is stored anywhere. One-time setup on
pypi.org/project/ichkil: Project settings →
Publishing → Add a publisher with github.com/Ichkil/ichkil-python,
workflow: publish.yml.
Sibling libraries
- ichkil-js — npm package (Node.js + browser)
- ichkil-go — Go module
- Core repo — training, evaluation, model spec, golden vectors
License
MIT © 2026 Maaouia BenHamed
Metadata
Release files for ichkil 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| ichkil-1.0.0.tar.gz | 18.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ichkil-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 32.8 kB
Release files / ichkil-1.0.0.tar.gz
| Download URL | ichkil-1.0.0.tar.gz |
|---|---|
| Size | 18.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
13edf40c8575fa3b57c795a6dcdcbcd54d45ceb3d7e781bdc3e08171a87cb0c2
|
|
BLAKE2b-256 checksum How to use checksums |
ca4553ab831ee1269f0e68c485b37713490f580fd9ecb2a228b1386da0787746
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|
Release files / ichkil-1.0.0-py3-none-any.whl
| Download URL | ichkil-1.0.0-py3-none-any.whl |
|---|---|
| Size | 14.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
91699daf9619be408868af4ce4d2177c64088d898b7668a0d4fc8c8d170545fd
|
|
BLAKE2b-256 checksum How to use checksums |
cf40f00e95807b94f22cf1601829a467b9a884904a44db39f70ed72f091eaaf2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|