Rishe (ریشه)
Fast Persian NLP and morphology, built in Rust.
Rishe (root in Persian) turns raw Persian text into clean, structured data in one call: normalized text, tokens, lemmas, sentences, ezafe markers, and a formal rewrite of colloquial writing. It also ships the morphology utilities that usually live in a separate library: stemming, verb conjugation, inflection, token splitting, spell correction, and stopword removal.
The core is Rust. You get it as a pip install with prebuilt wheels, no model
downloads, no runtime dependencies, and the same engine as a Rust crate.
from rishe import Pipeline
pipe = Pipeline()
doc = pipe("اون داره تو خونه کتاب میخونه، چیه؟")
doc.tokens # ['آن', 'دارد', 'تو', 'خانه', 'کتاب', 'میخواند', '،', 'چیست', '؟']
doc.lemmas # ['آن', 'داشت', 'تو', 'خانه', 'کتاب', 'خواند', '،', 'چیست', '؟']
doc.formal_text # 'آن دارد تو خانه کتاب میخواند، چیست؟'
Why Rishe
- Normalization about 80× faster than Hazm and Shekar: 1.2 µs per sentence against 96 µs and 104 µs.
- Best tokenization and lemmatization in this comparison. Token F1 of 1.0000 on UD-Seraji, 0.9989 on UD-PerDT and 0.9028 on PEYMA; lemma accuracy of 0.9209 and 0.9316, ahead of Hazm (0.9048 / 0.9009) and Shekar (0.81 / 0.82).
- Morphology in the same core. Stemming, conjugation, inflection, token splitting, spell correction and stopwords — no second library, no extra runtime. On the UD lemma proxy, stemming is 89.2% / 89.5% exact against Hazm (66.4% / 64.4%) and Shekar (76.1% / 72.0%).
- Spell correction that is fast enough to stay in the loop. 80.8% top-1 and 96.2% top-5 on synthetic 1-edit typos, at 0.16 ms per word; Shekar's statistical checker is 60.8% / 77.6% at 94 ms per word on the same set.
- Millions of tokens per second. 1.0M tokens/s on one thread;
pipe()runs batches in parallel with the GIL released and reaches 6.5M tokens/s on 12 threads. - Everything in one call. Normalization, informal → formal conversion,
tokenization, lemmatization, sentence splitting and ezafe detection from one
Pipelineobject, in about 16 µs per sentence. - Informal Persian handled. Colloquial forms (
اون,خونه,داره,میخوام,چیه) are rewritten to their formal spelling, and fused clitics such asبهشandازشare split intoبه+اوandاز+او. - Nothing to set up. Compiled-in lexicons (190k nouns, 1.2k verb stems, word frequencies, stopwords), no model downloads, no Python dependencies, no network access.
- Wheels for every major platform. Linux (glibc and musl, x86_64 and aarch64), macOS (Intel and Apple Silicon) and Windows, for Python 3.9+ (abi3). The same core is available as a Rust crate.
- Thread-safe. One
Pipelinecan be shared across threads.
Benchmarks
Measured against Hazm and Shekar on the full UD Persian-Seraji, UD Persian-PerDT and PEYMA test sets. Every library is built once and reused.
Core speed (per sentence, single thread)
| Rishe | Hazm | Shekar | |
|---|---|---|---|
| Normalize | 1.2 µs | 96 µs | 104 µs |
| Tokenize | 4.1 µs | 5.7 µs | 4.4 µs |
| Full pipeline | 16.3 µs | — | — |
Core accuracy
| Task | Dataset | Rishe | Compared with |
|---|---|---|---|
| Token F1 | UD-Seraji | 1.0000 | Shekar 0.9992, Hazm 0.9810 |
| Token F1 | UD-PerDT | 0.9989 | Shekar 0.9976, Hazm 0.9609 |
| Token F1 | PEYMA | 0.9028 | Shekar 0.9018, Hazm 0.8901 |
| Lemma accuracy | UD-Seraji | 0.9209 | Hazm 0.9048, Shekar 0.8058 |
| Lemma accuracy | UD-PerDT | 0.9316 | Hazm 0.9009, Shekar 0.8170 |
New feature highlights
| Feature | Metric | Rishe | Hazm | Shekar |
|---|---|---|---|---|
| Stemming | exact UD-lemma proxy (Seraji / PerDT) | 89.2% / 89.5% | 66.4% / 64.4% | 76.1% / 72.0% |
| Conjugation | hand-written spot-check (29 forms) | 29/29 | 28/29 | 29/29 |
| Conjugation | ms/verb | 0.010 | 0.152 | 0.080 |
| Inflection | comparative / superlative / plural | 100% | N/A | 100% |
| Token splitting | ms/token | 0.0006 | 12.05 | N/A |
| Spell correction | top-1 / top-5 on 1-edit typos | 80.8% / 96.2% | N/A | 60.8% / 77.6% |
| Stopwords | list size | 389 | 389 | 301 |
The full core tables, batch scaling and method are in docs/BENCHMARKS.md. The feature tables, proxy metrics and caveats are in docs/FEATURE_BENCHMARKS.md.
Reproduce:
python scripts/benchmark.py # core token/lemma/speed
python scripts/benchmark_features.py # stemming, conjugation, splitting, spelling
Install
pip install rishe # Python >= 3.9
or, from Rust (Cargo.toml): rishe = "0.2".
No Python dependencies. No model downloads. No network access at runtime.
Usage
from rishe import Pipeline
pipe = Pipeline() # unify digits, strip diacritics, fix ZWNJ
doc = pipe("کتابهای خوب را به دوستانم میدهم.")
doc.normalized_text, doc.formal_text, doc.sentences
doc.tokens, doc.lemmas, doc.ezafe_markers
docs = pipe.pipe(texts) # parallel batch -> list[ProcessedDoc]
pipe.normalize("مي كنم 2026") # 'میکنم ۲۰۲۶'
pipe.tokenize("سلام، دنیا!") # raw tokenization, no normalization
pipe.word_tokenize("سلام، دنیا!") # normalize + tokenize
pipe.sent_tokenize(text) # sentence splitting only
pipe.lemmatize("میروم") # 'رفت' (past-stem lemmas, UD style)
pipe.lemma_full("میروم") # ('رفت', 'رو') (past + present stem)
pipe(text) also rewrites colloquial words to formal ones, so its tokens can
differ from the surface text; word_tokenize tokenizes without rewriting.
tokenize is the fast raw path used for the tokenization benchmarks.
Morphology and utilities
pipe.stem("کتابها") # 'کتاب'
pipe.conjugate("رفت")["present"][:3] # ['میروم', 'میروی', 'میرود']
pipe.comparative("بزرگ") # 'بزرگتر'
pipe.superlative("بزرگ") # 'بزرگترین'
pipe.plural("کتاب") # 'کتابها'
pipe.possessive("خانه", 0) # 'خانهام'
pipe.split_token("بهش") # ['به', 'او']
pipe.spell_suggest("سسلام") # ['سلام', 'اسلام', ...]
pipe.spell_correct("سسلام بر ششما") # 'سلام بر شما'
pipe.tokenize_spans("سلام دنیا") # [('سلام', 0, 4), ('دنیا', 5, 9)] (char offsets)
pipe.remove_stopwords(tokens) # drop Persian stopwords
pipe.process_stages(text, ["normalize", "sentences"]) # choose pipeline stages
Spell correction uses a 190k-word frequency lexicon and edit-distance 1; typos with two or more edits are left unchanged.
use rishe::Pipeline;
let pipe = Pipeline::create(true, true, true);
let doc = pipe.process("کتابهای خوب را به دوستانم میدهم.");
println!("{:?}", doc.tokens);
println!("{}", pipe.stem("کتابها"));
Scope
Rishe is a text-preprocessing and morphology engine: normalization, tokenization, sentence splitting, lemmatization, stemming, verb conjugation, inflection, token splitting, spell correction, stopword removal, ezafe detection and informal → formal conversion.
It does not yet do POS tagging, chunking, NER, dependency parsing, embeddings or text classification. Those are the next optional model packs; the base stays zero-dependency and fast. Today, use Rishe as the preprocessing step in front of a tagger or parser.
Building from source
cargo test
maturin develop --release # Python extension into the current venv
python scripts/benchmark.py # needs: hazm shekar conllu
python scripts/benchmark_features.py
scripts/extract_lexicons.py regenerates data/*.tsv and
data/word_freq.tsv from Hazm's data files; build.rs compiles them into FSTs.
License
Dual-licensed under Apache-2.0 or MIT, at your option. The bundled lexicons, stopwords and word frequencies are derived from Hazm data (MIT); see NOTICE.md.
Metadata
Release files for rishe 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 | Provenance | |
|---|---|---|---|---|
| rishe-0.2.0.tar.gz | 1.8 MB | With provenance | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| rishe-0.2.0-cp39-abi3-win_amd64.whl | CPython 3.9 | abi3 | Windows x86-64 | Details |
| rishe-0.2.0-cp39-abi3-musllinux_1_2_x86_64.whl | CPython 3.9 | abi3 | Linux musl 1.2+ x86-64 | Details |
| rishe-0.2.0-cp39-abi3-musllinux_1_2_aarch64.whl | CPython 3.9 | abi3 | Linux musl 1.2+ ARM64 | Details |
| rishe-0.2.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | CPython 3.9 | abi3 | Linux glibc 2.17+ x86-64 | Details |
| rishe-0.2.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl | CPython 3.9 | abi3 | Linux glibc 2.17+ ARM64 | Details |
| rishe-0.2.0-cp39-abi3-macosx_11_0_arm64.whl | CPython 3.9 | abi3 | macOS 11.0+ ARM64 | Details |
| rishe-0.2.0-cp39-abi3-macosx_10_12_x86_64.whl | CPython 3.9 | abi3 | macOS 10.12+ x86-64 | Details |
Total release size: 16.0 MB
Release files / rishe-0.2.0.tar.gz
| Download URL | rishe-0.2.0.tar.gz |
|---|---|
| Size | 1.8 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8d8b934161b97c66f5347d512e4e0f471532dbcbc7fc970b6cdd643c30b5b5b7
|
|
BLAKE2b-256 checksum How to use checksums |
84bb2db437eaedd995b09898bf990e9c078c1c07109c40deef6e912f58864798
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.
Transparency logRelease files / rishe-0.2.0-cp39-abi3-win_amd64.whl
| Download URL | rishe-0.2.0-cp39-abi3-win_amd64.whl |
|---|---|
| Size | 1.9 MB |
| Tags | CPython 3.9 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
0419d2b5265c9c18f8e9d81ac07458905129d359c0b69208c526b9f590482f8e
|
|
BLAKE2b-256 checksum How to use checksums |
1c86e19699e4c154a0ac24bb219910da5fbc32f49d65678e9c2d63a5fd5c78b5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.
Transparency logRelease files / rishe-0.2.0-cp39-abi3-musllinux_1_2_x86_64.whl
| Download URL | rishe-0.2.0-cp39-abi3-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 2.2 MB |
| Tags | CPython 3.9 Linux musl 1.2+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
aa65dd2a41ed8c388be9f0e3274d2bbf940926ec6a3662d74fd9c41ba212f094
|
|
BLAKE2b-256 checksum How to use checksums |
45d6e14a6894d740e0d9f04c5ce0d969e07e7adfa2a3b14f17a8b8ece3124f57
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.
Transparency logRelease files / rishe-0.2.0-cp39-abi3-musllinux_1_2_aarch64.whl
| Download URL | rishe-0.2.0-cp39-abi3-musllinux_1_2_aarch64.whl |
|---|---|
| Size | 2.2 MB |
| Tags | CPython 3.9 Linux musl 1.2+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
d4a343497b4cde13f9b8ab70a944b468bb6b54f6005e4ac6b647502cb165e927
|
|
BLAKE2b-256 checksum How to use checksums |
fa927422bbfc8e0327cc9694acab69a0f0594e33e32f3de3d2655547e74a2033
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.
Transparency logRelease files / rishe-0.2.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | rishe-0.2.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 2.0 MB |
| Tags | CPython 3.9 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
6afb17b760cf8269d5dd4d33be2a778ffb24217297dfab2621516c9dadaef59c
|
|
BLAKE2b-256 checksum How to use checksums |
0c0bb7a0aed112a30063026ac994d936990ce3e7dbe9a986a5616725c6a3c1bd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.
Transparency logRelease files / rishe-0.2.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | rishe-0.2.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 2.0 MB |
| Tags | CPython 3.9 Linux glibc 2.17+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
3e8049a6f686e1b3e84066fb430e5c7d2b4ad69693f91a8fe7392ef05f9ccbd5
|
|
BLAKE2b-256 checksum How to use checksums |
01e2f2e1877fa122cdaf1a1b8cf5f69ac013d7dd3be069c65d63586908c86412
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.
Transparency logRelease files / rishe-0.2.0-cp39-abi3-macosx_11_0_arm64.whl
| Download URL | rishe-0.2.0-cp39-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 2.0 MB |
| Tags | CPython 3.9 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
56f5e0e67981428955c269cbe99d8a6d0e64382ca9c5ba54d130ad80adc13fce
|
|
BLAKE2b-256 checksum How to use checksums |
f6a6762c1f2e33088c920130910b6b8efbe9f8600263e97fab186bf760dcc576
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.
Transparency logRelease files / rishe-0.2.0-cp39-abi3-macosx_10_12_x86_64.whl
| Download URL | rishe-0.2.0-cp39-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 2.0 MB |
| Tags | CPython 3.9 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
83c49d9b18443c9cd12f4f7931b366f1ddc63d5fc9903207a72add8eaa79eebc
|
|
BLAKE2b-256 checksum How to use checksums |
82a0d2ac2651fe2e2f962b1ebc29e7c2ea082665b7be134f4005ff5454f3483c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.
Transparency logSecurity for rishe 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 8 files in this release have been uploaded with provenance metadata.
Attestation for rishe-0.2.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.