ppuzio commited on
Commit
caa10a8
·
verified ·
1 Parent(s): 407ef5f

Add NERGAL epoch-5 hybrid PII snapshot

Browse files
.gitattributes CHANGED
@@ -33,3 +33,6 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ figures/primary-three-model-curves.png filter=lfs diff=lfs merge=lfs -text
37
+ figures/xlmr-seven-epoch-curves.png filter=lfs diff=lfs merge=lfs -text
38
+ tokenizer.json filter=lfs diff=lfs merge=lfs -text
README.md ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: mit
3
+ language:
4
+ - pl
5
+ base_model: FacebookAI/xlm-roberta-large
6
+ library_name: transformers
7
+ pipeline_tag: token-classification
8
+ tags:
9
+ - polish
10
+ - pii
11
+ - ner
12
+ - xlm-roberta
13
+ - hybrid
14
+ ---
15
+
16
+ # NERGAL
17
+
18
+ **Named Entity Recognition with Grounded Additive Labels**
19
+
20
+ SlayerLab hybrid PII cleaner for Polish. Not a chat model. Not a drop-in `pipeline("token-classification")`.
21
+
22
+ ## TL;DR
23
+
24
+ Python rules do the identifiers they can prove. A transformer NER head adds phone and other PII spans the regex misses. The cleaner **unions** the two on the original text, then replaces hits with `[Telefon]` or `[PII]`.
25
+
26
+ - **Ground:** frozen `scrub_pii` regex
27
+ - **Additive labels:** XLM-RoBERTa-large token classifier, BIO tags `phone` / `pii`, threshold 0.95
28
+ - **This snapshot:** seed `202609160`, **epoch 5** of a seven-epoch schedule
29
+
30
+ ## 841-dev
31
+
32
+ Tables use one development split: 841 passages, 215 with gold PII, **354 spans** (169 phone, 185 other PII). It is the `dev` side of a 4,500-passage labelled tranche (3,655 train / 841 dev). Sources match Dynaword (EUR-Lex, HPLT, Wikipedia, parliamentary and government text, plus smaller news/literary slices). Labels mix unchanged silver with human review.
33
+
34
+ The files contain real identifiers, so they are not released with the weights.
35
+
36
+ ## Why XLM-R
37
+
38
+ GLiNER, HerBERT-large, and XLM-R-large were trained on the same split and unioned with the same regex. Plot: diagnostic threshold 0.50; selection used the full threshold grid. GLiNER covers more at 0.50 and then dumps precision. XLM-R is the architecture we kept.
39
+
40
+ ![Primary three-model curves](figures/primary-three-model-curves.png)
41
+
42
+ ## Why epoch 5
43
+
44
+ Fresh XLM-R, seven epochs. 133 epoch/threshold combinations. Epoch 5 at 0.95 was the only point that both beat the historical GLiNER∪regex incumbent on coverage and introduced zero new false-mask characters. Epoch 7 covers more PII (334/354) but adds 15 new false characters.
45
+
46
+ ![Seven-epoch XLM-R curves](figures/xlmr-seven-epoch-curves.png)
47
+
48
+ | Epoch | Covered @ 0.95 /354 | Residual passages | False characters | New false vs incumbent |
49
+ |---|---:|---:|---:|---:|
50
+ | 1 | 272 | 59 | 175 | 42 |
51
+ | 2 | 291 | 49 | 141 | 8 |
52
+ | 3 | 317 | 30 | 140 | 7 |
53
+ | 4 | 320 | 28 | 143 | 10 |
54
+ | **5** | **323** | **25** | **133** | **0** |
55
+ | 6 | 328 | 20 | 147 | 14 |
56
+ | 7 | 334 | 16 | 148 | 15 |
57
+
58
+ ## 841-dev scores
59
+
60
+ Union with unchanged rules. Character scores are on gold vs masked characters.
61
+
62
+ | System | Whole spans /354 | Residual passages | False chars | Char precision | Char recall |
63
+ |---|---:|---:|---:|---:|---:|
64
+ | Regex only | 245 | 73 | 133 | 97.36% | 81.01% |
65
+ | Historical GLiNER email12 ∪ regex | 289 | 51 | 143 | 97.54% | 93.48% |
66
+ | **NERGAL (this snapshot ∪ regex)** | **323** | **25** | **133** | **97.76%** | **95.95%** |
67
+
68
+ 144/169 phone, 179/185 other PII. Exact-span precision 87.50%, recall 88.98%, F1 88.24%.
69
+
70
+ ## Extra seeds
71
+
72
+ | Seed | Whole /354 | False chars | New false vs historical union |
73
+ |---|---:|---:|---:|
74
+ | 202609160 (this repo) | 323 | 133 | 0 |
75
+ | 202609161 | 322 | 134 | 1 |
76
+ | 202609162 | 316 | 151 | 18 |
77
+
78
+ ## Load
79
+
80
+ ```python
81
+ from transformers import AutoModelForTokenClassification, AutoTokenizer
82
+ tok = AutoTokenizer.from_pretrained("SlayerLab/NERGAL")
83
+ model = AutoModelForTokenClassification.from_pretrained("SlayerLab/NERGAL")
84
+ ```
85
+
86
+ Reproducing the table needs the windowed BIO decoder and regex union (`hybrid.json`: threshold 0.95, gap ids `250002`/`250003`). Vanilla token classification will not match.
87
+
88
+ Base weights: [`FacebookAI/xlm-roberta-large`](https://huggingface.co/FacebookAI/xlm-roberta-large) revision `c23d21b0620b635a76227c604d44e43a9f0ee389` (MIT).
config.json ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "XLMRobertaForTokenClassification"
4
+ ],
5
+ "attention_probs_dropout_prob": 0.1,
6
+ "bos_token_id": 0,
7
+ "classifier_dropout": null,
8
+ "dtype": "float32",
9
+ "eos_token_id": 2,
10
+ "hidden_act": "gelu",
11
+ "hidden_dropout_prob": 0.1,
12
+ "hidden_size": 1024,
13
+ "id2label": {
14
+ "0": "O",
15
+ "1": "B-phone",
16
+ "2": "I-phone",
17
+ "3": "B-pii",
18
+ "4": "I-pii"
19
+ },
20
+ "initializer_range": 0.02,
21
+ "intermediate_size": 4096,
22
+ "label2id": {
23
+ "B-phone": 1,
24
+ "B-pii": 3,
25
+ "I-phone": 2,
26
+ "I-pii": 4,
27
+ "O": 0
28
+ },
29
+ "layer_norm_eps": 1e-05,
30
+ "max_position_embeddings": 514,
31
+ "model_type": "xlm-roberta",
32
+ "num_attention_heads": 16,
33
+ "num_hidden_layers": 24,
34
+ "output_past": true,
35
+ "pad_token_id": 1,
36
+ "position_embedding_type": "absolute",
37
+ "transformers_version": "4.57.6",
38
+ "type_vocab_size": 1,
39
+ "use_cache": true,
40
+ "vocab_size": 250004
41
+ }
figures/primary-three-model-curves.png ADDED

