| --- |
| license: apache-2.0 |
| language: |
| - zh |
| - en |
| base_model: |
| - openai/privacy-filter |
| library_name: opf |
| tags: |
| - Taiwan |
| - R.O.C |
| - zhtw |
| - PII |
| - privacy |
| - ner |
| - token-classification |
| - OPF |
| datasets: |
| - lianghsun/tw-PII-chat |
| - lianghsun/tw-PII-bench |
|
|
| model-index: |
| - name: privacy-filter-tw |
| results: |
| - task: |
| type: token-classification |
| name: In-schema strict micro F1 (short, 15-120字) |
| dataset: |
| type: lianghsun/tw-PII-bench |
| name: tw-PII-bench (short) |
| split: short |
| metrics: |
| - name: micro F1 |
| type: f1 |
| value: 89.3 |
| - task: |
| type: token-classification |
| name: In-schema strict micro F1 (mid, 200-1000字) |
| dataset: |
| type: lianghsun/tw-PII-bench |
| name: tw-PII-bench (mid) |
| split: mid |
| metrics: |
| - name: micro F1 |
| type: f1 |
| value: 68.8 |
| - task: |
| type: token-classification |
| name: In-schema strict micro F1 (long, 1500-5000字) |
| dataset: |
| type: lianghsun/tw-PII-bench |
| name: tw-PII-bench (long) |
| split: long |
| metrics: |
| - name: micro F1 |
| type: f1 |
| value: 59.5 |
| - task: |
| type: token-classification |
| name: OOD generalization rate (across all splits) |
| dataset: |
| type: lianghsun/tw-PII-bench |
| name: tw-PII-bench |
| metrics: |
| - name: generalization rate |
| type: accuracy |
| value: 88.9 |
| metrics: |
| - f1 |
| - accuracy |
| --- |
| |
| # Model Card for privacy-filter-tw |
|
|
| <!-- Provide a quick summary of what the model is/does. --> |
| **privacy-filter-tw** 是專為中華民國台灣場景打造的 PII(個人識別資訊)偵測模型。本模型建構於 [`openai/privacy-filter`](https://huggingface.co/openai/privacy-filter) 之上,**新增 11 個台灣特有 PII 類別** (身分證、健保卡、統一編號、車牌、護照、駕照、LINE ID、PTT 帳號、戶號、醫事字號、軍人證號),並針對繁體中文場景做大規模強化訓練,使其能精準辨識台灣場景中的個資格式(含民國紀年、中文姓名邊界、台灣地址、09xx 手機等)。 |
|
|
| > ⚠️ 規格重點: |
| > 本模型為**單次 forward pass 的 token-classification 模型**,**不是** chat / generative LM;使用模型自帶的 constrained Viterbi decoder(OPF 格式),不能透過 HuggingFace `transformers.pipeline` 載入。 |
|
|
| ## Model Details |
|
|
| 承續 [`openai/privacy-filter`](https://huggingface.co/openai/privacy-filter) 開源的 PII 偵測架構(1.5B total / 50M active params, GPT-oss-style MoE backbone, banded bidirectional attention),原模型只支援 8 個 PII 類別且訓練語料以英文為主,在台灣場景有兩個明顯短板: |
| 1. **In-schema label 在 zh-TW 表現不均**:中文姓名邊界、民國紀年、台灣地址 / 帳號格式都需要補強 |
| 2. **大量台灣常見 PII 類別不在 schema 內**:身分證、健保卡、車牌、LINE ID 等都無法直接偵測 |
|
|
| `privacy-filter-tw` 透過 [`lianghsun/tw-PII-chat`](https://huggingface.co/datasets/lianghsun/tw-PII-chat) v3(183,588 筆合成訓練資料,涵蓋短句、中長文、PDF、專利、公眾人物 hard-negative 等多樣場景)做完整 fine-tune,把這兩個 gap 補起來。 |
|
|
| > **`-tw`** 後綴明示這是針對 **Taiwan locale** 的特化版本,與通用版 `openai/privacy-filter` 並列使用而非取代。 |
|
|
| **核心特點 (Key Features)** |
|
|
| 1. **新增 11 個台灣特有 PII labels**: |
| - `tw_national_id`(身分證字號)、`tw_nhi_card`(健保卡)、`tw_company_id`(統一編號) |
| - `tw_passport`(護照)、`tw_driver_license`(駕照)、`tw_license_plate`(車牌) |
| - `tw_line_id`(LINE ID)、`tw_ptt_id`(PTT 帳號) |
| - `tw_household_no`(戶號 / 房屋稅籍)、`tw_medical_license`(醫事人員字號)、`tw_military_id`(軍人證號) |
|
|
| 2. **In-schema 8 labels 全面強化**: |
| - In-schema 整體 strict micro F1 從 **57.6%** 提升到 **89.3%** (+31.7pp,short split);跨 3 個 split 加權平均 **72.7%** (▲ +18.6pp) |
| - 民國紀年 `private_date` 19.1% → 86.1%(+67.0pp);中文姓名 `private_person` 36.3% → 84.7%(+48.4pp);`private_url` 21.3% → 93.0%(+71.7pp) |
|
|
| 3. **保留 OPF 原生推論架構**: |
| - 完全相容於 `openai/privacy-filter` 的 inference 流程(custom Viterbi decoder + banded attention) |
| - 同樣的 `original/*` checkpoint 格式,可用 [`opf` CLI](https://github.com/openai/privacy-filter) 直接載入 |
| - Context window 128k,與 base 一致 |
|
|
| ### Model Description |
|
|
| - **Developed by:** [Liang Hsun Huang](https://huggingface.co/lianghsun) |
| - **Base model:** [`openai/privacy-filter`](https://huggingface.co/openai/privacy-filter) (1.5B total / 50M active params, MoE-128 top-4) |
| - **Model type:** Token Classification (BIOES, 77 classes = 1 background + 19 labels × 4 boundary tags) |
| - **Language(s) (NLP):** Traditional Chinese (Taiwan) & English |
| - **License:** Apache 2.0 |
| - **Format:** OPF-native checkpoint(**非** HuggingFace `AutoModelForTokenClassification` 相容格式) |
|
|
| ### Model Sources |
|
|
| - **Repository:** [lianghsun/privacy-filter-tw](https://huggingface.co/lianghsun/privacy-filter-tw) |
| - **Training dataset:** [lianghsun/tw-PII-chat](https://huggingface.co/datasets/lianghsun/tw-PII-chat)(gated, manual review) |
| - **Evaluation benchmark:** [lianghsun/tw-PII-bench](https://huggingface.co/datasets/lianghsun/tw-PII-bench) |
| - **Live dashboard:** [openai-pii-bench.lianghsun.dev](https://openai-pii-bench.lianghsun.dev) |
|
|
| ## Evaluation |
|
|
| ### Head-to-head vs `openai/privacy-filter` — across all 3 splits |
|
|
| 評測於 [`lianghsun/tw-PII-bench`](https://huggingface.co/datasets/lianghsun/tw-PII-bench) 全 3 個 split(910 題:short 310 + mid 300 + long 300)。兩個模型皆採用**模型原生 Viterbi decoder** (非 HF pipeline)。 |
|
|
| #### Per-split in-schema strict micro F1 |
|
|
| | Split | 文字長度 | Items | `openai/privacy-filter` | 🌟 `privacy-filter-tw` | Δ | |
| |---|---|---|---:|---:|---:| |
| | `short` | 15-120 字 | 310 | 57.6% | **89.3%** | ▲ +31.7pp | |
| | `mid` | 200-1000 字 | 300 | 59.9% | **68.8%** | ▲ +8.9pp | |
| | `long` | 1500-5000 字 | 300 | 51.7% | **59.5%** | ▲ +7.8pp | |
| | **all** | — | 910 | 54.1% | **72.7%** | ▲ +18.6pp | |
|
|
| > ✅ v3 訓練 ctx=4096、加入 pdf_short/mid/long 長文本資料,**long split F1 從 50.0% 提升至 59.5%** (▲ +7.8pp,已超越 base 模型 51.7%)。部分 TW 特有類別(`tw_passport`、`tw_driver_license`、`tw_medical_license`)在 mid/long context 中 recall 仍偏低,詳見 Known limitations。 |
|
|
| #### Overall metrics (all 3 splits combined) |
|
|
| | Metric | `openai/privacy-filter` | 🌟 `privacy-filter-tw` | Δ | |
| |---|---:|---:|---:| |
| | In-schema strict micro F1 | 54.1% | **72.7%** | ▲ +18.6pp | |
| | In-schema micro precision | 49.9% | **71.6%** | ▲ +21.7pp | |
| | In-schema micro recall | 59.1% | **74.5%** | ▲ +15.4pp | |
| | In-schema relaxed micro F1 (IOU>0.5) | 57.9% | — | — | |
| | **OOD detection rate** (any overlap) | 68.2% | — | — | |
| | **OOD generalization rate** (correct label) | 48.2% | — | — | |
| | Hard-negative FP rate (short_neg, ≥1 FP/例) | — | 77.5% | — | |
| |
| ### Per-label F1 — In-schema 8 labels (overall, strict span+label) |
| |
| | Label | `openai/privacy-filter` | 🌟 `privacy-filter-tw` | Δ | |
| |---|---:|---:|---:| |
| | `private_person` | 36.3% | **69.0%** | ▲ +32.7pp | |
| | `private_phone` | 86.7% | **94.6%** | ▲ +7.9pp | |
| | `private_email` | 67.8% | **78.6%** | ▲ +10.8pp | |
| | `private_address` | 69.9% | **91.1%** | ▲ +21.2pp | |
| | `private_date` | 19.1% | **63.2%** | ▲ +44.1pp | |
| | `private_url` | 21.3% | **91.4%** | ▲ +70.1pp | |
| | `account_number` | 72.7% | **87.2%** | ▲ +14.5pp | |
| | `secret` | **65.1%** | 68.6% | ▲ +3.5pp | |
|
|
| > v3 模型 in-schema 8 個類別**全數提升** (加權 overall)。短句場景 short split:`private_phone` 96.0%、`private_email` 88.9%、`secret` 81.1%。上表為跨三個 split 的加權平均近似值。 |
|
|
| ### Per-label F1 — Taiwan OOD 11 labels (overall, strict) |
|
|
| | Label | `openai/privacy-filter` | 🌟 `privacy-filter-tw` | Δ | |
| |---|---:|---:|---:| |
| | `tw_national_id` 身分證字號 | 0.0% | **85.6%** | ▲ +85.6pp | |
| | `tw_nhi_card` 健保卡 | 0.0% | **100.0%** | ▲ +100.0pp | |
| | `tw_company_id` 統一編號 | 0.0% | **76.0%** | ▲ +76.0pp | |
| | `tw_passport` 護照 | 0.0% | 40.6% | ▲ +40.6pp | |
| | `tw_driver_license` 駕照 | 0.0% | 46.2% | ▲ +46.2pp | |
| | `tw_license_plate` 車牌 | 0.0% | **69.2%** | ▲ +69.2pp | |
| | `tw_line_id` LINE ID | 0.0% | **84.7%** | ▲ +84.7pp | |
| | `tw_ptt_id` PTT 帳號 | 0.0% | 39.3% | ▲ +39.3pp | |
| | `tw_household_no` 戶號 | 0.0% | **93.8%** | ▲ +93.8pp | |
| | `tw_medical_license` 醫事字號 | 0.0% | 37.7% | ▲ +37.7pp | |
| | `tw_military_id` 軍人證號 | 0.0% | 30.8% | ▲ +30.8pp | |
|
|
| > 11 個 Taiwan OOD label 全部從 0% 提升;`tw_national_id`、`tw_nhi_card`、`tw_household_no`、`tw_line_id` 達 80%+ 加權平均。`tw_passport`、`tw_driver_license`、`tw_medical_license`、`tw_ptt_id`、`tw_military_id` 在 short split 表現良好,但在 mid/long context 中 recall 偏低,是下版優先強化目標。上表為跨三個 split 的加權平均近似值(short-only label 僅計 short split)。 |
| |
| ### Known limitations |
| |
| 1. **Long-context 明顯改善但仍有進步空間**:`long` split (1500-5000 字) F1 從 50.0% 提升至 **59.5%** (▲ +9.5pp,已超越 base 的 51.7%)。v3 訓練 ctx=4096,有效緩解長文本退步問題。部分 TW 類別(`tw_passport`、`tw_driver_license`、`tw_medical_license`)在 mid/long context 中 recall 仍偏低,是下版優先修復方向。 |
| 2. **Hard-negative FP 偏高(77.5% 的 hard-neg 例題觸發至少一個誤報)**:模型對「看起來像 PII 的非 PII」(公眾人物、組織名稱)仍有誤報。下版需進一步強化 hard negative 訓練資料。 |
| 3. **部分 TW OOD label 在 mid/long context 中 recall 偏低**:`tw_passport`(short 100%,long 13%)、`tw_driver_license`(short 96%,long 10%)、`tw_medical_license`(short 96%,long 5%)等在長文本中召回率大幅下滑,疑為訓練樣本分佈以短文為主所致。 |
| 4. **`tw_military_id` 仍為最弱類別**:整體加權 F1 僅 30.8%(short precision 100% 但 recall 只有 18%),Gemini 合成的軍人證號格式與實際不符,需補充真實樣本。 |
| 3. **未涵蓋少數族群名 / 罕見字**:原住民傳統名、客語姓名邊界判定仍有 edge case。 |
|
|
| ## How to Run Inference |
|
|
| ### 1️⃣ 安裝 OPF CLI |
|
|
| ```bash |
| pip install -e git+https://github.com/openai/privacy-filter#egg=opf |
| ``` |
|
|
| ### 2️⃣ 下載模型 |
|
|
| ```bash |
| huggingface-cli download lianghsun/privacy-filter-tw --local-dir ./privacy-filter-tw |
| ``` |
|
|
| ### 3️⃣ 跑單句推論 |
|
|
| ```bash |
| opf --checkpoint ./privacy-filter-tw "你好,我是王小明,身分證字號 A123456789,手機 0912-345-678。" |
| ``` |
|
|
| ### 4️⃣ Python 直接呼叫(vendored Decoder 範例) |
|
|
| 完整可執行範例見 [`tw-PII-bench` companion repo](https://huggingface.co/datasets/lianghsun/tw-PII-bench) 的 `scripts/lib/privacy_filter_lib.py`: |
|
|
| ```python |
| from pathlib import Path |
| import privacy_filter_lib as pf |
| |
| runtime = pf.get_runtime(model_dir=Path("./privacy-filter-tw")) |
| decoder = pf.Decoder(label_info=runtime.label_info, model_dir=Path("./privacy-filter-tw")) |
| |
| text = "您好,我是陸軍少校王志強,身分證字號 F128334452,駕照 ABC1234567,車牌 ABC-1234。" |
| result_text, spans = pf.predict_text(runtime, text, decoder) |
| |
| for s in spans: |
| print(f" [{s['start']:3d}:{s['end']:3d}] {s['entity']:20s} → {text[s['start']:s['end']]!r}") |
| ``` |
|
|
| ### Output 格式 |
|
|
| 與 `openai/privacy-filter` 原生輸出**完全相容**: |
|
|
| ```json |
| [ |
| {"entity": "private_person", "start": 6, "end": 11}, |
| {"entity": "tw_national_id", "start": 19, "end": 29}, |
| {"entity": "tw_driver_license", "start": 33, "end": 43}, |
| {"entity": "tw_license_plate", "start": 47, "end": 55} |
| ] |
| ``` |
|
|
| > ⚠️ **不要**用 `transformers.AutoModelForTokenClassification.from_pretrained()` 載入,會缺少 Viterbi decoding,導致中文 span fragmentation(嚴重時 strict F1 從 89% 掉到 < 5%)。 |
| |
| ## Training Details |
| |
| | 項目 | 值 | |
| |---|---| |
| | Base checkpoint | `openai/privacy-filter` (`original/*` weights) | |
| | Training data | [`lianghsun/tw-PII-chat`](https://huggingface.co/datasets/lianghsun/tw-PII-chat) v3(183,588 筆,含 pdf_short/mid/long、patent、neg_public_figure_real)| |
| | Train / Val / Test split | 165,228 / 9,180 / 9,180 | |
| | Optimizer | AdamW (lr=2e-4, weight_decay=0.0, max_grad_norm=1.0) | |
| | Schedule | 3 chunks × 1 epoch,early-stop on long_span_f1 (patience=2),batch_size=8 × grad_accum=4,ctx=4096,bf16 | |
| | Output head | 33 → 77 classes(前 33 列從 base 拷貝,後 44 列重新初始化)| |
| | Hardware | 1× NVIDIA B200 | |
| | Training time | ~6 小時(3 chunks × ~2h per chunk,B200)| |
| | Best checkpoint | chunk 2/3(long_span_f1=0.5952),val_loss=0.0318,val_token_accuracy=98.89% | |
| |
| ### Label space (`tw_pii_v1`) |
| |
| 20 個 span class(含 `O` background)= 8 個 in-schema + 11 個 Taiwan OOD: |
| |
| ``` |
| O, account_number, private_address, private_date, private_email, private_person, |
| private_phone, private_url, secret, |
| tw_national_id, tw_nhi_card, tw_company_id, tw_passport, tw_line_id, |
| tw_license_plate, tw_driver_license, tw_household_no, tw_ptt_id, |
| tw_medical_license, tw_military_id |
| ``` |
| |
| 完整 BIOES 展開為 1 + 19 × 4 = **77 classes**。Label space 定義見 `tw_label_space.json`。 |
| |
| ## Citation |
| |
| ```bibtex |
| @misc{privacy_filter_tw, |
| title = {privacy-filter-tw: A Taiwan-localized PII detector built on openai/privacy-filter}, |
| author = {Huang, Liang Hsun}, |
| year = {2026}, |
| howpublished = {\url{https://huggingface.co/lianghsun/privacy-filter-tw}}, |
| note = {Fine-tuned on lianghsun/tw-PII-chat with 11 Taiwan-specific OOD labels added.} |
| } |
| ``` |
| |
| ## Acknowledgements |
| |
| - [OpenAI](https://openai.com) 開源 [`openai/privacy-filter`](https://huggingface.co/openai/privacy-filter) 與其 OPF inference framework,提供堅實的 backbone。 |
| - Gemini 3.1 Pro / Flash Lite Preview 用於 [`tw-PII-chat`](https://huggingface.co/datasets/lianghsun/tw-PII-chat) 訓練資料合成。 |
| |
| ## Model Card Authors |
| |
| [Liang Hsun Huang](https://www.linkedin.com/in/lianghsunhuang/?locale=en_US) |
| |
| ## Model Card Contact |
| |
| [Liang Hsun Huang](https://www.linkedin.com/in/lianghsunhuang/?locale=en_US) |
| |