tawfeer-llm
Arabic text is expensive to tokenize. This library measures exactly how expensive — and safely trims the part that isn't necessary.
pip install ar-tokenwise[tokenizers] · works with Claude, GPT, Gemini, or any LLM API · no model access needed
Why
Arabic uses more tokens per word than English for the same content on
most tokenizers — higher cost, faster context exhaustion, slower
responses. tawfeer-llm normalizes Arabic conservatively (never
changes meaning) and tells you the exact, measured token savings —
not a marketing estimate.
What it doesn't claim: normalizing Arabic does not make a model understand it better. This library's entire value case is cost, context size, and speed — each independently measurable, none of it guesswork.
Install
pip install "ar-tokenwise[tokenizers]"
Optional extras (provider counters, framework integrations)
pip install "ar-tokenwise[tokenizers,providers]" # exact Anthropic/Gemini token counts
pip install "ar-tokenwise[tokenizers,integrations]" # LiteLLM / LangChain / LlamaIndex wrappers
First-time network note: the first call to
report_savings()(or anything usingget_default_counter()) downloads tiktoken's encoding file once, then caches it locally — no network needed after that. On a restrictive network, this first call can fail; seeCONTRIBUTING.mdfor what that looks like and how to work around it.
Quick start
from ar_tokenwise import normalize, NormalizationLevel, report_savings
text = "مَرْحَـبًا بكم، اليوم ٢٠٢٦."
optimized = normalize(text, level=NormalizationLevel.LIGHT)
report = report_savings(text, optimized, cost_per_million_tokens=3.0)
print(report.tokens_saved, report.percent_saved, report.estimated_cost_savings_usd)
Preserve verified Quranic passages
Use preserve_quran=True when the input may contain Quranic quotations.
The bundled reference corpus is loaded and indexed once per process; matching
uses text with tashkeel and tatweel removed, while a confirmed passage is
copied to the result exactly as the user supplied it. Four words are required
for an independent match. Shorter two- or three-word portions are preserved
only when they directly extend a confirmed quote.
from ar_tokenwise import normalize
text = "قال تعالى: بِسْمِ ٱللَّهِ ٱلرَّحْمَٰنِ ٱلرَّحِيمِ ٱلْحَمْدُ لِلَّهِ"
safe = normalize(text, preserve_quran=True)
The bundled source is Quran JSON; see
QURAN_DATA_NOTICE.md for
attribution. It remains a direct-text verifier, not a classifier: genuine
spelling changes outside the configured comparison key will not match.
Before you normalize anything: Quranic/Hadith text, embedded ID numbers, and text displayed verbatim to a user should not be normalized — see
skill/SKILL.mdfor the full, non-negotiable list.
What's included
| 🧹 Conservative normalization | Strips decorative elongation & optional diacritics, unifies digit forms — never changes meaning |
| 📊 Transparent reporting | Real before/after token counts against an actual tokenizer, never estimated |
| ✂️ RAG chunking | Sentence-boundary-aware, token-budgeted chunk_text() |
| 🔤 Mixed-text & Arabizi handling | Separate fertility for Arabic / Latin / Arabizi ("7abibi") words in the same text |
| 🗣️ Dialect signal (experimental) | Probability distribution across MSA/Gulf/Egyptian/Levantine/Maghrebi — never a confident single label |
| ⚠️ Content-sensitivity warnings | Advisory-only religious/legal/medical flags, opt-in, never automatic |
| 🔑 Cache-key generation | Diacritized & undiacritized text hash to the same cache/embedding key |
| ⚡ Prompt-caching optimizer | Reorders labeled prompt segments for Anthropic/OpenAI prompt-cache hits |
| 🎯 Exact provider token counts | Real counts via Anthropic's and Gemini's own APIs, not an approximation |
| 🔌 Framework integrations | Thin, optional wrappers for LiteLLM, LangChain, LlamaIndex |
Every item above is a heuristic where a heuristic is involved, and says
so in its own docstring — see skill/REFERENCE.md
for full usage and every documented limitation before relying on one in
production.
How this compares
| Works with closed APIs | Arabic-specific | Reports token savings | |
|---|---|---|---|
| AraToken / aranizer (alt. tokenizers) | ❌ | ✅ | ❌ |
| PyArabic (text preprocessing) | ✅ | ✅ | ❌ |
| tawfeer-llm | ✅ | ✅ | ✅ |
AraToken/aranizer require retraining or hosting your own model. PyArabic
has no concept of LLM token cost. tawfeer-llm is middleware: drop-in
normalization plus measurable reporting for any API you already call.
Benchmark
242 hand-authored sentences across MSA, four dialect regions, mixed Arabic-English, and formal/legal register — run it yourself:
python benchmark/run_benchmark.py
Full corpus methodology, a reusable quality-check tool, and honest
caveats on every measured number: benchmark/README.md.
Docs
skill/SKILL.md |
Core usage rules — read this before normalizing anything sensitive |
skill/REFERENCE.md |
Every advanced module, in full detail |
benchmark/README.md |
Corpus methodology & measured results |
integrations/README.md |
Notes for extending a framework integration |
CONTRIBUTING.md |
Dev setup, running tests, code conventions, PR process |
License
Apache License 2.0 — see LICENSE.
Metadata
Release files for ar-tokenwise 0.2.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 | |
|---|---|---|---|
| ar_tokenwise-0.2.0.tar.gz | 377.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ar_tokenwise-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 707.1 kB
Release files / ar_tokenwise-0.2.0.tar.gz
| Download URL | ar_tokenwise-0.2.0.tar.gz |
|---|---|
| Size | 377.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
36d3575e47036f3faf8ca277ad943836764bdd6de8d55c9f22d5c9c1e17ced43
|
|
BLAKE2b-256 checksum How to use checksums |
1497d98133922b44d8cddd370413e0fafd92dcd27aeecb0d8de6640764178649
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.6
|
Release files / ar_tokenwise-0.2.0-py3-none-any.whl
| Download URL | ar_tokenwise-0.2.0-py3-none-any.whl |
|---|---|
| Size | 330.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d7c88ada316a0b002df783c47c3a8c48a78db8c3e64ec61fbda1334c21513f9f
|
|
BLAKE2b-256 checksum How to use checksums |
dd1587193499bdbdc040069d08f86303a6500a17739905dda582afe38abdffda
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.6
|