Instructions to use luispoveda93/MiniCPM5-1B-PII-tagger-lora-100k with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- PEFT
How to use luispoveda93/MiniCPM5-1B-PII-tagger-lora-100k with PEFT:
from peft import PeftModel from transformers import AutoModelForTokenClassification base_model = AutoModelForTokenClassification.from_pretrained("openbmb/MiniCPM5-1B") model = PeftModel.from_pretrained(base_model, "luispoveda93/MiniCPM5-1B-PII-tagger-lora-100k") - Notebooks
- Google Colab
- Kaggle
MiniCPM5-1B PII Tagger (LoRA, full 100K)
A LoRA adapter on openbmb/MiniCPM5-1B that turns the model into a token-classification PII/PHI detector, trained on the full 100K-example train split of nvidia/Nemotron-PII. A 20K-pilot version of this adapter is at luispoveda93/MiniCPM5-1B-PII-tagger-lora โ this full run scores higher and is the one to use.
What it does
Given English text, the model predicts one of 55 PII/PHI category labels per token (IO scheme): first_name, last_name, date_of_birth, ssn, street_address, email, phone_number, credit_debit_card, blood_type, medical_record_number, api_key, password, ipv4, mac_address, and 40 more.
Label list (sorted): account_number, age, api_key, bank_routing_number, biometric_identifier, blood_type, certificate_license_number, city, company_name, coordinate, country, county, credit_debit_card, customer_id, cvv, date, date_of_birth, date_time, device_identifier, education_level, email, employee_id, employment_status, fax_number, first_name, gender, health_plan_beneficiary_number, http_cookie, ipv4, ipv6, language, last_name, license_plate, mac_address, medical_record_number, national_id, occupation, password, phone_number, pin, political_view, postcode, race_ethnicity, religious_belief, sexuality, ssn, state, street_address, swift_bic, tax_id, time, unique_id, url, user_name, vehicle_identifier.
Results
Evaluated on 2,000 held-out examples from the nvidia/Nemotron-PII test split (seed 42 shuffle). Metrics are exact token/span match against char-offset-derived gold labels; a span is a maximal run of consecutive tokens with the same non-O label.
| Metric | 20K pilot | This run (100K) |
|---|---|---|
| Token precision / recall / F1 | 0.9635 / 0.9626 / 0.9631 | 0.9741 / 0.9704 / 0.9723 |
| Span precision / recall / F1 | 0.8645 / 0.9046 / 0.8841 | 0.8942 / 0.9225 / 0.9081 |
| eval_loss | 0.0409 | 0.0301 |
The full 100K split is 5ร the data and lifted span F1 by +2.4 points over the pilot. Label vocabulary is identical in both runs (55 categories), so the adapters are interchangeable with respect to label space.
Usage
import torch
from transformers import AutoTokenizer, AutoModelForTokenClassification
from peft import PeftModel
labels = ["account_number", "age", "api_key", "bank_routing_number", "biometric_identifier",
"blood_type", "certificate_license_number", "city", "company_name", "coordinate", "country",
"county", "credit_debit_card", "customer_id", "cvv", "date", "date_of_birth", "date_time",
"device_identifier", "education_level", "email", "employee_id", "employment_status", "fax_number",
"first_name", "gender", "health_plan_beneficiary_number", "http_cookie", "ipv4", "ipv6",
"language", "last_name", "license_plate", "mac_address", "medical_record_number", "national_id",
"occupation", "password", "phone_number", "pin", "political_view", "postcode", "race_ethnicity",
"religious_belief", "sexuality", "ssn", "state", "street_address", "swift_bic", "tax_id", "time",
"unique_id", "url", "user_name", "vehicle_identifier"]
id2label = {i: l for i, l in enumerate(labels)}
label2id = {l: i for i, l in enumerate(labels)}
base = AutoModelForTokenClassification.from_pretrained(
"openbmb/MiniCPM5-1B", id2label=id2label, label2id={l: i for i, l in enumerate(labels)},
dtype="bfloat16",
)
model = PeftModel.from_pretrained(base, "luispoveda93/MiniCPM5-1B-PII-tagger-lora-100k")
tok = AutoTokenizer.from_pretrained("luispoveda93/MiniCPM5-1B-PII-tagger-lora-100k")
text = "My date of birth is 1987-05-22 and I live at 87 Avenida De La Estrella."
enc = tok(text, return_tensors="pt", return_offsets_mapping=True, truncation=True, max_length=1024)
offsets = enc.pop("offset_mapping")[0].tolist()
with torch.no_grad():
preds = model(**enc).logits.argmax(-1)[0].tolist()
for (s, e), p in zip(offsets, preds):
if p != 0 and not (s == 0 and e == 0):
print(text[s:e], "->", id2label[p])
Adjacent predicted tokens with the same label form one entity span.
Training details
- Base: openbmb/MiniCPM5-1B (
LlamaForTokenClassificationhead, 55 labels, bf16, SDPA attention) - Data: all 100,000 examples of
nvidia/Nemotron-PIIdefault/trainafter a seed-42 shuffle; spans mapped to tokens via fast-tokenizeroffset_mapping(IO scheme,-100on special tokens);max_length=1024(only ~0.07% of spans lost to truncation, measured on the pilot sample) - LoRA: r=16, alpha=32, dropout=0.1, target modules
q/k/v/o/gate/up/down_projโ 11.3M trainable params (1.27%) - Hyperparameters: lr 2e-4 (cosine, no warmup), effective batch 32 (8 ร grad-accum 4), 1 epoch (3,125 optimizer steps), bf16, seed 42
- Hardware: 1ร A10G (24 GB), peak GPU memory 22.39 GB, train runtime 2 h 41 min
Known data caveats (from nvidia/Nemotron-PII)
- ~1.5% of spans have a char-level mismatch between
spans[i].textandtext[start:end]in the source dataset (measured over 182K spans in the pilot sample). Offsets were treated as ground truth for labeling. - 55 unique labels confirmed across the full 100K + 2K sample (842,660 spans, ~4.2 spans/example).
Limitations
- Single epoch, no per-label breakdown โ rare categories likely underperform.
- Synthetic, persona-grounded text only; real-world documents may shift.
- Token-level boundaries are exact-match; adjacent same-label spans merge into one prediction.
Job provenance
Trained with HF Jobs (pii-tagger-full-100k-minicpm5-a10g, job 6aa0708832d5d0c22c5ae6f2), A10G-small, 2026-09-08. Pilot: pii-tagger-pilot-20k-minicpm5-a10g-v2-push (job 6aa0653d32d5d0c22c5ae52c).
- Downloads last month
- 18
Model tree for luispoveda93/MiniCPM5-1B-PII-tagger-lora-100k
Base model
openbmb/MiniCPM5-1B