Skip to content

Commit 4ff5398

Browse files
committed
Enhance README with detailed features, integration examples, and performance metrics
1 parent aff75df commit 4ff5398

1 file changed

Lines changed: 133 additions & 20 deletions

File tree

README.md

Lines changed: 133 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -38,21 +38,45 @@
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
4457
cargo build --release --package pii-engineer-server
4558
cargo 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
5173
curl -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
```
118194
Request → 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
155246
cargo 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

Comments
 (0)