Git LFS Details

  • SHA256: c84b632606f398fc49b2289cc13d22c5ec6481cb6fcf147fdf0a315e46053deb
  • Pointer size: 131 Bytes
  • Size of remote file: 177 kB
figures/xlmr-seven-epoch-curves.png ADDED

Git LFS Details

  • SHA256: 3ccce9f3bdf6ee636f08b9fa3277a4582370e3ed193ec3bbb4ad1792819b7eb6
  • Pointer size: 131 Bytes
  • Size of remote file: 210 kB
hybrid.json ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "full_name": "Named Entity Recognition with Grounded Additive Labels",
3
+ "hub_id": "SlayerLab/NERGAL",
4
+ "mode": "rules_union",
5
+ "epoch": 5,
6
+ "seed": 202609160,
7
+ "threshold": 0.95,
8
+ "rules_sha256": "547c0428b0799bf051566d6ac489987eff27f09e1bda36a5665452fe155b3966",
9
+ "weights_sha256": "063ee5f9782c1b4d99e838be5a836328718e1372e213d5b87098b371b5c162af",
10
+ "gaps": [
11
+ "[PII_SPACE]",
12
+ "[PII_BREAK]"
13
+ ],
14
+ "gap_ids": [
15
+ 250002,
16
+ 250003
17
+ ],
18
+ "drop_in_token_classification_pipeline": false,
19
+ "promotion_authorized": false,
20
+ "backbone": {
21
+ "repo": "FacebookAI/xlm-roberta-large",
22
+ "revision": "c23d21b0620b635a76227c604d44e43a9f0ee389"
23
+ }
24
+ }
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1d42c34459e90cd25db44f92bb31fb2be1ef3a1b1e34c599162e1895057c08f6
3
+ size 2235440548
sentencepiece.bpe.model ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:cfc8146abe2a0488e9e2a0c56de7952f7c11ab059eca145a0a727afce0db2865
3
+ size 5069051
special_tokens_map.json ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "bos_token": "<s>",
3
+ "cls_token": "<s>",
4
+ "eos_token": "</s>",
5
+ "mask_token": {
6
+ "content": "<mask>",
7
+ "lstrip": true,
8
+ "normalized": false,
9
+ "rstrip": false,
10
+ "single_word": false
11
+ },
12
+ "pad_token": "<pad>",
13
+ "sep_token": "</s>",
14
+ "unk_token": "<unk>"
15
+ }
tokenizer.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a54cb01d8728aea3cca3f62eac3940b59b564193f41b548a1e03bb59da22acee
3
+ size 17083110
tokenizer_config.json ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "added_tokens_decoder": {
3
+ "0": {
4
+ "content": "<s>",
5
+ "lstrip": false,
6
+ "normalized": false,
7
+ "rstrip": false,
8
+ "single_word": false,
9
+ "special": true
10
+ },
11
+ "1": {
12
+ "content": "<pad>",
13
+ "lstrip": false,
14
+ "normalized": false,
15
+ "rstrip": false,
16
+ "single_word": false,
17
+ "special": true
18
+ },
19
+ "2": {
20
+ "content": "</s>",
21
+ "lstrip": false,
22
+ "normalized": false,
23
+ "rstrip": false,
24
+ "single_word": false,
25
+ "special": true
26
+ },
27
+ "3": {
28
+ "content": "<unk>",
29
+ "lstrip": false,
30
+ "normalized": false,
31
+ "rstrip": false,
32
+ "single_word": false,
33
+ "special": true
34
+ },
35
+ "250001": {
36
+ "content": "<mask>",
37
+ "lstrip": true,
38
+ "normalized": false,
39
+ "rstrip": false,
40
+ "single_word": false,
41
+ "special": true
42
+ },
43
+ "250002": {
44
+ "content": "[PII_SPACE]",
45
+ "lstrip": false,
46
+ "normalized": false,
47
+ "rstrip": false,
48
+ "single_word": false,
49
+ "special": true
50
+ },
51
+ "250003": {
52
+ "content": "[PII_BREAK]",
53
+ "lstrip": false,
54
+ "normalized": false,
55
+ "rstrip": false,
56
+ "single_word": false,
57
+ "special": true
58
+ }
59
+ },
60
+ "bos_token": "<s>",
61
+ "clean_up_tokenization_spaces": false,
62
+ "cls_token": "<s>",
63
+ "eos_token": "</s>",
64
+ "extra_special_tokens": {},
65
+ "mask_token": "<mask>",
66
+ "model_max_length": 512,
67
+ "pad_token": "<pad>",
68
+ "sep_token": "</s>",
69
+ "tokenizer_class": "XLMRobertaTokenizer",
70
+ "unk_token": "<unk>"
71
+ }