Instructions to use HMC83/name-detector-32m with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use HMC83/name-detector-32m with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("token-classification", model="HMC83/name-detector-32m")# pip install -U transformers accelerate # Load model directly from transformers import AutoTokenizer, AutoModelForTokenClassification tokenizer = AutoTokenizer.from_pretrained("HMC83/name-detector-32m") model = AutoModelForTokenClassification.from_pretrained("HMC83/name-detector-32m", device_map="auto") - Notebooks
- Google Colab
- Kaggle
Name detector 32M
A small model that finds people's names in documents so they can be masked or passed to a person for review. It was built for UK FOI correspondence and public-sector documents (letters, emails, minutes, registers, reports and scanned pages).
| Finds | People's names: full names, first names, surnames and initials |
| Size | 32.0 million weights, 19.3 million of them the token-embedding table. 128 MB as full-precision ONNX or safetensors |
| Context | Windows of up to 2,046 tokens with 256 overlap |
| Base model | jhu-clsp/ettin-encoder-32m (10 layers × 384, ModernBERT architecture), distilled from a 149M teacher |
| Licence | MIT |
Results
A name counts as found only when every character of it is masked. Stock Presidio here is presidio-analyzer 2.2.354 with spaCy en_core_web_lg, PERSON only.
On 86 real documents published by UK public bodies, with every name marked by two people, the model finds 1,611 of 1,628 names and wrongly masks 1,137 characters outside them. Its 149M teacher finds 1,624. Stock Presidio finds 929 and wrongly masks 5,063 characters.
On 100 real FOI requests chosen at random it finds 132 of 132 names, and on 64 test documents with layout and OCR faults added it finds 1,195 of 1,197.
Names from different backgrounds
Each of 179 real FOI messages was rewritten 24 times with names most commonly associated with twelve different backgrounds: Black Caribbean, East African, East Asian, Eastern European, Hispanic and Latin American, Irish, Middle Eastern and Arab, North African, South Asian, South-East Asian, West African and White English. A group describes where a name is most common, and does not determine the heritage of a person.
The model finds 7,176 of the 7,248 names, and between 98.3% and 99.3% in every group, a gap of 1.0 points. A gap that size turns up by chance about 33 times in 100. Stock Presidio's gap on the same test was 28 points.
Public test sets
F1 over the characters of person names. Other documents from TAB and Nemotron-PII were used in training. PrivacyBench is scored with its own overlap rule on given and family names.
| Test set | Stock Presidio | Teacher (149M) | This model |
|---|---|---|---|
| OntoNotes 5 (mixed genres) | 92.2 | 92.9 | 91.5 |
| WNUT-17 (social media) | 49.1 | 64.1 | 61.3 |
| TAB (court judgments) | 81.9 | 93.6 | 93.2 |
| Nemotron-PII (synthetic records) | 78.3 | 98.5 | 98.3 |
| Gretel PII (synthetic documents) | 70.6 | 92.4 | 89.3 |
| AI4Privacy 300k (English) | 36.3 | 82.1 | 79.8 |
| Tonic PrivacyBench (synthetic emails, chat and documents) | 87.9 | 95.5 | 92.8 |
How to use it
With the code in this repository (onnxruntime, tokenizers and numpy; no PyTorch). Every figure above was measured this way.
import sys
from huggingface_hub import snapshot_download
path = snapshot_download("HMC83/name-detector-32m")
sys.path.insert(0, path + "/code")
import runtime
detector = runtime.Detector(path)
text = "Dear Ms Okonjo,\n\nSam Hill has checked the figures. AR to circulate.\n\nPriya Raman\nInformation Governance"
for f in detector.findings(text):
print(text[f["start"]:f["end"]], f["score"])
detector.findings(text, requester="…", authority="…") can optionally take the requester's and the authority's names where known. The authority's name is then never masked and the requester's always is.
The code masks a whole word when any piece of it scores at or above the threshold (0.2, the tau value in namecfg.json). It also masks initials that the document defines, such as "AR" after "Anjali Raval (AR)", and reads long texts in overlapping windows. A lower threshold finds more names and masks more text that is not a name. Titles such as "Dr" are left unmasked.
With transformers, for a quick look (this skips the steps above and finds slightly fewer names):
from transformers import pipeline
tagger = pipeline("token-classification", model="HMC83/name-detector-32m", aggregation_strategy="simple")
tagger("Sam Hill has checked the figures with Priya.")
How it was trained
A teacher, ModernBERT-base (149M weights), was fine-tuned to tag the tokens of people's names. Its training text was NVIDIA Nemotron-PII, court judgments from the Text Anonymization Benchmark, Few-NERD, and invented domain text: templates, generated documents covering initials, OCR faults and names that are ordinary words, and UK public-sector documents.
This model starts from the public Ettin 32M weights and was trained for three passes to copy the teacher. Its training text adds 728 copies of 91 documents published by 40 UK public bodies under the Open Government Licence, with every person's name replaced by an invented one, and long windows so it learns to use an attendee list far above the line it is reading. The threshold was chosen by a rule fixed in advance, on development sets only. No real FOI correspondence was used for training, and none of the real test documents.
Limits
- It misses some names, most often initials: 16 of the 17 it missed in the real documents were two or three capital letters.
- It is built for English in the UK public sector. Names in Welsh-language text are found less reliably, and other languages are untested.
- It sometimes masks abbreviations, status letters, role words such as "Clerk", and organisations or places named after people.
- It misses more lower-case first names in informal chat.
- It finds names only. Pair it with patterns for email addresses, phone numbers and reference numbers.
- A second training run with a different random seed found 1,605 names in the real documents where this one found 1,611, so differences that small between models are within run-to-run variation.
Licence and attribution
The model is released under the MIT licence (see LICENSE). It is a fine-tune of Ettin 32M (MIT, Johns Hopkins University Center for Language and Speech Processing) and was distilled from a fine-tune of ModernBERT-base (Apache-2.0). Training text and its licences are listed in ATTRIBUTION.md, which also carries the Open Government Licence attribution.
@misc{weller2025seqvsseqopen,
title = {Seq vs Seq: An Open Suite of Paired Encoders and Decoders},
author = {Weller, Orion and Ricci, Kathryn and Marone, Marc and Chaffin, Antoine and Lawrie, Dawn and Van Durme, Benjamin},
year = {2025},
eprint = {2507.11412},
archivePrefix = {arXiv}
}
- Downloads last month
- 37
Model tree for HMC83/name-detector-32m
Base model
jhu-clsp/ettin-encoder-32m