PII Router Policy - OpenMed Privacy Filter Multilingual v2 (ONNX)

A Lemonade collection.router policy JSON: routes any prompt containing PII to a local model, and everything else to a cloud model, using lemonade-sdk/openmed-privacy-filter-multilingual-v2-onnx as the PII classifier.

This repo holds only the policy config - not model weights. It's meant to be pulled directly into a running Lemonade server.

What this policy does

  • Runs every prompt through the PII classifier first (216 non-"O" BIOES labels across 54 entity types: names, emails, phone numbers, financial/government IDs, addresses, demographic attributes, credentials, and more - see the classifier's model card for the full label list).
  • If any label crosses min_score: 0.5, the prompt routes to the local candidate (Qwen3.5-0.8B-GGUF by default).
  • Otherwise it routes to the cloud candidate (fireworks.kimi-k2p6 by default).

On the Nemotron-PII benchmark (20,000 PII-bearing prompts, 20,001 total), this policy scored a 0% leak rate - zero PII-bearing prompts routed to the cloud candidate.

Usage

1. Register the classifier. Lemonade's onnxruntime backend (ort-server) needs a manifest.json next to model.onnx to know this is a token-classification model - one score per token, not one per prompt - rather than the default it assumes otherwise (single-label text-classification, one score for the whole input, like a sentiment model). Without the right manifest, ort-server either errors on the shape mismatch or silently misreads the output. Unlike some other Lemonade PII classifiers, lemonade-sdk/openmed-privacy-filter-multilingual-v2-onnx already ships its manifest.json alongside model.onnx at the repo root - nothing extra to place, this one pull is all it needs:

curl -X POST http://localhost:13305/v1/pull -H "Content-Type: application/json" -d '{
  "model_name": "user.privacy-filter-ml-v2-onnx",
  "checkpoint": "lemonade-sdk/openmed-privacy-filter-multilingual-v2-onnx",
  "recipe": "onnxruntime"
}'

2. Register this policy:

hf download lemonade-sdk/pii_policy_openmed-privacy-filter-multilingual-v2-onnx --local-dir .
curl -X POST http://localhost:13305/v1/pull -H "Content-Type: application/json" \
  --data-binary @pii_policy_openmed-privacy-filter-multilingual-v2-onnx.json

3. Use it - send chat completions to "model": "user.PII-ONNX-PrivacyFilter-Router" and the server will route each request per the policy above.

Why the manifest keeps all 217 raw labels distinct

The manifest deliberately keeps every BIOES-prefixed label separate (B-EMAIL, I-EMAIL, E-EMAIL, S-EMAIL, ...) rather than collapsing each entity type into one bare name. Per-label scores land in a map keyed by label string in ort-server - collapsing several label indices onto the same key would let the last-processed one silently overwrite the others' scores instead of combining them. That's why this policy's match rule checks "does the B-, I-, E-, or S- variant cross threshold" per entity type (216 leaf conditions) rather than 54 collapsed ones.

Adapting this policy

routing.candidates (local/cloud model names) and min_score are starting points, not fixed requirements - point them at whatever models you have registered, or tighten/loosen the threshold for your own precision/recall tradeoff. The classifiers[].labels list must stay in sync with whatever classifier model you point at (this one matches the 217-label BIOES scheme of openmed-privacy-filter-multilingual-v2-onnx exactly).

For building a routing policy from scratch, or a more sophisticated one (multiple classifiers, LLM-based routing, custom match logic), see the lemonade-router-builder skill - it turns a natural-language description of routing intent into a valid collection.router policy JSON.

License

Apache 2.0.

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support