Instructions to use noczero/pii-xlmr-bilingual with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use noczero/pii-xlmr-bilingual with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("token-classification", model="noczero/pii-xlmr-bilingual")# Load model directly from transformers import AutoTokenizer, AutoModelForTokenClassification tokenizer = AutoTokenizer.from_pretrained("noczero/pii-xlmr-bilingual") model = AutoModelForTokenClassification.from_pretrained("noczero/pii-xlmr-bilingual", device_map="auto") - Notebooks
- Google Colab
- Kaggle
pii-xlmr-bilingual โ EN/KO PII detection and redaction
A fine-tuned xlm-roberta-base span tagger that finds and redacts personal data in English,
Korean, and code-switched text, for seven entity types: PER, RRN (์ฃผ๋ฏผ๋ฑ๋ก๋ฒํธ), PHONE,
EMAIL, ADDRESS, CARD, ORG.
Runs on CPU at ~15.6 ms/sentence and makes no network calls at inference โ both enforced in code and verified. Trains in ~28 minutes on one consumer GPU (measured on Apple M3 Pro / MPS).
Full training pipeline, evaluation harness, data card and design rationale: https://github.com/noczero/security-and-swe-agent-harness
Results
Exact-span F1 โ a hit counts only if both the entity type and the exact character boundaries match. This is the strict rule; overlap-based scoring reads much higher and is reported separately in the repo.
| set | what it measures | micro-F1 |
|---|---|---|
gen |
held-out entity pools and held-out sentence frames | 0.9711 |
test |
a third partition, scored once, nothing tuned against it | 0.9804 |
switched |
ENโKO code-switched, held-out pools | 0.9161 |
real |
public corpus rows quarantined from training | 0.7356 |
dev |
shares pools and frames with training | 1.0000 โ memorisation, not skill |
dev is listed only so nobody can quote it as model quality. The headline number is 0.9711.
Separately for English and Korean
| bucket | gen |
test |
switched |
real |
|---|---|---|---|---|
| English | 1.000 (235) | 1.000 (244) | โ | 0.767 (811) |
| Korean | 0.965 (491) | 0.969 (490) | โ | 0.707 (890) |
| code-switched | 0.946 (148) | 0.985 (132) | 0.916 (1200) | โ |
Support (gold spans) in brackets. Korean is the harder language โ it carries most of the
held-out spans and essentially all the residual error on synthetic text, because a Korean span must
stop before an attached particle (๊น๋ฏผ์ inside ๊น๋ฏผ์๋).
Against an off-the-shelf baseline
fastino/gliner2-privacy-filter-PII-multi, zero-shot, same sentences and same scorer:
| set | GLiNER2 (strict) | ours (strict) | GLiNER2 (relaxed) | ours (relaxed) |
|---|---|---|---|---|
gen |
0.6130 | 0.9711 | 0.9385 | 0.9904 |
switched |
0.5083 | 0.9161 | 0.9698 | 0.9748 |
real |
0.4778 | 0.7356 | 0.7808 | 0.8363 |
Read the relaxed columns first โ they are the honest control. Most of the advantage is boundaries,
not detection: on switched both models find essentially the same entities, and the strict gap
comes from cutting them in the right place. Word-level span representations cannot express the gold
Korean span at all.
Usage
from transformers import AutoTokenizer, AutoModelForTokenClassification
tok = AutoTokenizer.from_pretrained("noczero/pii-xlmr-bilingual")
model = AutoModelForTokenClassification.from_pretrained("noczero/pii-xlmr-bilingual")
Use the repo's inference path rather than a naive decode. Correct spans depend on two things this model was built around:
- NFC normalisation, never NFKC. NFKC turns
ใํ๊ตญfrom 3 characters into 5 and shifts every later offset. - Hangul pre-splitting to one tagging unit per syllable, which raises the exact-span ceiling
from 97.1% to 100%. Labels ride on units; offsets are never read from the tokenizer โ
trusting
return_offsets_mappinghere scored a correct model 0/6 in testing.
The repo ships this as one command:
python scripts/redact.py --weights <path-to-this-model> \
--text "๊น์ฒ ์๋ 010-2345-6789 ๋ก ์ฐ๋ฝ ์ฃผ์ธ์"
๊น์ฒ ์๋ 010-2345-6789 ๋ก ์ฐ๋ฝ ์ฃผ์ธ์
-> [PER]๋ [PHONE] ๋ก ์ฐ๋ฝ ์ฃผ์ธ์
[ 0:3 ] PER ๊น์ฒ ์
[ 5:18 ] PHONE 010-2345-6789
Output is the NFC-normalised text, zero or more non-overlapping spans with exact [start, end)
offsets, and a redacted copy. No confidence scores โ the operating point is plain argmax.
Training data
Synthesised, not scraped. Public Korean PII corpora with the entity types this task needs do not
exist at usable licence terms, so the training set is generated: 33,953 examples / 41,806 gold spans,
built from partitioned entity pools and sentence frames, plus real PER/ORG rows from KLUE-NER
and Few-NERD (both CC-BY-SA-4.0).
Two design choices carry most of the quality:
- Type-agnostic frames. The same sentence frames are shared verbatim across
RRN,PHONEandCARD, so only a value's structure can assign its label โ not a nearby cue word. The first model had learned "the number after ์ฃผ๋ฏผ๋ฑ๋ก๋ฒํธ" and mislabelled 40 of 61 held-out RRNs asPHONE. - Confusable negatives. Sentences with digits and no PII, deliberately RRN-shaped (order numbers). Nothing card-shaped โ a Luhn-valid negative would teach the model to miss real cards. This, not frame widening, is what fixed RRN to 1.000 precision at 1.000 recall.
Full data card (composition, EN/KO balance, synthesis method, licences, failure modes):
DATA_CARD.md.
Limitations โ read before deploying
- Real prose is much weaker than synthetic.
realis 0.7356, andORGis the weakest thing in the model (P 0.621 / R 0.667). The strong numbers describe our generator's held-out sets; they are not a promise about arbitrary text. realis quarantined by row, not by entity. A news corpus repeats the same people, so it shares 315 entity surfaces with training rows โ it measures unseen sentences about partly-seen entities.realcovers onlyPERandORG. The other five types have no real-text measurement at all.testis not calibrated to be as hard asgenand reads slightly higher for that reason.- Trailing digits are noise. Training on MPS is not bitwise reproducible (max parameter delta 9.96e-05 over 12 steps; a CPU control reproduces at 0.0). Inference is exactly reproducible.
- Recall-oriented balance. For redaction a missed entity is a leak and a false positive is cosmetic, but the shipped operating point is plain argmax rather than a tuned threshold โ see the design doc's precision/recall discussion.
- Not a compliance control. This is a detection aid; it should not be the only thing standing between raw text and a disclosure.
Licence and citation
MIT, following the xlm-roberta-base base model. Training corpora (KLUE-NER, Few-NERD) are
CC-BY-SA-4.0 and are cited in the data card.
- Downloads last month
- 10
Model tree for noczero/pii-xlmr-bilingual
Base model
FacebookAI/xlm-roberta-base