3838
3939[ Full benchmarks →] ( https://pii.engineer/benchmarks )
4040
41+ ## Features
42+
43+ - ** Multilingual** — single model handles 50+ languages including CJK, SEA, South Asian, and European languages
44+ - ** High accuracy** — 0.90 F1 overall, outperforms regex-based tools on non-English text
45+ - ** Fast** — ~ 180ms p50 on CPU (INT8 quantized ONNX inference)
46+ - ** Zero-shot labels** — detect custom entity types without retraining
47+ - ** Self-hosted** — runs on a $42/mo VPS, no external API calls, your data never leaves your server
48+ - ** Single binary** — Rust binary with embedded static assets, no Python runtime or dependency hell
49+ - ** Auto-redaction** — returns both detected entities and redacted text in one call
50+ - ** 9 PII types** — person names, phone numbers, government IDs, addresses, DOB, emails, passports, license plates, bank accounts
51+
4152## Quick Start
4253
54+ ### From Source
55+
4356``` bash
4457cargo build --release --package pii-engineer-server
4558cargo run --release --package pii-engineer-server
4659# Models auto-download from HuggingFace on first run
4760# API ready at http://localhost:8000
4861```
4962
63+ ### Docker
64+
65+ ``` bash
66+ docker build -t pii-engineer .
67+ docker run -p 8000:8000 -v ./models:/app/models pii-engineer
68+ ```
69+
70+ ### Test It
71+
5072``` bash
5173curl -X POST http://localhost:8000/api/detect \
5274 -H " Content-Type: application/json" \
5375 -d ' {"text": "John Doe, NRIC S9012345B, born 12 March 1985"}'
5476```
5577
78+ Response:
79+
5680``` json
5781{
5882 "entities" : [
@@ -64,11 +88,45 @@ curl -X POST http://localhost:8000/api/detect \
6488}
6589```
6690
67- ### Docker
91+ ## Integration Examples
92+
93+ ### Python
94+
95+ ``` python
96+ import requests
97+
98+ response = requests.post(" http://localhost:8000/api/detect" , json = {
99+ " text" : " Ahmad bin Abdullah, +60 12-345 6789, IC 901201-14-5678"
100+ })
101+ data = response.json()
102+ print (data[" redacted" ])
103+ # [PERSON_NAME], [PHONE_NUMBER], IC [GOVERNMENT_ID]
104+ ```
105+
106+ ### JavaScript / Node.js
107+
108+ ``` javascript
109+ const res = await fetch (" http://localhost:8000/api/detect" , {
110+ method: " POST" ,
111+ headers: { " Content-Type" : " application/json" },
112+ body: JSON .stringify ({
113+ text: " Nguyễn Văn A, CCCD 079201012345, sinh ngày 15/03/1990"
114+ }),
115+ });
116+ const { entities , redacted } = await res .json ();
117+ console .log (redacted);
118+ // [PERSON_NAME], CCCD [GOVERNMENT_ID], sinh ngày [DATE_OF_BIRTH]
119+ ```
120+
121+ ### cURL (batch labels)
68122
69123``` bash
70- docker build -t pii-engineer .
71- docker run -p 8000:8000 -v ./models:/app/models pii-engineer
124+ curl -X POST http://localhost:8000/api/detect \
125+ -H " Content-Type: application/json" \
126+ -d ' {
127+ "text": "Call me at 9123 4567 or email john@acme.com",
128+ "labels": ["phone_number", "email_address"]
129+ }'
72130```
73131
74132## PII Types
@@ -87,11 +145,22 @@ docker run -p 8000:8000 -v ./models:/app/models pii-engineer
87145
88146## Supported Languages
89147
90- ** Primary:** English, Malay, Tamil, Chinese, Indonesian, Vietnamese
148+ ** Primary (highest accuracy):** English, Malay, Tamil, Chinese, Indonesian, Vietnamese
149+
150+ ** Secondary:** Thai, Hindi, Bengali, Korean, Japanese, German, French, Spanish, Portuguese, Russian, Arabic, Turkish, Polish, Dutch, Italian, Swedish, and [ 35+ more] ( https://pii.engineer/benchmarks )
151+
152+ The model handles multilingual text natively — mixed-language documents (e.g., English + Chinese + Malay in one paragraph) work without language selection.
153+
154+ ## Use Cases
91155
92- ** Secondary:** Thai, Hindi, Bengali, Korean, Japanese, German, French, Russian, and [ 40+ more] ( https://pii.engineer/benchmarks )
156+ - ** PDPA / GDPR compliance** — scan documents, databases, and logs for personal data before audits
157+ - ** LLM guardrails** — redact PII before sending user input to GPT/Claude/Gemini
158+ - ** Data pipelines** — clean PII from ETL outputs, data warehouse columns, Kafka streams
159+ - ** Chat moderation** — detect PII in real-time in Slack, support tickets, or chat apps
160+ - ** Code review** — catch hardcoded PII in test fixtures, config files, and documentation
161+ - ** Document redaction** — auto-redact contracts, resumes, medical records before sharing
93162
94- ## API
163+ ## API Reference
95164
96165### ` POST /api/detect `
97166
@@ -101,31 +170,45 @@ docker run -p 8000:8000 -v ./models:/app/models pii-engineer
101170| ` labels ` | string[ ] | all 9 types | PII types to detect |
102171| ` boost ` | string[ ] | [ ] | Labels to boost with description matching |
103172
104- ### ` GET /api/health `
173+ ** Response: **
105174
106175``` json
107176{
108- "status" : " ok" ,
109- "version" : " 1.0.0" ,
110- "gliner_loaded" : true ,
111- "chinese_loaded" : true
177+ "entities" : [
178+ { "type" : " person_name" , "value" : " John Doe" , "start" : 0 , "end" : 8 , "score" : 0.99 , "needs_review" : false }
179+ ],
180+ "redacted" : " [PERSON_NAME] lives at [STREET_ADDRESS]" ,
181+ "original" : " John Doe lives at 123 Main St"
112182}
113183```
114184
185+ ### ` GET /api/health `
186+
187+ ``` json
188+ { "status" : " ok" , "version" : " 1.0.0" , "gliner_loaded" : true , "chinese_loaded" : true }
189+ ```
190+
115191## Architecture
116192
117193```
118194Request → Language detection → GLiNER2 NER + (Chinese NER if CJK)
119195 ↓
120- Post-processing pipeline
121- ( reclassify → validate → filter → normalize → email/IP detect → threshold → dedup → merge)
196+ Post-processing pipeline (8 stages)
197+ reclassify → validate → filter → normalize → email/IP detect → threshold → dedup → merge
122198 ↓
123199 Response (entities + redacted text)
124200```
125201
126- ** Model:** Fine-tuned [ GLiNER2] ( https://huggingface.co/fastino/gliner2-multi-v1 ) (mDeBERTa-v3-base, 280M params) with 5 ONNX models. INT8 quantized encoder for CPU inference.
202+ ** Model:** Fine-tuned [ GLiNER2] ( https://huggingface.co/fastino/gliner2-multi-v1 ) (mDeBERTa-v3-base, 280M params) split into 5 ONNX models. INT8 quantized encoder for CPU inference.
127203
128- ** Stack:** Rust + Axum + ONNX Runtime + HuggingFace Tokenizers
204+ ** Stack:** Rust + Axum + ONNX Runtime + HuggingFace Tokenizers + mimalloc
205+
206+ ** How it works:**
207+ 1 . Text and entity labels are encoded together by the transformer encoder
208+ 2 . Span representation layer scores all possible token spans (up to 8 tokens wide)
209+ 3 . Classifier determines which spans match which PII labels
210+ 4 . 8-stage post-processing pipeline validates, deduplicates, and merges results
211+ 5 . Regex-based detection supplements NER for emails and IP addresses
129212
130213## Configuration
131214
@@ -141,10 +224,18 @@ Request → Language detection → GLiNER2 NER + (Chinese NER if CJK)
141224
142225## Performance
143226
144- | Setup | Latency | Throughput |
145- | ----------------------- | ------- | ---------- |
146- | MacBook M-series (FP32) | ~ 150ms | ~ 6 req/s |
147- | 4-vCPU AMD (INT8) | ~ 250ms | ~ 4 req/s |
227+ | Setup | Latency (p50) | Throughput |
228+ | ----------------------- | ------------- | ---------- |
229+ | MacBook M-series (FP32) | ~ 150ms | ~ 6 req/s |
230+ | 4-vCPU AMD (INT8) | ~ 250ms | ~ 4 req/s |
231+ | 8-vCPU AMD (INT8) | ~ 180ms | ~ 5 req/s |
232+
233+ Memory usage: ~ 800MB (model weights loaded in RAM).
234+
235+ Tips:
236+ - Set ` ORT_INTRA_THREADS ` equal to your vCPU count
237+ - INT8 encoder gives ~ 40% speedup with <0.5% accuracy loss
238+ - First request after idle is slower — the server runs periodic warmup to mitigate this
148239
149240## Development
150241
@@ -155,9 +246,31 @@ cargo clippy --workspace
155246cargo run --release -p pii-engineer-server
156247```
157248
249+ ### Project Structure
250+
251+ ```
252+ crates/
253+ ├── pii-engineer-core/ # NER engine, pipeline, model loading
254+ │ └── src/
255+ │ ├── gliner/ # GLiNER2 ONNX inference (v1, v2-compat, v2-full)
256+ │ ├── pipeline.rs # 8-stage post-processing
257+ │ ├── labels.rs # PII label definitions and canonicalization
258+ │ └── lang.rs # Language detection (CJK)
259+ ├── pii-engineer-server/ # HTTP server (Axum)
260+ │ └── src/
261+ │ ├── routes.rs # API endpoints
262+ │ ├── state.rs # App state, model loading
263+ │ └── middleware.rs # Rate limiting, error handling
264+ static/ # Embedded frontend (rust-embed)
265+ models/ # ONNX models (auto-downloaded)
266+ ```
267+
158268## Contributing
159269
160- See [ CONTRIBUTING.md] ( CONTRIBUTING.md ) for guidelines.
270+ See [ CONTRIBUTING.md] ( CONTRIBUTING.md ) for guidelines. We especially welcome:
271+ - Validation rules for country-specific ID formats
272+ - Test cases for underrepresented languages
273+ - Performance optimizations
161274
162275## License
163276
0 commit comments