File size: 10,111 Bytes
13bfb0e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
---
license: other
license_name: proprietary-sciencesoft
license_link: https://huggingface.co/ScienceSoft/scnsoft-pii-encoder-small/blob/main/README.md#licence
language: [en, de, fr, it, es, ru, ar]
pipeline_tag: token-classification
tags: [pii, ner, privacy, dlp, onnx, minilm, distillation]
library_name: onnxruntime
base_model: microsoft/Multilingual-MiniLM-L12-H384
base_model_relation: finetune
model-index:
- name: scnsoft-pii-encoder-small
  results:
  - task:
      type: token-classification
      name: PII detection (format-less entities)
    dataset:
      type: ScienceSoft/piibench
      name: PII Bench (piibench)
    metrics:
    - type: f1
      value: 0.5965
      name: F1, character-level, label-agnostic, averaged over 7 datasets (production engine, before post-filters)
    - type: precision
      value: 0.4580
      name: Precision
    - type: recall
      value: 0.9024
      name: Recall
---

# ScienceSoft PII encoder — small

A fast, multilingual token-classification model for personal data **without a fixed format**:
names of people and organisations, locations, addresses and dates. It is a 6-layer, 384-wide
student of [`ScienceSoft/scnsoft-pii-encoder`](https://huggingface.co/ScienceSoft/scnsoft-pii-encoder),
and it runs **3.9× faster** than that model on CPU.

**It is considerably less accurate than the model it was distilled from.** Its recall matches the
full model's, but its precision does not: on real text it marks far more words that are not
personal data. Before training, a bar was set for releasing a small model: an average PII Bench
F1 of at least 0.72, with no language more than 0.08 below the full model. **This model does not
meet that bar.** It is published with that result stated, so the trade between speed and accuracy
can be judged on the numbers.

Architecture: [`microsoft/Multilingual-MiniLM-L12-H384`](https://huggingface.co/microsoft/Multilingual-MiniLM-L12-H384),
reduced to 6 of its 12 layers (layers 1, 3, 5, 7, 9 and 11), with XLM-R's tokenizer. It is trained
on the full model's synthetic corpus with the full model as teacher, then exported to ONNX and
quantised to int8. The file is **107 MB**, and inference runs on CPU.

## Labels

`PERSON` `ORGANIZATION` `LOCATION` `ADDRESS` `DATE_TIME` (BIO tagging, 11 classes), the same set
and order as the full model.

Identifiers with a fixed format (email addresses, telephone, payment-card, IBAN and passport
numbers) are not labels; a regular expression recognises them exactly. The full model is trained
to leave them unmarked. This model does so much less reliably; see *touch rate* below.

## Speed

Measured on 300 PII Bench rows:

- int8 ONNX Runtime 1.19.2 on CPU, batch size 1;
- all three models interleaved row by row;
- an Apple M4 Max with 16 cores, a shared workstation with a 1-minute load average of 18–19.

Absolute milliseconds depend on the host; the ratio is the informative part.

| model | layers × width | int8 size | median ms per row | 95th percentile | speed-up |
|---|---|---|---|---|---|
| `scnsoft-pii-encoder` | 12 × 768 | 278 MB | 22.2 | 36.0 | 1.0× |
| [`scnsoft-pii-encoder-pruned-6l`](https://huggingface.co/ScienceSoft/scnsoft-pii-encoder-pruned-6l) | 6 × 768 | 235 MB | 12.2 | 20.7 | 1.8× |
| **this model** | 6 × 384 | 107 MB | **5.7** | **8.5** | **3.9×** |

## Evaluation on PII Bench

[PII Bench](https://huggingface.co/datasets/ScienceSoft/piibench) (piibench) scores detection
of the five entity types above in text serialised the way outbound traffic carries it (JSON,
XML, SQL, CSV, key=value, log lines, Markdown tables, OCR output) as well as prose.

- It comprises 3,500 rows, 500 from each of seven third-party datasets.
- Precision, recall and F1 are computed over characters and are label-agnostic.
- Scores are micro-averaged within each dataset and then averaged across the seven.
- Leaderboard: [ScienceSoft/piibench-leaderboard](https://huggingface.co/spaces/ScienceSoft/piibench-leaderboard).

**How these numbers were produced.** All models in the tables below are scored the same way: by
the production Rust inference engine, before its post-filters. That is the same path as the
leaderboard's `scnsoft-pii-encoder-engine-raw` row, which this scoring reproduces exactly
(0.7725). The intervals are 95 % percentile bootstrap intervals over rows, resampled within each
dataset (1,000 resamples).

**Conflict of interest.** PII Bench is built and published by ScienceSoft, the developer of
this model. Four of its seven datasets (TAB, FactRuEval, MEDDOCAN, IAHLT) informed changes to the
training corpus this model shares with the full model.

| | this model | `scnsoft-pii-encoder` | bar set before training |
|---|---|---|---|
| F1 | **0.597** [0.587, 0.605] | 0.773 [0.765, 0.780] | ≥ 0.72 |
| precision | 0.458 | 0.685 | |
| recall | 0.902 | 0.908 | |
| touch rate (lower is better) | 0.237 | 0.020 | |

| language | this model | `scnsoft-pii-encoder` | bar (full model − 0.08) |
|---|---|---|---|
| ar | 0.525 | 0.681 | 0.601 |
| de | 0.435 | 0.657 | 0.577 |
| en | 0.640 | 0.804 | 0.724 |
| es | 0.678 | 0.844 | 0.764 |
| ru | 0.599 | 0.754 | 0.674 |

**Where the accuracy is lost.**

- Recall is the full model's (0.902 against 0.908). The loss is in **precision** (0.458 against
  0.685), and it appears in every dataset and in every free-text format.
- On an in-distribution synthetic evaluation, drawn from the training generator, the model scores
  F1 0.986, close to the full model's 0.993. It learned the task on the kind of text it was trained
  on. It fires too often on real text, which its training data (synthetic, like the full model's)
  never showed it.
- Distillation did not close the gap, because the teacher's guidance was also only given on
  synthetic text.
- **Touch rate** is the share of characters belonging to format-fixed identifiers that a model
  marks anyway: 0.237 here, against 0.020 for the full model. In a product that already masks
  those identifiers by regular expression, this costs little. As a stand-alone detector, it
  over-marks them.

### Variability across training seeds

Two training runs of the same recipe, differing only in the random seed:

| training seed | F1 | 95 % CI | precision | recall |
|---|---|---|---|---|
| 1234 — **this model** (`main`) | 0.5965 | [0.5871, 0.6052] | 0.458 | 0.902 |
| 4321 (branch `seed-4321`) | 0.6035 | [0.5944, 0.6123] | 0.465 | 0.901 |

The two runs agree to within 0.007 F1. Seed 1234 is published on `main` by convention, not
because it scored better; it did not.

## Training

- **Corpus:** the same synthetic corpus as `scnsoft-pii-encoder` (v23), rebuilt from that run's
  own generator snapshot and configuration and verified row for row by count: 155,141 training and
  5,300 evaluation rows.
- **Distillation from `scnsoft-pii-encoder`:** the loss is 0.5 × cross-entropy on the gold labels
  plus 0.5 × T² × KL(teacher ‖ student) on the teacher's token distributions at temperature
  T = 2, over non-padding tokens.
- **Schedule:** two epochs, 19 minutes on one GPU.
- **Stack:** `transformers==4.57.1`, `tokenizers==0.22.1`, `torch==2.9.0a0`, `faker==37.12.0`.
- **int8 against fp32:** −0.0037 F1 on the synthetic evaluation, 95 % CI [−0.0055, −0.0022].

## Limitations

- **Below the release bar in every language** (see above). Where accuracy matters more than
  latency, use [`scnsoft-pii-encoder`](https://huggingface.co/ScienceSoft/scnsoft-pii-encoder).
- **Low precision on real text.** Expect far more false positives than from the full model, and
  many more format-fixed identifiers marked.
- **Trained only on synthetic data**, like the full model. Scores on generated text overstate
  real-world ability.
- The limitations of the full model apply too. Arabic is its weakest language; Arabizi is a
  reconstruction; `DATE_TIME` is kept by the product only next to a birth-date cue.

## Use

Required files: `config.json`, `tokenizer.json`, `onnx/model_quantized.onnx`.

```python
import json, onnxruntime as ort
from transformers import AutoTokenizer

tok = AutoTokenizer.from_pretrained("ScienceSoft/scnsoft-pii-encoder-small")
cfg = json.load(open("config.json"))
id2label = {int(k): v for k, v in cfg["id2label"].items()}
sess = ort.InferenceSession("onnx/model_quantized.onnx",
                            providers=["CPUExecutionProvider"])

enc = tok(text, return_offsets_mapping=True, return_tensors="np",
          truncation=True, max_length=256)
offsets = enc.pop("offset_mapping")[0]
logits = sess.run(None, {i.name: enc[i.name] for i in sess.get_inputs()})[0]
# argmax -> id2label -> merge BIO spans using `offsets` for character positions
```

The ONNX graph takes `input_ids` and `attention_mask` only. Encode with the special tokens
`<s>` and `</s>`, as the model was trained; `AutoTokenizer.__call__` adds them by default.

## Provenance

The training corpus is synthetic text produced by ScienceSoft's own generator; no production
traffic and no scraped text is used for training. Entity values come from project-written lists
and from Faker (person, company and city names), libpostal (address vocabulary) and GeoNames
(Arabic-script city names).

## Licence

Proprietary to ScienceSoft. The weights are published so that the results on this page can be
evaluated and reproduced; no licence to use them in production, to modify them or to redistribute
them is granted. For licensing, contact ScienceSoft (https://www.scnsoft.com).

**Basis for these terms.**

- **Initialised from** `microsoft/Multilingual-MiniLM-L12-H384` (MIT licence).
- **Uses the tokenizer of** `FacebookAI/xlm-roberta-base` (MIT licence).
- **Distilled from** ScienceSoft's own `scnsoft-pii-encoder`.
- **Training corpus** includes entity values from Faker (MIT), libpostal (MIT) and GeoNames
  (CC BY 4.0).

All of these licences permit a derivative work to be distributed under proprietary terms,
provided their notices are retained and GeoNames is attributed. None is share-alike, and none
restricts commercial use. The notices and the attribution are in
[THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md).