decima-pii (preview)

Try it in your browser: https://amyrmahdy-decima-playground.static.hf.space/pii.html

decima-pii on the command line: an Arabic, a Persian, a Turkish, an Urdu and an English message redacted, then a message whose order number and hotline are left alone

Finds personal data in Arabic, Persian, Urdu, Turkish and English text, on a CPU, in about 13 ms per message (6 threads). Names, phone numbers, emails, national IDs, IBANs, card numbers, passports, addresses, dates of birth and IP addresses, including numbers written in Arabic-Indic or Persian digits (۰۹۱۲…, ٠٥٥…).

I built it because the tools I had treat these languages as an afterthought. In my tests Presidio's defaults missed close to half of the values written in Persian or Arabic-Indic digits, and OpenAI's privacy filter scored well below its English level on Arabic, Persian and Turkish (table below). This model is small (140M parameters, 148 MB as int8), runs offline, and nothing you scan leaves your machine.

It is a preview. The numbers below are real, and so are the limits. Please read them.

Results on a test set I did not make

MultiGraSCCo (Baroud et al., LREC 2026) is a set of clinical letters translated into ten languages, built by other researchers. decima-pii never trained on it. I scored the five types it shares with this model (names, phones, emails, addresses, dates of birth; 1,814 spans), relaxed typed F1 as in their paper.

Finding personal data in text the model never saw: MultiGraSCCo relaxed typed F1 (lenient) per language for decima-pii, openai/privacy-filter and Presidio

all 4 English Arabic Persian Turkish recall
decima-pii 0.870 0.957 0.843 0.805 0.889 0.96
openai/privacy-filter 0.647 0.901 0.581 0.508 0.626 0.66
Presidio (English defaults) 0.117 0.357 0.048 0.060 0.110 0.47

"Lenient" scoring: a prediction on real personal data that this test does not label for these five types (a clinic name, a visit date) is not counted as a false positive. Strict scoring, which does count them: decima-pii 0.814, privacy filter 0.415, Presidio 0.099. Their paper's own models score higher on this set, but they were trained on it and are scored on all of its types, so the numbers are not comparable.

How blind is this? No text, label or name from MultiGraSCCo was used in training. But an earlier version of this model (pii1) was tested on it first, and its mistakes there led me to add clinical-letter-style training text. That earlier, fully blind version scored 0.652 (with the same decoding as below). Treat 0.87 as "measured after one look", not as a pure first look.

More test sets made by other people

Scored zero-shot: none of these were used in training, with no exact text overlap and almost no template overlap (0–1 rows per set). Each set's own system was trained on that set, and it beats decima-pii on it.

set language decima-pii the set's own best (in-domain)
Bayanat Labs arabic-pii-eval, test (1,000 sentences; MSA, Gulf, Egyptian; Arabic-Indic and Persian digits) ar exact typed F1 0.953 rules on ID formats 0.98–1.00, names 0.874
Reza Sayar's persian-pii-masking-openpii, test, first 2,000 rows fa relaxed typed F1 0.881 Sayar's mBERT, 0.974
Boran Toktay's turkish-privacy-pii-ner, test (10,393 rows) tr relaxed typed F1 0.886 Toktay's fine-tuned filter, 0.998
REDACT (Vats et al., EMNLP 2026 Industry), locked split, Arabic/Turkish/English records (51 types; 41 are not ours and count as misses) ar / tr / en partial micro-F1 0.51 / 0.50 / 0.49 Claude Sonnet 4.6 0.68 / 0.59 / 0.60; OpenAI privacy filter as published by the authors 0.44 / 0.39 / 0.41

Where it loses on these: Kuwaiti civil IDs and Bahraini CPRs (about 2 in 3 found), Turkish TCKN sometimes read as a phone number, spelled-out numbers (not found), exact address boundaries in Persian and Turkish forms, and founding years or invoice numbers read as birth dates (16 of 200 no-PII Bayanat sentences got a false hit).

Results on our own test (synthetic, 6,000 messages)

Held-out templates, names and random seeds; balanced over the five languages, with 9,252 look-alike values that are not personal data (order numbers, hotlines, product codes, flight numbers).

typed F1 finds the value at all look-alike values wrongly hit messages with no PII flagged
decima-pii (int8) 0.994 0.998 0.1% 0.3%
openai/privacy-filter 0.481 0.855 66.7% 70.8%
Presidio (English defaults) 0.257 0.703 74.0% 91.4%

