temsa commited on
Commit
005620f
·
verified ·
1 Parent(s): d7d331c

Add files using upload-large-folder tool

Browse files
Files changed (50) hide show
  1. .gitattributes +0 -30
  2. .gitignore +3 -0
  3. LICENSE +73 -0
  4. NOTICE +13 -0
  5. PORTFOLIO_COMPARISON.md +92 -0
  6. README.md +187 -0
  7. base_common.py +628 -0
  8. common.py +0 -0
  9. config.json +318 -0
  10. eval/benchmark_summary.json +94 -0
  11. eval/benchmark_summary.md +28 -0
  12. eval/full_globalpointer_context_holdout_v16_exact.json +108 -0
  13. eval/full_irish_core_pii_v1.json +108 -0
  14. eval/full_irish_gov_chatbot_gap_holdout_v2.json +92 -0
  15. eval/full_irish_gov_chatbot_redteam_v2.json +108 -0
  16. eval/full_irish_gov_contact_policy_v1.json +76 -0
  17. eval/full_multilingual_ppsn_v1_all.json +28 -0
  18. eval/q8_globalpointer_context_holdout_v16_exact.json +108 -0
  19. eval/q8_globalpointer_context_holdout_v17.json +92 -0
  20. eval/q8_globalpointer_context_holdout_v17_exact.json +92 -0
  21. eval/q8_globalpointer_context_holdout_v18_exact.json +84 -0
  22. eval/q8_globalpointer_context_holdout_v19_exact.json +108 -0
  23. eval/q8_globalpointer_context_holdout_v20_exact.json +100 -0
  24. eval/q8_irish_core_pii_v1.json +108 -0
  25. eval/q8_irish_gov_assistant_public_policy_v1.json +45 -0
  26. eval/q8_irish_gov_chatbot_gap_holdout_v2.json +92 -0
  27. eval/q8_irish_gov_chatbot_redteam_v2.json +108 -0
  28. eval/q8_irish_gov_contact_policy_v1.json +76 -0
  29. eval/q8_irish_gov_user_contextual_policy_v1.json +61 -0
  30. eval/q8_multilingual_ppsn_v1_all.json +28 -0
  31. eval/q8_runtime_profile_source.json +28 -0
  32. eval/role_profile_usage.md +15 -0
  33. global_pointer_meta.json +57 -0
  34. inference_mask.py +86 -0
  35. inference_mask_onnx.py +69 -0
  36. model.py +135 -0
  37. onnx/config.json +318 -0
  38. onnx/onnx_export.json +11 -0
  39. onnx/quantization.json +26 -0
  40. onnx/special_tokens_map.json +37 -0
  41. onnx/tokenizer.json +0 -0
  42. onnx/tokenizer_config.json +61 -0
  43. pyproject.toml +17 -0
  44. qa_config.json +34 -0
  45. special_tokens_map.json +37 -0
  46. tokenizer.json +0 -0
  47. tokenizer_config.json +61 -0
  48. training_sources.json +14 -0
  49. uv.lock +0 -0
  50. vocab.txt +0 -0
.gitattributes CHANGED
@@ -1,35 +1,5 @@
1
- *.7z filter=lfs diff=lfs merge=lfs -text
2
- *.arrow filter=lfs diff=lfs merge=lfs -text
3
  *.bin filter=lfs diff=lfs merge=lfs -text
4
- *.bz2 filter=lfs diff=lfs merge=lfs -text
5
- *.ckpt filter=lfs diff=lfs merge=lfs -text
6
- *.ftz filter=lfs diff=lfs merge=lfs -text
7
- *.gz filter=lfs diff=lfs merge=lfs -text
8
- *.h5 filter=lfs diff=lfs merge=lfs -text
9
- *.joblib filter=lfs diff=lfs merge=lfs -text
10
- *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
- *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
- *.model filter=lfs diff=lfs merge=lfs -text
13
- *.msgpack filter=lfs diff=lfs merge=lfs -text
14
- *.npy filter=lfs diff=lfs merge=lfs -text
15
- *.npz filter=lfs diff=lfs merge=lfs -text
16
  *.onnx filter=lfs diff=lfs merge=lfs -text
17
- *.ot filter=lfs diff=lfs merge=lfs -text
18
- *.parquet filter=lfs diff=lfs merge=lfs -text
19
- *.pb filter=lfs diff=lfs merge=lfs -text
20
- *.pickle filter=lfs diff=lfs merge=lfs -text
21
- *.pkl filter=lfs diff=lfs merge=lfs -text
22
  *.pt filter=lfs diff=lfs merge=lfs -text
23
  *.pth filter=lfs diff=lfs merge=lfs -text
24
- *.rar filter=lfs diff=lfs merge=lfs -text
25
  *.safetensors filter=lfs diff=lfs merge=lfs -text
26
- saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
- *.tar.* filter=lfs diff=lfs merge=lfs -text
28
- *.tar filter=lfs diff=lfs merge=lfs -text
29
- *.tflite filter=lfs diff=lfs merge=lfs -text
30
- *.tgz filter=lfs diff=lfs merge=lfs -text
31
- *.wasm filter=lfs diff=lfs merge=lfs -text
32
- *.xz 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
 
 
 
1
  *.bin filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
 
2
  *.onnx filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
3
  *.pt filter=lfs diff=lfs merge=lfs -text
4
  *.pth filter=lfs diff=lfs merge=lfs -text
 
5
  *.safetensors filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
