--- language: - ko - en license: apache-2.0 library_name: transformers pipeline_tag: token-classification base_model: openai/privacy-filter tags: - token-classification - ner - pii - privacy - pii-masking - korean - english - finance - customer-service - security - infrastructure - bioes - viterbi - mixture-of-experts datasets: - BCCard/privacy-filter-openpii-masking metrics: - precision - recall - f1 --- # MoAI-Privacy-Filter `MoAI-Privacy-Filter` is a Korean and English privacy-related entity detection model built by full fine-tuning [`openai/privacy-filter`](https://huggingface.co/openai/privacy-filter). It recognizes 29 entity types and emits 117 BIOES token classes. The training data emphasizes financial services and customer-service/VOC text while also covering identity, security, and infrastructure scenarios. The model detects entity spans but does not decide how they should be masked or retained. Applications can apply their own handling policy to each predicted label. This distinction is especially important for `PORT` and `ORGANIZATION`, which are non-PII disambiguation labels included in the output taxonomy. On held-out validation, strict micro F1 is **0.9824 for ko** and **0.9708 for en**. On an independently generated Golden Set, strict micro F1 is **0.9732 for ko** and **0.9650 for en**. ## 1. Model Summary | Item | Value | |---|---| | Model version | v3 | | Training dataset | [`BCCard/privacy-filter-openpii-masking`](https://huggingface.co/datasets/BCCard/privacy-filter-openpii-masking) v1 | | Base model | [`openai/privacy-filter`](https://huggingface.co/openai/privacy-filter) | | Architecture | Approximately 1.4B-parameter MoE, 8 layers, hidden size 640, 128 local experts, top-4 expert routing | | Task | Token classification with BIOES span boundaries | | Languages | Korean and English | | Primary domains | Financial services, customer service/VOC, identity, security, and infrastructure | | Entity labels | 29 | | Output classes | 117 - `O` plus four BIOES classes for each entity label | | Training sequence limit | 1024 tokens before special tokens | | Artifact format | BF16 safetensors with 8 attention `sinks` tensors retained in FP32 | | Tested software | Transformers 5.13.1 and PyTorch 2.13.0 | | License | Apache 2.0 | The model version and dataset version use independent version numbers. This model is v3 and was trained on dataset v1. ## 2. Label Taxonomy | Label | Definition | |---|---| | `PERSON` | Full personal name as one span. | | `RRN` | Korean resident registration number. | | `FRN` | Korean foreign resident registration number. | | `SSN` | Social-security-number family inherited from ai4privacy `SOCIALNUM`; not limited to the US 9-digit form. | | `GENERIC_ID` | Identity-card or tax identifier that cannot be assigned to a more specific country-level label. | | `CARD_NUMBER` | Credit or debit card PAN. | | `ACCOUNT_NUMBER` | Bank account number. | | `SECRET` | Password, API key, access token, or similar authentication secret. | | `USER_ID` | Online account or member identifier. | | `EMAIL` | Email address, including intentionally obfuscated forms represented in the training data. | | `PHONE` | Mobile or landline telephone number, including intentionally verbalized forms represented in the training data. | | `PASSPORT` | Passport number. | | `DRIVER_LICENSE` | Driver's license number. | | `ADDRESS` | City, street, and building components represented as one address span. | | `ZIPCODE` | Postal code kept separate from `ADDRESS`. | | `DATE` | Date or time. Timezone-only strings are not included in this label. | | `CARD_EXPIRY` | Payment-card expiration date. | | `CVC` | Card verification code. | | `IPIN` | Korean I-PIN identifier. | | `TRANSACTION_APPROVAL_ID` | Payment authorization or transaction approval identifier. | | `BUSINESS_ID` | Business registration number or merchant identifier. | | `VIRTUAL_CARD_NUMBER` | Alternate or virtual card number. | | `CI` | Korean identity-linkage information value. | | `IPADDRESS` | IPv4 network address. | | `MACADDRESS` | 48-bit MAC address. | | `IMEI` | Mobile-equipment identifier. | | `PORT` | Network service port from 0 to 65535; a non-PII disambiguation label. | | `ORGANIZATION` | Company, bank, hospital, or other organization name; a non-PII disambiguation label. | | `URL` | Full web URL, including path, query, and fragment when present. | Each entity label has `B-`, `I-`, `E-`, and `S-` boundary classes. Together with `O`, the model therefore has `4 x 29 + 1 = 117` output classes. `O` means that the model predicts no taxonomy entity at that token; it does not guarantee that the surrounding text is non-sensitive. ## 3. Usage ```python import torch from transformers import AutoModelForTokenClassification, AutoTokenizer model_id = "BCCard/MoAI-Privacy-Filter" tokenizer = AutoTokenizer.from_pretrained(model_id) model = AutoModelForTokenClassification.from_pretrained(model_id) model.eval() text = "고객 모아이님(900101-1234569)께서 010-0000-0000로 연락 요청하셨습니다." encoded = tokenizer( text, return_offsets_mapping=True, add_special_tokens=False, truncation=True, max_length=1024, return_tensors="pt", ) offsets = encoded.pop("offset_mapping")[0].tolist() with torch.no_grad(): logits = model(**encoded).logits.float() print(tuple(logits.shape)) # (1, sequence_length, 117) ``` Apply constrained BIOES Viterbi decoding to `logits[0]`, then map the decoded token spans to the original text with `offsets`. Character-span records can then be represented in the following form. ```text [ {'start': 3, 'end': 6, 'label': 'PERSON'}, {'start': 8, 'end': 22, 'label': 'RRN'}, {'start': 26, 'end': 39, 'label': 'PHONE'} ] ``` Character offsets use Python's half-open interval `[start, end)`. A downstream application could render those spans as follows, but this replacement behavior is not part of the model. ```text 고객 [PERSON]님([RRN])께서 [PHONE]로 연락 요청하셨습니다. ``` ### 3.1. Decoding The reported metrics use constrained Viterbi decoding over the BIOES transition grammar, followed by whitespace boundary refinement. Independent per-token argmax can emit invalid BIOES sequences and is not the reported decoding path. The bundled `viterbi_calibration.json` contains six transition biases. The default operating point sets all biases to zero, so BIOES transition constraints remain active without an additional precision-recall adjustment. Convert logits to FP32 before decoding. Use a decoder that implements this BIOES constraint contract. The upstream [`openai/privacy-filter`](https://github.com/openai/privacy-filter) project provides the reference implementation and decoding behavior on which this model is based. For batches, use right padding and pass only `input_ids` and `attention_mask` to the model. Keep `offset_mapping` outside the model for character-span reconstruction. Inputs longer than 1024 tokens were not represented in the training regime and should be chunked with enough overlap for the target use case. ## 4. Training ### 4.1. Data | Dataset | Role | Size | |---|---|---:| | [`BCCard/privacy-filter-openpii-masking`](https://huggingface.co/datasets/BCCard/privacy-filter-openpii-masking) v1 | Training | 57,851 rows | | [`BCCard/privacy-filter-openpii-masking`](https://huggingface.co/datasets/BCCard/privacy-filter-openpii-masking) v1 | Validation and checkpoint selection | 14,524 rows | | Independent non-public Golden Set | Final evaluation only | 4,000 rows - ko 2,920 and en 1,080 | The Golden Set was not used for training, checkpoint selection, or calibration. The training and validation data contain all 29 labels in both languages. English represents 25.74% of train and 26.03% of validation. The dataset combines relabeled rows from [`ai4privacy/pii-masking-openpii-1.5m`](https://huggingface.co/datasets/ai4privacy/pii-masking-openpii-1.5m) with Korean perturbation, English replay, and statically authored synthesis rows. Synthesis covers positive, confusion, hard-negative, weak-cue, long-context, and multi-label scenarios. The dataset is designed as synthetic training data and contains no operational customer records. ### 4.2. Procedure