
inverse du filtre de confidentialité d'openai. même modèle 1.5b, renvoie les pii sous forme de spans structurés au lieu de les masquer
Trouvez chaque élément de données personnelles (PII) dans un texte et récupérez-le sous forme de spans structurés.
Basé sur OpenAI Privacy Filter : même modèle 1.5B, mêmes labels, mêmes poids.
Privacy Filter masque. Privacy Parser extrait.
Hi Quindle Testwick ([email protected] / +1-415-555-0102),
account 40702810500001234567, 14 Beautiful Ct, Anytown USA,
password Priv4cy-Filt3r-2026.
private_person Quindle Testwick
private_email [email protected]
private_phone +1-415-555-0102
account_number 40702810500001234567
private_address 14 Beautiful Ct, Anytown USA
secret Priv4cy-Filt3r-2026
Au lieu de <REDACTED>, vous obtenez ce qui a été trouvé, où cela se trouve (start, end) et de quel type il s'agit.
Privacy Filter répond à « rendez ce texte sûr ». Parfois, vous avez besoin d'une réponse différente : « qu'y a-t-il exactement ici ? »
| Backend | Nécessite des poids | Vitesse | F1 * | À utiliser quand |
|---|---|---|---|---|
PIIParser | non | µs | 1.000 | zéro dépendance, motifs structurés |
ModelPIIParser | 1.5B | ~500 ms CPU | 0.733 | sortie brute du modèle |
HybridPIIParser | 1.5B | ~600 ms CPU | 0.929 | choix par défaut |
* correspondance exacte des segments sur les cinq fixtures d'exemple opf. Un petit ensemble : à considérer comme un test de fumée, pas comme un benchmark.
git clone https://github.com/openai/privacy-filter
git clone https://github.com/chiefautism/privacy-parser
uv venv
uv pip install -e ./privacy-filter # only for the model backends
uv pip install -e ./privacy-parser
Le premier lancement du modèle télécharge le checkpoint opf (~3 Go) dans ~/.opf/privacy_filter/.
Définissez OPF_CHECKPOINT ou passez model= pour utiliser un autre emplacement.
from pii_parser.hybrid import HybridPIIParser
parser = HybridPIIParser(device="cpu") # or "cuda"
result = parser.parse("Hi Quindle Testwick, call me at +1-415-555-0102")
for s in result.spans:
print(s.label, s.start, s.end, s.text)
print(result.to_json())
from pii_parser import parse
result = parse("mail [email protected], token ghp_abcdefghijklmnopqrstuvwxyz0123456789")
result.detected_spans # (DetectedSpan(label='private_email', ...), ...)
result.redacted_text # 'mail <REDACTED>, token <REDACTED>'
result.summary # {'span_counts': {...}, 'total_spans': 2}
Backend regex, sans modèle :
$ echo "Alice paid 40702810500001234567 on 2026-05-17." | pii-parser --mode spans
account_number 11 31 40702810500001234567
private_date 35 45 2026-05-17
$ pii-parser "mail [email protected]" --mode redacted
mail <REDACTED>
| Option | Valeurs | Par défaut |
|---|---|---|
TEXT | texte, ou -f FILE, ou stdin | |
--mode | json · spans · redacted | json |
--placeholder | n'importe quelle chaîne | <REDACTED> |
--indent | int, 0 pour un JSON compact | 2 |
Backend du modèle :
python -m pii_parser.cli_model "Alice paid 40702810500001234567 on 2026-05-17."
python -m pii_parser.cli_model -f dump.txt --device cuda --mode spans
taxonomie opf v2, 8 catégories :
| Label | Exemple |
|---|---|
private_person | Quindle Testwick |
private_email | [email protected] |
private_phone | +1-415-555-0102 |
private_address | 14 Beautiful Ct, Anytown USA |
private_url | https://example.com/u/quindle |
private_date | 2026-05-17 |
account_number | 40702810500001234567 |
secret | sk-…, ghp_…, AKIA…, Bearer … |
Lorsque des spans se chevauchent, le plus long l'emporte, puis le label de priorité la plus élevée : email > url > secret > account > phone > date > address > person.
text
│
▼
opf 1.5B ──► BIOES logits ──► Viterbi (tuned biases) ──► char spans
│
▼
span merge glues "Quindle" + "Testwick" into one person
│
▼
regex backstop adds url / secret / account where the model missed them
│
▼
spans[]
Chaque étape peut être désactivée :
HybridPIIParser(
enable_merge=True,
enable_regex_backstop=True,
enable_viterbi_tuning=True,
decode_mode="viterbi", # or "argmax"
)
{
"text": "Hi Quindle Testwick ...",
"spans": [
{ "label": "private_person", "start": 3, "end": 19, "text": "Quindle Testwick" }
]
}
Le regex PIIParser reflète opf.RedactionResult (schema_version, summary, detected_spans, redacted_text), ce qui vous permet de changer de backend sans toucher aux consommateurs.
Les tests s'attendent à ce que privacy-filter soit cloné à côté de ce dépôt (ils lisent ses fixtures d'exemple).
python tests/test_hybrid.py
Fixture F1: 0.929
Scenarios: 8/8 passed
Latency: ~600 ms CPU
Il s'agit d'un outil à double usage. Exécutez-le sur des données que vous possédez ou que vous êtes autorisé à traiter. L'extraction de données personnelles à partir de sources divulguées ou volées est illégale dans la plupart des juridictions.