This test is easier than real text and the model was tuned with its error categories in mind, so read it as "these formats are covered", not as accuracy on your data. National IDs (Iran melli code, Qatar QID, Saudi ID and Iqama, Emirates ID, Pakistan CNIC, Turkey TC Kimlik, Egypt, Morocco, UK NINO, US SSN) are found every time here, in Western, Arabic-Indic and Persian digits. On the outside test above they are not measured.

Use it

pip install onnxruntime tokenizers numpy huggingface_hub
wget https://huggingface.co/amyrmahdy/decima-pii/resolve/main/decima_pii.py
python decima_pii.py "اسم من علی رضایی است و کد ملی من ۰۰۱۲۳۴۵۶۷۸ و شماره موبایلم ۰۹۱۲۳۴۵۶۷۸۹ است."
from decima_pii import DecimaPII

pii = DecimaPII.from_pretrained("amyrmahdy/decima-pii")
pii.find("Merhaba, ben Ayşe Yılmaz, TC kimlik numaram 10000000146.")
# [{'start': 13, 'end': 24, 'label': 'PERSON_NAME', 'text': 'Ayşe Yılmaz'},
#  {'start': 44, 'end': 55, 'label': 'NATIONAL_ID', 'text': '10000000146'}]
pii.redact("مرحبا، أنا أحمد الكعبي، رقم هاتفي +974 5512 3456")
# 'مرحبا، أنا [PERSON_NAME]، رقم هاتفي [PHONE]'

Use decima_pii.py (or port its two short functions) rather than a plain token-classification pipeline. It does two things the raw model output needs: it keeps a spaced number such as 5185 5272 2255 5565 as one span, and it drops spans that cannot be what they claim (a 3-digit phone, an email without "@", a span that cuts through a word). Without the second step the outside score drops from 0.814 to 0.730 (strict). Long texts are tagged in overlapping windows.

Files:

  • onnx/model_nbits8.onnx: int8, 148 MB, the default (all numbers above use it).
  • onnx/model_quantized.onnx: int8 for the browser (onnxruntime-web / transformers.js), 143 MB; 0.971 on our test.
  • onnx/model.onnx: fp32, 563 MB.
  • model.safetensors + config.json: the PyTorch weights (ModernBertForTokenClassification), if you want to fine-tune.

Labels

PERSON_NAME, PHONE, EMAIL, NATIONAL_ID, IBAN, CARD, PASSPORT, ADDRESS, DATE_OF_BIRTH, IP_ADDRESS (BIO tags; see pii_meta.json).

Languages and scripts in training: Arabic (MSA, Gulf, Egyptian, Levantine, Maghrebi, Arabizi), Persian (and Finglish), Urdu (and Roman Urdu), Turkish, English.

Limits

  • Only 5 of the 10 types are measured on outside data. National IDs, IBANs, cards, passports and IP addresses are measured only on our synthetic test.
  • Urdu has no outside test yet. The outside test is itself machine-translated clinical text, not real user messages.
  • In medical text it tags some drug names and medical eponyms that are also surnames (Babinski, Lasègue) as names, and some visit dates as dates of birth. Arabic dates of birth are the weakest cell (strict 0.589).
  • Exact span edges are weaker than detection: on the outside test, exact-span typed F1 is 0.749.
  • It does not tag dates in general, ages, organisations, record numbers or job titles. It is a PII detector, not a complete HIPAA or GDPR de-identification tool. If you need that, use it as one layer and review the output.
  • The browser int8 file is 2.3 points below the default on our test.

How it was made

The backbone is jhu-clsp/mmBERT-small (MIT), fine-tuned for token classification on 150,000 synthetic messages. The values are generated in their real formats by code (valid check digits for national IDs, mod-97 IBANs, Luhn cards), and placed in hand-written and model-written carrier sentences, so every label is exact. Test templates, names and seeds are disjoint from training. Training took 37 minutes on one GPU.

decima-pii is part of Decima, small models for decisions inside LLM systems (see also decima-guard).

If you have real, consented text where it fails, I would like to see the misses. Open a discussion on this page.

Licence: Apache-2.0. The backbone is MIT; its notice is kept in NOTICE.

Downloads last month
29
Safetensors
Model size
0.1B params
Tensor type
F32
·
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for amyrmahdy/decima-pii

Quantized
(297)
this model

Space using amyrmahdy/decima-pii 1

Collection including amyrmahdy/decima-pii