.gitignore ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ __pycache__/
2
+ *.pyc
3
+ .venv/
LICENSE ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
10
+
11
+ "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
12
+
13
+ "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
14
+
15
+ "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
16
+
17
+ "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
18
+
19
+ "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
20
+
21
+ "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
22
+
23
+ "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
24
+
25
+ "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
26
+
27
+ "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
28
+
29
+ 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
30
+
31
+ 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
32
+
33
+ 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
34
+
35
+ (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
36
+
37
+ (b) You must cause any modified files to carry prominent notices stating that You changed the files; and
38
+
39
+ (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
40
+
41
+ (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
42
+
43
+ You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
44
+
45
+ 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
46
+
47
+ 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
48
+
49
+ 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
50
+
51
+ 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
52
+
53
+ 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
54
+
55
+ END OF TERMS AND CONDITIONS
56
+
57
+ APPENDIX: How to apply the Apache License to your work.
58
+
59
+ To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
60
+
61
+ Copyright [yyyy] [name of copyright owner]
62
+
63
+ Licensed under the Apache License, Version 2.0 (the "License");
64
+ you may not use this file except in compliance with the License.
65
+ You may obtain a copy of the License at
66
+
67
+ http://www.apache.org/licenses/LICENSE-2.0
68
+
69
+ Unless required by applicable law or agreed to in writing, software
70
+ distributed under the License is distributed on an "AS IS" BASIS,
71
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
72
+ See the License for the specific language governing permissions and
73
+ limitations under the License.
NOTICE ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ IrishCore-GlobalPointer-ContextPII-135M-v1-rc19
2
+
3
+ This release is derived from:
4
+ - OpenMed/OpenMed-PII-mLiteClinical-Base-135M-v1 (Apache-2.0)
5
+
6
+ Training and evaluation data used for this derivative included:
7
+ - temsa/OpenMed-Irish-CorePII-TrainMix-v1
8
+ - temsa/OpenMed-Irish-PPSN-Eircode-Spec-v1
9
+ - joelniklaus/mapa (CC-BY-4.0)
10
+ - gretelai/synthetic_pii_finance_multilingual (Apache-2.0)
11
+
12
+ Additional local synthetic hardening, UAT replay, and holdout sets were used during model selection.
13
+ Please review upstream licenses and dataset cards before redistributing derivative datasets.
PORTFOLIO_COMPARISON.md ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Portfolio Comparison
2
+
3
+ Updated: `2026-03-16`.
4
+
5
+ Use this section for the fastest public comparison across the `temsa` PII masking portfolio.
6
+
7
+ - The first core table only includes public checkpoints that ship both comparable q8 accuracy and q8 CPU throughput.
8
+ - The first PPSN table only includes public artifacts that ship comparable PPSN accuracy and CPU throughput.
9
+ - Missing cells in the archive tables mean the older release did not ship that metric in its public bundle.
10
+ - DiffMask rows use the reconciled `clean_single_pass` harness that matches the deployed runtime.
11
+ - GlobalPointer rows use the public raw-only span-matrix release bundle and its packaged q8 ONNX artifact.
12
+ - The same content is shipped as `PORTFOLIO_COMPARISON.md` inside each public model repo.
13
+
14
+ ### Irish Core PII: Comparable Public Checkpoints
15
+
16
+ | Repo | Stack | Full Core F1 | Q8 Core F1 | Q8 Multilingual PPSN F1 | Q8 Core ex/s |
17
+ |---|---|---:|---:|---:|---:|
18
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-4L-122M-v1-rc5`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-4L-122M-v1-rc5) | 4-layer GlobalPointer distilled fast student | 1.0000 | 1.0000 | 0.9333 | 282.9 |
19
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-4L-122M-v1-rc3`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-4L-122M-v1-rc3) | 4-layer GlobalPointer distilled fast student | 1.0000 | 1.0000 | 0.9333 | 317.9 |
20
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-4L-122M-v1-rc2`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-4L-122M-v1-rc2) | 4-layer GlobalPointer distilled fast student | 1.0000 | 1.0000 | 0.9333 | 292.5 |
21
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-4L-122M-v1-rc1`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-4L-122M-v1-rc1) | 4-layer GlobalPointer distilled fast student | 1.0000 | 1.0000 | 0.9333 | 337.3 |
22
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc28`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc28) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 232.7 |
23
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc25`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc25) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 212.1 |
24
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc24`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc24) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 278.9 |
25
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc23`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc23) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 237.6 |
26
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc22`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc22) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 106.8 |
27
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc21`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc21) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 150.8 |
28
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc20`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc20) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 181.9 |
29
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc19`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc19) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 73.1 |
30
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc18`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc18) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 126.2 |
31
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc17`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc17) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 125.5 |
32
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc16`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc16) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 125.5 |
33
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc15`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc15) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 125.5 |
34
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc14`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc14) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 119.2 |
35
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc13`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc13) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 126.1 |
36
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc12`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc12) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 73.6 |
37
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc11`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc11) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 94.1 |
38
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc10`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc10) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 125.8 |
39
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc9`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc9) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 119.8 |
40
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc8`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc8) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 128.9 |
41
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc7`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc7) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 89.0 |
42
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc6`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc6) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 89.0 |
43
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc5`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc5) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 84.5 |
44
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc4`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc4) | GlobalPointer raw-only + context labels | 0.9935 | 0.9935 | 0.9333 | 61.5 |
45
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc3`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc3) | GlobalPointer raw-only + context labels | 0.9935 | 0.9935 | 0.9333 | 61.5 |
46
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc2`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc2) | GlobalPointer raw-only + context labels | 0.9935 | 0.9935 | 0.9222 | 61.5 |
47
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc1`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc1) | GlobalPointer raw-only + context labels | 0.9935 | 0.9935 | 0.9222 | 61.5 |
48
+ | [`temsa/IrishCore-GlobalPointer-135M-v1-rc4`](https://huggingface.co/temsa/IrishCore-GlobalPointer-135M-v1-rc4) | GlobalPointer raw-only span-matrix | 1.0000 | 1.0000 | 0.9333 | 221.6 |
49
+ | [`temsa/IrishCore-GlobalPointer-135M-v1-rc3`](https://huggingface.co/temsa/IrishCore-GlobalPointer-135M-v1-rc3) | GlobalPointer raw-only span-matrix | 1.0000 | 1.0000 | 0.9213 | 204.9 |
50
+ | [`temsa/IrishCore-GlobalPointer-135M-v1-rc2`](https://huggingface.co/temsa/IrishCore-GlobalPointer-135M-v1-rc2) | GlobalPointer raw-only span-matrix | 0.9934 | 0.9934 | 0.9326 | 231.2 |
51
+ | [`temsa/OpenMed-mLiteClinical-IrishCorePII-135M-v2-rc8`](https://huggingface.co/temsa/OpenMed-mLiteClinical-IrishCorePII-135M-v2-rc8) | Raw-only token-span | 0.9737 | 0.9737 | 0.9176 | 46.1 |
52
+ | [`temsa/OpenMed-mLiteClinical-IrishCorePII-135M-v2-rc7`](https://huggingface.co/temsa/OpenMed-mLiteClinical-IrishCorePII-135M-v2-rc7) | Hybrid classifier + generated scanner spec | 1.0000 | 0.9934 | 1.0000 | 30.0 |
53
+ | [`temsa/OpenMed-mLiteClinical-IrishCorePII-135M-v2-rc6`](https://huggingface.co/temsa/OpenMed-mLiteClinical-IrishCorePII-135M-v2-rc6) | Hybrid classifier + repair decoders | 1.0000 | 0.9934 | 1.0000 | 29.5 |
54
+ | [`temsa/OpenMed-mLiteClinical-IrishCorePII-135M-v2-rc5`](https://huggingface.co/temsa/OpenMed-mLiteClinical-IrishCorePII-135M-v2-rc5) | Hybrid classifier + repair decoders | 0.9737 | 0.9669 | 0.9333 | 34.4 |
55
+ | [`temsa/OpenMed-mLiteClinical-IrishCorePII-135M-v2-rc4`](https://huggingface.co/temsa/OpenMed-mLiteClinical-IrishCorePII-135M-v2-rc4) | Hybrid classifier + repair decoders | 0.9870 | 0.9740 | 0.9600 | 114.2 |
56
+ | [`temsa/OpenMed-mLiteClinical-IrishCorePII-135M-v2-rc3`](https://huggingface.co/temsa/OpenMed-mLiteClinical-IrishCorePII-135M-v2-rc3) | Hybrid classifier + repair decoders | 0.9806 | 0.9677 | 0.9333 | 44.9 |
57
+ | [`temsa/OpenMed-mLiteClinical-IrishCorePII-135M-v2-rc2`](https://huggingface.co/temsa/OpenMed-mLiteClinical-IrishCorePII-135M-v2-rc2) | Hybrid classifier + repair decoders | 0.9554 | 0.9615 | 0.7887 | 119.1 |
58
+ | [`temsa/OpenMed-mLiteClinical-IrishCorePII-135M-v1`](https://huggingface.co/temsa/OpenMed-mLiteClinical-IrishCorePII-135M-v1) | Hybrid classifier baseline | 0.9530 | 0.9333 | 0.9882 | 103.3 |
59
+ | [`temsa/IrishCore-DiffMask-135M-v1-rc6`](https://huggingface.co/temsa/IrishCore-DiffMask-135M-v1-rc6) | DiffMask token-span, scanner-free | 0.9801 | 0.9733 | 0.9274 | 130.3 |
60
+ | [`temsa/IrishCore-DiffMask-135M-v1-rc5`](https://huggingface.co/temsa/IrishCore-DiffMask-135M-v1-rc5) | DiffMask token-span, scanner-free | 0.9733 | 0.9733 | 0.9379 | 249.2 |
61
+ | [`temsa/IrishCore-DiffMask-135M-v1-rc4`](https://huggingface.co/temsa/IrishCore-DiffMask-135M-v1-rc4) | DiffMask token-span, scanner-free | 0.9733 | 0.9733 | 0.9371 | 29.5 |
62
+ | [`temsa/IrishCore-DiffMask-135M-v1-rc3`](https://huggingface.co/temsa/IrishCore-DiffMask-135M-v1-rc3) | DiffMask token-span, scanner-free | 0.9664 | 0.9664 | 0.9591 | 30.0 |
63
+ | [`temsa/IrishCore-DiffMask-135M-v1-rc2`](https://huggingface.co/temsa/IrishCore-DiffMask-135M-v1-rc2) | DiffMask token-span, scanner-free | 0.9664 | 0.9664 | 0.9212 | 247.1 |
64
+ | [`temsa/IrishCore-DiffMask-135M-v1-rc1`](https://huggingface.co/temsa/IrishCore-DiffMask-135M-v1-rc1) | DiffMask token-span, scanner-free | 0.9801 | 0.9934 | 0.9412 | 251.2 |
65
+
66
+ ### Irish Core PII: Other Public Checkpoints
67
+
68
+ | Repo | Stack | Full Core F1 | Q8 Core F1 | Q8 Multilingual PPSN F1 | Notes |
69
+ |---|---|---:|---:|---:|---|
70
+ | [`temsa/OpenMed-mLiteClinical-IrishCorePII-135M-v2-rc1`](https://huggingface.co/temsa/OpenMed-mLiteClinical-IrishCorePII-135M-v2-rc1) | Hybrid classifier prototype | 0.9487 | — | — | Predates the public q8 artifact. |
71
+
72
+ Finance-boundary q8 F1 is `1.0000` for `OpenMed-mLiteClinical-IrishCorePII-135M-v2-rc6`, `OpenMed-mLiteClinical-IrishCorePII-135M-v2-rc7`, `OpenMed-mLiteClinical-IrishCorePII-135M-v2-rc8`, and all public `IrishCore-DiffMask` releases from `rc1` to `rc6`. `OpenMed-mLiteClinical-IrishCorePII-135M-v2-rc5` ships `0.8750` on that public q8 suite.
73
+
74
+ ### PPSN-Only: Comparable Public Artifacts
75
+
76
+ | Repo | Artifact | Irish Large F1 | Multilingual PPSN F1 | User Raw F1 | QA v8 F1 | CPU ex/s |
77
+ |---|---|---:|---:|---:|---:|---:|
78
+ | [`temsa/OpenMed-mLiteClinical-IrishPPSN-135M-v1`](https://huggingface.co/temsa/OpenMed-mLiteClinical-IrishPPSN-135M-v1) | fp32 canonical checkpoint | 0.8979 | 0.9704 | 0.8000 | 0.7385 | 57.4 |
79
+ | [`temsa/OpenMed-mLiteClinical-IrishPPSN-135M-v1-fp16`](https://huggingface.co/temsa/OpenMed-mLiteClinical-IrishPPSN-135M-v1-fp16) | fp16 CPU/GPU artifact | — | 0.9704 | 0.8000 | 0.7385 | 45.8 |
80
+ | [`temsa/OpenMed-mLiteClinical-IrishPPSN-135M-v1-q8`](https://huggingface.co/temsa/OpenMed-mLiteClinical-IrishPPSN-135M-v1-q8) | dynamic int8 CPU artifact | — | 0.9040 | — | — | 132.1 |
81
+
82
+ ### PPSN-Only: Historical Public Checkpoints
83
+
84
+ | Repo | Main Published Metrics | Notes |
85
+ |---|---|---|
86
+ | [`temsa/OpenMed-PPSN-mLiteClinical-v1`](https://huggingface.co/temsa/OpenMed-PPSN-mLiteClinical-v1) | same as canonical fp32 repo: multilingual 0.9704, user raw 0.8000 | Legacy alias; prefer `temsa/OpenMed-mLiteClinical-IrishPPSN-135M-v1`. |
87
+ | [`temsa/OpenMed-PPSN-v6-raw-rc2`](https://huggingface.co/temsa/OpenMed-PPSN-v6-raw-rc2) | irish_reg_v5 0.8750; user_raw 0.8000; qa_v8 0.7385 | Raw PPSN-only research checkpoint; no packaged multilingual CPU benchmark row. |
88
+ | [`temsa/OpenMed-PPSN-v5_1`](https://huggingface.co/temsa/OpenMed-PPSN-v5_1) | irish_large_v2 raw 0.9285; qa_v6 hybrid strict 1.0000 | Hybrid PPSN-only checkpoint; predates the canonical multilingual suite packaging. |
89
+ | [`temsa/OpenMed-PPSN-v5`](https://huggingface.co/temsa/OpenMed-PPSN-v5) | irish_reg_v5 raw 0.8235; irish_reg_v5 hybrid strict 1.0000 | Hybrid PPSN-only checkpoint; predates the canonical multilingual suite packaging. |
90
+ | [`temsa/OpenMed-PPSN-v4`](https://huggingface.co/temsa/OpenMed-PPSN-v4) | synthetic non-PPSN drift check only | Predates the current PPSN eval suite; no packaged apples-to-apples multilingual CPU row. |
91
+
92
+ If you need the strongest current raw-only Irish core model, start with `IrishCore-GlobalPointer-135M-v1-rc4`. If you need the fastest CPU-first raw-only line, compare it against `IrishCore-DiffMask-135M-v1-rc6`. If you need a PPSN-only artifact, compare the canonical `fp32`, `fp16`, and `q8` variants of `OpenMed-mLiteClinical-IrishPPSN-135M-v1` directly in the table above.
README.md ADDED
@@ -0,0 +1,187 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ language:
3
+ - en
4
+ - ga
5
+ license: apache-2.0
6
+ pipeline_tag: token-classification
7
+ tags:
8
+ - pii-masking
9
+ - token-classification
10
+ - globalpointer
11
+ - onnx
12
+ - dynamic-quantization
13
+ - ireland
14
+ - irish
15
+ - gaelic
16
+ ---
17
+ # IrishCore-GlobalPointer-ContextPII-4L-122M-v1-rc6
18
+
19
+ `IrishCore-GlobalPointer-ContextPII-4L-122M-v1-rc6` is the current raw-only contextual PII masking release for Irish public-sector, HSE, and citizen-support flows.
20
+
21
+ It keeps the same weights and ONNX graph as the public `temsa/IrishCore-GlobalPointer-ContextPII-4L-122M-v1-rc5`, but adds the same role-aware decode policy for assistant/public prose and fixes the shared decoder inventory handling.
22
+
23
+ ## Positioning
24
+
25
+ - raw-only
26
+ - scanner-free
27
+ - validator-free
28
+ - single-pass GlobalPointer span extraction
29
+ - deterministic `[PII:LABEL]` replacement
30
+
31
+ ## What Changed
32
+
33
+ - adds a role-aware decode policy: `assistant_public` for assistant/public prose, `default` for user turns and search queries
34
+ - fixes the shared decoder so it respects the model label inventory instead of inventing contextual labels on non-context releases
35
+ - keeps the same weights and ONNX graph as the previous public checkpoint; this is a decode/runtime packaging release
36
+
37
+ - recovers Gaelic `Árasán/Aonad + Teach/building-name + street` address spans more completely
38
+ - restores full prefixed Irish city forms such as `nDún Dealgan` instead of suffix fragments
39
+ - keeps mixed contact phones after names/emails from being missed in assistant or user turns
40
+ - adds the fresh unseen contextual exact holdout `v20` to the public release bundle
41
+
42
+ ## Benchmarks
43
+
44
+ ### ONNX q8
45
+
46
+ | Suite | F1 | Examples/s |
47
+ | --- | ---: | ---: |
48
+ | Irish gov assistant public policy v1 | 1.0000 | 125.1353 |
49
+ | Irish gov user contextual policy v1 | 1.0000 | 58.0223 |
50
+ | Irish core | 1.0000 | 282.8890 |
51
+ | Gov contact policy v1 | 1.0000 | 193.9946 |
52
+ | Gov chatbot red-team v2 | 0.9861 | 161.5569 |
53
+ | Gov chatbot gap holdout v2 | 1.0000 | 173.1551 |
54
+ | Context holdout v18 exact | 1.0000 | 171.6274 |
55
+ | Context holdout v19 exact | 1.0000 | 232.4761 |
56
+ | Context holdout v20 exact | 1.0000 | 169.1861 |
57
+ | Multilingual PPSN overall | 0.9333 | 345.7077 |
58
+ | Multilingual PPSN label-only | 1.0000 | — |
59
+
60
+ ## Evaluation Notes
61
+
62
+ - `eval/q8_irish_gov_assistant_public_policy_v1.json`: role-aware assistant/public policy suite; measures the conservative assistant profile on English and Irish assistant text
63
+ - `eval/q8_irish_gov_user_contextual_policy_v1.json`: role-aware user-contextual policy suite; measures the default profile on English and Irish user turns
64
+ - `eval/q8_globalpointer_context_holdout_v18_exact.json`: fresh unseen contextual holdout for public-office addresses, mixed public/private contacts, and Irish month-name negatives
65
+ - `eval/q8_globalpointer_context_holdout_v19_exact.json`: fresh unseen contextual holdout for standalone unit/building address spans and multilingual admin cue negatives
66
+ - `eval/q8_globalpointer_context_holdout_v20_exact.json`: fresh unseen contextual holdout for Gaelic Teach/building spans, prefixed Irish city forms, mixed contact phones, and admin-code negatives
67
+ - `eval/q8_irish_gov_chatbot_gap_holdout_v2.json`: Irish gov-chatbot holdout, `1.0000`
68
+ - `eval/q8_irish_gov_chatbot_redteam_v2.json`: Irish gov-chatbot red-team suite, `0.9861`
69
+
70
+ ## Role-Aware Usage
71
+
72
+ Use the model per message, not on a flattened whole transcript.
73
+
74
+ - `--role user` or `--role search_query`: uses the default contextual profile. This is the intended path for citizen turns and search queries.
75
+ - `--role assistant`: switches to the conservative `assistant_public` profile. This keeps direct structured identifiers such as `PHONE_NUMBER`, `EMAIL`, and `POSTCODE`, but suppresses contextual/demographic labels such as `AGE`, `DATE_OF_BIRTH`, `CITY`, `COUNTY`, `STREET_ADDRESS`, `FIRST_NAME`, and `LAST_NAME` in public explanatory prose.
76
+ - `--profile ...` overrides the role-derived default if you need explicit control.
77
+
78
+ Examples:
79
+
80
+ ```bash
81
+ python3 inference_mask_onnx.py --model temsa/IrishCore-GlobalPointer-ContextPII-4L-122M-v1-rc6 --role user --text "I'm 76 and I live at Rose Cottage, Galway Road, Loughrea, Galway County (H62 HF96)."
82
+
83
+ python3 inference_mask_onnx.py --model temsa/IrishCore-GlobalPointer-ContextPII-4L-122M-v1-rc6 --role assistant --text "If you need to contact the Carer’s Allowance Section directly: Phone: 0818 927 999. Email: carers@example.gov.ie. Address: ... N39 E4E0."
84
+ ```
85
+
86
+ ```bash
87
+ python3 inference_mask_onnx.py --model temsa/IrishCore-GlobalPointer-ContextPII-4L-122M-v1-rc6 --text "Address line 1: Apartment 8A, River Walk House
88
+ Address line 2: 17 Bridge Street
89
+ City/Town: Kilkenny
90
+ County: County Kilkenny
91
+ Eircode: R95 AB12"
92
+ ```
93
+
94
+ <!-- portfolio-comparison:start -->
95
+ ## Portfolio Comparison
96
+
97
+ Updated: `2026-03-16`.
98
+
99
+ Use this section for the fastest public comparison across the `temsa` PII masking portfolio.
100
+
101
+ - The first core table only includes public checkpoints that ship both comparable q8 accuracy and q8 CPU throughput.
102
+ - The first PPSN table only includes public artifacts that ship comparable PPSN accuracy and CPU throughput.
103
+ - Missing cells in the archive tables mean the older release did not ship that metric in its public bundle.
104
+ - DiffMask rows use the reconciled `clean_single_pass` harness that matches the deployed runtime.
105
+ - GlobalPointer rows use the public raw-only span-matrix release bundle and its packaged q8 ONNX artifact.
106
+ - The same content is shipped as `PORTFOLIO_COMPARISON.md` inside each public model repo.
107
+
108
+ ### Irish Core PII: Comparable Public Checkpoints
109
+
110
+ | Repo | Stack | Full Core F1 | Q8 Core F1 | Q8 Multilingual PPSN F1 | Q8 Core ex/s |
111
+ |---|---|---:|---:|---:|---:|
112
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-4L-122M-v1-rc6`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-4L-122M-v1-rc6) | 4-layer GlobalPointer distilled fast student | 1.0000 | 1.0000 | 0.9333 | 282.9 |
113
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-4L-122M-v1-rc3`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-4L-122M-v1-rc3) | 4-layer GlobalPointer distilled fast student | 1.0000 | 1.0000 | 0.9333 | 317.9 |
114
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-4L-122M-v1-rc2`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-4L-122M-v1-rc2) | 4-layer GlobalPointer distilled fast student | 1.0000 | 1.0000 | 0.9333 | 292.5 |
115
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-4L-122M-v1-rc1`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-4L-122M-v1-rc1) | 4-layer GlobalPointer distilled fast student | 1.0000 | 1.0000 | 0.9333 | 337.3 |
116
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc28`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc28) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 232.7 |
117
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc25`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc25) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 212.1 |
118
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc24`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc24) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 278.9 |
119
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc23`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc23) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 237.6 |
120
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc22`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc22) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 106.8 |
121
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc21`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc21) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 150.8 |
122
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc20`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc20) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 181.9 |
123
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc19`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc19) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 73.1 |
124
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc18`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc18) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 126.2 |
125
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc17`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc17) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 125.5 |
126
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc16`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc16) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 125.5 |
127
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc15`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc15) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 125.5 |
128
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc14`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc14) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 119.2 |
129
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc13`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc13) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 126.1 |
130
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc12`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc12) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 73.6 |
131
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc11`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc11) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 94.1 |
132
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc10`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc10) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 125.8 |
133
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc9`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc9) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 119.8 |
134
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc8`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc8) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 128.9 |
135
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc7`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc7) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 89.0 |
136
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc6`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc6) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 89.0 |
137
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc5`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc5) | GlobalPointer raw-only + context labels | 1.0000 | 1.0000 | 0.9333 | 84.5 |
138
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc4`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc4) | GlobalPointer raw-only + context labels | 0.9935 | 0.9935 | 0.9333 | 61.5 |
139
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc3`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc3) | GlobalPointer raw-only + context labels | 0.9935 | 0.9935 | 0.9333 | 61.5 |
140
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc2`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc2) | GlobalPointer raw-only + context labels | 0.9935 | 0.9935 | 0.9222 | 61.5 |
141
+ | [`temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc1`](https://huggingface.co/temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc1) | GlobalPointer raw-only + context labels | 0.9935 | 0.9935 | 0.9222 | 61.5 |
142
+ | [`temsa/IrishCore-GlobalPointer-135M-v1-rc4`](https://huggingface.co/temsa/IrishCore-GlobalPointer-135M-v1-rc4) | GlobalPointer raw-only span-matrix | 1.0000 | 1.0000 | 0.9333 | 221.6 |
143
+ | [`temsa/IrishCore-GlobalPointer-135M-v1-rc3`](https://huggingface.co/temsa/IrishCore-GlobalPointer-135M-v1-rc3) | GlobalPointer raw-only span-matrix | 1.0000 | 1.0000 | 0.9213 | 204.9 |
144
+ | [`temsa/IrishCore-GlobalPointer-135M-v1-rc2`](https://huggingface.co/temsa/IrishCore-GlobalPointer-135M-v1-rc2) | GlobalPointer raw-only span-matrix | 0.9934 | 0.9934 | 0.9326 | 231.2 |
145
+ | [`temsa/OpenMed-mLiteClinical-IrishCorePII-135M-v2-rc8`](https://huggingface.co/temsa/OpenMed-mLiteClinical-IrishCorePII-135M-v2-rc8) | Raw-only token-span | 0.9737 | 0.9737 | 0.9176 | 46.1 |
146
+ | [`temsa/OpenMed-mLiteClinical-IrishCorePII-135M-v2-rc7`](https://huggingface.co/temsa/OpenMed-mLiteClinical-IrishCorePII-135M-v2-rc7) | Hybrid classifier + generated scanner spec | 1.0000 | 0.9934 | 1.0000 | 30.0 |
147
+ | [`temsa/OpenMed-mLiteClinical-IrishCorePII-135M-v2-rc6`](https://huggingface.co/temsa/OpenMed-mLiteClinical-IrishCorePII-135M-v2-rc6) | Hybrid classifier + repair decoders | 1.0000 | 0.9934 | 1.0000 | 29.5 |
148
+ | [`temsa/OpenMed-mLiteClinical-IrishCorePII-135M-v2-rc5`](https://huggingface.co/temsa/OpenMed-mLiteClinical-IrishCorePII-135M-v2-rc5) | Hybrid classifier + repair decoders | 0.9737 | 0.9669 | 0.9333 | 34.4 |
149
+ | [`temsa/OpenMed-mLiteClinical-IrishCorePII-135M-v2-rc4`](https://huggingface.co/temsa/OpenMed-mLiteClinical-IrishCorePII-135M-v2-rc4) | Hybrid classifier + repair decoders | 0.9870 | 0.9740 | 0.9600 | 114.2 |
150
+ | [`temsa/OpenMed-mLiteClinical-IrishCorePII-135M-v2-rc3`](https://huggingface.co/temsa/OpenMed-mLiteClinical-IrishCorePII-135M-v2-rc3) | Hybrid classifier + repair decoders | 0.9806 | 0.9677 | 0.9333 | 44.9 |
151
+ | [`temsa/OpenMed-mLiteClinical-IrishCorePII-135M-v2-rc2`](https://huggingface.co/temsa/OpenMed-mLiteClinical-IrishCorePII-135M-v2-rc2) | Hybrid classifier + repair decoders | 0.9554 | 0.9615 | 0.7887 | 119.1 |
152
+ | [`temsa/OpenMed-mLiteClinical-IrishCorePII-135M-v1`](https://huggingface.co/temsa/OpenMed-mLiteClinical-IrishCorePII-135M-v1) | Hybrid classifier baseline | 0.9530 | 0.9333 | 0.9882 | 103.3 |
153
+ | [`temsa/IrishCore-DiffMask-135M-v1-rc6`](https://huggingface.co/temsa/IrishCore-DiffMask-135M-v1-rc6) | DiffMask token-span, scanner-free | 0.9801 | 0.9733 | 0.9274 | 130.3 |
154
+ | [`temsa/IrishCore-DiffMask-135M-v1-rc5`](https://huggingface.co/temsa/IrishCore-DiffMask-135M-v1-rc5) | DiffMask token-span, scanner-free | 0.9733 | 0.9733 | 0.9379 | 249.2 |
155
+ | [`temsa/IrishCore-DiffMask-135M-v1-rc4`](https://huggingface.co/temsa/IrishCore-DiffMask-135M-v1-rc4) | DiffMask token-span, scanner-free | 0.9733 | 0.9733 | 0.9371 | 29.5 |
156
+ | [`temsa/IrishCore-DiffMask-135M-v1-rc3`](https://huggingface.co/temsa/IrishCore-DiffMask-135M-v1-rc3) | DiffMask token-span, scanner-free | 0.9664 | 0.9664 | 0.9591 | 30.0 |
157
+ | [`temsa/IrishCore-DiffMask-135M-v1-rc2`](https://huggingface.co/temsa/IrishCore-DiffMask-135M-v1-rc2) | DiffMask token-span, scanner-free | 0.9664 | 0.9664 | 0.9212 | 247.1 |
158
+ | [`temsa/IrishCore-DiffMask-135M-v1-rc1`](https://huggingface.co/temsa/IrishCore-DiffMask-135M-v1-rc1) | DiffMask token-span, scanner-free | 0.9801 | 0.9934 | 0.9412 | 251.2 |
159
+
160
+ ### Irish Core PII: Other Public Checkpoints
161
+
162
+ | Repo | Stack | Full Core F1 | Q8 Core F1 | Q8 Multilingual PPSN F1 | Notes |
163
+ |---|---|---:|---:|---:|---|
164
+ | [`temsa/OpenMed-mLiteClinical-IrishCorePII-135M-v2-rc1`](https://huggingface.co/temsa/OpenMed-mLiteClinical-IrishCorePII-135M-v2-rc1) | Hybrid classifier prototype | 0.9487 | — | — | Predates the public q8 artifact. |
165
+
166
+ Finance-boundary q8 F1 is `1.0000` for `OpenMed-mLiteClinical-IrishCorePII-135M-v2-rc6`, `OpenMed-mLiteClinical-IrishCorePII-135M-v2-rc7`, `OpenMed-mLiteClinical-IrishCorePII-135M-v2-rc8`, and all public `IrishCore-DiffMask` releases from `rc1` to `rc6`. `OpenMed-mLiteClinical-IrishCorePII-135M-v2-rc5` ships `0.8750` on that public q8 suite.
167
+
168
+ ### PPSN-Only: Comparable Public Artifacts
169
+
170
+ | Repo | Artifact | Irish Large F1 | Multilingual PPSN F1 | User Raw F1 | QA v8 F1 | CPU ex/s |
171
+ |---|---|---:|---:|---:|---:|---:|
172
+ | [`temsa/OpenMed-mLiteClinical-IrishPPSN-135M-v1`](https://huggingface.co/temsa/OpenMed-mLiteClinical-IrishPPSN-135M-v1) | fp32 canonical checkpoint | 0.8979 | 0.9704 | 0.8000 | 0.7385 | 57.4 |
173
+ | [`temsa/OpenMed-mLiteClinical-IrishPPSN-135M-v1-fp16`](https://huggingface.co/temsa/OpenMed-mLiteClinical-IrishPPSN-135M-v1-fp16) | fp16 CPU/GPU artifact | — | 0.9704 | 0.8000 | 0.7385 | 45.8 |
174
+ | [`temsa/OpenMed-mLiteClinical-IrishPPSN-135M-v1-q8`](https://huggingface.co/temsa/OpenMed-mLiteClinical-IrishPPSN-135M-v1-q8) | dynamic int8 CPU artifact | — | 0.9040 | — | — | 132.1 |
175
+
176
+ ### PPSN-Only: Historical Public Checkpoints
177
+
178
+ | Repo | Main Published Metrics | Notes |
179
+ |---|---|---|
180
+ | [`temsa/OpenMed-PPSN-mLiteClinical-v1`](https://huggingface.co/temsa/OpenMed-PPSN-mLiteClinical-v1) | same as canonical fp32 repo: multilingual 0.9704, user raw 0.8000 | Legacy alias; prefer `temsa/OpenMed-mLiteClinical-IrishPPSN-135M-v1`. |
181
+ | [`temsa/OpenMed-PPSN-v6-raw-rc2`](https://huggingface.co/temsa/OpenMed-PPSN-v6-raw-rc2) | irish_reg_v5 0.8750; user_raw 0.8000; qa_v8 0.7385 | Raw PPSN-only research checkpoint; no packaged multilingual CPU benchmark row. |
182
+ | [`temsa/OpenMed-PPSN-v5_1`](https://huggingface.co/temsa/OpenMed-PPSN-v5_1) | irish_large_v2 raw 0.9285; qa_v6 hybrid strict 1.0000 | Hybrid PPSN-only checkpoint; predates the canonical multilingual suite packaging. |
183
+ | [`temsa/OpenMed-PPSN-v5`](https://huggingface.co/temsa/OpenMed-PPSN-v5) | irish_reg_v5 raw 0.8235; irish_reg_v5 hybrid strict 1.0000 | Hybrid PPSN-only checkpoint; predates the canonical multilingual suite packaging. |
184
+ | [`temsa/OpenMed-PPSN-v4`](https://huggingface.co/temsa/OpenMed-PPSN-v4) | synthetic non-PPSN drift check only | Predates the current PPSN eval suite; no packaged apples-to-apples multilingual CPU row. |
185
+
186
+ If you need the strongest current raw-only Irish core model, start with `IrishCore-GlobalPointer-135M-v1-rc4`. If you need the fastest CPU-first raw-only line, compare it against `IrishCore-DiffMask-135M-v1-rc6`. If you need a PPSN-only artifact, compare the canonical `fp32`, `fp16`, and `q8` variants of `OpenMed-mLiteClinical-IrishPPSN-135M-v1` directly in the table above.
187
+ <!-- portfolio-comparison:end -->
base_common.py ADDED
@@ -0,0 +1,628 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ from __future__ import annotations
3
+
4
+ import json
5
+ import tempfile
6
+ import os
7
+ from pathlib import Path
8
+ from typing import Any
9
+
10
+ import numpy as np
11
+ from huggingface_hub import HfApi, hf_hub_download
12
+ from transformers import AutoConfig, AutoTokenizer
13
+
14
+ TOKENIZER_FILES = [
15
+ "tokenizer_config.json",
16
+ "tokenizer.json",
17
+ "special_tokens_map.json",
18
+ "vocab.txt",
19
+ "vocab.json",
20
+ "merges.txt",
21
+ "added_tokens.json",
22
+ "sentencepiece.bpe.model",
23
+ "spiece.model",
24
+ ]
25
+ DEFAULT_LABEL_MAX_SPAN_TOKENS = {
26
+ # Token-piece limits, not word limits. These need to reflect how the
27
+ # underlying tokenizer actually fragments compact identifiers.
28
+ "PPSN": 9,
29
+ "POSTCODE": 7,
30
+ "PHONE_NUMBER": 10,
31
+ "PASSPORT_NUMBER": 8,
32
+ "BANK_ROUTING_NUMBER": 5,
33
+ "ACCOUNT_NUMBER": 19,
34
+ "CREDIT_DEBIT_CARD": 12,
35
+ "SWIFT_BIC": 8,
36
+ "EMAIL": 15,
37
+ "FIRST_NAME": 5,
38
+ "LAST_NAME": 8,
39
+ }
40
+ DEFAULT_LABEL_MIN_NONSPACE_CHARS = {
41
+ "PPSN": 8,
42
+ "POSTCODE": 6,
43
+ "PHONE_NUMBER": 7,
44
+ "PASSPORT_NUMBER": 7,
45
+ "BANK_ROUTING_NUMBER": 6,
46
+ "ACCOUNT_NUMBER": 6,
47
+ "CREDIT_DEBIT_CARD": 12,
48
+ "SWIFT_BIC": 8,
49
+ "EMAIL": 6,
50
+ "FIRST_NAME": 2,
51
+ "LAST_NAME": 2,
52
+ }
53
+ WHITESPACE_BRIDGE_LABELS = {
54
+ "PPSN",
55
+ "POSTCODE",
56
+ "PHONE_NUMBER",
57
+ "PASSPORT_NUMBER",
58
+ "BANK_ROUTING_NUMBER",
59
+ "ACCOUNT_NUMBER",
60
+ "CREDIT_DEBIT_CARD",
61
+ "SWIFT_BIC",
62
+ }
63
+ SIMPLE_PUNCT_BRIDGE_LABELS = {
64
+ "PHONE_NUMBER",
65
+ "BANK_ROUTING_NUMBER",
66
+ "ACCOUNT_NUMBER",
67
+ "CREDIT_DEBIT_CARD",
68
+ }
69
+ MIN_CHAR_FALLBACK_LABELS = {
70
+ "PHONE_NUMBER",
71
+ "BANK_ROUTING_NUMBER",
72
+ "ACCOUNT_NUMBER",
73
+ "CREDIT_DEBIT_CARD",
74
+ "EMAIL",
75
+ }
76
+ CONSERVATIVE_BOUNDARY_REFINEMENT_LABELS = {
77
+ "PPSN",
78
+ "POSTCODE",
79
+ "PHONE_NUMBER",
80
+ "PASSPORT_NUMBER",
81
+ "BANK_ROUTING_NUMBER",
82
+ "ACCOUNT_NUMBER",
83
+ "CREDIT_DEBIT_CARD",
84
+ "SWIFT_BIC",
85
+ "EMAIL",
86
+ }
87
+ OUTPUT_PRIORITY = {
88
+ "PPSN": 0,
89
+ "PASSPORT_NUMBER": 1,
90
+ "ACCOUNT_NUMBER": 2,
91
+ "BANK_ROUTING_NUMBER": 3,
92
+ "CREDIT_DEBIT_CARD": 4,
93
+ "PHONE_NUMBER": 5,
94
+ "SWIFT_BIC": 6,
95
+ "POSTCODE": 7,
96
+ "EMAIL": 8,
97
+ "FIRST_NAME": 9,
98
+ "LAST_NAME": 10,
99
+ }
100
+
101
+
102
+ def normalize_entity_name(label: str) -> str:
103
+ label = (label or "").strip()
104
+ if label.startswith("B-") or label.startswith("I-"):
105
+ label = label[2:]
106
+ return label.upper()
107
+
108
+
109
+ def _sanitize_tokenizer_dir(tokenizer_path: Path) -> str:
110
+ tokenizer_cfg_path = tokenizer_path / "tokenizer_config.json"
111
+ if not tokenizer_cfg_path.exists():
112
+ return str(tokenizer_path)
113
+ data = json.loads(tokenizer_cfg_path.read_text(encoding="utf-8"))
114
+ if "fix_mistral_regex" not in data:
115
+ return str(tokenizer_path)
116
+ tmpdir = Path(tempfile.mkdtemp(prefix="openmed_span_tokenizer_"))
117
+ keep = set(TOKENIZER_FILES)
118
+ for child in tokenizer_path.iterdir():
119
+ if child.is_file() and child.name in keep:
120
+ (tmpdir / child.name).write_bytes(child.read_bytes())
121
+ data.pop("fix_mistral_regex", None)
122
+ (tmpdir / "tokenizer_config.json").write_text(json.dumps(data, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
123
+ return str(tmpdir)
124
+
125
+
126
+ def safe_auto_tokenizer(tokenizer_ref: str):
127
+ tokenizer_path = Path(tokenizer_ref)
128
+ if tokenizer_path.exists():
129
+ tokenizer_ref = _sanitize_tokenizer_dir(tokenizer_path)
130
+ else:
131
+ api = HfApi()
132
+ files = set(api.list_repo_files(repo_id=tokenizer_ref, repo_type="model"))
133
+ tmpdir = Path(tempfile.mkdtemp(prefix="openmed_remote_span_tokenizer_"))
134
+ copied = False
135
+ for name in TOKENIZER_FILES:
136
+ if name not in files:
137
+ continue
138
+ src = hf_hub_download(repo_id=tokenizer_ref, filename=name, repo_type="model")
139
+ (tmpdir / Path(name).name).write_bytes(Path(src).read_bytes())
140
+ copied = True
141
+ if copied:
142
+ tokenizer_ref = _sanitize_tokenizer_dir(tmpdir)
143
+
144
+ try:
145
+ return AutoTokenizer.from_pretrained(tokenizer_ref, use_fast=True, fix_mistral_regex=True)
146
+ except Exception:
147
+ pass
148
+ try:
149
+ return AutoTokenizer.from_pretrained(tokenizer_ref, use_fast=True, fix_mistral_regex=False)
150
+ except TypeError:
151
+ pass
152
+ try:
153
+ return AutoTokenizer.from_pretrained(tokenizer_ref, use_fast=True)
154
+ except Exception:
155
+ return AutoTokenizer.from_pretrained(tokenizer_ref, use_fast=False)
156
+
157
+
158
+ def label_names_from_config(config) -> list[str]:
159
+ names = list(getattr(config, "span_label_names", []))
160
+ if not names:
161
+ raise ValueError("Missing span_label_names in config")
162
+ return [normalize_entity_name(name) for name in names]
163
+
164
+
165
+ def label_thresholds_from_config(config, default_threshold: float) -> dict[str, float]:
166
+ raw = getattr(config, "span_label_thresholds", None) or {}
167
+ out = {normalize_entity_name(key): float(value) for key, value in raw.items()}
168
+ for label in label_names_from_config(config):
169
+ out.setdefault(label, float(default_threshold))
170
+ return out
171
+
172
+
173
+ def token_label_thresholds_from_config(config, default_threshold: float) -> dict[str, float]:
174
+ raw = getattr(config, "token_label_thresholds", None) or {}
175
+ out = {normalize_entity_name(key): float(value) for key, value in raw.items()}
176
+ for label in label_names_from_config(config):
177
+ out.setdefault(label, float(default_threshold))
178
+ return out
179
+
180
+
181
+ def token_extend_thresholds_from_config(config, default_fraction: float = 0.6) -> dict[str, float]:
182
+ raw = getattr(config, "token_extend_thresholds", None) or {}
183
+ out = {normalize_entity_name(key): float(value) for key, value in raw.items()}
184
+ for label in label_names_from_config(config):
185
+ out.setdefault(label, max(0.0, min(1.0, float(token_label_thresholds_from_config(config, 0.5).get(label, 0.5)) * default_fraction)))
186
+ return out
187
+
188
+
189
+ def boundary_label_thresholds_from_config(config, default_threshold: float = 0.0) -> dict[str, float]:
190
+ raw = getattr(config, "boundary_label_thresholds", None) or {}
191
+ out = {normalize_entity_name(key): float(value) for key, value in raw.items()}
192
+ for label in label_names_from_config(config):
193
+ out.setdefault(label, float(default_threshold))
194
+ return out
195
+
196
+
197
+ def label_max_span_tokens_from_config(config) -> dict[str, int]:
198
+ raw = getattr(config, "span_label_max_span_tokens", None) or {}
199
+ out = {normalize_entity_name(key): int(value) for key, value in raw.items()}
200
+ for label, value in DEFAULT_LABEL_MAX_SPAN_TOKENS.items():
201
+ out.setdefault(label, value)
202
+ for label in label_names_from_config(config):
203
+ out.setdefault(label, 8)
204
+ return out
205
+
206
+
207
+ def label_min_nonspace_chars_from_config(config) -> dict[str, int]:
208
+ raw = getattr(config, "span_label_min_nonspace_chars", None) or {}
209
+ out = {normalize_entity_name(key): int(value) for key, value in raw.items()}
210
+ for label, value in DEFAULT_LABEL_MIN_NONSPACE_CHARS.items():
211
+ out.setdefault(label, value)
212
+ for label in label_names_from_config(config):
213
+ out.setdefault(label, 1)
214
+ return out
215
+
216
+
217
+ def overlaps(a: dict, b: dict) -> bool:
218
+ return not (a["end"] <= b["start"] or b["end"] <= a["start"])
219
+
220
+
221
+ def dedupe_spans(spans: list[dict]) -> list[dict]:
222
+ ordered = sorted(
223
+ spans,
224
+ key=lambda item: (-float(item.get("score", 0.0)), item["start"], item["end"], OUTPUT_PRIORITY.get(item["label"], 99)),
225
+ )
226
+ kept = []
227
+ for span in ordered:
228
+ if any(overlaps(span, other) for other in kept):
229
+ continue
230
+ kept.append(span)
231
+ kept.sort(key=lambda item: (item["start"], item["end"], OUTPUT_PRIORITY.get(item["label"], 99)))
232
+ return kept
233
+
234
+
235
+ def _valid_offset(offset: tuple[int, int]) -> bool:
236
+ return bool(offset) and offset[1] > offset[0]
237
+
238
+
239
+ def _has_skippable_bridge(text: str, left: tuple[int, int], right: tuple[int, int], label: str) -> bool:
240
+ bridge = text[int(left[1]) : int(right[0])]
241
+ if bridge == "":
242
+ return True
243
+ if label == "PPSN" and bridge.isspace():
244
+ next_token = _token_text(text, right).strip()
245
+ return 0 < len(next_token) <= 2 and next_token.isalnum()
246
+ if label in WHITESPACE_BRIDGE_LABELS and bridge.isspace():
247
+ return True
248
+ if label in SIMPLE_PUNCT_BRIDGE_LABELS:
249
+ normalized = bridge.replace("\u00A0", " ").replace("\u202F", " ").strip()
250
+ if normalized == "-":
251
+ return True
252
+ return False
253
+
254
+
255
+ def _has_left_extension_bridge(text: str, left: tuple[int, int], right: tuple[int, int]) -> bool:
256
+ bridge = text[int(left[1]) : int(right[0])]
257
+ return bridge == ""
258
+
259
+
260
+ def _nonspace_length(text: str, start: int, end: int) -> int:
261
+ return sum(0 if ch.isspace() else 1 for ch in text[int(start) : int(end)])
262
+
263
+
264
+ def _is_simple_punct_token(text: str, offset: tuple[int, int], label: str) -> bool:
265
+ if label not in SIMPLE_PUNCT_BRIDGE_LABELS or not _valid_offset(offset):
266
+ return False
267
+ token_text = text[int(offset[0]) : int(offset[1])].replace("\u00A0", " ").replace("\u202F", " ").strip()
268
+ return token_text == "-"
269
+
270
+
271
+ def _token_text(text: str, offset: tuple[int, int]) -> str:
272
+ return text[int(offset[0]) : int(offset[1])]
273
+
274
+
275
+ def _is_short_alnum_token(text: str, offset: tuple[int, int], max_len: int = 4) -> bool:
276
+ token_text = _token_text(text, offset).strip()
277
+ return 0 < len(token_text) <= max_len and token_text.isalnum()
278
+
279
+
280
+ def _rescue_structured_start(
281
+ text: str,
282
+ offsets: list[tuple[int, int]],
283
+ valid: list[bool],
284
+ token_scores: np.ndarray,
285
+ start_scores: np.ndarray,
286
+ label: str,
287
+ label_index: int,
288
+ threshold: float,
289
+ boundary_threshold: float,
290
+ start_idx: int,
291
+ end_idx: int,
292
+ ) -> int | None:
293
+ if label not in {"ACCOUNT_NUMBER", "CREDIT_DEBIT_CARD"}:
294
+ return None
295
+ segment_text = text[int(offsets[start_idx][0]) : int(offsets[end_idx][1])]
296
+ if label == "ACCOUNT_NUMBER" and not any(ch.isspace() for ch in segment_text):
297
+ return None
298
+ best_idx = None
299
+ best_score = -1.0
300
+ for cand_idx in range(start_idx, end_idx + 1):
301
+ if not valid[cand_idx]:
302
+ continue
303
+ token_score = float(token_scores[cand_idx, label_index])
304
+ start_score = float(start_scores[cand_idx, label_index])
305
+ if token_score < threshold or start_score < boundary_threshold:
306
+ continue
307
+ token_text = _token_text(text, offsets[cand_idx]).strip()
308
+ score = start_score + 0.2 * token_score
309
+ if label == "ACCOUNT_NUMBER":
310
+ next_text = _token_text(text, offsets[cand_idx + 1]).strip() if cand_idx + 1 <= end_idx and valid[cand_idx + 1] else ""
311
+ if token_text.upper() == "I" and next_text.upper() == "E":
312
+ score += 1.0
313
+ elif token_text.upper().startswith("IE"):
314
+ score += 0.6
315
+ elif label == "CREDIT_DEBIT_CARD" and token_text.isdigit():
316
+ score += 0.3
317
+ if score > best_score:
318
+ best_idx = cand_idx
319
+ best_score = score
320
+ return best_idx
321
+
322
+
323
+ def _rescue_email_outer_span(span_text: str, outer_text: str) -> bool:
324
+ if "@" not in span_text or " " in outer_text:
325
+ return False
326
+ if "@" not in outer_text:
327
+ return False
328
+ _, _, span_domain = span_text.partition("@")
329
+ _, _, outer_domain = outer_text.partition("@")
330
+ if "." in span_domain and not span_text.endswith("@"):
331
+ return False
332
+ return "." in outer_domain and not outer_text.endswith("@")
333
+
334
+
335
+ def _rescue_iban_tail(text: str, offsets: list[tuple[int, int]], valid: list[bool], start_idx: int, end_idx: int) -> int:
336
+ next_idx = end_idx + 1
337
+ span_text = text[int(offsets[start_idx][0]) : int(offsets[end_idx][1])]
338
+ if not any(ch.isspace() for ch in span_text):
339
+ return end_idx
340
+ compact = "".join(ch for ch in span_text if not ch.isspace())
341
+ if not compact.upper().startswith("IE"):
342
+ return end_idx
343
+ while next_idx < len(offsets) and valid[next_idx]:
344
+ if not _has_skippable_bridge(text, offsets[end_idx], offsets[next_idx], "ACCOUNT_NUMBER"):
345
+ break
346
+ if not _is_short_alnum_token(text, offsets[next_idx]):
347
+ break
348
+ end_idx = next_idx
349
+ span_text = text[int(offsets[start_idx][0]) : int(offsets[end_idx][1])]
350
+ compact = "".join(ch for ch in span_text if not ch.isspace())
351
+ if len(compact) >= 22:
352
+ break
353
+ next_idx += 1
354
+ return end_idx
355
+
356
+
357
+ def decode_span_logits(
358
+ text: str,
359
+ offsets: list[tuple[int, int]],
360
+ start_scores: np.ndarray,
361
+ end_scores: np.ndarray,
362
+ label_names: list[str],
363
+ default_threshold: float,
364
+ label_thresholds: dict[str, float] | None = None,
365
+ label_max_span_tokens: dict[str, int] | None = None,
366
+ ) -> list[dict]:
367
+ thresholds = {label: float(default_threshold) for label in label_names}
368
+ if label_thresholds:
369
+ thresholds.update({normalize_entity_name(key): float(value) for key, value in label_thresholds.items()})
370
+ max_tokens = dict(DEFAULT_LABEL_MAX_SPAN_TOKENS)
371
+ if label_max_span_tokens:
372
+ max_tokens.update({normalize_entity_name(key): int(value) for key, value in label_max_span_tokens.items()})
373
+
374
+ spans: list[dict] = []
375
+ for label_index, label in enumerate(label_names):
376
+ threshold = thresholds.get(label, float(default_threshold))
377
+ max_span = max_tokens.get(label, 8)
378
+ start_candidates = [idx for idx in range(len(offsets)) if _valid_offset(offsets[idx]) and float(start_scores[idx, label_index]) >= threshold]
379
+ for start_idx in start_candidates:
380
+ best = None
381
+ for end_idx in range(start_idx, min(len(offsets), start_idx + max_span)):
382
+ if not _valid_offset(offsets[end_idx]):
383
+ continue
384
+ end_score = float(end_scores[end_idx, label_index])
385
+ if end_score < threshold:
386
+ continue
387
+ score = min(float(start_scores[start_idx, label_index]), end_score)
388
+ if best is None or score > best["score"]:
389
+ best = {
390
+ "label": label,
391
+ "start": int(offsets[start_idx][0]),
392
+ "end": int(offsets[end_idx][1]),
393
+ "score": score,
394
+ }
395
+ if best is not None and best["start"] < best["end"]:
396
+ best["text"] = text[best["start"]:best["end"]]
397
+ spans.append(best)
398
+ return dedupe_spans(spans)
399
+
400
+
401
+ def decode_token_presence_segments(
402
+ text: str,
403
+ offsets: list[tuple[int, int]],
404
+ token_scores: np.ndarray,
405
+ label_names: list[str],
406
+ default_threshold: float,
407
+ label_thresholds: dict[str, float] | None = None,
408
+ label_extend_thresholds: dict[str, float] | None = None,
409
+ label_max_span_tokens: dict[str, int] | None = None,
410
+ label_min_nonspace_chars: dict[str, int] | None = None,
411
+ boundary_label_thresholds: dict[str, float] | None = None,
412
+ start_scores: np.ndarray | None = None,
413
+ end_scores: np.ndarray | None = None,
414
+ ) -> list[dict]:
415
+ thresholds = {label: float(default_threshold) for label in label_names}
416
+ if label_thresholds:
417
+ thresholds.update({normalize_entity_name(key): float(value) for key, value in label_thresholds.items()})
418
+ extend_thresholds = {label: max(0.0, min(1.0, thresholds[label] * 0.6)) for label in label_names}
419
+ if label_extend_thresholds:
420
+ extend_thresholds.update({normalize_entity_name(key): float(value) for key, value in label_extend_thresholds.items()})
421
+ max_tokens = dict(DEFAULT_LABEL_MAX_SPAN_TOKENS)
422
+ if label_max_span_tokens:
423
+ max_tokens.update({normalize_entity_name(key): int(value) for key, value in label_max_span_tokens.items()})
424
+ min_nonspace_chars = dict(DEFAULT_LABEL_MIN_NONSPACE_CHARS)
425
+ if label_min_nonspace_chars:
426
+ min_nonspace_chars.update({normalize_entity_name(key): int(value) for key, value in label_min_nonspace_chars.items()})
427
+ boundary_thresholds = {label: 0.0 for label in label_names}
428
+ if boundary_label_thresholds:
429
+ boundary_thresholds.update({normalize_entity_name(key): float(value) for key, value in boundary_label_thresholds.items()})
430
+
431
+ spans: list[dict] = []
432
+ valid = [_valid_offset(offset) for offset in offsets]
433
+ num_tokens = len(offsets)
434
+ for label_index, label in enumerate(label_names):
435
+ threshold = thresholds.get(label, float(default_threshold))
436
+ extend_threshold = min(threshold, extend_thresholds.get(label, threshold))
437
+ max_span = max_tokens.get(label, 8)
438
+ idx = 0
439
+ while idx < num_tokens:
440
+ if not valid[idx] or float(token_scores[idx, label_index]) < threshold:
441
+ idx += 1
442
+ continue
443
+ start_idx = idx
444
+ end_idx = idx
445
+ outer_start_idx = start_idx
446
+ outer_end_idx = end_idx
447
+ while end_idx + 1 < num_tokens and valid[end_idx + 1] and float(token_scores[end_idx + 1, label_index]) >= threshold and (end_idx + 1 - start_idx + 1) <= max_span:
448
+ end_idx += 1
449
+ while (
450
+ start_idx - 1 >= 0
451
+ and valid[start_idx - 1]
452
+ and _has_left_extension_bridge(text, offsets[start_idx - 1], offsets[start_idx])
453
+ and float(token_scores[start_idx - 1, label_index]) >= extend_threshold
454
+ and (end_idx - (start_idx - 1) + 1) <= max_span
455
+ ):
456
+ start_idx -= 1
457
+ while end_idx + 1 < num_tokens:
458
+ next_idx = end_idx + 1
459
+ if not valid[next_idx]:
460
+ break
461
+ if (
462
+ _has_skippable_bridge(text, offsets[end_idx], offsets[next_idx], label)
463
+ and float(token_scores[next_idx, label_index]) >= extend_threshold
464
+ and (next_idx - start_idx + 1) <= max_span
465
+ ):
466
+ end_idx = next_idx
467
+ continue
468
+ if (
469
+ _is_simple_punct_token(text, offsets[next_idx], label)
470
+ and next_idx + 1 < num_tokens
471
+ and valid[next_idx + 1]
472
+ and _has_skippable_bridge(text, offsets[end_idx], offsets[next_idx], label)
473
+ and _has_skippable_bridge(text, offsets[next_idx], offsets[next_idx + 1], label)
474
+ and float(token_scores[next_idx + 1, label_index]) >= extend_threshold
475
+ and ((next_idx + 1) - start_idx + 1) <= max_span
476
+ ):
477
+ end_idx = next_idx + 1
478
+ continue
479
+ break
480
+ outer_start_idx = start_idx
481
+ outer_end_idx = end_idx
482
+ presence_slice = token_scores[start_idx : end_idx + 1, label_index]
483
+ score = float(presence_slice.mean())
484
+ out_start_idx = start_idx
485
+ out_end_idx = end_idx
486
+ if start_scores is not None and end_scores is not None:
487
+ refine_window = min(3, end_idx - start_idx + 1)
488
+ start_window = start_scores[start_idx : start_idx + refine_window, label_index]
489
+ best_start_rel = int(np.argmax(start_window))
490
+ best_start_idx = start_idx + best_start_rel
491
+ end_window_start = max(best_start_idx, end_idx - refine_window + 1)
492
+ end_window = end_scores[end_window_start : end_idx + 1, label_index]
493
+ best_end_rel = int(np.argmax(end_window))
494
+ best_end_idx = end_window_start + best_end_rel
495
+ if (
496
+ float(start_scores[best_start_idx, label_index]) < boundary_thresholds.get(label, 0.0)
497
+ or float(end_scores[best_end_idx, label_index]) < boundary_thresholds.get(label, 0.0)
498
+ ):
499
+ rescued_start_idx = _rescue_structured_start(
500
+ text,
501
+ offsets,
502
+ valid,
503
+ token_scores,
504
+ start_scores,
505
+ label,
506
+ label_index,
507
+ threshold,
508
+ boundary_thresholds.get(label, 0.0),
509
+ start_idx,
510
+ end_idx,
511
+ )
512
+ if rescued_start_idx is not None:
513
+ out_start_idx = rescued_start_idx
514
+ out_end_idx = end_idx
515
+ else:
516
+ idx = end_idx + 1
517
+ continue
518
+ else:
519
+ out_start_idx = best_start_idx
520
+ out_end_idx = best_end_idx
521
+ if label in CONSERVATIVE_BOUNDARY_REFINEMENT_LABELS and (
522
+ best_start_idx != start_idx or best_end_idx != end_idx
523
+ ):
524
+ outer_boundary = min(float(start_scores[start_idx, label_index]), float(end_scores[end_idx, label_index]))
525
+ refined_boundary = min(
526
+ float(start_scores[best_start_idx, label_index]),
527
+ float(end_scores[best_end_idx, label_index]),
528
+ )
529
+ if refined_boundary < outer_boundary + 0.08:
530
+ out_start_idx = start_idx
531
+ out_end_idx = end_idx
532
+ score = (
533
+ 0.65 * score
534
+ + 0.175 * float(start_scores[out_start_idx, label_index])
535
+ + 0.175 * float(end_scores[out_end_idx, label_index])
536
+ )
537
+ min_chars = int(min_nonspace_chars.get(label, 1))
538
+ if _nonspace_length(text, offsets[out_start_idx][0], offsets[out_end_idx][1]) < min_chars:
539
+ if (
540
+ label in MIN_CHAR_FALLBACK_LABELS
541
+ and (out_start_idx != start_idx or out_end_idx != end_idx)
542
+ and _nonspace_length(text, offsets[start_idx][0], offsets[end_idx][1]) >= min_chars
543
+ ):
544
+ out_start_idx = start_idx
545
+ out_end_idx = end_idx
546
+ else:
547
+ idx = end_idx + 1
548
+ continue
549
+ if label == "ACCOUNT_NUMBER":
550
+ out_end_idx = _rescue_iban_tail(text, offsets, valid, out_start_idx, out_end_idx)
551
+ span_text = text[int(offsets[out_start_idx][0]) : int(offsets[out_end_idx][1])]
552
+ outer_text = text[int(offsets[outer_start_idx][0]) : int(offsets[outer_end_idx][1])]
553
+ if label == "EMAIL" and _rescue_email_outer_span(span_text, outer_text):
554
+ out_start_idx = outer_start_idx
555
+ out_end_idx = outer_end_idx
556
+ span_text = outer_text
557
+ if label in {"FIRST_NAME", "LAST_NAME"} and any(ch.isdigit() for ch in span_text):
558
+ idx = end_idx + 1
559
+ continue
560
+ spans.append(
561
+ {
562
+ "label": label,
563
+ "start": int(offsets[out_start_idx][0]),
564
+ "end": int(offsets[out_end_idx][1]),
565
+ "score": score,
566
+ "text": span_text,
567
+ }
568
+ )
569
+ idx = end_idx + 1
570
+ return dedupe_spans(spans)
571
+
572
+
573
+ def load_onnx_session(model_ref: str, onnx_file: str = "model_quantized.onnx", onnx_subfolder: str = "onnx"):
574
+ import onnxruntime as ort
575
+
576
+ model_path = Path(model_ref)
577
+ if model_path.exists():
578
+ candidates = []
579
+ if onnx_subfolder:
580
+ candidates.append(model_path / onnx_subfolder / onnx_file)
581
+ candidates.append(model_path / onnx_file)
582
+ onnx_path = next((path for path in candidates if path.exists()), candidates[0])
583
+ config = AutoConfig.from_pretrained(model_ref)
584
+ tokenizer = safe_auto_tokenizer(model_ref)
585
+ else:
586
+ remote_name = f"{onnx_subfolder}/{onnx_file}" if onnx_subfolder else onnx_file
587
+ onnx_path = Path(hf_hub_download(repo_id=model_ref, filename=remote_name, repo_type="model"))
588
+ config = AutoConfig.from_pretrained(model_ref)
589
+ tokenizer = safe_auto_tokenizer(model_ref)
590
+ sess_options = ort.SessionOptions()
591
+ sess_options.graph_optimization_level = ort.GraphOptimizationLevel.ORT_ENABLE_ALL
592
+ intra_threads_raw = os.environ.get("OPENMED_ORT_INTRA_OP_THREADS", "").strip()
593
+ if intra_threads_raw:
594
+ try:
595
+ intra_threads = max(1, int(intra_threads_raw))
596
+ except ValueError:
597
+ intra_threads = 4
598
+ else:
599
+ cpu_count = os.cpu_count() or 4
600
+ intra_threads = max(1, min(4, cpu_count))
601
+ sess_options.intra_op_num_threads = intra_threads
602
+ sess_options.inter_op_num_threads = 1
603
+ sess_options.execution_mode = ort.ExecutionMode.ORT_SEQUENTIAL
604
+ session = ort.InferenceSession(str(onnx_path), sess_options=sess_options, providers=["CPUExecutionProvider"])
605
+ return session, tokenizer, config
606
+
607
+
608
+ def run_onnx(session, encoded: dict[str, Any]) -> tuple[np.ndarray, np.ndarray]:
609
+ feed = {}
610
+ input_names = {item.name for item in session.get_inputs()}
611
+ for key, value in encoded.items():
612
+ if key == "offset_mapping":
613
+ continue
614
+ if key in input_names:
615
+ feed[key] = value
616
+ outputs = session.run(None, feed)
617
+ return outputs[0], outputs[1]
618
+
619
+
620
+ def run_onnx_all(session, encoded: dict[str, Any]) -> list[np.ndarray]:
621
+ feed = {}
622
+ input_names = {item.name for item in session.get_inputs()}
623
+ for key, value in encoded.items():
624
+ if key == "offset_mapping":
625
+ continue
626
+ if key in input_names:
627
+ feed[key] = value
628
+ return session.run(None, feed)
common.py ADDED
The diff for this file is too large to render. See raw diff
 
config.json ADDED
@@ -0,0 +1,318 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "activation": "gelu",
3
+ "architectures": [
4
+ "IrishCoreGlobalPointerModel"
5
+ ],
6
+ "attention_dropout": 0.1,
7
+ "dim": 768,
8
+ "dropout": 0.1,
9
+ "dtype": "float32",
10
+ "global_pointer_head_size": 64,
11
+ "global_pointer_min_negatives": 256,
12
+ "global_pointer_negative_ratio": 16,
13
+ "global_pointer_use_rope": true,
14
+ "hidden_dim": 3072,
15
+ "id2label": {
16
+ "0": "O",
17
+ "1": "B-account_number",
18
+ "2": "B-age",
19
+ "3": "B-api_key",
20
+ "4": "B-bank_routing_number",
21
+ "5": "B-biometric_identifier",
22
+ "6": "B-blood_type",
23
+ "7": "B-certificate_license_number",
24
+ "8": "B-city",
25
+ "9": "B-company_name",
26
+ "10": "B-coordinate",
27
+ "11": "B-country",
28
+ "12": "B-county",
29
+ "13": "B-credit_debit_card",
30
+ "14": "B-customer_id",
31
+ "15": "B-cvv",
32
+ "16": "B-date",
33
+ "17": "B-date_of_birth",
34
+ "18": "B-date_time",
35
+ "19": "B-device_identifier",
36
+ "20": "B-education_level",
37
+ "21": "B-email",
38
+ "22": "B-employee_id",
39
+ "23": "B-employment_status",
40
+ "24": "B-fax_number",
41
+ "25": "B-first_name",
42
+ "26": "B-gender",
43
+ "27": "B-health_plan_beneficiary_number",
44
+ "28": "B-http_cookie",
45
+ "29": "B-ipv4",
46
+ "30": "B-ipv6",
47
+ "31": "B-language",
48
+ "32": "B-last_name",
49
+ "33": "B-license_plate",
50
+ "34": "B-mac_address",
51
+ "35": "B-medical_record_number",
52
+ "36": "B-occupation",
53
+ "37": "B-password",
54
+ "38": "B-phone_number",
55
+ "39": "B-pin",
56
+ "40": "B-political_view",
57
+ "41": "B-postcode",
58
+ "42": "B-race_ethnicity",
59
+ "43": "B-religious_belief",
60
+ "44": "B-sexuality",
61
+ "45": "B-ssn",
62
+ "46": "B-state",
63
+ "47": "B-street_address",
64
+ "48": "B-swift_bic",
65
+ "49": "B-tax_id",
66
+ "50": "B-time",
67
+ "51": "B-unique_id",
68
+ "52": "B-url",
69
+ "53": "B-user_name",
70
+ "54": "B-vehicle_identifier",
71
+ "55": "I-account_number",
72
+ "56": "I-api_key",
73
+ "57": "I-biometric_identifier",
74
+ "58": "I-blood_type",
75
+ "59": "I-certificate_license_number",
76
+ "60": "I-city",
77
+ "61": "I-company_name",
78
+ "62": "I-coordinate",
79
+ "63": "I-country",
80
+ "64": "I-county",
81
+ "65": "I-credit_debit_card",
82
+ "66": "I-customer_id",
83
+ "67": "I-date",
84
+ "68": "I-date_of_birth",
85
+ "69": "I-date_time",
86
+ "70": "I-device_identifier",
87
+ "71": "I-education_level",
88
+ "72": "I-email",
89
+ "73": "I-employee_id",
90
+ "74": "I-employment_status",
91
+ "75": "I-fax_number",
92
+ "76": "I-first_name",
93
+ "77": "I-gender",
94
+ "78": "I-health_plan_beneficiary_number",
95
+ "79": "I-http_cookie",
96
+ "80": "I-ipv4",
97
+ "81": "I-ipv6",
98
+ "82": "I-language",
99
+ "83": "I-last_name",
100
+ "84": "I-license_plate",
101
+ "85": "I-mac_address",
102
+ "86": "I-medical_record_number",
103
+ "87": "I-occupation",
104
+ "88": "I-password",
105
+ "89": "I-phone_number",
106
+ "90": "I-pin",
107
+ "91": "I-political_view",
108
+ "92": "I-postcode",
109
+ "93": "I-race_ethnicity",
110
+ "94": "I-religious_belief",
111
+ "95": "I-sexuality",
112
+ "96": "I-ssn",
113
+ "97": "I-state",
114
+ "98": "I-street_address",
115
+ "99": "I-swift_bic",
116
+ "100": "I-tax_id",
117
+ "101": "I-time",
118
+ "102": "I-unique_id",
119
+ "103": "I-url",
120
+ "104": "I-user_name",
121
+ "105": "I-vehicle_identifier"
122
+ },
123
+ "initializer_range": 0.02,
124
+ "label2id": {
125
+ "B-account_number": 1,
126
+ "B-age": 2,
127
+ "B-api_key": 3,
128
+ "B-bank_routing_number": 4,
129
+ "B-biometric_identifier": 5,
130
+ "B-blood_type": 6,
131
+ "B-certificate_license_number": 7,
132
+ "B-city": 8,
133
+ "B-company_name": 9,
134
+ "B-coordinate": 10,
135
+ "B-country": 11,
136
+ "B-county": 12,
137
+ "B-credit_debit_card": 13,
138
+ "B-customer_id": 14,
139
+ "B-cvv": 15,
140
+ "B-date": 16,
141
+ "B-date_of_birth": 17,
142
+ "B-date_time": 18,
143
+ "B-device_identifier": 19,
144
+ "B-education_level": 20,
145
+ "B-email": 21,
146
+ "B-employee_id": 22,
147
+ "B-employment_status": 23,
148
+ "B-fax_number": 24,
149
+ "B-first_name": 25,
150
+ "B-gender": 26,
151
+ "B-health_plan_beneficiary_number": 27,
152
+ "B-http_cookie": 28,
153
+ "B-ipv4": 29,
154
+ "B-ipv6": 30,
155
+ "B-language": 31,
156
+ "B-last_name": 32,
157
+ "B-license_plate": 33,
158
+ "B-mac_address": 34,
159
+ "B-medical_record_number": 35,
160
+ "B-occupation": 36,
161
+ "B-password": 37,
162
+ "B-phone_number": 38,
163
+ "B-pin": 39,
164
+ "B-political_view": 40,
165
+ "B-postcode": 41,
166
+ "B-race_ethnicity": 42,
167
+ "B-religious_belief": 43,
168
+ "B-sexuality": 44,
169
+ "B-ssn": 45,
170
+ "B-state": 46,
171
+ "B-street_address": 47,
172
+ "B-swift_bic": 48,
173
+ "B-tax_id": 49,
174
+ "B-time": 50,
175
+ "B-unique_id": 51,
176
+ "B-url": 52,
177
+ "B-user_name": 53,
178
+ "B-vehicle_identifier": 54,
179
+ "I-account_number": 55,
180
+ "I-api_key": 56,
181
+ "I-biometric_identifier": 57,
182
+ "I-blood_type": 58,
183
+ "I-certificate_license_number": 59,
184
+ "I-city": 60,
185
+ "I-company_name": 61,
186
+ "I-coordinate": 62,
187
+ "I-country": 63,
188
+ "I-county": 64,
189
+ "I-credit_debit_card": 65,
190
+ "I-customer_id": 66,
191
+ "I-date": 67,
192
+ "I-date_of_birth": 68,
193
+ "I-date_time": 69,
194
+ "I-device_identifier": 70,
195
+ "I-education_level": 71,
196
+ "I-email": 72,
197
+ "I-employee_id": 73,
198
+ "I-employment_status": 74,
199
+ "I-fax_number": 75,
200
+ "I-first_name": 76,
201
+ "I-gender": 77,
202
+ "I-health_plan_beneficiary_number": 78,
203
+ "I-http_cookie": 79,
204
+ "I-ipv4": 80,
205
+ "I-ipv6": 81,
206
+ "I-language": 82,
207
+ "I-last_name": 83,
208
+ "I-license_plate": 84,
209
+ "I-mac_address": 85,
210
+ "I-medical_record_number": 86,
211
+ "I-occupation": 87,
212
+ "I-password": 88,
213
+ "I-phone_number": 89,
214
+ "I-pin": 90,
215
+ "I-political_view": 91,
216
+ "I-postcode": 92,
217
+ "I-race_ethnicity": 93,
218
+ "I-religious_belief": 94,
219
+ "I-sexuality": 95,
220
+ "I-ssn": 96,
221
+ "I-state": 97,
222
+ "I-street_address": 98,
223
+ "I-swift_bic": 99,
224
+ "I-tax_id": 100,
225
+ "I-time": 101,
226
+ "I-unique_id": 102,
227
+ "I-url": 103,
228
+ "I-user_name": 104,
229
+ "I-vehicle_identifier": 105,
230
+ "O": 0
231
+ },
232
+ "max_position_embeddings": 512,
233
+ "model_type": "distilbert",
234
+ "n_heads": 12,
235
+ "n_layers": 4,
236
+ "num_span_labels": 16,
237
+ "output_past": true,
238
+ "pad_token_id": 0,
239
+ "qa_dropout": 0.1,
240
+ "seq_classif_dropout": 0.2,
241
+ "sinusoidal_pos_embds": false,
242
+ "span_label_max_span_tokens": {
243
+ "ACCOUNT_NUMBER": 19,
244
+ "AGE": 8,
245
+ "BANK_ROUTING_NUMBER": 6,
246
+ "CITY": 8,
247
+ "COUNTY": 10,
248
+ "CREDIT_DEBIT_CARD": 12,
249
+ "DATE_OF_BIRTH": 8,
250
+ "EMAIL": 16,
251
+ "FIRST_NAME": 6,
252
+ "LAST_NAME": 8,
253
+ "PASSPORT_NUMBER": 8,
254
+ "PHONE_NUMBER": 10,
255
+ "POSTCODE": 8,
256
+ "PPSN": 9,
257
+ "STREET_ADDRESS": 13,
258
+ "SWIFT_BIC": 8
259
+ },
260
+ "span_label_min_nonspace_chars": {
261
+ "ACCOUNT_NUMBER": 6,
262
+ "AGE": 1,
263
+ "BANK_ROUTING_NUMBER": 6,
264
+ "CITY": 1,
265
+ "COUNTY": 1,
266
+ "CREDIT_DEBIT_CARD": 12,
267
+ "DATE_OF_BIRTH": 1,
268
+ "EMAIL": 6,
269
+ "FIRST_NAME": 2,
270
+ "LAST_NAME": 2,
271
+ "PASSPORT_NUMBER": 7,
272
+ "PHONE_NUMBER": 7,
273
+ "POSTCODE": 6,
274
+ "PPSN": 8,
275
+ "STREET_ADDRESS": 1,
276
+ "SWIFT_BIC": 8
277
+ },
278
+ "span_label_names": [
279
+ "ACCOUNT_NUMBER",
280
+ "AGE",
281
+ "BANK_ROUTING_NUMBER",
282
+ "CITY",
283
+ "COUNTY",
284
+ "CREDIT_DEBIT_CARD",
285
+ "DATE_OF_BIRTH",
286
+ "EMAIL",
287
+ "FIRST_NAME",
288
+ "LAST_NAME",
289
+ "PASSPORT_NUMBER",
290
+ "PHONE_NUMBER",
291
+ "POSTCODE",
292
+ "PPSN",
293
+ "STREET_ADDRESS",
294
+ "SWIFT_BIC"
295
+ ],
296
+ "span_label_thresholds": {
297
+ "ACCOUNT_NUMBER": 0.5,
298
+ "AGE": 0.5,
299
+ "BANK_ROUTING_NUMBER": 0.5,
300
+ "CITY": 0.5,
301
+ "COUNTY": 0.5,
302
+ "CREDIT_DEBIT_CARD": 0.5,
303
+ "DATE_OF_BIRTH": 0.5,
304
+ "EMAIL": 0.5,
305
+ "FIRST_NAME": 0.5,
306
+ "LAST_NAME": 0.5,
307
+ "PASSPORT_NUMBER": 0.5,
308
+ "PHONE_NUMBER": 0.5,
309
+ "POSTCODE": 0.5,
310
+ "PPSN": 0.5,
311
+ "STREET_ADDRESS": 0.5,
312
+ "SWIFT_BIC": 0.5
313
+ },
314
+ "span_positive_weight": 8.0,
315
+ "tie_weights_": true,
316
+ "transformers_version": "4.57.6",
317
+ "vocab_size": 119547
318
+ }
eval/benchmark_summary.json ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "release": "IrishCore-GlobalPointer-ContextPII-4L-122M-v1-rc6",
3
+ "repo_id": "temsa/IrishCore-GlobalPointer-ContextPII-4L-122M-v1-rc6",
4
+ "architecture": {
5
+ "family": "4-layer DistilBERT-size GlobalPointer span extractor",
6
+ "base_head": "typed span matrix",
7
+ "raw_only": true,
8
+ "scanner_free": true,
9
+ "validator_free": true,
10
+ "uses_rope": true,
11
+ "runtime_diffusion": false,
12
+ "expanded_context_labels": [
13
+ "STREET_ADDRESS",
14
+ "CITY",
15
+ "COUNTY",
16
+ "DATE_OF_BIRTH",
17
+ "AGE"
18
+ ],
19
+ "student_layers": 4,
20
+ "teacher_release": "temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc24"
21
+ },
22
+ "base_model": "OpenMed/OpenMed-PII-mLiteClinical-Base-135M-v1",
23
+ "notes": [
24
+ "This release keeps the public rc5 weights and ONNX graph, but adds the same role-aware decode profile for assistant/public prose and the shared decoder inventory fix.",
25
+ "This release keeps the rc4 4-layer distilled student weights and ONNX graph but bundles the broader contextual decoder path.",
26
+ "The bundled decoder now recovers Gaelic Unit/Aonad plus Teach/building plus street spans, restores full prefixed Irish city forms such as nDún Dealgan, and reaches farther back for mixed contact-phone cues after emails or names.",
27
+ "On the fresh contextual holdout v20, q8 reaches 1.0000 F1 and 1.0000 exact F1 while preserving the Irish-first gates and the fast CPU profile.",
28
+ "This remains the fast CPU-first student line: single-pass GlobalPointer span extraction plus deterministic [PII:LABEL] replacement.",
29
+ "The public bundle now exposes role-aware masking: use `assistant_public` for assistant/public prose and `default` for user turns or search queries.",
30
+ "The recommended integration path is per-turn masking. Do not flatten an entire multi-turn transcript into one string before masking."
31
+ ],
32
+ "labels": [
33
+ "ACCOUNT_NUMBER",
34
+ "AGE",
35
+ "BANK_ROUTING_NUMBER",
36
+ "CITY",
37
+ "COUNTY",
38
+ "CREDIT_DEBIT_CARD",
39
+ "DATE_OF_BIRTH",
40
+ "EMAIL",
41
+ "FIRST_NAME",
42
+ "LAST_NAME",
43
+ "PASSPORT_NUMBER",
44
+ "PHONE_NUMBER",
45
+ "POSTCODE",
46
+ "PPSN",
47
+ "STREET_ADDRESS",
48
+ "SWIFT_BIC"
49
+ ],
50
+ "full": {
51
+ "core_f1": 1.0,
52
+ "core_examples_per_second": 51.331639360185136,
53
+ "contact_policy_f1": 1.0,
54
+ "contact_policy_examples_per_second": 25.371453404671357,
55
+ "chatbot_redteam_v2_f1": 0.9861111111111112,
56
+ "chatbot_redteam_v2_examples_per_second": 39.40799139945813,
57
+ "chatbot_gap_holdout_v2_f1": 1.0,
58
+ "chatbot_gap_holdout_v2_examples_per_second": 73.04992197895868,
59
+ "multilingual_f1": 0.9333333333333333,
60
+ "multilingual_examples_per_second": 80.71982069510497,
61
+ "multilingual_ppsn_label_f1": 1.0,
62
+ "context_holdout_v16_exact_f1": 1.0,
63
+ "context_holdout_v16_exact_examples_per_second": 18.469391352927687
64
+ },
65
+ "onnx_q8": {
66
+ "core_f1": 1.0,
67
+ "core_examples_per_second": 282.8890150894415,
68
+ "contact_policy_f1": 1.0,
69
+ "contact_policy_examples_per_second": 193.9946217272834,
70
+ "chatbot_redteam_v2_f1": 0.9861111111111112,
71
+ "chatbot_redteam_v2_examples_per_second": 161.55689047776917,
72
+ "chatbot_gap_holdout_v2_f1": 1.0,
73
+ "chatbot_gap_holdout_v2_examples_per_second": 173.15511250005449,
74
+ "multilingual_f1": 0.9333333333333333,
75
+ "multilingual_examples_per_second": 345.70774657699235,
76
+ "multilingual_ppsn_label_f1": 1.0,
77
+ "context_holdout_v16_exact_f1": 1.0,
78
+ "context_holdout_v16_exact_examples_per_second": 146.09,
79
+ "runtime_profile_f1": 0.8471459278719847,
80
+ "runtime_profile_examples_per_second": 160.0359407173945,
81
+ "context_holdout_v17_exact_f1": 1.0,
82
+ "context_holdout_v17_exact_examples_per_second": 167.42,
83
+ "context_holdout_v18_exact_f1": 1.0,
84
+ "context_holdout_v18_exact_examples_per_second": 171.6273668805399,
85
+ "context_holdout_v19_exact_f1": 1.0,
86
+ "context_holdout_v19_exact_examples_per_second": 232.47612837640656,
87
+ "context_holdout_v20_exact_f1": 1.0,
88
+ "context_holdout_v20_exact_examples_per_second": 169.18611117003,
89
+ "assistant_public_policy_f1": 1.0,
90
+ "assistant_public_policy_examples_per_second": 125.13534958071618,
91
+ "user_contextual_policy_f1": 1.0,
92
+ "user_contextual_policy_examples_per_second": 58.022274387128306
93
+ }
94
+ }
eval/benchmark_summary.md ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Benchmark Summary
2
+
3
+ ## ONNX q8
4
+
5
+ | Suite | F1 | Examples/s |
6
+ | --- | ---: | ---: |
7
+ | Irish core | 1.0000 | 282.8890 |
8
+ | Gov contact policy v1 | 1.0000 | 193.9946 |
9
+ | Gov chatbot red-team v2 | 0.9861 | 161.5569 |
10
+ | Gov chatbot gap holdout v2 | 1.0000 | 173.1551 |
11
+ | Context holdout v18 exact | 1.0000 | 171.6274 |
12
+ | Context holdout v19 exact | 1.0000 | 232.4761 |
13
+ | Context holdout v20 exact | 1.0000 | 169.1861 |
14
+ | Multilingual PPSN overall | 0.9333 | 345.7077 |
15
+ | Multilingual PPSN label-only | 1.0000 | — |
16
+
17
+
18
+ ## Role-Aware Policy
19
+
20
+ | Suite | Profile | F1 | Examples/s |
21
+ | --- | --- | ---: | ---: |
22
+ | Irish gov assistant public policy v1 | `assistant_public` | 1.0000 | 125.1353 |
23
+ | Irish gov user contextual policy v1 | `default` | 1.0000 | 58.0223 |
24
+
25
+ Notes:
26
+ - Use `assistant_public` for assistant/public informational text.
27
+ - Use `default` for user turns and search queries.
28
+ - Do not flatten a whole conversation into one string before masking.
eval/full_globalpointer_context_holdout_v16_exact.json ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "model": "models/irishcore-globalpointer-contextpii-4l-b02-distill-e020",
3
+ "input": "eval/globalpointer_context_holdout_v16.jsonl",
4
+ "loader_type": "global_pointer_pt",
5
+ "examples": 8,
6
+ "min_score": 0.5,
7
+ "iou_threshold": 1.0,
8
+ "elapsed_seconds": 0.43314908689353615,
9
+ "examples_per_second": 18.469391352927687,
10
+ "overall": {
11
+ "precision": 1.0,
12
+ "recall": 1.0,
13
+ "f1": 1.0,
14
+ "tp": 33,
15
+ "fp": 0,
16
+ "fn": 0
17
+ },
18
+ "by_label": {
19
+ "AGE": {
20
+ "precision": 1.0,
21
+ "recall": 1.0,
22
+ "f1": 1.0,
23
+ "tp": 1,
24
+ "fp": 0,
25
+ "fn": 0
26
+ },
27
+ "CITY": {
28
+ "precision": 1.0,
29
+ "recall": 1.0,
30
+ "f1": 1.0,
31
+ "tp": 3,
32
+ "fp": 0,
33
+ "fn": 0
34
+ },
35
+ "COUNTY": {
36
+ "precision": 1.0,
37
+ "recall": 1.0,
38
+ "f1": 1.0,
39
+ "tp": 2,
40
+ "fp": 0,
41
+ "fn": 0
42
+ },
43
+ "DATE_OF_BIRTH": {
44
+ "precision": 1.0,
45
+ "recall": 1.0,
46
+ "f1": 1.0,
47
+ "tp": 5,
48
+ "fp": 0,
49
+ "fn": 0
50
+ },
51
+ "EMAIL": {
52
+ "precision": 1.0,
53
+ "recall": 1.0,
54
+ "f1": 1.0,
55
+ "tp": 3,
56
+ "fp": 0,
57
+ "fn": 0
58
+ },
59
+ "FIRST_NAME": {
60
+ "precision": 1.0,
61
+ "recall": 1.0,
62
+ "f1": 1.0,
63
+ "tp": 2,
64
+ "fp": 0,
65
+ "fn": 0
66
+ },
67
+ "LAST_NAME": {
68
+ "precision": 1.0,
69
+ "recall": 1.0,
70
+ "f1": 1.0,
71
+ "tp": 2,
72
+ "fp": 0,
73
+ "fn": 0
74
+ },
75
+ "PHONE_NUMBER": {
76
+ "precision": 1.0,
77
+ "recall": 1.0,
78
+ "f1": 1.0,
79
+ "tp": 2,
80
+ "fp": 0,
81
+ "fn": 0
82
+ },
83
+ "POSTCODE": {
84
+ "precision": 1.0,
85
+ "recall": 1.0,
86
+ "f1": 1.0,
87
+ "tp": 3,
88
+ "fp": 0,
89
+ "fn": 0
90
+ },
91
+ "PPSN": {
92
+ "precision": 1.0,
93
+ "recall": 1.0,
94
+ "f1": 1.0,
95
+ "tp": 5,
96
+ "fp": 0,
97
+ "fn": 0
98
+ },
99
+ "STREET_ADDRESS": {
100
+ "precision": 1.0,
101
+ "recall": 1.0,
102
+ "f1": 1.0,
103
+ "tp": 5,
104
+ "fp": 0,
105
+ "fn": 0
106
+ }
107
+ }
108
+ }
eval/full_irish_core_pii_v1.json ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "model": "models/irishcore-globalpointer-contextpii-4l-b02-distill-e020",
3
+ "input": "eval/irish_core_pii_v1.jsonl",
4
+ "loader_type": "global_pointer_pt",
5
+ "examples": 37,
6
+ "min_score": 0.5,
7
+ "iou_threshold": 0.5,
8
+ "elapsed_seconds": 0.7208030069014058,
9
+ "examples_per_second": 51.331639360185136,
10
+ "overall": {
11
+ "precision": 1.0,
12
+ "recall": 1.0,
13
+ "f1": 1.0,
14
+ "tp": 76,
15
+ "fp": 0,
16
+ "fn": 0
17
+ },
18
+ "by_label": {
19
+ "ACCOUNT_NUMBER": {
20
+ "precision": 1.0,
21
+ "recall": 1.0,
22
+ "f1": 1.0,
23
+ "tp": 3,
24
+ "fp": 0,
25
+ "fn": 0
26
+ },
27
+ "BANK_ROUTING_NUMBER": {
28
+ "precision": 1.0,
29
+ "recall": 1.0,
30
+ "f1": 1.0,
31
+ "tp": 1,
32
+ "fp": 0,
33
+ "fn": 0
34
+ },
35
+ "CREDIT_DEBIT_CARD": {
36
+ "precision": 1.0,
37
+ "recall": 1.0,
38
+ "f1": 1.0,
39
+ "tp": 2,
40
+ "fp": 0,
41
+ "fn": 0
42
+ },
43
+ "EMAIL": {
44
+ "precision": 1.0,
45
+ "recall": 1.0,
46
+ "f1": 1.0,
47
+ "tp": 6,
48
+ "fp": 0,
49
+ "fn": 0
50
+ },
51
+ "FIRST_NAME": {
52
+ "precision": 1.0,
53
+ "recall": 1.0,
54
+ "f1": 1.0,
55
+ "tp": 19,
56
+ "fp": 0,
57
+ "fn": 0
58
+ },
59
+ "LAST_NAME": {
60
+ "precision": 1.0,
61
+ "recall": 1.0,
62
+ "f1": 1.0,
63
+ "tp": 19,
64
+ "fp": 0,
65
+ "fn": 0
66
+ },
67
+ "PASSPORT_NUMBER": {
68
+ "precision": 1.0,
69
+ "recall": 1.0,
70
+ "f1": 1.0,
71
+ "tp": 2,
72
+ "fp": 0,
73
+ "fn": 0
74
+ },
75
+ "PHONE_NUMBER": {
76
+ "precision": 1.0,
77
+ "recall": 1.0,
78
+ "f1": 1.0,
79
+ "tp": 12,
80
+ "fp": 0,
81
+ "fn": 0
82
+ },
83
+ "POSTCODE": {
84
+ "precision": 1.0,
85
+ "recall": 1.0,
86
+ "f1": 1.0,
87
+ "tp": 4,
88
+ "fp": 0,
89
+ "fn": 0
90
+ },
91
+ "PPSN": {
92
+ "precision": 1.0,
93
+ "recall": 1.0,
94
+ "f1": 1.0,
95
+ "tp": 6,
96
+ "fp": 0,
97
+ "fn": 0
98
+ },
99
+ "SWIFT_BIC": {
100
+ "precision": 1.0,
101
+ "recall": 1.0,
102
+ "f1": 1.0,
103
+ "tp": 2,
104
+ "fp": 0,
105
+ "fn": 0
106
+ }
107
+ }
108
+ }
eval/full_irish_gov_chatbot_gap_holdout_v2.json ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "model": "models/irishcore-globalpointer-contextpii-4l-b02-distill-e020",
3
+ "input": "eval/irish_gov_chatbot_gap_holdout_v2.jsonl",
4
+ "loader_type": "global_pointer_pt",
5
+ "examples": 160,
6
+ "min_score": 0.5,
7
+ "iou_threshold": 0.5,
8
+ "elapsed_seconds": 2.190282969037071,
9
+ "examples_per_second": 73.04992197895868,
10
+ "overall": {
11
+ "precision": 1.0,
12
+ "recall": 1.0,
13
+ "f1": 1.0,
14
+ "tp": 652,
15
+ "fp": 0,
16
+ "fn": 0
17
+ },
18
+ "by_label": {
19
+ "ACCOUNT_NUMBER": {
20
+ "precision": 1.0,
21
+ "recall": 1.0,
22
+ "f1": 1.0,
23
+ "tp": 38,
24
+ "fp": 0,
25
+ "fn": 0
26
+ },
27
+ "EMAIL": {
28
+ "precision": 1.0,
29
+ "recall": 1.0,
30
+ "f1": 1.0,
31
+ "tp": 104,
32
+ "fp": 0,
33
+ "fn": 0
34
+ },
35
+ "FIRST_NAME": {
36
+ "precision": 1.0,
37
+ "recall": 1.0,
38
+ "f1": 1.0,
39
+ "tp": 68,
40
+ "fp": 0,
41
+ "fn": 0
42
+ },
43
+ "LAST_NAME": {
44
+ "precision": 1.0,
45
+ "recall": 1.0,
46
+ "f1": 1.0,
47
+ "tp": 68,
48
+ "fp": 0,
49
+ "fn": 0
50
+ },
51
+ "PASSPORT_NUMBER": {
52
+ "precision": 1.0,
53
+ "recall": 1.0,
54
+ "f1": 1.0,
55
+ "tp": 33,
56
+ "fp": 0,
57
+ "fn": 0
58
+ },
59
+ "PHONE_NUMBER": {
60
+ "precision": 1.0,
61
+ "recall": 1.0,
62
+ "f1": 1.0,
63
+ "tp": 101,
64
+ "fp": 0,
65
+ "fn": 0
66
+ },
67
+ "POSTCODE": {
68
+ "precision": 1.0,
69
+ "recall": 1.0,
70
+ "f1": 1.0,
71
+ "tp": 101,
72
+ "fp": 0,
73
+ "fn": 0
74
+ },
75
+ "PPSN": {
76
+ "precision": 1.0,
77
+ "recall": 1.0,
78
+ "f1": 1.0,
79
+ "tp": 101,
80
+ "fp": 0,
81
+ "fn": 0
82
+ },
83
+ "SWIFT_BIC": {
84
+ "precision": 1.0,
85
+ "recall": 1.0,
86
+ "f1": 1.0,
87
+ "tp": 38,
88
+ "fp": 0,
89
+ "fn": 0
90
+ }
91
+ }
92
+ }
eval/full_irish_gov_chatbot_redteam_v2.json ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "model": "models/irishcore-globalpointer-contextpii-4l-b02-distill-e020",
3
+ "input": "eval/irish_gov_chatbot_redteam_v2.jsonl",
4
+ "loader_type": "global_pointer_pt",
5
+ "examples": 25,
6
+ "min_score": 0.5,
7
+ "iou_threshold": 0.5,
8
+ "elapsed_seconds": 0.6343890950083733,
9
+ "examples_per_second": 39.40799139945813,
10
+ "overall": {
11
+ "precision": 0.9726027397260274,
12
+ "recall": 1.0,
13
+ "f1": 0.9861111111111112,
14
+ "tp": 71,
15
+ "fp": 2,
16
+ "fn": 0
17
+ },
18
+ "by_label": {
19
+ "ACCOUNT_NUMBER": {
20
+ "precision": 1.0,
21
+ "recall": 1.0,
22
+ "f1": 1.0,
23
+ "tp": 4,
24
+ "fp": 0,
25
+ "fn": 0
26
+ },
27
+ "BANK_ROUTING_NUMBER": {
28
+ "precision": 1.0,
29
+ "recall": 1.0,
30
+ "f1": 1.0,
31
+ "tp": 1,
32
+ "fp": 0,
33
+ "fn": 0
34
+ },
35
+ "CREDIT_DEBIT_CARD": {
36
+ "precision": 1.0,
37
+ "recall": 1.0,
38
+ "f1": 1.0,
39
+ "tp": 1,
40
+ "fp": 0,
41
+ "fn": 0
42
+ },
43
+ "EMAIL": {
44
+ "precision": 1.0,
45
+ "recall": 1.0,
46
+ "f1": 1.0,
47
+ "tp": 10,
48
+ "fp": 0,
49
+ "fn": 0
50
+ },
51
+ "FIRST_NAME": {
52
+ "precision": 1.0,
53
+ "recall": 1.0,
54
+ "f1": 1.0,
55
+ "tp": 7,
56
+ "fp": 0,
57
+ "fn": 0
58
+ },
59
+ "LAST_NAME": {
60
+ "precision": 1.0,
61
+ "recall": 1.0,
62
+ "f1": 1.0,
63
+ "tp": 7,
64
+ "fp": 0,
65
+ "fn": 0
66
+ },
67
+ "PASSPORT_NUMBER": {
68
+ "precision": 1.0,
69
+ "recall": 1.0,
70
+ "f1": 1.0,
71
+ "tp": 2,
72
+ "fp": 0,
73
+ "fn": 0
74
+ },
75
+ "PHONE_NUMBER": {
76
+ "precision": 1.0,
77
+ "recall": 1.0,
78
+ "f1": 1.0,
79
+ "tp": 17,
80
+ "fp": 0,
81
+ "fn": 0
82
+ },
83
+ "POSTCODE": {
84
+ "precision": 1.0,
85
+ "recall": 1.0,
86
+ "f1": 1.0,
87
+ "tp": 7,
88
+ "fp": 0,
89
+ "fn": 0
90
+ },
91
+ "PPSN": {
92
+ "precision": 1.0,
93
+ "recall": 1.0,
94
+ "f1": 1.0,
95
+ "tp": 11,
96
+ "fp": 0,
97
+ "fn": 0
98
+ },
99
+ "SWIFT_BIC": {
100
+ "precision": 1.0,
101
+ "recall": 1.0,
102
+ "f1": 1.0,
103
+ "tp": 4,
104
+ "fp": 0,
105
+ "fn": 0
106
+ }
107
+ }
108
+ }
eval/full_irish_gov_contact_policy_v1.json ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "model": "models/irishcore-globalpointer-contextpii-4l-b02-distill-e020",
3
+ "input": "eval/irish_gov_contact_policy_v1.jsonl",
4
+ "loader_type": "global_pointer_pt",
5
+ "examples": 12,
6
+ "min_score": 0.5,
7
+ "iou_threshold": 0.5,
8
+ "elapsed_seconds": 0.4729725100332871,
9
+ "examples_per_second": 25.371453404671357,
10
+ "overall": {
11
+ "precision": 1.0,
12
+ "recall": 1.0,
13
+ "f1": 1.0,
14
+ "tp": 30,
15
+ "fp": 0,
16
+ "fn": 0
17
+ },
18
+ "by_label": {
19
+ "CITY": {
20
+ "precision": 1.0,
21
+ "recall": 1.0,
22
+ "f1": 1.0,
23
+ "tp": 4,
24
+ "fp": 0,
25
+ "fn": 0
26
+ },
27
+ "COUNTY": {
28
+ "precision": 1.0,
29
+ "recall": 1.0,
30
+ "f1": 1.0,
31
+ "tp": 2,
32
+ "fp": 0,
33
+ "fn": 0
34
+ },
35
+ "DATE_OF_BIRTH": {
36
+ "precision": 1.0,
37
+ "recall": 1.0,
38
+ "f1": 1.0,
39
+ "tp": 4,
40
+ "fp": 0,
41
+ "fn": 0
42
+ },
43
+ "EMAIL": {
44
+ "precision": 1.0,
45
+ "recall": 1.0,
46
+ "f1": 1.0,
47
+ "tp": 4,
48
+ "fp": 0,
49
+ "fn": 0
50
+ },
51
+ "PHONE_NUMBER": {
52
+ "precision": 1.0,
53
+ "recall": 1.0,
54
+ "f1": 1.0,
55
+ "tp": 8,
56
+ "fp": 0,
57
+ "fn": 0
58
+ },
59
+ "POSTCODE": {
60
+ "precision": 1.0,
61
+ "recall": 1.0,
62
+ "f1": 1.0,
63
+ "tp": 4,
64
+ "fp": 0,
65
+ "fn": 0
66
+ },
67
+ "STREET_ADDRESS": {
68
+ "precision": 1.0,
69
+ "recall": 1.0,
70
+ "f1": 1.0,
71
+ "tp": 4,
72
+ "fp": 0,
73
+ "fn": 0
74
+ }
75
+ }
76
+ }
eval/full_multilingual_ppsn_v1_all.json ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "model": "models/irishcore-globalpointer-contextpii-4l-b02-distill-e020",
3
+ "input": "eval/multilingual_ppsn_v1_all.jsonl",
4
+ "loader_type": "global_pointer_pt",
5
+ "examples": 168,
6
+ "min_score": 0.5,
7
+ "iou_threshold": 0.5,
8
+ "elapsed_seconds": 2.081273205927573,
9
+ "examples_per_second": 80.71982069510497,
10
+ "overall": {
11
+ "precision": 0.875,
12
+ "recall": 1.0,
13
+ "f1": 0.9333333333333333,
14
+ "tp": 84,
15
+ "fp": 12,
16
+ "fn": 0
17
+ },
18
+ "by_label": {
19
+ "PPSN": {
20
+ "precision": 1.0,
21
+ "recall": 1.0,
22
+ "f1": 1.0,
23
+ "tp": 84,
24
+ "fp": 0,
25
+ "fn": 0
26
+ }
27
+ }
28
+ }
eval/q8_globalpointer_context_holdout_v16_exact.json ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "model": "release/IrishCore-GlobalPointer-ContextPII-4L-122M-v1-rc1",
3
+ "input": "eval/globalpointer_context_holdout_v16.jsonl",
4
+ "loader_type": "global_pointer_onnx",
5
+ "examples": 8,
6
+ "min_score": 0.5,
7
+ "iou_threshold": 0.5,
8
+ "elapsed_seconds": 0.05475943395867944,
9
+ "examples_per_second": 146.0935481187893,
10
+ "overall": {
11
+ "precision": 1.0,
12
+ "recall": 1.0,
13
+ "f1": 1.0,
14
+ "tp": 33,
15
+ "fp": 0,
16
+ "fn": 0
17
+ },
18
+ "by_label": {
19
+ "AGE": {
20
+ "precision": 1.0,
21
+ "recall": 1.0,
22
+ "f1": 1.0,
23
+ "tp": 1,
24
+ "fp": 0,
25
+ "fn": 0
26
+ },
27
+ "CITY": {
28
+ "precision": 1.0,
29
+ "recall": 1.0,
30
+ "f1": 1.0,
31
+ "tp": 3,
32
+ "fp": 0,
33
+ "fn": 0
34
+ },
35
+ "COUNTY": {
36
+ "precision": 1.0,
37
+ "recall": 1.0,
38
+ "f1": 1.0,
39
+ "tp": 2,
40
+ "fp": 0,
41
+ "fn": 0
42
+ },
43
+ "DATE_OF_BIRTH": {
44
+ "precision": 1.0,
45
+ "recall": 1.0,
46
+ "f1": 1.0,
47
+ "tp": 5,
48
+ "fp": 0,
49
+ "fn": 0
50
+ },
51
+ "EMAIL": {
52
+ "precision": 1.0,
53
+ "recall": 1.0,
54
+ "f1": 1.0,
55
+ "tp": 3,
56
+ "fp": 0,
57
+ "fn": 0
58
+ },
59
+ "FIRST_NAME": {
60
+ "precision": 1.0,
61
+ "recall": 1.0,
62
+ "f1": 1.0,
63
+ "tp": 2,
64
+ "fp": 0,
65
+ "fn": 0
66
+ },
67
+ "LAST_NAME": {
68
+ "precision": 1.0,
69
+ "recall": 1.0,
70
+ "f1": 1.0,
71
+ "tp": 2,
72
+ "fp": 0,
73
+ "fn": 0
74
+ },
75
+ "PHONE_NUMBER": {
76
+ "precision": 1.0,
77
+ "recall": 1.0,
78
+ "f1": 1.0,
79
+ "tp": 2,
80
+ "fp": 0,
81
+ "fn": 0
82
+ },
83
+ "POSTCODE": {
84
+ "precision": 1.0,
85
+ "recall": 1.0,
86
+ "f1": 1.0,
87
+ "tp": 3,
88
+ "fp": 0,
89
+ "fn": 0
90
+ },
91
+ "PPSN": {
92
+ "precision": 1.0,
93
+ "recall": 1.0,
94
+ "f1": 1.0,
95
+ "tp": 5,
96
+ "fp": 0,
97
+ "fn": 0
98
+ },
99
+ "STREET_ADDRESS": {
100
+ "precision": 1.0,
101
+ "recall": 1.0,
102
+ "f1": 1.0,
103
+ "tp": 5,
104
+ "fp": 0,
105
+ "fn": 0
106
+ }
107
+ }
108
+ }
eval/q8_globalpointer_context_holdout_v17.json ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "model": "release/IrishCore-GlobalPointer-ContextPII-4L-122M-v1-rc1",
3
+ "input": "eval/globalpointer_context_holdout_v17.jsonl",
4
+ "loader_type": "global_pointer_onnx",
5
+ "examples": 10,
6
+ "min_score": 0.5,
7
+ "iou_threshold": 0.5,
8
+ "elapsed_seconds": 0.0675472590373829,
9
+ "examples_per_second": 148.04449717886655,
10
+ "overall": {
11
+ "precision": 1.0,
12
+ "recall": 1.0,
13
+ "f1": 1.0,
14
+ "tp": 30,
15
+ "fp": 0,
16
+ "fn": 0
17
+ },
18
+ "by_label": {
19
+ "AGE": {
20
+ "precision": 1.0,
21
+ "recall": 1.0,
22
+ "f1": 1.0,
23
+ "tp": 2,
24
+ "fp": 0,
25
+ "fn": 0
26
+ },
27
+ "CITY": {
28
+ "precision": 1.0,
29
+ "recall": 1.0,
30
+ "f1": 1.0,
31
+ "tp": 4,
32
+ "fp": 0,
33
+ "fn": 0
34
+ },
35
+ "COUNTY": {
36
+ "precision": 1.0,
37
+ "recall": 1.0,
38
+ "f1": 1.0,
39
+ "tp": 2,
40
+ "fp": 0,
41
+ "fn": 0
42
+ },
43
+ "DATE_OF_BIRTH": {
44
+ "precision": 1.0,
45
+ "recall": 1.0,
46
+ "f1": 1.0,
47
+ "tp": 2,
48
+ "fp": 0,
49
+ "fn": 0
50
+ },
51
+ "EMAIL": {
52
+ "precision": 1.0,
53
+ "recall": 1.0,
54
+ "f1": 1.0,
55
+ "tp": 4,
56
+ "fp": 0,
57
+ "fn": 0
58
+ },
59
+ "PHONE_NUMBER": {
60
+ "precision": 1.0,
61
+ "recall": 1.0,
62
+ "f1": 1.0,
63
+ "tp": 4,
64
+ "fp": 0,
65
+ "fn": 0
66
+ },
67
+ "POSTCODE": {
68
+ "precision": 1.0,
69
+ "recall": 1.0,
70
+ "f1": 1.0,
71
+ "tp": 4,
72
+ "fp": 0,
73
+ "fn": 0
74
+ },
75
+ "PPSN": {
76
+ "precision": 1.0,
77
+ "recall": 1.0,
78
+ "f1": 1.0,
79
+ "tp": 2,
80
+ "fp": 0,
81
+ "fn": 0
82
+ },
83
+ "STREET_ADDRESS": {
84
+ "precision": 1.0,
85
+ "recall": 1.0,
86
+ "f1": 1.0,
87
+ "tp": 6,
88
+ "fp": 0,
89
+ "fn": 0
90
+ }
91
+ }
92
+ }
eval/q8_globalpointer_context_holdout_v17_exact.json ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "model": "release/IrishCore-GlobalPointer-ContextPII-4L-122M-v1-rc1",
3
+ "input": "eval/globalpointer_context_holdout_v17.jsonl",
4
+ "loader_type": "global_pointer_onnx",
5
+ "examples": 10,
6
+ "min_score": 0.5,
7
+ "iou_threshold": 1.0,
8
+ "elapsed_seconds": 0.05972867493983358,
9
+ "examples_per_second": 167.42377107935658,
10
+ "overall": {
11
+ "precision": 1.0,
12
+ "recall": 1.0,
13
+ "f1": 1.0,
14
+ "tp": 30,
15
+ "fp": 0,
16
+ "fn": 0
17
+ },
18
+ "by_label": {
19
+ "AGE": {
20
+ "precision": 1.0,
21
+ "recall": 1.0,
22
+ "f1": 1.0,
23
+ "tp": 2,
24
+ "fp": 0,
25
+ "fn": 0
26
+ },
27
+ "CITY": {
28
+ "precision": 1.0,
29
+ "recall": 1.0,
30
+ "f1": 1.0,
31
+ "tp": 4,
32
+ "fp": 0,
33
+ "fn": 0
34
+ },
35
+ "COUNTY": {
36
+ "precision": 1.0,
37
+ "recall": 1.0,
38
+ "f1": 1.0,
39
+ "tp": 2,
40
+ "fp": 0,
41
+ "fn": 0
42
+ },
43
+ "DATE_OF_BIRTH": {
44
+ "precision": 1.0,
45
+ "recall": 1.0,
46
+ "f1": 1.0,
47
+ "tp": 2,
48
+ "fp": 0,
49
+ "fn": 0
50
+ },
51
+ "EMAIL": {
52
+ "precision": 1.0,
53
+ "recall": 1.0,
54
+ "f1": 1.0,
55
+ "tp": 4,
56
+ "fp": 0,
57
+ "fn": 0
58
+ },
59
+ "PHONE_NUMBER": {
60
+ "precision": 1.0,
61
+ "recall": 1.0,
62
+ "f1": 1.0,
63
+ "tp": 4,
64
+ "fp": 0,
65
+ "fn": 0
66
+ },
67
+ "POSTCODE": {
68
+ "precision": 1.0,
69
+ "recall": 1.0,
70
+ "f1": 1.0,
71
+ "tp": 4,
72
+ "fp": 0,
73
+ "fn": 0
74
+ },
75
+ "PPSN": {
76
+ "precision": 1.0,
77
+ "recall": 1.0,
78
+ "f1": 1.0,
79
+ "tp": 2,
80
+ "fp": 0,
81
+ "fn": 0
82
+ },
83
+ "STREET_ADDRESS": {
84
+ "precision": 1.0,
85
+ "recall": 1.0,
86
+ "f1": 1.0,
87
+ "tp": 6,
88
+ "fp": 0,
89
+ "fn": 0
90
+ }
91
+ }
92
+ }
eval/q8_globalpointer_context_holdout_v18_exact.json ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "model": "release/IrishCore-GlobalPointer-ContextPII-4L-122M-v1-rc3",
3
+ "input": "eval/globalpointer_context_holdout_v18.jsonl",
4
+ "loader_type": "global_pointer_onnx",
5
+ "examples": 10,
6
+ "min_score": 0.5,
7
+ "iou_threshold": 1.0,
8
+ "elapsed_seconds": 0.058265766012482345,
9
+ "examples_per_second": 171.6273668805399,
10
+ "overall": {
11
+ "precision": 1.0,
12
+ "recall": 1.0,
13
+ "f1": 1.0,
14
+ "tp": 34,
15
+ "fp": 0,
16
+ "fn": 0
17
+ },
18
+ "by_label": {
19
+ "CITY": {
20
+ "precision": 1.0,
21
+ "recall": 1.0,
22
+ "f1": 1.0,
23
+ "tp": 6,
24
+ "fp": 0,
25
+ "fn": 0
26
+ },
27
+ "COUNTY": {
28
+ "precision": 1.0,
29
+ "recall": 1.0,
30
+ "f1": 1.0,
31
+ "tp": 4,
32
+ "fp": 0,
33
+ "fn": 0
34
+ },
35
+ "DATE_OF_BIRTH": {
36
+ "precision": 1.0,
37
+ "recall": 1.0,
38
+ "f1": 1.0,
39
+ "tp": 2,
40
+ "fp": 0,
41
+ "fn": 0
42
+ },
43
+ "EMAIL": {
44
+ "precision": 1.0,
45
+ "recall": 1.0,
46
+ "f1": 1.0,
47
+ "tp": 2,
48
+ "fp": 0,
49
+ "fn": 0
50
+ },
51
+ "PHONE_NUMBER": {
52
+ "precision": 1.0,
53
+ "recall": 1.0,
54
+ "f1": 1.0,
55
+ "tp": 4,
56
+ "fp": 0,
57
+ "fn": 0
58
+ },
59
+ "POSTCODE": {
60
+ "precision": 1.0,
61
+ "recall": 1.0,
62
+ "f1": 1.0,
63
+ "tp": 6,
64
+ "fp": 0,
65
+ "fn": 0
66
+ },
67
+ "PPSN": {
68
+ "precision": 1.0,
69
+ "recall": 1.0,
70
+ "f1": 1.0,
71
+ "tp": 2,
72
+ "fp": 0,
73
+ "fn": 0
74
+ },
75
+ "STREET_ADDRESS": {
76
+ "precision": 1.0,
77
+ "recall": 1.0,
78
+ "f1": 1.0,
79
+ "tp": 8,
80
+ "fp": 0,
81
+ "fn": 0
82
+ }
83
+ }
84
+ }
eval/q8_globalpointer_context_holdout_v19_exact.json ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "model": "release/IrishCore-GlobalPointer-ContextPII-4L-122M-v1-rc3",
3
+ "input": "eval/globalpointer_context_holdout_v19.jsonl",
4
+ "loader_type": "global_pointer_onnx",
5
+ "examples": 12,
6
+ "min_score": 0.5,
7
+ "iou_threshold": 1.0,
8
+ "elapsed_seconds": 0.051618203055113554,
9
+ "examples_per_second": 232.47612837640656,
10
+ "overall": {
11
+ "precision": 1.0,
12
+ "recall": 1.0,
13
+ "f1": 1.0,
14
+ "tp": 25,
15
+ "fp": 0,
16
+ "fn": 0
17
+ },
18
+ "by_label": {
19
+ "ACCOUNT_NUMBER": {
20
+ "precision": 1.0,
21
+ "recall": 1.0,
22
+ "f1": 1.0,
23
+ "tp": 1,
24
+ "fp": 0,
25
+ "fn": 0
26
+ },
27
+ "CITY": {
28
+ "precision": 1.0,
29
+ "recall": 1.0,
30
+ "f1": 1.0,
31
+ "tp": 2,
32
+ "fp": 0,
33
+ "fn": 0
34
+ },
35
+ "COUNTY": {
36
+ "precision": 1.0,
37
+ "recall": 1.0,
38
+ "f1": 1.0,
39
+ "tp": 2,
40
+ "fp": 0,
41
+ "fn": 0
42
+ },
43
+ "DATE_OF_BIRTH": {
44
+ "precision": 1.0,
45
+ "recall": 1.0,
46
+ "f1": 1.0,
47
+ "tp": 1,
48
+ "fp": 0,
49
+ "fn": 0
50
+ },
51
+ "EMAIL": {
52
+ "precision": 1.0,
53
+ "recall": 1.0,
54
+ "f1": 1.0,
55
+ "tp": 3,
56
+ "fp": 0,
57
+ "fn": 0
58
+ },
59
+ "PASSPORT_NUMBER": {
60
+ "precision": 1.0,
61
+ "recall": 1.0,
62
+ "f1": 1.0,
63
+ "tp": 1,
64
+ "fp": 0,
65
+ "fn": 0
66
+ },
67
+ "PHONE_NUMBER": {
68
+ "precision": 1.0,
69
+ "recall": 1.0,
70
+ "f1": 1.0,
71
+ "tp": 3,
72
+ "fp": 0,
73
+ "fn": 0
74
+ },
75
+ "POSTCODE": {
76
+ "precision": 1.0,
77
+ "recall": 1.0,
78
+ "f1": 1.0,
79
+ "tp": 2,
80
+ "fp": 0,
81
+ "fn": 0
82
+ },
83
+ "PPSN": {
84
+ "precision": 1.0,
85
+ "recall": 1.0,
86
+ "f1": 1.0,
87
+ "tp": 7,
88
+ "fp": 0,
89
+ "fn": 0
90
+ },
91
+ "STREET_ADDRESS": {
92
+ "precision": 1.0,
93
+ "recall": 1.0,
94
+ "f1": 1.0,
95
+ "tp": 2,
96
+ "fp": 0,
97
+ "fn": 0
98
+ },
99
+ "SWIFT_BIC": {
100
+ "precision": 1.0,
101
+ "recall": 1.0,
102
+ "f1": 1.0,
103
+ "tp": 1,
104
+ "fp": 0,
105
+ "fn": 0
106
+ }
107
+ }
108
+ }
eval/q8_globalpointer_context_holdout_v20_exact.json ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "model": "release/IrishCore-GlobalPointer-ContextPII-4L-122M-v1-rc4",
3
+ "input": "eval/globalpointer_context_holdout_v20.jsonl",
4
+ "loader_type": "global_pointer_onnx",
5
+ "examples": 12,
6
+ "min_score": 0.5,
7
+ "iou_threshold": 1.0,
8
+ "elapsed_seconds": 0.07092780794482678,
9
+ "examples_per_second": 169.18611117003,
10
+ "overall": {
11
+ "precision": 1.0,
12
+ "recall": 1.0,
13
+ "f1": 1.0,
14
+ "tp": 35,
15
+ "fp": 0,
16
+ "fn": 0
17
+ },
18
+ "by_label": {
19
+ "CITY": {
20
+ "precision": 1.0,
21
+ "recall": 1.0,
22
+ "f1": 1.0,
23
+ "tp": 6,
24
+ "fp": 0,
25
+ "fn": 0
26
+ },
27
+ "COUNTY": {
28
+ "precision": 1.0,
29
+ "recall": 1.0,
30
+ "f1": 1.0,
31
+ "tp": 1,
32
+ "fp": 0,
33
+ "fn": 0
34
+ },
35
+ "DATE_OF_BIRTH": {
36
+ "precision": 1.0,
37
+ "recall": 1.0,
38
+ "f1": 1.0,
39
+ "tp": 2,
40
+ "fp": 0,
41
+ "fn": 0
42
+ },
43
+ "EMAIL": {
44
+ "precision": 1.0,
45
+ "recall": 1.0,
46
+ "f1": 1.0,
47
+ "tp": 5,
48
+ "fp": 0,
49
+ "fn": 0
50
+ },
51
+ "FIRST_NAME": {
52
+ "precision": 1.0,
53
+ "recall": 1.0,
54
+ "f1": 1.0,
55
+ "tp": 2,
56
+ "fp": 0,
57
+ "fn": 0
58
+ },
59
+ "LAST_NAME": {
60
+ "precision": 1.0,
61
+ "recall": 1.0,
62
+ "f1": 1.0,
63
+ "tp": 2,
64
+ "fp": 0,
65
+ "fn": 0
66
+ },
67
+ "PHONE_NUMBER": {
68
+ "precision": 1.0,
69
+ "recall": 1.0,
70
+ "f1": 1.0,
71
+ "tp": 3,
72
+ "fp": 0,
73
+ "fn": 0
74
+ },
75
+ "POSTCODE": {
76
+ "precision": 1.0,
77
+ "recall": 1.0,
78
+ "f1": 1.0,
79
+ "tp": 6,
80
+ "fp": 0,
81
+ "fn": 0
82
+ },
83
+ "PPSN": {
84
+ "precision": 1.0,
85
+ "recall": 1.0,
86
+ "f1": 1.0,
87
+ "tp": 2,
88
+ "fp": 0,
89
+ "fn": 0
90
+ },
91
+ "STREET_ADDRESS": {
92
+ "precision": 1.0,
93
+ "recall": 1.0,
94
+ "f1": 1.0,
95
+ "tp": 6,
96
+ "fp": 0,
97
+ "fn": 0
98
+ }
99
+ }
100
+ }
eval/q8_irish_core_pii_v1.json ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "model": "release/IrishCore-GlobalPointer-ContextPII-4L-122M-v1-rc4",
3
+ "input": "eval/irish_core_pii_v1.jsonl",
4
+ "loader_type": "global_pointer_onnx",
5
+ "examples": 37,
6
+ "min_score": 0.5,
7
+ "iou_threshold": 0.5,
8
+ "elapsed_seconds": 0.13079334306530654,
9
+ "examples_per_second": 282.8890150894415,
10
+ "overall": {
11
+ "precision": 1.0,
12
+ "recall": 1.0,
13
+ "f1": 1.0,
14
+ "tp": 76,
15
+ "fp": 0,
16
+ "fn": 0
17
+ },
18
+ "by_label": {
19
+ "ACCOUNT_NUMBER": {
20
+ "precision": 1.0,
21
+ "recall": 1.0,
22
+ "f1": 1.0,
23
+ "tp": 3,
24
+ "fp": 0,
25
+ "fn": 0
26
+ },
27
+ "BANK_ROUTING_NUMBER": {
28
+ "precision": 1.0,
29
+ "recall": 1.0,
30
+ "f1": 1.0,
31
+ "tp": 1,
32
+ "fp": 0,
33
+ "fn": 0
34
+ },
35
+ "CREDIT_DEBIT_CARD": {
36
+ "precision": 1.0,
37
+ "recall": 1.0,
38
+ "f1": 1.0,
39
+ "tp": 2,
40
+ "fp": 0,
41
+ "fn": 0
42
+ },
43
+ "EMAIL": {
44
+ "precision": 1.0,
45
+ "recall": 1.0,
46
+ "f1": 1.0,
47
+ "tp": 6,
48
+ "fp": 0,
49
+ "fn": 0
50
+ },
51
+ "FIRST_NAME": {
52
+ "precision": 1.0,
53
+ "recall": 1.0,
54
+ "f1": 1.0,
55
+ "tp": 19,
56
+ "fp": 0,
57
+ "fn": 0
58
+ },
59
+ "LAST_NAME": {
60
+ "precision": 1.0,
61
+ "recall": 1.0,
62
+ "f1": 1.0,
63
+ "tp": 19,
64
+ "fp": 0,
65
+ "fn": 0
66
+ },
67
+ "PASSPORT_NUMBER": {
68
+ "precision": 1.0,
69
+ "recall": 1.0,
70
+ "f1": 1.0,
71
+ "tp": 2,
72
+ "fp": 0,
73
+ "fn": 0
74
+ },
75
+ "PHONE_NUMBER": {
76
+ "precision": 1.0,
77
+ "recall": 1.0,
78
+ "f1": 1.0,
79
+ "tp": 12,
80
+ "fp": 0,
81
+ "fn": 0
82
+ },
83
+ "POSTCODE": {
84
+ "precision": 1.0,
85
+ "recall": 1.0,
86
+ "f1": 1.0,
87
+ "tp": 4,
88
+ "fp": 0,
89
+ "fn": 0
90
+ },
91
+ "PPSN": {
92
+ "precision": 1.0,
93
+ "recall": 1.0,
94
+ "f1": 1.0,
95
+ "tp": 6,
96
+ "fp": 0,
97
+ "fn": 0
98
+ },
99
+ "SWIFT_BIC": {
100
+ "precision": 1.0,
101
+ "recall": 1.0,
102
+ "f1": 1.0,
103
+ "tp": 2,
104
+ "fp": 0,
105
+ "fn": 0
106
+ }
107
+ }
108
+ }
eval/q8_irish_gov_assistant_public_policy_v1.json ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "model": "release/IrishCore-GlobalPointer-ContextPII-4L-122M-v1-rc5",
3
+ "input": "eval/irish_gov_assistant_public_policy_v1.jsonl",
4
+ "loader_type": "global_pointer_onnx",
5
+ "examples": 2,
6
+ "min_score": 0.5,
7
+ "profile": "assistant_public",
8
+ "iou_threshold": 0.5,
9
+ "elapsed_seconds": 0.01598269399255514,
10
+ "examples_per_second": 125.13534958071618,
11
+ "overall": {
12
+ "precision": 1.0,
13
+ "recall": 1.0,
14
+ "f1": 1.0,
15
+ "tp": 8,
16
+ "fp": 0,
17
+ "fn": 0
18
+ },
19
+ "by_label": {
20
+ "EMAIL": {
21
+ "precision": 1.0,
22
+ "recall": 1.0,
23
+ "f1": 1.0,
24
+ "tp": 2,
25
+ "fp": 0,
26
+ "fn": 0
27
+ },
28
+ "PHONE_NUMBER": {
29
+ "precision": 1.0,
30
+ "recall": 1.0,
31
+ "f1": 1.0,
32
+ "tp": 4,
33
+ "fp": 0,
34
+ "fn": 0
35
+ },
36
+ "POSTCODE": {
37
+ "precision": 1.0,
38
+ "recall": 1.0,
39
+ "f1": 1.0,
40
+ "tp": 2,
41
+ "fp": 0,
42
+ "fn": 0
43
+ }
44
+ }
45
+ }
eval/q8_irish_gov_chatbot_gap_holdout_v2.json ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "model": "release/IrishCore-GlobalPointer-ContextPII-4L-122M-v1-rc4",
3
+ "input": "eval/irish_gov_chatbot_gap_holdout_v2.jsonl",
4
+ "loader_type": "global_pointer_onnx",
5
+ "examples": 160,
6
+ "min_score": 0.5,
7
+ "iou_threshold": 0.5,
8
+ "elapsed_seconds": 0.9240270049776882,
9
+ "examples_per_second": 173.15511250005449,
10
+ "overall": {
11
+ "precision": 1.0,
12
+ "recall": 1.0,
13
+ "f1": 1.0,
14
+ "tp": 652,
15
+ "fp": 0,
16
+ "fn": 0
17
+ },
18
+ "by_label": {
19
+ "ACCOUNT_NUMBER": {
20
+ "precision": 1.0,
21
+ "recall": 1.0,
22
+ "f1": 1.0,
23
+ "tp": 38,
24
+ "fp": 0,
25
+ "fn": 0
26
+ },
27
+ "EMAIL": {
28
+ "precision": 1.0,
29
+ "recall": 1.0,
30
+ "f1": 1.0,
31
+ "tp": 104,
32
+ "fp": 0,
33
+ "fn": 0
34
+ },
35
+ "FIRST_NAME": {
36
+ "precision": 1.0,
37
+ "recall": 1.0,
38
+ "f1": 1.0,
39
+ "tp": 68,
40
+ "fp": 0,
41
+ "fn": 0
42
+ },
43
+ "LAST_NAME": {
44
+ "precision": 1.0,
45
+ "recall": 1.0,
46
+ "f1": 1.0,
47
+ "tp": 68,
48
+ "fp": 0,
49
+ "fn": 0
50
+ },
51
+ "PASSPORT_NUMBER": {
52
+ "precision": 1.0,
53
+ "recall": 1.0,
54
+ "f1": 1.0,
55
+ "tp": 33,
56
+ "fp": 0,
57
+ "fn": 0
58
+ },
59
+ "PHONE_NUMBER": {
60
+ "precision": 1.0,
61
+ "recall": 1.0,
62
+ "f1": 1.0,
63
+ "tp": 101,
64
+ "fp": 0,
65
+ "fn": 0
66
+ },
67
+ "POSTCODE": {
68
+ "precision": 1.0,
69
+ "recall": 1.0,
70
+ "f1": 1.0,
71
+ "tp": 101,
72
+ "fp": 0,
73
+ "fn": 0
74
+ },
75
+ "PPSN": {
76
+ "precision": 1.0,
77
+ "recall": 1.0,
78
+ "f1": 1.0,
79
+ "tp": 101,
80
+ "fp": 0,
81
+ "fn": 0
82
+ },
83
+ "SWIFT_BIC": {
84
+ "precision": 1.0,
85
+ "recall": 1.0,
86
+ "f1": 1.0,
87
+ "tp": 38,
88
+ "fp": 0,
89
+ "fn": 0
90
+ }
91
+ }
92
+ }
eval/q8_irish_gov_chatbot_redteam_v2.json ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "model": "release/IrishCore-GlobalPointer-ContextPII-4L-122M-v1-rc4",
3
+ "input": "eval/irish_gov_chatbot_redteam_v2.jsonl",
4
+ "loader_type": "global_pointer_onnx",
5
+ "examples": 25,
6
+ "min_score": 0.5,
7
+ "iou_threshold": 0.5,
8
+ "elapsed_seconds": 0.15474425093270838,
9
+ "examples_per_second": 161.55689047776917,
10
+ "overall": {
11
+ "precision": 0.9726027397260274,
12
+ "recall": 1.0,
13
+ "f1": 0.9861111111111112,
14
+ "tp": 71,
15
+ "fp": 2,
16
+ "fn": 0
17
+ },
18
+ "by_label": {
19
+ "ACCOUNT_NUMBER": {
20
+ "precision": 1.0,
21
+ "recall": 1.0,
22
+ "f1": 1.0,
23
+ "tp": 4,
24
+ "fp": 0,
25
+ "fn": 0
26
+ },
27
+ "BANK_ROUTING_NUMBER": {
28
+ "precision": 1.0,
29
+ "recall": 1.0,
30
+ "f1": 1.0,
31
+ "tp": 1,
32
+ "fp": 0,
33
+ "fn": 0
34
+ },
35
+ "CREDIT_DEBIT_CARD": {
36
+ "precision": 1.0,
37
+ "recall": 1.0,
38
+ "f1": 1.0,
39
+ "tp": 1,
40
+ "fp": 0,
41
+ "fn": 0
42
+ },
43
+ "EMAIL": {
44
+ "precision": 1.0,
45
+ "recall": 1.0,
46
+ "f1": 1.0,
47
+ "tp": 10,
48
+ "fp": 0,
49
+ "fn": 0
50
+ },
51
+ "FIRST_NAME": {
52
+ "precision": 1.0,
53
+ "recall": 1.0,
54
+ "f1": 1.0,
55
+ "tp": 7,
56
+ "fp": 0,
57
+ "fn": 0
58
+ },
59
+ "LAST_NAME": {
60
+ "precision": 1.0,
61
+ "recall": 1.0,
62
+ "f1": 1.0,
63
+ "tp": 7,
64
+ "fp": 0,
65
+ "fn": 0
66
+ },
67
+ "PASSPORT_NUMBER": {
68
+ "precision": 1.0,
69
+ "recall": 1.0,
70
+ "f1": 1.0,
71
+ "tp": 2,
72
+ "fp": 0,
73
+ "fn": 0
74
+ },
75
+ "PHONE_NUMBER": {
76
+ "precision": 1.0,
77
+ "recall": 1.0,
78
+ "f1": 1.0,
79
+ "tp": 17,
80
+ "fp": 0,
81
+ "fn": 0
82
+ },
83
+ "POSTCODE": {
84
+ "precision": 1.0,
85
+ "recall": 1.0,
86
+ "f1": 1.0,
87
+ "tp": 7,
88
+ "fp": 0,
89
+ "fn": 0
90
+ },
91
+ "PPSN": {
92
+ "precision": 1.0,
93
+ "recall": 1.0,
94
+ "f1": 1.0,
95
+ "tp": 11,
96
+ "fp": 0,
97
+ "fn": 0
98
+ },
99
+ "SWIFT_BIC": {
100
+ "precision": 1.0,
101
+ "recall": 1.0,
102
+ "f1": 1.0,
103
+ "tp": 4,
104
+ "fp": 0,
105
+ "fn": 0
106
+ }
107
+ }
108
+ }
eval/q8_irish_gov_contact_policy_v1.json ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "model": "release/IrishCore-GlobalPointer-ContextPII-4L-122M-v1-rc4",
3
+ "input": "eval/irish_gov_contact_policy_v1.jsonl",
4
+ "loader_type": "global_pointer_onnx",
5
+ "examples": 12,
6
+ "min_score": 0.5,
7
+ "iou_threshold": 0.5,
8
+ "elapsed_seconds": 0.06185738497879356,
9
+ "examples_per_second": 193.9946217272834,
10
+ "overall": {
11
+ "precision": 1.0,
12
+ "recall": 1.0,
13
+ "f1": 1.0,
14
+ "tp": 30,
15
+ "fp": 0,
16
+ "fn": 0
17
+ },
18
+ "by_label": {
19
+ "CITY": {
20
+ "precision": 1.0,
21
+ "recall": 1.0,
22
+ "f1": 1.0,
23
+ "tp": 4,
24
+ "fp": 0,
25
+ "fn": 0
26
+ },
27
+ "COUNTY": {
28
+ "precision": 1.0,
29
+ "recall": 1.0,
30
+ "f1": 1.0,
31
+ "tp": 2,
32
+ "fp": 0,
33
+ "fn": 0
34
+ },
35
+ "DATE_OF_BIRTH": {
36
+ "precision": 1.0,
37
+ "recall": 1.0,
38
+ "f1": 1.0,
39
+ "tp": 4,
40
+ "fp": 0,
41
+ "fn": 0
42
+ },
43
+ "EMAIL": {
44
+ "precision": 1.0,
45
+ "recall": 1.0,
46
+ "f1": 1.0,
47
+ "tp": 4,
48
+ "fp": 0,
49
+ "fn": 0
50
+ },
51
+ "PHONE_NUMBER": {
52
+ "precision": 1.0,
53
+ "recall": 1.0,
54
+ "f1": 1.0,
55
+ "tp": 8,
56
+ "fp": 0,
57
+ "fn": 0
58
+ },
59
+ "POSTCODE": {
60
+ "precision": 1.0,
61
+ "recall": 1.0,
62
+ "f1": 1.0,
63
+ "tp": 4,
64
+ "fp": 0,
65
+ "fn": 0
66
+ },
67
+ "STREET_ADDRESS": {
68
+ "precision": 1.0,
69
+ "recall": 1.0,
70
+ "f1": 1.0,
71
+ "tp": 4,
72
+ "fp": 0,
73
+ "fn": 0
74
+ }
75
+ }
76
+ }
eval/q8_irish_gov_user_contextual_policy_v1.json ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "model": "release/IrishCore-GlobalPointer-ContextPII-4L-122M-v1-rc5",
3
+ "input": "eval/irish_gov_user_contextual_policy_v1.jsonl",
4
+ "loader_type": "global_pointer_onnx",
5
+ "examples": 2,
6
+ "min_score": 0.5,
7
+ "profile": "default",
8
+ "iou_threshold": 0.5,
9
+ "elapsed_seconds": 0.03446952090598643,
10
+ "examples_per_second": 58.022274387128306,
11
+ "overall": {
12
+ "precision": 1.0,
13
+ "recall": 1.0,
14
+ "f1": 1.0,
15
+ "tp": 8,
16
+ "fp": 0,
17
+ "fn": 0
18
+ },
19
+ "by_label": {
20
+ "AGE": {
21
+ "precision": 1.0,
22
+ "recall": 1.0,
23
+ "f1": 1.0,
24
+ "tp": 2,
25
+ "fp": 0,
26
+ "fn": 0
27
+ },
28
+ "CITY": {
29
+ "precision": 1.0,
30
+ "recall": 1.0,
31
+ "f1": 1.0,
32
+ "tp": 1,
33
+ "fp": 0,
34
+ "fn": 0
35
+ },
36
+ "COUNTY": {
37
+ "precision": 1.0,
38
+ "recall": 1.0,
39
+ "f1": 1.0,
40
+ "tp": 1,
41
+ "fp": 0,
42
+ "fn": 0
43
+ },
44
+ "POSTCODE": {
45
+ "precision": 1.0,
46
+ "recall": 1.0,
47
+ "f1": 1.0,
48
+ "tp": 2,
49
+ "fp": 0,
50
+ "fn": 0
51
+ },
52
+ "STREET_ADDRESS": {
53
+ "precision": 1.0,
54
+ "recall": 1.0,
55
+ "f1": 1.0,
56
+ "tp": 2,
57
+ "fp": 0,
58
+ "fn": 0
59
+ }
60
+ }
61
+ }
eval/q8_multilingual_ppsn_v1_all.json ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "model": "release/IrishCore-GlobalPointer-ContextPII-4L-122M-v1-rc4",
3
+ "input": "eval/multilingual_ppsn_v1_all.jsonl",
4
+ "loader_type": "global_pointer_onnx",
5
+ "examples": 168,
6
+ "min_score": 0.5,
7
+ "iou_threshold": 0.5,
8
+ "elapsed_seconds": 0.4859596050810069,
9
+ "examples_per_second": 345.70774657699235,
10
+ "overall": {
11
+ "precision": 0.875,
12
+ "recall": 1.0,
13
+ "f1": 0.9333333333333333,
14
+ "tp": 84,
15
+ "fp": 12,
16
+ "fn": 0
17
+ },
18
+ "by_label": {
19
+ "PPSN": {
20
+ "precision": 1.0,
21
+ "recall": 1.0,
22
+ "f1": 1.0,
23
+ "tp": 84,
24
+ "fp": 0,
25
+ "fn": 0
26
+ }
27
+ }
28
+ }
eval/q8_runtime_profile_source.json ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "model": "models/irishcore-globalpointer-contextpii-4l-b02-distill-e020_onnx_q8",
3
+ "input": "eval/runtime_profile_source.jsonl",
4
+ "loader_type": "global_pointer_onnx",
5
+ "examples": 3223,
6
+ "min_score": 0.5,
7
+ "iou_threshold": 0.5,
8
+ "elapsed_seconds": 20.13922613603063,
9
+ "examples_per_second": 160.0359407173945,
10
+ "overall": {
11
+ "precision": 0.7348249430287963,
12
+ "recall": 1.0,
13
+ "f1": 0.8471459278719847,
14
+ "tp": 3547,
15
+ "fp": 1280,
16
+ "fn": 0
17
+ },
18
+ "by_label": {
19
+ "PPSN": {
20
+ "precision": 0.9383597883597884,
21
+ "recall": 1.0,
22
+ "f1": 0.9681998089258906,
23
+ "tp": 3547,
24
+ "fp": 233,
25
+ "fn": 0
26
+ }
27
+ }
28
+ }
eval/role_profile_usage.md ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Role-Aware Usage
2
+
3
+ Use the model per message, not on a flattened whole transcript.
4
+
5
+ - `--role user` or `--role search_query`: uses the default contextual profile. This is the intended path for citizen turns and search queries.
6
+ - `--role assistant`: switches to the conservative `assistant_public` profile. This keeps direct structured identifiers such as `PHONE_NUMBER`, `EMAIL`, and `POSTCODE`, but suppresses contextual/demographic labels such as `AGE`, `DATE_OF_BIRTH`, `CITY`, `COUNTY`, `STREET_ADDRESS`, `FIRST_NAME`, and `LAST_NAME` in public explanatory prose.
7
+ - `--profile ...` overrides the role-derived default if you need explicit control.
8
+
9
+ Examples:
10
+
11
+ ```bash
12
+ python3 inference_mask_onnx.py --model temsa/IrishCore-GlobalPointer-ContextPII-4L-122M-v1-rc6 --role user --text "I'm 76 and I live at Rose Cottage, Galway Road, Loughrea, Galway County (H62 HF96)."
13
+
14
+ python3 inference_mask_onnx.py --model temsa/IrishCore-GlobalPointer-ContextPII-4L-122M-v1-rc6 --role assistant --text "If you need to contact the Carer’s Allowance Section directly: Phone: 0818 927 999. Email: carers@example.gov.ie. Address: ... N39 E4E0."
15
+ ```
global_pointer_meta.json ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "base_model": "models/irishcore-globalpointer-contextpii-4l-student-init-v1",
3
+ "init_from": "",
4
+ "init_encoder_from": "",
5
+ "init_mode": "full_global_pointer",
6
+ "label_names": [
7
+ "ACCOUNT_NUMBER",
8
+ "AGE",
9
+ "BANK_ROUTING_NUMBER",
10
+ "CITY",
11
+ "COUNTY",
12
+ "CREDIT_DEBIT_CARD",
13
+ "DATE_OF_BIRTH",
14
+ "EMAIL",
15
+ "FIRST_NAME",
16
+ "LAST_NAME",
17
+ "PASSPORT_NUMBER",
18
+ "PHONE_NUMBER",
19
+ "POSTCODE",
20
+ "PPSN",
21
+ "STREET_ADDRESS",
22
+ "SWIFT_BIC"
23
+ ],
24
+ "max_length": 128,
25
+ "task": "Irish core PII global-pointer span extraction",
26
+ "freeze_layers": 1,
27
+ "span_positive_weight": 8.0,
28
+ "global_pointer_head_size": 64,
29
+ "global_pointer_use_rope": true,
30
+ "global_pointer_negative_ratio": 16,
31
+ "global_pointer_min_negatives": 256,
32
+ "boundary_smoothing": 0.0,
33
+ "teacher_model": "release/IrishCore-GlobalPointer-ContextPII-135M-v1-rc22",
34
+ "distill_weight": 0.2,
35
+ "fitted_label_max_span_tokens": {
36
+ "ACCOUNT_NUMBER": 19,
37
+ "AGE": 8,
38
+ "BANK_ROUTING_NUMBER": 6,
39
+ "CITY": 8,
40
+ "COUNTY": 10,
41
+ "CREDIT_DEBIT_CARD": 12,
42
+ "DATE_OF_BIRTH": 8,
43
+ "EMAIL": 16,
44
+ "FIRST_NAME": 6,
45
+ "LAST_NAME": 8,
46
+ "PASSPORT_NUMBER": 8,
47
+ "PHONE_NUMBER": 10,
48
+ "POSTCODE": 8,
49
+ "PPSN": 9,
50
+ "STREET_ADDRESS": 13,
51
+ "SWIFT_BIC": 8
52
+ },
53
+ "train_examples": 11078,
54
+ "valid_examples": 1436,
55
+ "test_examples": 1404,
56
+ "data": "data/irish_core_globalpointer_focus_extended_distill_v3_contextonly"
57
+ }
inference_mask.py ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ from __future__ import annotations
3
+
4
+ import argparse
5
+ import json
6
+ import os
7
+
8
+ os.environ.setdefault("TRANSFORMERS_NO_TF", "1")
9
+ os.environ.setdefault("TRANSFORMERS_NO_FLAX", "1")
10
+ os.environ.setdefault("TRANSFORMERS_NO_TORCHVISION", "1")
11
+ os.environ["USE_TF"] = "0"
12
+ os.environ["USE_FLAX"] = "0"
13
+ os.environ["USE_TORCH"] = "1"
14
+
15
+ import torch
16
+ from transformers import AutoConfig
17
+
18
+ from common import decode_span_matrix, safe_auto_tokenizer
19
+ from model import IrishCoreGlobalPointerModel
20
+
21
+
22
+ def replacement(label: str) -> str:
23
+ return f"[PII:{label}]"
24
+
25
+
26
+ def mask_text(text: str, spans: list[dict]) -> str:
27
+ out = text
28
+ for span in sorted(spans, key=lambda item: (item["start"], item["end"]), reverse=True):
29
+ out = out[: span["start"]] + replacement(span["label"]) + out[span["end"] :]
30
+ return out
31
+
32
+
33
+ def predict(text: str, model, tokenizer, min_score: float, profile: str):
34
+ encoded = tokenizer(text, return_offsets_mapping=True, return_tensors="pt", truncation=True)
35
+ offsets = [tuple(item) for item in encoded.pop("offset_mapping")[0].tolist()]
36
+ device = next(model.parameters()).device
37
+ encoded = {key: value.to(device) for key, value in encoded.items()}
38
+ with torch.no_grad():
39
+ output = model(**encoded)
40
+ span_scores = torch.sigmoid(output.span_logits[0]).cpu().numpy()
41
+ spans = decode_span_matrix(text, offsets, span_scores, model.config, min_score, profile=profile)
42
+ for span in spans:
43
+ span["replacement"] = replacement(span["label"])
44
+ return spans
45
+
46
+
47
+ def main() -> None:
48
+ parser = argparse.ArgumentParser()
49
+ parser.add_argument("--model", required=True)
50
+ parser.add_argument("--text", required=True)
51
+ parser.add_argument("--min-score", type=float, default=0.5)
52
+ parser.add_argument("--role", choices=["user", "assistant", "search_query"], default=None)
53
+ parser.add_argument("--profile", default=None, choices=["default", "assistant_public", "assistant", "chatbot_assistant"])
54
+ parser.add_argument("--device", choices=["auto", "cpu", "cuda"], default="auto")
55
+ parser.add_argument("--json", action="store_true")
56
+ args = parser.parse_args()
57
+
58
+ tokenizer = safe_auto_tokenizer(args.model)
59
+ config = AutoConfig.from_pretrained(args.model)
60
+ model = IrishCoreGlobalPointerModel.from_pretrained(args.model, config=config)
61
+ if args.device == "auto":
62
+ device = "cuda" if torch.cuda.is_available() else "cpu"
63
+ else:
64
+ device = args.device
65
+ model.to(device)
66
+ model.eval()
67
+
68
+ profile = args.profile or ("assistant_public" if args.role == "assistant" else "default")
69
+ spans = predict(args.text, model, tokenizer, args.min_score, profile)
70
+ result = {
71
+ "model": args.model,
72
+ "backend": "transformers_global_pointer",
73
+ "min_score": args.min_score,
74
+ "role": args.role,
75
+ "profile": profile,
76
+ "spans": spans,
77
+ "masked_text": mask_text(args.text, spans),
78
+ }
79
+ if args.json:
80
+ print(json.dumps(result, indent=2, ensure_ascii=False))
81
+ else:
82
+ print(result["masked_text"])
83
+
84
+
85
+ if __name__ == "__main__":
86
+ main()
inference_mask_onnx.py ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ from __future__ import annotations
3
+
4
+ import argparse
5
+ import json
6
+ import os
7
+
8
+ os.environ.setdefault("TRANSFORMERS_NO_TF", "1")
9
+ os.environ.setdefault("TRANSFORMERS_NO_FLAX", "1")
10
+ os.environ.setdefault("TRANSFORMERS_NO_TORCHVISION", "1")
11
+ os.environ["USE_TF"] = "0"
12
+ os.environ["USE_FLAX"] = "0"
13
+ os.environ["USE_TORCH"] = "1"
14
+
15
+ from common import decode_span_matrix, load_onnx_session, run_onnx_span, sigmoid_np
16
+
17
+
18
+ def replacement(label: str) -> str:
19
+ return f"[PII:{label}]"
20
+
21
+
22
+ def mask_text(text: str, spans: list[dict]) -> str:
23
+ out = text
24
+ for span in sorted(spans, key=lambda item: (item["start"], item["end"]), reverse=True):
25
+ out = out[: span["start"]] + replacement(span["label"]) + out[span["end"] :]
26
+ return out
27
+
28
+
29
+ def predict(text: str, session, tokenizer, config, min_score: float, profile: str):
30
+ encoded = tokenizer(text, return_offsets_mapping=True, return_tensors="np", truncation=True)
31
+ offsets = [tuple(item) for item in encoded["offset_mapping"][0].tolist()]
32
+ span_logits = run_onnx_span(session, encoded)
33
+ span_scores = sigmoid_np(span_logits[0])
34
+ spans = decode_span_matrix(text, offsets, span_scores, config, min_score, profile=profile)
35
+ for span in spans:
36
+ span["replacement"] = replacement(span["label"])
37
+ return spans
38
+
39
+
40
+ def main() -> None:
41
+ parser = argparse.ArgumentParser()
42
+ parser.add_argument("--model", required=True)
43
+ parser.add_argument("--text", required=True)
44
+ parser.add_argument("--min-score", type=float, default=0.5)
45
+ parser.add_argument("--role", choices=["user", "assistant", "search_query"], default=None)
46
+ parser.add_argument("--profile", default=None, choices=["default", "assistant_public", "assistant", "chatbot_assistant"])
47
+ parser.add_argument("--json", action="store_true")
48
+ args = parser.parse_args()
49
+
50
+ session, tokenizer, config = load_onnx_session(args.model, onnx_file="model_quantized.onnx", onnx_subfolder="onnx")
51
+ profile = args.profile or ("assistant_public" if args.role == "assistant" else "default")
52
+ spans = predict(args.text, session, tokenizer, config, args.min_score, profile)
53
+ result = {
54
+ "model": args.model,
55
+ "backend": "onnx_global_pointer_q8",
56
+ "min_score": args.min_score,
57
+ "role": args.role,
58
+ "profile": profile,
59
+ "spans": spans,
60
+ "masked_text": mask_text(args.text, spans),
61
+ }
62
+ if args.json:
63
+ print(json.dumps(result, indent=2, ensure_ascii=False))
64
+ else:
65
+ print(result["masked_text"])
66
+
67
+
68
+ if __name__ == "__main__":
69
+ main()
model.py ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ from __future__ import annotations
3
+
4
+ import math
5
+ from dataclasses import dataclass
6
+ from pathlib import Path
7
+ import sys
8
+ from typing import Optional
9
+
10
+ import torch
11
+ import torch.nn as nn
12
+ import torch.nn.functional as F
13
+ from transformers import AutoConfig, AutoModel, PreTrainedModel
14
+ from transformers.utils import ModelOutput
15
+
16
+ ROOT_DIR = Path(__file__).resolve().parents[2]
17
+ if str(ROOT_DIR) not in sys.path:
18
+ sys.path.insert(0, str(ROOT_DIR))
19
+
20
+ try:
21
+ from ..irish_core_span_raw_only.model import hidden_size_from_config
22
+ except ImportError:
23
+ from experiments.irish_core_span_raw_only.model import hidden_size_from_config
24
+
25
+
26
+ @dataclass
27
+ class GlobalPointerSpanOutput(ModelOutput):
28
+ loss: Optional[torch.Tensor] = None
29
+ span_logits: Optional[torch.Tensor] = None
30
+
31
+
32
+ def build_rope_cache(seq_len: int, head_size: int, device, dtype) -> tuple[torch.Tensor, torch.Tensor]:
33
+ position = torch.arange(seq_len, device=device, dtype=dtype).unsqueeze(-1)
34
+ index = torch.arange(head_size // 2, device=device, dtype=dtype)
35
+ theta = torch.pow(torch.tensor(10000.0, device=device, dtype=dtype), -2.0 * index / head_size)
36
+ angles = position * theta
37
+ sin_base = torch.sin(angles)
38
+ cos_base = torch.cos(angles)
39
+ sin = torch.stack((sin_base, sin_base), dim=-1).reshape(seq_len, head_size)
40
+ cos = torch.stack((cos_base, cos_base), dim=-1).reshape(seq_len, head_size)
41
+ return sin, cos
42
+
43
+
44
+ def apply_rope(x: torch.Tensor, sin: torch.Tensor, cos: torch.Tensor) -> torch.Tensor:
45
+ x_even = x[..., ::2]
46
+ x_odd = x[..., 1::2]
47
+ rotated = torch.stack((-x_odd, x_even), dim=-1).reshape_as(x)
48
+ return x * cos.unsqueeze(0).unsqueeze(2) + rotated * sin.unsqueeze(0).unsqueeze(2)
49
+
50
+
51
+ class IrishCoreGlobalPointerModel(PreTrainedModel):
52
+ config_class = AutoConfig
53
+ base_model_prefix = "encoder"
54
+
55
+ def __init__(self, config):
56
+ super().__init__(config)
57
+ self.encoder = AutoModel.from_config(config)
58
+ self.num_span_labels = int(getattr(config, "num_span_labels"))
59
+ self.head_size = int(getattr(config, "global_pointer_head_size", 64))
60
+ self.use_rope = bool(getattr(config, "global_pointer_use_rope", True))
61
+ self.negative_ratio = int(getattr(config, "global_pointer_negative_ratio", 16))
62
+ self.min_negatives = int(getattr(config, "global_pointer_min_negatives", 256))
63
+ hidden_size = hidden_size_from_config(config)
64
+ dropout = float(getattr(config, "seq_classif_dropout", getattr(config, "dropout", 0.1)))
65
+ self.dropout = nn.Dropout(dropout)
66
+ self.proj = nn.Linear(hidden_size, self.num_span_labels * self.head_size * 2)
67
+ pos_weight = float(getattr(config, "span_positive_weight", 6.0))
68
+ self.register_buffer("loss_pos_weight", torch.full((self.num_span_labels,), pos_weight), persistent=False)
69
+ self.post_init()
70
+
71
+ def forward(
72
+ self,
73
+ input_ids=None,
74
+ attention_mask=None,
75
+ token_type_ids=None,
76
+ span_labels=None,
77
+ token_mask=None,
78
+ **kwargs,
79
+ ) -> GlobalPointerSpanOutput:
80
+ encoder_kwargs = {
81
+ "input_ids": input_ids,
82
+ "attention_mask": attention_mask,
83
+ **kwargs,
84
+ }
85
+ if token_type_ids is not None and getattr(self.config, "model_type", "") not in {"distilbert", "roberta"}:
86
+ encoder_kwargs["token_type_ids"] = token_type_ids
87
+ outputs = self.encoder(**encoder_kwargs)
88
+ hidden = self.dropout(outputs.last_hidden_state)
89
+ batch_size, seq_len, _ = hidden.shape
90
+
91
+ projected = self.proj(hidden).view(batch_size, seq_len, self.num_span_labels, self.head_size * 2)
92
+ query, key = torch.chunk(projected, 2, dim=-1)
93
+
94
+ if self.use_rope:
95
+ sin, cos = build_rope_cache(seq_len, self.head_size, hidden.device, hidden.dtype)
96
+ query = apply_rope(query, sin, cos)
97
+ key = apply_rope(key, sin, cos)
98
+
99
+ span_logits = torch.einsum("bshd,bthd->bhst", query, key) / math.sqrt(self.head_size)
100
+
101
+ if token_mask is None:
102
+ token_mask = attention_mask
103
+ if token_mask is None:
104
+ token_mask = torch.ones((batch_size, seq_len), device=hidden.device, dtype=hidden.dtype)
105
+ token_mask = token_mask.to(hidden.dtype)
106
+ pair_mask = token_mask[:, None, :, None] * token_mask[:, None, None, :]
107
+ upper_mask = torch.triu(torch.ones((seq_len, seq_len), device=hidden.device, dtype=hidden.dtype))
108
+ pair_mask = pair_mask * upper_mask.unsqueeze(0).unsqueeze(0)
109
+ masked_logits = span_logits.masked_fill(pair_mask <= 0.0, -1e4)
110
+
111
+ loss = None
112
+ if span_labels is not None:
113
+ targets = span_labels.float()
114
+ pos_weight = self.loss_pos_weight.to(hidden.device).view(1, self.num_span_labels, 1, 1)
115
+ raw_loss = F.binary_cross_entropy_with_logits(span_logits, targets, reduction="none", pos_weight=pos_weight)
116
+ valid_mask = pair_mask > 0.0
117
+ positive_mask = (targets > 0.0) & valid_mask
118
+ negative_mask = (~positive_mask) & valid_mask
119
+
120
+ positive_loss = raw_loss.masked_select(positive_mask)
121
+ negative_loss = raw_loss.masked_select(negative_mask)
122
+ if negative_loss.numel() > 0 and self.negative_ratio > 0:
123
+ positive_count = int(positive_mask.sum().item())
124
+ keep_negatives = max(self.min_negatives, positive_count * self.negative_ratio)
125
+ keep_negatives = min(keep_negatives, negative_loss.numel())
126
+ negative_loss = torch.topk(negative_loss, keep_negatives).values
127
+
128
+ parts = []
129
+ if positive_loss.numel() > 0:
130
+ parts.append(positive_loss.mean())
131
+ if negative_loss.numel() > 0:
132
+ parts.append(negative_loss.mean())
133
+ loss = sum(parts) / len(parts) if parts else raw_loss.sum() * 0.0
134
+
135
+ return GlobalPointerSpanOutput(loss=loss, span_logits=masked_logits)
onnx/config.json ADDED
@@ -0,0 +1,318 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "activation": "gelu",
3
+ "architectures": [
4
+ "IrishCoreGlobalPointerModel"
5
+ ],
6
+ "attention_dropout": 0.1,
7
+ "dim": 768,
8
+ "dropout": 0.1,
9
+ "dtype": "float32",
10
+ "global_pointer_head_size": 64,
11
+ "global_pointer_min_negatives": 256,
12
+ "global_pointer_negative_ratio": 16,
13
+ "global_pointer_use_rope": true,
14
+ "hidden_dim": 3072,
15
+ "id2label": {
16
+ "0": "O",
17
+ "1": "B-account_number",
18
+ "2": "B-age",
19
+ "3": "B-api_key",
20
+ "4": "B-bank_routing_number",
21
+ "5": "B-biometric_identifier",
22
+ "6": "B-blood_type",
23
+ "7": "B-certificate_license_number",
24
+ "8": "B-city",
25
+ "9": "B-company_name",
26
+ "10": "B-coordinate",
27
+ "11": "B-country",
28
+ "12": "B-county",
29
+ "13": "B-credit_debit_card",
30
+ "14": "B-customer_id",
31
+ "15": "B-cvv",
32
+ "16": "B-date",
33
+ "17": "B-date_of_birth",
34
+ "18": "B-date_time",
35
+ "19": "B-device_identifier",
36
+ "20": "B-education_level",
37
+ "21": "B-email",
38
+ "22": "B-employee_id",
39
+ "23": "B-employment_status",
40
+ "24": "B-fax_number",
41
+ "25": "B-first_name",
42
+ "26": "B-gender",
43
+ "27": "B-health_plan_beneficiary_number",
44
+ "28": "B-http_cookie",
45
+ "29": "B-ipv4",
46
+ "30": "B-ipv6",
47
+ "31": "B-language",
48
+ "32": "B-last_name",
49
+ "33": "B-license_plate",
50
+ "34": "B-mac_address",
51
+ "35": "B-medical_record_number",
52
+ "36": "B-occupation",
53
+ "37": "B-password",
54
+ "38": "B-phone_number",
55
+ "39": "B-pin",
56
+ "40": "B-political_view",
57
+ "41": "B-postcode",
58
+ "42": "B-race_ethnicity",
59
+ "43": "B-religious_belief",
60
+ "44": "B-sexuality",
61
+ "45": "B-ssn",
62
+ "46": "B-state",
63
+ "47": "B-street_address",
64
+ "48": "B-swift_bic",
65
+ "49": "B-tax_id",
66
+ "50": "B-time",
67
+ "51": "B-unique_id",
68
+ "52": "B-url",
69
+ "53": "B-user_name",
70
+ "54": "B-vehicle_identifier",
71
+ "55": "I-account_number",
72
+ "56": "I-api_key",
73
+ "57": "I-biometric_identifier",
74
+ "58": "I-blood_type",
75
+ "59": "I-certificate_license_number",
76
+ "60": "I-city",
77
+ "61": "I-company_name",
78
+ "62": "I-coordinate",
79
+ "63": "I-country",
80
+ "64": "I-county",
81
+ "65": "I-credit_debit_card",
82
+ "66": "I-customer_id",
83
+ "67": "I-date",
84
+ "68": "I-date_of_birth",
85
+ "69": "I-date_time",
86
+ "70": "I-device_identifier",
87
+ "71": "I-education_level",
88
+ "72": "I-email",
89
+ "73": "I-employee_id",
90
+ "74": "I-employment_status",
91
+ "75": "I-fax_number",
92
+ "76": "I-first_name",
93
+ "77": "I-gender",
94
+ "78": "I-health_plan_beneficiary_number",
95
+ "79": "I-http_cookie",
96
+ "80": "I-ipv4",
97
+ "81": "I-ipv6",
98
+ "82": "I-language",
99
+ "83": "I-last_name",
100
+ "84": "I-license_plate",
101
+ "85": "I-mac_address",
102
+ "86": "I-medical_record_number",
103
+ "87": "I-occupation",
104
+ "88": "I-password",
105
+ "89": "I-phone_number",
106
+ "90": "I-pin",
107
+ "91": "I-political_view",
108
+ "92": "I-postcode",
109
+ "93": "I-race_ethnicity",
110
+ "94": "I-religious_belief",
111
+ "95": "I-sexuality",
112
+ "96": "I-ssn",
113
+ "97": "I-state",
114
+ "98": "I-street_address",
115
+ "99": "I-swift_bic",
116
+ "100": "I-tax_id",
117
+ "101": "I-time",
118
+ "102": "I-unique_id",
119
+ "103": "I-url",
120
+ "104": "I-user_name",
121
+ "105": "I-vehicle_identifier"
122
+ },
123
+ "initializer_range": 0.02,
124
+ "label2id": {
125
+ "B-account_number": 1,
126
+ "B-age": 2,
127
+ "B-api_key": 3,
128
+ "B-bank_routing_number": 4,
129
+ "B-biometric_identifier": 5,
130
+ "B-blood_type": 6,
131
+ "B-certificate_license_number": 7,
132
+ "B-city": 8,
133
+ "B-company_name": 9,
134
+ "B-coordinate": 10,
135
+ "B-country": 11,
136
+ "B-county": 12,
137
+ "B-credit_debit_card": 13,
138
+ "B-customer_id": 14,
139
+ "B-cvv": 15,
140
+ "B-date": 16,
141
+ "B-date_of_birth": 17,
142
+ "B-date_time": 18,
143
+ "B-device_identifier": 19,
144
+ "B-education_level": 20,
145
+ "B-email": 21,
146
+ "B-employee_id": 22,
147
+ "B-employment_status": 23,
148
+ "B-fax_number": 24,
149
+ "B-first_name": 25,
150
+ "B-gender": 26,
151
+ "B-health_plan_beneficiary_number": 27,
152
+ "B-http_cookie": 28,
153
+ "B-ipv4": 29,
154
+ "B-ipv6": 30,
155
+ "B-language": 31,
156
+ "B-last_name": 32,
157
+ "B-license_plate": 33,
158
+ "B-mac_address": 34,
159
+ "B-medical_record_number": 35,
160
+ "B-occupation": 36,
161
+ "B-password": 37,
162
+ "B-phone_number": 38,
163
+ "B-pin": 39,
164
+ "B-political_view": 40,
165
+ "B-postcode": 41,
166
+ "B-race_ethnicity": 42,
167
+ "B-religious_belief": 43,
168
+ "B-sexuality": 44,
169
+ "B-ssn": 45,
170
+ "B-state": 46,
171
+ "B-street_address": 47,
172
+ "B-swift_bic": 48,
173
+ "B-tax_id": 49,
174
+ "B-time": 50,
175
+ "B-unique_id": 51,
176
+ "B-url": 52,
177
+ "B-user_name": 53,
178
+ "B-vehicle_identifier": 54,
179
+ "I-account_number": 55,
180
+ "I-api_key": 56,
181
+ "I-biometric_identifier": 57,
182
+ "I-blood_type": 58,
183
+ "I-certificate_license_number": 59,
184
+ "I-city": 60,
185
+ "I-company_name": 61,
186
+ "I-coordinate": 62,
187
+ "I-country": 63,
188
+ "I-county": 64,
189
+ "I-credit_debit_card": 65,
190
+ "I-customer_id": 66,
191
+ "I-date": 67,
192
+ "I-date_of_birth": 68,
193
+ "I-date_time": 69,
194
+ "I-device_identifier": 70,
195
+ "I-education_level": 71,
196
+ "I-email": 72,
197
+ "I-employee_id": 73,
198
+ "I-employment_status": 74,
199
+ "I-fax_number": 75,
200
+ "I-first_name": 76,
201
+ "I-gender": 77,
202
+ "I-health_plan_beneficiary_number": 78,
203
+ "I-http_cookie": 79,
204
+ "I-ipv4": 80,
205
+ "I-ipv6": 81,
206
+ "I-language": 82,
207
+ "I-last_name": 83,
208
+ "I-license_plate": 84,
209
+ "I-mac_address": 85,
210
+ "I-medical_record_number": 86,
211
+ "I-occupation": 87,
212
+ "I-password": 88,
213
+ "I-phone_number": 89,
214
+ "I-pin": 90,
215
+ "I-political_view": 91,
216
+ "I-postcode": 92,
217
+ "I-race_ethnicity": 93,
218
+ "I-religious_belief": 94,
219
+ "I-sexuality": 95,
220
+ "I-ssn": 96,
221
+ "I-state": 97,
222
+ "I-street_address": 98,
223
+ "I-swift_bic": 99,
224
+ "I-tax_id": 100,
225
+ "I-time": 101,
226
+ "I-unique_id": 102,
227
+ "I-url": 103,
228
+ "I-user_name": 104,
229
+ "I-vehicle_identifier": 105,
230
+ "O": 0
231
+ },
232
+ "max_position_embeddings": 512,
233
+ "model_type": "distilbert",
234
+ "n_heads": 12,
235
+ "n_layers": 4,
236
+ "num_span_labels": 16,
237
+ "output_past": true,
238
+ "pad_token_id": 0,
239
+ "qa_dropout": 0.1,
240
+ "seq_classif_dropout": 0.2,
241
+ "sinusoidal_pos_embds": false,
242
+ "span_label_max_span_tokens": {
243
+ "ACCOUNT_NUMBER": 19,
244
+ "AGE": 8,
245
+ "BANK_ROUTING_NUMBER": 6,
246
+ "CITY": 8,
247
+ "COUNTY": 10,
248
+ "CREDIT_DEBIT_CARD": 12,
249
+ "DATE_OF_BIRTH": 8,
250
+ "EMAIL": 16,
251
+ "FIRST_NAME": 6,
252
+ "LAST_NAME": 8,
253
+ "PASSPORT_NUMBER": 8,
254
+ "PHONE_NUMBER": 10,
255
+ "POSTCODE": 8,
256
+ "PPSN": 9,
257
+ "STREET_ADDRESS": 13,
258
+ "SWIFT_BIC": 8
259
+ },
260
+ "span_label_min_nonspace_chars": {
261
+ "ACCOUNT_NUMBER": 6,
262
+ "AGE": 1,
263
+ "BANK_ROUTING_NUMBER": 6,
264
+ "CITY": 1,
265
+ "COUNTY": 1,
266
+ "CREDIT_DEBIT_CARD": 12,
267
+ "DATE_OF_BIRTH": 1,
268
+ "EMAIL": 6,
269
+ "FIRST_NAME": 2,
270
+ "LAST_NAME": 2,
271
+ "PASSPORT_NUMBER": 7,
272
+ "PHONE_NUMBER": 7,
273
+ "POSTCODE": 6,
274
+ "PPSN": 8,
275
+ "STREET_ADDRESS": 1,
276
+ "SWIFT_BIC": 8
277
+ },
278
+ "span_label_names": [
279
+ "ACCOUNT_NUMBER",
280
+ "AGE",
281
+ "BANK_ROUTING_NUMBER",
282
+ "CITY",
283
+ "COUNTY",
284
+ "CREDIT_DEBIT_CARD",
285
+ "DATE_OF_BIRTH",
286
+ "EMAIL",
287
+ "FIRST_NAME",
288
+ "LAST_NAME",
289
+ "PASSPORT_NUMBER",
290
+ "PHONE_NUMBER",
291
+ "POSTCODE",
292
+ "PPSN",
293
+ "STREET_ADDRESS",
294
+ "SWIFT_BIC"
295
+ ],
296
+ "span_label_thresholds": {
297
+ "ACCOUNT_NUMBER": 0.5,
298
+ "AGE": 0.5,
299
+ "BANK_ROUTING_NUMBER": 0.5,
300
+ "CITY": 0.5,
301
+ "COUNTY": 0.5,
302
+ "CREDIT_DEBIT_CARD": 0.5,
303
+ "DATE_OF_BIRTH": 0.5,
304
+ "EMAIL": 0.5,
305
+ "FIRST_NAME": 0.5,
306
+ "LAST_NAME": 0.5,
307
+ "PASSPORT_NUMBER": 0.5,
308
+ "PHONE_NUMBER": 0.5,
309
+ "POSTCODE": 0.5,
310
+ "PPSN": 0.5,
311
+ "STREET_ADDRESS": 0.5,
312
+ "SWIFT_BIC": 0.5
313
+ },
314
+ "span_positive_weight": 8.0,
315
+ "tie_weights_": true,
316
+ "transformers_version": "4.57.6",
317
+ "vocab_size": 119547
318
+ }
onnx/onnx_export.json ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "source_model": "models/irishcore-globalpointer-contextpii-4l-b02-distill-e020",
3
+ "onnx_path": "models/irishcore-globalpointer-contextpii-4l-b02-distill-e020_onnx/model.onnx",
4
+ "task": "global-pointer-span-extraction",
5
+ "opset": 18,
6
+ "max_length": 256,
7
+ "dynamo": false,
8
+ "output_names": [
9
+ "span_logits"
10
+ ]
11
+ }
onnx/quantization.json ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "source_dir": "models/irishcore-globalpointer-contextpii-4l-b02-distill-e020_onnx",
3
+ "input_model": "models/irishcore-globalpointer-contextpii-4l-b02-distill-e020_onnx_q8/model.onnx",
4
+ "preprocessed_input_model": "models/irishcore-globalpointer-contextpii-4l-b02-distill-e020_onnx_q8/model.preprocessed.onnx",
5
+ "output_model": "models/irishcore-globalpointer-contextpii-4l-b02-distill-e020_onnx_q8/model_quantized.onnx",
6
+ "weight_type": "qint8",
7
+ "per_channel": true,
8
+ "reduce_range": false,
9
+ "preprocess_applied": true,
10
+ "op_types": [
11
+ "MatMul",
12
+ "Gemm",
13
+ "Attention"
14
+ ],
15
+ "copied_assets": [
16
+ "models/irishcore-globalpointer-contextpii-4l-b02-distill-e020_onnx/model.onnx",
17
+ "onnx_export.json",
18
+ "config.json",
19
+ "special_tokens_map.json",
20
+ "tokenizer.json",
21
+ "tokenizer_config.json",
22
+ "vocab.txt"
23
+ ],
24
+ "format": "onnx_dynamic_quantized",
25
+ "task": "token-classification"
26
+ }
onnx/special_tokens_map.json ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cls_token": {
3
+ "content": "[CLS]",
4
+ "lstrip": false,
5
+ "normalized": false,
6
+ "rstrip": false,
7
+ "single_word": false
8
+ },
9
+ "mask_token": {
10
+ "content": "[MASK]",
11
+ "lstrip": false,
12
+ "normalized": false,
13
+ "rstrip": false,
14
+ "single_word": false
15
+ },
16
+ "pad_token": {
17
+ "content": "[PAD]",
18
+ "lstrip": false,
19
+ "normalized": false,
20
+ "rstrip": false,
21
+ "single_word": false
22
+ },
23
+ "sep_token": {
24
+ "content": "[SEP]",
25
+ "lstrip": false,
26
+ "normalized": false,
27
+ "rstrip": false,
28
+ "single_word": false
29
+ },
30
+ "unk_token": {
31
+ "content": "[UNK]",
32
+ "lstrip": false,
33
+ "normalized": false,
34
+ "rstrip": false,
35
+ "single_word": false
36
+ }
37
+ }
onnx/tokenizer.json ADDED
The diff for this file is too large to render. See raw diff
 
onnx/tokenizer_config.json ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "added_tokens_decoder": {
3
+ "0": {
4
+ "content": "[PAD]",
5
+ "lstrip": false,
6
+ "normalized": false,
7
+ "rstrip": false,
8
+ "single_word": false,
9
+ "special": true
10
+ },
11
+ "100": {
12
+ "content": "[UNK]",
13
+ "lstrip": false,
14
+ "normalized": false,
15
+ "rstrip": false,
16
+ "single_word": false,
17
+ "special": true
18
+ },
19
+ "101": {
20
+ "content": "[CLS]",
21
+ "lstrip": false,
22
+ "normalized": false,
23
+ "rstrip": false,
24
+ "single_word": false,
25
+ "special": true
26
+ },
27
+ "102": {
28
+ "content": "[SEP]",
29
+ "lstrip": false,
30
+ "normalized": false,
31
+ "rstrip": false,
32
+ "single_word": false,
33
+ "special": true
34
+ },
35
+ "103": {
36
+ "content": "[MASK]",
37
+ "lstrip": false,
38
+ "normalized": false,
39
+ "rstrip": false,
40
+ "single_word": false,
41
+ "special": true
42
+ }
43
+ },
44
+ "clean_up_tokenization_spaces": false,
45
+ "cls_token": "[CLS]",
46
+ "do_lower_case": false,
47
+ "extra_special_tokens": {},
48
+ "fix_mistral_regex": true,
49
+ "mask_token": "[MASK]",
50
+ "max_length": 512,
51
+ "model_max_length": 512,
52
+ "pad_token": "[PAD]",
53
+ "sep_token": "[SEP]",
54
+ "stride": 0,
55
+ "strip_accents": null,
56
+ "tokenize_chinese_chars": true,
57
+ "tokenizer_class": "DistilBertTokenizer",
58
+ "truncation_side": "right",
59
+ "truncation_strategy": "longest_first",
60
+ "unk_token": "[UNK]"
61
+ }
pyproject.toml ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [project]
2
+ name = "irishcore-globalpointer"
3
+ version = "0.1.0"
4
+ description = "IrishCore GlobalPointer raw-only PII masking release with dynamic q8 ONNX export"
5
+ requires-python = ">=3.10"
6
+ readme = "README.md"
7
+ license = { text = "Apache-2.0" }
8
+ dependencies = [
9
+ "transformers>=4.41.0",
10
+ "torch",
11
+ "numpy>=1.26.0",
12
+ "onnxruntime>=1.20.0",
13
+ "huggingface_hub>=0.36.0",
14
+ ]
15
+
16
+ [tool.uv]
17
+ package = false
qa_config.json ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "recommended_backend": "onnx_q8_cpu",
3
+ "onnx_file": "onnx/model_quantized.onnx",
4
+ "policy_note": "Use irish_gov_contact_policy_v1, globalpointer_context_redteam_v1-v11, globalpointer_context_holdout_v12-v16, globalpointer_location_coverage_v1-v3, and globalpointer_demographic_patch_v2_test for contextual assistant/public-contact/location/age/DOB masking. rc22 additionally hardens Gaelic appointment-vs-DOB disambiguation.",
5
+ "priority_suites": [
6
+ "eval/q8_irish_core_pii_v1.json",
7
+ "eval/q8_irish_extended_pii_v1.json",
8
+ "eval/q8_globalpointer_demographic_patch_v2_test.json",
9
+ "eval/q8_irish_gov_contact_policy_v1.json",
10
+ "eval/q8_irish_gov_chatbot_redteam_v2.json",
11
+ "eval/q8_irish_gov_chatbot_gap_holdout_v2.json",
12
+ "eval/q8_irish_numeric_qafix_v2.json",
13
+ "eval/q8_globalpointer_context_redteam_v1.json",
14
+ "eval/q8_globalpointer_context_redteam_v2.json",
15
+ "eval/q8_globalpointer_location_coverage_v1.json",
16
+ "eval/q8_globalpointer_context_redteam_v3.json",
17
+ "eval/q8_globalpointer_context_redteam_v4.json",
18
+ "eval/q8_globalpointer_context_redteam_v5.json",
19
+ "eval/q8_globalpointer_context_redteam_v6.json",
20
+ "eval/q8_globalpointer_context_redteam_v7.json",
21
+ "eval/q8_globalpointer_context_redteam_v8.json",
22
+ "eval/q8_globalpointer_context_redteam_v9.json",
23
+ "eval/q8_globalpointer_context_redteam_v10.json",
24
+ "eval/q8_globalpointer_context_redteam_v11.json",
25
+ "eval/q8_globalpointer_location_coverage_v2.json",
26
+ "eval/q8_globalpointer_location_coverage_v3.json",
27
+ "eval/q8_globalpointer_context_holdout_v12_exact.json",
28
+ "eval/q8_globalpointer_context_holdout_v13_exact.json",
29
+ "eval/q8_globalpointer_context_holdout_v14_exact.json",
30
+ "eval/q8_globalpointer_context_holdout_v15_exact.json",
31
+ "eval/q8_globalpointer_context_holdout_v16_exact.json"
32
+ ],
33
+ "repo_id": "temsa/IrishCore-GlobalPointer-ContextPII-4L-122M-v1-rc1"
34
+ }
special_tokens_map.json ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cls_token": {
3
+ "content": "[CLS]",
4
+ "lstrip": false,
5
+ "normalized": false,
6
+ "rstrip": false,
7
+ "single_word": false
8
+ },
9
+ "mask_token": {
10
+ "content": "[MASK]",
11
+ "lstrip": false,
12
+ "normalized": false,
13
+ "rstrip": false,
14
+ "single_word": false
15
+ },
16
+ "pad_token": {
17
+ "content": "[PAD]",
18
+ "lstrip": false,
19
+ "normalized": false,
20
+ "rstrip": false,
21
+ "single_word": false
22
+ },
23
+ "sep_token": {
24
+ "content": "[SEP]",
25
+ "lstrip": false,
26
+ "normalized": false,
27
+ "rstrip": false,
28
+ "single_word": false
29
+ },
30
+ "unk_token": {
31
+ "content": "[UNK]",
32
+ "lstrip": false,
33
+ "normalized": false,
34
+ "rstrip": false,
35
+ "single_word": false
36
+ }
37
+ }
tokenizer.json ADDED
The diff for this file is too large to render. See raw diff
 
tokenizer_config.json ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "added_tokens_decoder": {
3
+ "0": {
4
+ "content": "[PAD]",
5
+ "lstrip": false,
6
+ "normalized": false,
7
+ "rstrip": false,
8
+ "single_word": false,
9
+ "special": true
10
+ },
11
+ "100": {
12
+ "content": "[UNK]",
13
+ "lstrip": false,
14
+ "normalized": false,
15
+ "rstrip": false,
16
+ "single_word": false,
17
+ "special": true
18
+ },
19
+ "101": {
20
+ "content": "[CLS]",
21
+ "lstrip": false,
22
+ "normalized": false,
23
+ "rstrip": false,
24
+ "single_word": false,
25
+ "special": true
26
+ },
27
+ "102": {
28
+ "content": "[SEP]",
29
+ "lstrip": false,
30
+ "normalized": false,
31
+ "rstrip": false,
32
+ "single_word": false,
33
+ "special": true
34
+ },
35
+ "103": {
36
+ "content": "[MASK]",
37
+ "lstrip": false,
38
+ "normalized": false,
39
+ "rstrip": false,
40
+ "single_word": false,
41
+ "special": true
42
+ }
43
+ },
44
+ "clean_up_tokenization_spaces": false,
45
+ "cls_token": "[CLS]",
46
+ "do_lower_case": false,
47
+ "extra_special_tokens": {},
48
+ "fix_mistral_regex": true,
49
+ "mask_token": "[MASK]",
50
+ "max_length": 512,
51
+ "model_max_length": 512,
52
+ "pad_token": "[PAD]",
53
+ "sep_token": "[SEP]",
54
+ "stride": 0,
55
+ "strip_accents": null,
56
+ "tokenize_chinese_chars": true,
57
+ "tokenizer_class": "DistilBertTokenizer",
58
+ "truncation_side": "right",
59
+ "truncation_strategy": "longest_first",
60
+ "unk_token": "[UNK]"
61
+ }
training_sources.json ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "teacher_release": "temsa/IrishCore-GlobalPointer-ContextPII-135M-v1-rc23",
3
+ "student_init": "models/irishcore-globalpointer-contextpii-4l-student-init-v1",
4
+ "student_model": "models/irishcore-globalpointer-contextpii-4l-b02-distill-e020",
5
+ "datasets": [
6
+ "data/irish_core_globalpointer_focus_extended_distill_v3_contextonly",
7
+ "data/globalpointer_rc22_pseudolabel_bank_v3_contextonly_nonempty"
8
+ ],
9
+ "notes": [
10
+ "4-layer student initialized from teacher layers [0,2,3,5]",
11
+ "teacher-student span distillation plus contextual-only pseudo-label bank",
12
+ "final bundled decoder also adds guarded routing-number, Gaelic passport-cue, and card recovery"
13
+ ]
14
+ }
uv.lock ADDED
The diff for this file is too large to render. See raw diff
 
vocab.txt ADDED
The diff for this file is too large to render. See raw diff
 
Free AI Image Generator No sign-up. Instant results. Open Now