PrivaParse
Local PII detection and pseudonymisation for text sent to an LLM — nothing leaves the machine.
A local privacy layer for text you want to send to an LLM. It detects personally identifiable information, replaces it with deterministic placeholders, keeps the mapping in a local database, and restores the original values in the model's answer.
Nothing leaves the machine. Phase 1 calls no external service at all.
Hallo, Hallo,
mein Name ist Max Mustermann. mein Name ist [[PERSON_A1]].
Sie erreichen mich unter ──▶ Sie erreichen mich unter
max@test.de [[EMAIL_A2]]
oder +49 170 1234567. oder [[PHONE_A3]].
The LLM only ever sees the right-hand side. reverse puts the left-hand side
back into whatever the model replies.
Install
pipx install "privaparse[gateway]"
That gives you the CLI and the local gateway. Person detection needs the model backend, which pulls in PyTorch — roughly 2 GB:
pipx install "privaparse[gateway,model]"
GPU setup, Docker, and installing from source are in docs/install.md.
Try it
Save this as brief.md:
Mein Name ist Max Mustermann, erreichbar unter max@test.de.
privaparse --detector regex demo brief.md
demo runs the whole round trip and prints every stage. Person detection
needs the [model] extra; without it (the plain [gateway] install above),
--detector regex keeps detection to email and phone — drop it once
[model] is installed. The real workflow is two commands:
privaparse pseudonymize brief.md -o brief.pseudo.md
privaparse reverse antwort.md -o antwort.klar.md
More commands, and the Python library, are in docs/quickstart.md.
Gateway
Point any OpenAI-compatible client at PrivaParse and it pseudonymises requests going out, restores answers coming back — no code changes on the client side.
privaparse run -- aider
Without the [model] extra, run privaparse --detector regex serve —
otherwise the server starts fine but every request that reaches detection
returns a 500.
Which clients this works with today, what it costs, and its known gaps are in docs/gateway.md.
Evidence
Phase 1 ships a 25-type entity catalogue — 21 enabled by default, three disabled on measured false positives and one (COUNTRY) on judgement rather than evidence (see docs/benchmarks/labels.md) — for plain text and Markdown, as a CLI and a Python library. No OCR, no PDF, no cloud models.
Does GLiNER2 need fine-tuning for German? No.
Measured on the German gold set in eval/gold/ — 124 documents, 33 of them
containing no PII at all (a corpus of nothing but real PII can never produce
a false positive, which is exactly where a wider catalogue turns out to
struggle) — scored at the shipped catalogue's 21 enabled types. The threshold
was fixed before this run: fine-tuning is warranted if PERSON partial-match
recall drops below 0.90 or precision below 0.85.
| Type | Precision (partial) | Recall (partial) | F1 | Support |
|---|---|---|---|---|
| PERSON | 0.969 | 0.960 | 0.964 | 99 |
| 1.000 | 1.000 | 1.000 | 21 | |
| PHONE | 0.818 | 1.000 | 0.900 | 18 |
| IBAN | 1.000 | 1.000 | 1.000 | 6 |
PERSON clears both floors comfortably — fine-tuning not warranted — and
has at every catalogue width measured, including an older, narrower one
that scored it higher (see
why that isn't the better number).
fastino/gliner2-privacy-filter-PII-multi is built on
microsoft/mdeberta-v3-base, so German is not a special case for it. EMAIL
and PHONE come from rules, not the model, so they are the control group:
EMAIL is clean, PHONE is not — its 0.818 precision and TAX_ID's 0.000 recall
are the same defect, counted from opposite ends; see
One defect, two numbers
for the mechanism.
The rest of the catalogue is measured too, and it is not uniformly clean. Eight types rest on three gold entities each — thin. Seven more, measured for the first time this run, were not all clean either: LICENSE_NUMBER and ROUTING_NUMBER measured 0.000 recall — they detect nothing — and CARD_CVV measured 0.167 precision. Full tables, the per-label breakdown, and every missed or spurious detection are in docs/benchmarks/detection-quality.md.
Reproduce with privaparse eval (needs GLiNER2 — see
Install). Chunk size as a recall setting is in
docs/benchmarks/performance-notes.md;
throughput is in docs/benchmarks/throughput.md.
Documentation
| Page | Covers |
|---|---|
| Install | pipx and source installs, CPU/GPU, Docker |
| Quickstart | privaparse demo, the CLI, the Python library |
| Gateway | The local OpenAI-compatible gateway |
| Configuration | Every PRIVAPARSE_* setting |
| Architecture | The pipeline, the vault, Markdown handling |
| Testing | Running the suite, coverage |
| Benchmarks | Every measured number, with the command that reproduces it |
Contributing
See CONTRIBUTING.md for issues and pull requests. The rule that matters most: no real PII in examples, tests, or gold documents, ever.
Licence
Apache 2.0. See LICENSE.
Metadata
Release files for privaparse 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| privaparse-0.1.0.tar.gz | 182.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| privaparse-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 323.5 kB
Release files / privaparse-0.1.0.tar.gz
| Download URL | privaparse-0.1.0.tar.gz |
|---|---|
| Size | 182.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
127c89403662c96887531cf0beca671d410dfd0bc80aa12232ac154d1915b2d5
|
|
BLAKE2b-256 checksum How to use checksums |
e251c7bdc93e91326915be637bdeca2c0c21445db5f90d51426e5ce8be58c2bb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 14, 2026.
Transparency logRelease files / privaparse-0.1.0-py3-none-any.whl
| Download URL | privaparse-0.1.0-py3-none-any.whl |
|---|---|
| Size | 140.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d61edb2f6853caf86c921015384dc3d4ba235f02302aa5f250d90a1181fe9b2e
|
|
BLAKE2b-256 checksum How to use checksums |
26550e876de4629a666af420a7f80cd304db1b9eedf7536933dc3e3e1f81abbb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 14, 2026.
Transparency log