You need to agree to share your Hugging Face information to access this model

This repository is publicly accessible, but you have to accept the conditions to access its files and content.

Log in or Sign Up to review the conditions and access this model content.

PII Tagger Edge

A 45M-parameter GLiNER span tagger for personal data in text. It marks names, addresses, emails, phone numbers, account and ID numbers, usernames and dates of birth, and gives their exact positions; it writes no text. It runs on a CPU: about half a second for a page of text on four cores, so it can screen text before it is sent to a language model.

This is round 7 of its training: round 6's model, trained for three more 500-step segments (4,000 chunks each) on a mix that adds US tax forms (W-2s and the other forms of the K-1, W-9, W-4, 1099, 1040, 1095 and 1098 families, generated and written by agents), more agent-written documents of many kinds, and labelled real emails, tweets and chats. Round 6 is tagged round-6.

Use

from gliner import GLiNER

model = GLiNER.from_pretrained("Deerpark/pii-tagger-edge")            # PyTorch
model = GLiNER.from_pretrained("Deerpark/pii-tagger-edge",             # or ONNX, 91 MB
                               load_onnx_model=True, load_tokenizer=True,
                               onnx_model_file="onnx/model_f16.onnx")

LABELS = ["name", "street address", "city", "postcode", "email address", "phone number", "ssn",
          "account number", "credit card number", "iban", "swift code", "date of birth", "customer id",
          "employee id", "username", "passport number", "driver license number", "tax id"]
model.predict_entities(text, LABELS, threshold=0.35)
  • Ask with these label names: it was trained on them.
  • 0.35 is the threshold chosen on dev sets: the one with the highest share found among thresholds whose share of other words hidden is no higher than the previous best model's.
  • Give it up to about 200 words at a time (whole lines); split longer text into chunks that way.
  • onnx/model_f16.onnx stores the weights in 16 bits and casts them to 32 as ONNX Runtime loads them. Don't quantize it with ONNX Runtime's usual int8 (quantize_dynamic): many scores sit near the threshold.

Redact

The model only detects: it returns spans and leaves the text unchanged. To hide what it finds, replace each span with a placeholder:

def redact(text, threshold=0.35):
    spans = model.predict_entities(text, LABELS, threshold=threshold)
    for s in sorted(spans, key=lambda s: s["start"], reverse=True):  # replace from the end so offsets stay valid
        tag = s["label"].upper().replace(" ", "_")
        text = text[:s["start"]] + f"[{tag}]" + text[s["end"]:]
    return text

redact("Hi, I'm Maria Lopez. Email maria.lopez@example.com or call 415-555-0134. SSN 123-45-6789.")
# "Hi, I'm [NAME]. Email [EMAIL_ADDRESS] or call [PHONE_NUMBER]. SSN [SSN]."

For text longer than about 200 words, run redact on each chunk. Keep the original text on your side if you need to restore the values later.

Results

Locked test: 165 documents (3,850 labelled details, 148 document types) written by agents who saw neither the training documents nor any earlier test, made before round 7's data existed and scored once with this model at 0.35. Found is the share of labelled details hidden in full; the interval is a 95% bootstrap over documents.

System Found Other words hidden
this model 94.0% [92.7, 95.1] 4.2%
Presidio (default recognizers, spaCy en_core_web_lg) 49.5% [46.6, 52.4] 7.3%
spaCy en_core_web_lg (people, facilities) 26.5% 3.7%
scrubadub (default detectors) 12.0% 1.1%

Open PII models on the same documents, at a single threshold of 0.5 (this favours eager models on finds): NVIDIA GLiNER-PII 61.5% / 3.6%, Piiranha 50.8% / 4.7%, GLiNER PII edge (this model's base) 50.2% / 3.5%, GLiNER PII large 48.9% / 1.7%, GLiNER PII base 46.3% / 2.6%, GLiNER multi-PII 30.2% / 2.3%.

By type of data: SSN 100%, passport 100%, driver licence 100%, email 98.5%, phone 98.4%, tax / national ID 96.9%, date of birth 96.7%, IBAN 94.0%, username 94.2%, name 93.8% (1,781 details), customer ID 93.4%, credit card 89.4%, account number 88.4%, address 88.1%, employee ID 76.5%.

Limitations

  • It reaches 99% on none of these sets. Names (93.8%), addresses (88.1%), account numbers and employee IDs are where most real misses are.
  • Hand-written W-2s: about 86% found on a small dev set. Training on generated W-2 layouts did not transfer to documents written by other authors.
  • Scanned documents lose about 5 points to OCR before the model reads them (Tesseract on degraded pages).
  • It hides some public figures' and fictional characters' names, which protects no one.
  • The documents in the test sets were written by Claude agents to written rules, and the labels are theirs; no human second review has been done of these labels. It's one layer of a redaction pipeline, not a guarantee.

Data and privacy

Every person in the agent-written documents and the synthetic forms is made up. The WildChat turns are as WildChat-1M published them, after Presidio's de-identification, with the details Presidio missed labelled so the model learned to find them. Enron's emails were used only as a test. A span tagger returns positions in the text it's given and can't generate text.

Attribution

Downloads last month
10
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for Deerpark/pii-tagger-edge

Quantized
(2)
this model

Datasets used to train Deerpark/pii-tagger-edge