cbx-pii-extractor-17M

Finds personal information (PII) in English text and returns the exact position of each value with one of 18 labels. 17M parameters, about 6 ms per 1,000 tokens on a GPU and 37 ms on a CPU.

This is the fastest size, and the one to use on CPU. Fine-tuned from jhu-clsp/ettin-encoder-17m. Current version: v0.2 (use --revision v0.2 to pin it). Also available in 68M and 32M sizes.

What's new in v0.2

  • 18 labels instead of 12. Account numbers, government IDs and other IDs are split into specific types (table below).
  • More accurate on chat and business documents:
    • lowercase and first-name-only names;
    • Slack mentions such as <@U02NORA>;
    • verification codes;
    • policy, member and account references;
    • employee IDs in tables.
  • The same speed as v0.1.

Upgrading from v0.1. The label names changed. Pin --revision v0.1 to keep the old ones, or map the new labels back like this:

V01 = {"DATE_OF_BIRTH": "DATE", "BANK_ACCOUNT": "ACCOUNT_NUMBER", "PAYMENT_CARD": "ACCOUNT_NUMBER",
       "CUSTOMER_ID": "ACCOUNT_NUMBER", "NATIONAL_ID": "GOV_ID", "PASSPORT": "GOV_ID", "TAX_ID": "GOV_ID",
       "DRIVERS_LICENSE": "GOV_ID", "EMPLOYEE_ID": "OTHER_ID", "PATIENT_ID": "OTHER_ID"}
spans = [dict(s, label=V01.get(s["label"], s["label"])) for s in pii.extract(text)]

Labels

Label Covers v0.1 label
PERSON Names, including first names only, initials, nicknames and lowercase names PERSON
DATE_OF_BIRTH Dates of birth only (other dates are not labelled) DATE
EMAIL Email addresses EMAIL
PHONE Phone and fax numbers, including extensions PHONE
ADDRESS Full street addresses, with unit, city and postcode (a city or country on its own is not labelled) ADDRESS
BANK_ACCOUNT Bank account numbers and IBANs ACCOUNT_NUMBER
PAYMENT_CARD Card numbers, including the last four digits ACCOUNT_NUMBER
CUSTOMER_ID Customer, member and policy numbers, and account references (not ticket or order numbers) ACCOUNT_NUMBER
NATIONAL_ID Social security and national ID numbers GOV_ID
PASSPORT Passport numbers GOV_ID
TAX_ID Tax IDs GOV_ID
DRIVERS_LICENSE Driving licence numbers GOV_ID
USERNAME Usernames and handles; @ mentions include the @, and Slack mentions include <@ and > USERNAME
URL Web addresses, with or without https:// URL
IP_ADDRESS IPv4 and IPv6 addresses IP_ADDRESS
SECRET Passwords, PINs, verification and access codes, API keys and tokens SECRET
EMPLOYEE_ID Employee and staff IDs OTHER_ID
PATIENT_ID Patient IDs and medical record numbers OTHER_ID

How to use

1. Download and install

pip install -U huggingface_hub
hf download CobuildX-AI/cbx-pii-extractor-17M --revision v0.2 --local-dir cbx-pii-extractor-17M
cd cbx-pii-extractor-17M
pip install -r requirements.txt

2. Use it in your code

PIIExtractor (in pii.py, part of this repo) loads the model once:

from pii import PIIExtractor

pii = PIIExtractor()                 # uses a GPU if one is available
pii.extract("Hi team, I'm Priya Raman (priya.raman@northwind.com).")
# [{'label': 'PERSON', 'text': 'Priya Raman', 'start': 13, 'end': 24},
#  {'label': 'EMAIL', 'text': 'priya.raman@northwind.com', 'start': 26, 'end': 51}]

pii.redact("Hi team, I'm Priya Raman (priya.raman@northwind.com).")
# "Hi team, I'm [PERSON] ([EMAIL])."

pii.extract(text, labels=["PERSON", "EMAIL"])   # keep only some labels
  • The model finds the PII. redact() replaces each value it found with its label, or with your own template.
  • Context length is 7,999 tokens, read in a single pass. Longer texts are split automatically.

3. Optional: check your setup

python example.py runs four sample texts and prints what it finds.

Results

Exact-match span F1 on three public benchmarks never used for training. A value counts only if its start, end and label are all correct.

Model Size Privacy-Bench docs Privacy-Bench messages PII-TRACE GPU, 1,000 tokens
cbx-pii-extractor-68M 68M 88.1% 91.7% 93.2% 13 ms
cbx-pii-extractor-32M 32M 88.0% 87.0% 93.5% 8 ms
cbx-pii-extractor-17M 17M 86.1% 83.1% 91.6% 6 ms
PII-Tracer 596M 86.9% 82.0% 92.5% 160 ms
GLiNER2-PII 205M 80.8% 86.9% 66.2% 91 ms
Presidio (spaCy lg) – 82.4% 85.8% 64.7% 85 ms (CPU)
  • Privacy-Bench docs: 656 human-annotated pages of business documents.
  • Privacy-Bench messages: 5,198 chat messages.
  • PII-TRACE: 500 conversations. It is PII-Tracer's own benchmark. Most of our remaining gap there is dates other than dates of birth, which we deliberately don't label. Without dates, this model scores 96.0% against 91.9% for PII-Tracer.

On text with no PII at all, this model flags 0.08 false values per 1,000 characters, against 1.6–3.6 for the other models.

How we evaluated

  • Same runs for every model. We ran every model ourselves, on the same texts, with the same scoring.

  • Benchmark sizes:

    Benchmark Contents Annotated values in the scored types
    Privacy-Bench docs 656 pages of Word and PDF business documents 8,700
    Privacy-Bench messages 5,198 chat messages 6,594
    PII-TRACE 500 multi-turn conversations (public subset) 2,442
  • No overlap with training data. No training text shares a 13-word sequence with any benchmark.

  • How the benchmarks were used. Half of each benchmark was used to study errors while we designed the training data. Scores on the other half are within 0.6 points of the full-set numbers above.

A prediction counts as correct only when its start, end and type all match the annotation. Each benchmark's types were mapped to ours as below. Every model was scored on the types that both the benchmark and the model support.

CBX PII Extractor Privacy-Bench PII-TRACE
PERSON NAME_GIVEN + NAME_FAMILY (one name) private_person
EMAIL EMAIL_ADDRESS private_email
PHONE PHONE_NUMBER private_phone
ADDRESS LOCATION_ADDRESS private_address
URL URL private_url
BANK_ACCOUNT, PAYMENT_CARD, CUSTOMER_ID ACCOUNT_NUMBER account_number
USERNAME USERNAME Not annotated
EMPLOYEE_ID EMPLOYEE_ID Not annotated
DATE_OF_BIRTH Not annotated private_date
SECRET Not annotated secret

Government IDs, IP addresses and patient IDs are not annotated in either benchmark, so this evaluation does not cover them.

Speed. Latency is the median over 50 texts of 1,000 tokens, processed one at a time, end to end (text in, spans out). It was measured on an NVIDIA TITAN RTX GPU (fp16) and an Intel i7-10700 CPU (8 threads), with all models on the same machine. The v0.1 card used a Tesla T4, so its timings are not directly comparable.

Limitations

  • English only.
  • Sensitive attributes such as health, religion or ethnicity are not detected.
  • Account and reference numbers inside long documents, and usernames in documents, are found less reliably than names, emails and phones.
  • Addresses are always labelled in full. Benchmarks that mark only the street will count them as boundary errors.
  • A detection aid, not a guarantee: keep human review where redaction must be complete.

Licence

Apache-2.0. Trained on NVIDIA Nemotron-PII (CC-BY-4.0), Gretel PII masking EN v1 and Gretel synthetic PII finance (Apache-2.0), Wismut nym-pii (MIT), Kiji PII training data (Apache-2.0) and data we generated. Base model: Ettin (MIT, arXiv:2507.11412).

Downloads last month
10
Safetensors
Model size
16.8M params
Tensor type
F32
Β·
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support

Model tree for CobuildX-AI/cbx-pii-extractor-17M

Finetuned
(48)
this model

Paper for CobuildX-AI/cbx-pii-extractor-17M