TulipAkiki commited on
Commit
2fa2371
·
verified ·
1 Parent(s): 554419b

Akiki MiniLM-L6-v2 Clover intent classifier (seed 2)

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +1 -34
  2. .gitignore +3 -0
  3. LICENSE +176 -0
  4. NOTICE +17 -0
  5. README.md +209 -0
  6. SHA256SUMS +80 -0
  7. adapter.safetensors +3 -0
  8. base_model/1_Pooling/config.json +7 -0
  9. base_model/README.md +175 -0
  10. base_model/config.json +24 -0
  11. base_model/config_sentence_transformers.json +7 -0
  12. base_model/model.safetensors +3 -0
  13. base_model/modules.json +20 -0
  14. base_model/sentence_bert_config.json +4 -0
  15. base_model/special_tokens_map.json +1 -0
  16. base_model/tokenizer.json +0 -0
  17. base_model/tokenizer_config.json +1 -0
  18. base_model/vocab.txt +0 -0
  19. checkpoints/seed-0.safetensors +3 -0
  20. checkpoints/seed-1.safetensors +3 -0
  21. checkpoints/seed-2.safetensors +3 -0
  22. checks/packaged-inference-verification.json +60 -0
  23. data/README.md +23 -0
  24. data/audit-drops.jsonl +186 -0
  25. data/audit.json +30 -0
  26. data/manifest.json +186 -0
  27. data/test.jsonl +0 -0
  28. data/train.jsonl +3 -0
  29. data/validation.jsonl +0 -0
  30. model.py +122 -0
  31. model_config.json +37 -0
  32. provenance/original/CREDITS.md +26 -0
  33. provenance/original/README.md +117 -0
  34. provenance/original/final-verification.json +197 -0
  35. provenance/original/minilm-l6-v2/MODEL_CARD.md +65 -0
  36. provenance/original/minilm-l6-v2/model.json +15 -0
  37. provenance/original/protocol/PASSMARK-CLOVER-1.md +9 -0
  38. provenance/original/protocol/plan.json +291 -0
  39. provenance/original/results.md +67 -0
  40. provenance/original/source/ariadne_bench/clover.py +117 -0
  41. provenance/original/source/ariadne_bench/clover_models.py +210 -0
  42. provenance/original/source/ariadne_bench/interfaces.py +121 -0
  43. provenance/original/source/scripts/package_clover_minilm.py +154 -0
  44. provenance/original/source/scripts/predict_clover.py +61 -0
  45. provenance/original/source/scripts/run_clover_experiments.py +373 -0
  46. requirements.txt +4 -0
  47. results/baselines/embedding-class_centroids.json +419 -0
  48. results/baselines/embedding-kmeans-seed-0.json +439 -0
  49. results/baselines/embedding-kmeans-seed-1.json +439 -0
  50. results/baselines/embedding-kmeans-seed-2.json +439 -0
.gitattributes CHANGED
@@ -1,35 +1,2 @@
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
  *.safetensors filter=lfs diff=lfs merge=lfs -text
2
+ data/train.jsonl filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
.gitignore ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ __pycache__/
2
+ *.pyc
3
+ .venv/
LICENSE ADDED
@@ -0,0 +1,176 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
NOTICE ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Akiki MiniLM-L6-v2 Clover intent classifier
2
+ Developed by AKIKI.AI.
3
+
4
+ Project code is supplied under the Apache License, Version 2.0 (see LICENSE).
5
+ Base model: sentence-transformers/all-MiniLM-L6-v2, revision
6
+ 1110a243fdf4706b3f48f1d95db1a4f5529b4d41, Apache-2.0.
7
+ Original base-model card and attribution: base_model/README.md.
8
+ https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2
9
+
10
+ Clover intent data (data/) is synthetic, generated and reviewed locally by AKIKI.AI with
11
+ cached Qwen checkpoints; see data/README.md and provenance/original/CREDITS.md.
12
+ Labels are model-reviewed; human review is pending.
13
+
14
+ provenance/original/source/ preserves the original experiment implementation for audit,
15
+ under its internal project names. The root-level model.py is portable and needs no
16
+ original project files. Result and manifest files copied verbatim from the experiment
17
+ keep the internal method name 'ariadne', which is the Akiki input affine.
README.md ADDED
@@ -0,0 +1,209 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ language:
3
+ - en
4
+ license: apache-2.0
5
+ library_name: pytorch
6
+ pipeline_tag: text-classification
7
+ base_model: sentence-transformers/all-MiniLM-L6-v2
8
+ base_model_relation: adapter
9
+ tags:
10
+ - akiki
11
+ - clover
12
+ - minilm
13
+ - intent-classification
14
+ - frozen-encoder
15
+ - custom-code
16
+ metrics:
17
+ - accuracy
18
+ - f1
19
+ ---
20
+
21
+ # Akiki-MiniLM-L6-v2-clover-intent
22
+
23
+ Developed by AKIKI.AI.
24
+
25
+ An English six-way intent router for Clover, built on a **completely frozen**
26
+ `sentence-transformers/all-MiniLM-L6-v2`. Only two small pieces were trained: an
27
+ identity-initialized **384 × 384 Akiki input affine** on the word embeddings
28
+ (147,840 parameters) and a **six-class head** (2,310 parameters), 150,150 in total.
29
+ The 22,713,216 backbone parameters are untouched and hash-checked against the
30
+ original.
31
+
32
+ Given the current user message and, optionally, earlier conversation turns, it
33
+ returns one of:
34
+
35
+ | Token | Label | Meaning |
36
+ |---|---|---|
37
+ | A | chat | Conversation, explanation, how-to advice, general knowledge |
38
+ | B | question | Inspect or report the state of the user's actual system, without changing it |
39
+ | C | build | Create or modify software, a feature, a site or an app |
40
+ | D | task | Perform a specified operational action (restart, move, change a setting) |
41
+ | E | fix | Diagnose and remedy a malfunction when no specific remedy is prescribed |
42
+ | F | unclear | The route or referent cannot be identified from message and context |
43
+
44
+ > **Experimental.** Labels are synthetic and model-reviewed; human review is
45
+ > pending. This model classifies intent only. It does not write contracts, run
46
+ > actions, or implement Clover's refusal policy. It has not been approved for
47
+ > serving.
48
+
49
+ ## Results
50
+
51
+ Held-out test split: 714 examples (120 per class; 114 unclear), balanced across
52
+ easy / medium / hard.
53
+
54
+ | Method (MiniLM-L6-v2, frozen backbone) | Test accuracy | Macro F1 | Hard accuracy |
55
+ |---|---:|---:|---:|
56
+ | Label-description similarity, no training | 34.9% | 0.313 | 36.7% |
57
+ | Frozen embeddings + regularized linear classifier | 92.3% | 0.923 | 91.7% |
58
+ | Head-only training, 3-seed mean | 91.7% ± 0.3 | 0.917 | 91.1% |
59
+ | Akiki affine + head, 3-seed mean | 96.6% ± 0.6 | 0.966 | 95.6% |
60
+ | **This checkpoint (Akiki, seed 2)** | **97.2%** | **0.972** | **96.2%** |
61
+
62
+ **Which seed, and why:** three seeds were trained. Seed 2 is released because it
63
+ has the lowest validation NLL (0.121 vs 0.131 and 0.141), which is the
64
+ experiment's checkpoint criterion. Test results played no part in the choice.
65
+ Seed 2 happens to be the best on test as well, so treat the **three-seed mean
66
+ (96.6%)** as the honest estimate of what this recipe gives. All three seeds ship
67
+ in `checkpoints/`.
68
+
69
+ Seed 2 detail: easy 99.6%, medium 95.8%, hard 96.2%; test NLL 0.082, Brier 0.043.
70
+
71
+ | Class | Precision | Recall | F1 |
72
+ |---|---:|---:|---:|
73
+ | chat | 0.991 | 0.958 | 0.975 |
74
+ | question | 0.967 | 0.992 | 0.979 |
75
+ | build | 1.000 | 0.967 | 0.983 |
76
+ | task | 0.934 | 0.950 | 0.942 |
77
+ | fix | 0.967 | 0.992 | 0.979 |
78
+ | unclear | 0.974 | 0.974 | 0.974 |
79
+
80
+ Rows are gold labels, columns are predictions:
81
+
82
+ | gold \ pred | chat | question | build | task | fix | unclear |
83
+ |---|---:|---:|---:|---:|---:|---:|
84
+ | chat | 115 | 2 | 0 | 1 | 0 | 2 |
85
+ | question | 1 | 119 | 0 | 0 | 0 | 0 |
86
+ | build | 0 | 0 | 116 | 3 | 0 | 1 |
87
+ | task | 0 | 2 | 0 | 114 | 4 | 0 |
88
+ | fix | 0 | 0 | 0 | 1 | 119 | 0 |
89
+ | unclear | 0 | 0 | 0 | 3 | 0 | 111 |
90
+
91
+ **Pass mark not met.** The experiment requires at least 95% accuracy **and zero
92
+ action predictions (build/task/fix) on chat/question**. This checkpoint makes
93
+ **1 action prediction on 240 chat/question examples** (a chat message read as
94
+ task) and 3 on 114 unclear examples. Downstream code should therefore not treat
95
+ a `task`/`build`/`fix` label as authorization by itself.
96
+
97
+ ## Usage
98
+
99
+ ```bash
100
+ pip install -r requirements.txt
101
+ python model.py 'Restart my web server.' # -> D
102
+ python model.py --output label 'Restart my web server.' # -> task
103
+ python model.py --output json --context-file ctx.json 'yes'
104
+ ```
105
+
106
+ ```python
107
+ from model import CloverIntent
108
+
109
+ clf = CloverIntent.from_pretrained(".") # loads base_model/ + adapter.safetensors, CPU by default
110
+ clf.predict("Restart my web server.")["label"] # 'task'
111
+ clf.predict("yes", context=[
112
+ {"role": "assistant", "text": "Would you like me to check whether last night's backup ran?"},
113
+ ])["label"] # 'question'
114
+ clf.probabilities([{"message": "fix it"}]) # (1, 6) tensor, label order above
115
+ ```
116
+
117
+ `predict` returns `label`, `token` (A–F) and the six `probabilities`. Everything
118
+ loads from this repository with `local_files_only=True`; nothing is downloaded at
119
+ run time. Download the whole repo first, e.g.
120
+ `hf download Akiki-AI/Akiki-MiniLM-L6-v2-clover-intent --local-dir clover-intent`.
121
+
122
+ ### Input format
123
+
124
+ The model sees exactly this text (the context block is omitted when empty):
125
+
126
+ ```
127
+ Conversation context:
128
+ assistant: Would you like me to restart the web server?
129
+
130
+ Current user message: yes
131
+ ```
132
+
133
+ Context turns are `{"role": ..., "text": ...}` objects. The limit is 512 tokens
134
+ including special tokens. Longer inputs **raise an error rather than being
135
+ truncated**. The longest training/test input is 126 tokens, so these results say
136
+ nothing about long briefings or full chat histories.
137
+
138
+ Probabilities are a plain softmax of the head logits, with no calibration fitted.
139
+
140
+ ## Architecture
141
+
142
+ ```
143
+ tokens → MiniLM word embeddings (frozen)
144
+ → Akiki affine W·x + b (384×384, identity-initialized, FP32)
145
+ → + position/type embeddings → 6 BERT layers (frozen)
146
+ → attention-masked mean pooling → L2 normalize
147
+ → linear head (384 → 6) → softmax
148
+ ```
149
+
150
+ `adapter.safetensors` holds `interface.proj.{weight,bias}` and `head.{weight,bias}`.
151
+ `base_model/` is an unmodified copy of all-MiniLM-L6-v2 at revision
152
+ `1110a243fdf4706b3f48f1d95db1a4f5529b4d41`.
153
+
154
+ ## Training
155
+
156
+ - **Data:** 9,913 train / 707 validation / 714 test synthetic English examples
157
+ (`data/`, documented in `data/README.md`). Scenario groups never cross splits;
158
+ near-duplicates across splits were removed, protecting test first. Hard
159
+ examples need the conversation context to resolve the intent, using follow-up
160
+ phrase families kept separate between splits.
161
+ - **Labels:** generated locally by Qwen3.8-27B-FP8 and independently classified by
162
+ Qwen3.5-9B; disagreements were rejected. Not human-verified.
163
+ - **Optimization:** Adam; head lr 1e-3, affine lr 1e-4; early stopping on
164
+ validation NLL. Seed 2 selected epoch 8 of 11. Each fit took about 30 s on one
165
+ RTX PRO 6000. The full recipe is in `provenance/original/protocol/plan.json`.
166
+
167
+ ## Latency
168
+
169
+ Warm CPU inference with FP32 PyTorch/Transformers, 8 threads, batch size 1, on a
170
+ short contextual input (tokenization included, model loading excluded): **2.47 ms
171
+ median, 2.62 ms p95**. Head-only measured 2.40 ms. This was measured with seed 0,
172
+ which is architecturally identical, on the training server, not on a laptop. See
173
+ `results/inference-comparison.json` and `results/cpu-latency.json`.
174
+
175
+ ## Verification
176
+
177
+ `checks/packaged-inference-verification.json` re-runs this repository's
178
+ `model.py` on CPU for all three seeds. It checks that:
179
+
180
+ - the bundled backbone's tensor hash equals the frozen training backbone;
181
+ - every test label matches the recorded GPU predictions, with probabilities
182
+ within 5.4e-6;
183
+ - validation accuracy and NLL match the training history.
184
+
185
+ Verify file integrity with `sha256sum -c SHA256SUMS`.
186
+
187
+ ## Repository contents
188
+
189
+ | Path | What it is |
190
+ |---|---|
191
+ | `model.py` | Portable inference: `CloverIntent` class and CLI |
192
+ | `adapter.safetensors` | Released weights (seed 2) |
193
+ | `checkpoints/seed-{0,1,2}.safetensors` | All three trained seeds |
194
+ | `base_model/` | Unmodified all-MiniLM-L6-v2 |
195
+ | `model_config.json` | Labels, tokens, hashes, parameter counts |
196
+ | `results/` | Test report, per-example predictions and uncertainty, per-seed histories, baselines, latency |
197
+ | `data/` | Exact train/validation/test splits, dataset card, manifest, audit |
198
+ | `checks/` | Packaged-inference verification |
199
+ | `provenance/original/` | Original experiment protocol, reports and source, under internal project names |
200
+
201
+ Files copied verbatim from the experiment (under `results/`, `data/` and
202
+ `provenance/`) use the internal method name `ariadne`, which is the Akiki
203
+ input affine described here.
204
+
205
+ ## Licence and credits
206
+
207
+ Apache-2.0 (see `LICENSE` and `NOTICE`). The base model,
208
+ [sentence-transformers/all-MiniLM-L6-v2](https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2),
209
+ is Apache-2.0; its original card is in `base_model/README.md`.
SHA256SUMS ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ee05350c7fda0af4da116020dd7b976d731de3beed4f5e717d5bcc95ead24550 .gitattributes
2
+ 4cad133d4f0a6cf4bba15f1b8bbae48d6a55f20b94f75487c51a93cc6a5af59f .gitignore
3
+ a6cba85bc92e0cff7a450b1d873c0eaa2e9fc96bf472df0247a26bec77bf3ff9 LICENSE
4
+ 198b75bff2665ac699c4289c43916fb7cef607874372fa315216e7b0a38d3ffe NOTICE
5
+ 7768ff7cd3039381491eb86efb286cde39bf7662e5719542cf66348d7cad57bc README.md
6
+ 37b5302e645423512b6fcd6328a4f371ab8f5220457514dcd8bf2d27bdbc5a8d adapter.safetensors
7
+ 4be450dde3b0273bb9787637cfbd28fe04a7ba6ab9d36ac48e92b11e350ffc23 base_model/1_Pooling/config.json
8
+ dcd602d2fd35c203a247304a06fec6654a12f7941b739f9221a064fe8dc3b7f0 base_model/README.md
9
+ 953f9c0d463486b10a6871cc2fd59f223b2c70184f49815e7efbcab5d8908b41 base_model/config.json
10
+ 061ca9d39661d6c6d6de5ba27f79a1cd5770ea247f8d46412a68a498dc5ac9f3 base_model/config_sentence_transformers.json
11
+ 53aa51172d142c89d9012cce15ae4d6cc0ca6895895114379cacb4fab128d9db base_model/model.safetensors
12
+ 84e40c8e006c9b1d6c122e02cba9b02458120b5fb0c87b746c41e0207cf642cf base_model/modules.json
13
+ fc1993fde0a95c24ec6c022539d41cf6e2f7c9721e5415d6fb6897472a9cd4b7 base_model/sentence_bert_config.json
14
+ 303df45a03609e4ead04bc3dc1536d0ab19b5358db685b6f3da123d05ec200e3 base_model/special_tokens_map.json
15
+ be50c3628f2bf5bb5e3a7f17b1f74611b2561a3a27eeab05e5aa30f411572037 base_model/tokenizer.json
16
+ acb92769e8195aabd29b7b2137a9e6d6e25c476a4f15aa4355c233426c61576b base_model/tokenizer_config.json
17
+ 07eced375cec144d27c900241f3e339478dec958f92fddbc551f295c992038a3 base_model/vocab.txt
18
+ 5c38aa73b22d91591d644829259c9c6a790e76380fb49ff947d52fee4f6fd40a checkpoints/seed-0.safetensors
19
+ 1b74e3473191677c943d3f36b9437213be23ab5e3cf2cf0300773c489f0fafd8 checkpoints/seed-1.safetensors
20
+ 37b5302e645423512b6fcd6328a4f371ab8f5220457514dcd8bf2d27bdbc5a8d checkpoints/seed-2.safetensors
21
+ 6717ab4a8158c70f6ce53435b139b2537bfd14bfd71d203d41e27665b0892f7b checks/packaged-inference-verification.json
22
+ 5ac817fc011a53b16c3826c920e6d80dba45f188234552b59f0783ddf17b959c data/README.md
23
+ 591017f301654e0d26ad884fa37f4378acedf38e57eacaf44c409253f15e641e data/audit-drops.jsonl
24
+ 3ed02c8fb676df20988b89adb1e04ed4fcb99565e3f6bab1e0eabc5bd2778607 data/audit.json
25
+ 857d674c7b0cf9bc9ab112fce5b6db2cdead4055c8e9c9b2901f2706bc8f7c59 data/manifest.json
26
+ 8e1fde3f1074fb216e73b879fe3905d4448faf1c7a83d1fef6b3078dc1560c28 data/test.jsonl
27
+ 2e3edef9182471d0fcd3738fdf886fdbe78fac5e6f3855373ab92a6ad0f1ca72 data/train.jsonl
28
+ 40759974effb15fe000589d5e9082ae94c7c760a9dfef40cb364d95bc74c953b data/validation.jsonl
29
+ b80737e8f5d49d4f506de953fff0a96744e8bb10509a5e9a0f7d970f52b9b0b4 model.py
30
+ 9168869c1b35dba0b61f2f0d8e786109c7da2ab0e79f41713d42c57d041e4e6a model_config.json
31
+ c90a6e3a8dfa1a48a96def4d416e816cfc671343602a4c07ba7a581d06730032 provenance/original/CREDITS.md
32
+ 53d9f11712d524f505cafce98728bb0f460f27b95c4bf8ef945a7bc38ecd2262 provenance/original/README.md
33
+ 873c0b5f9e6120d974fc5a29405a9c51b7fe57f5fc589851ffe8d628143f05df provenance/original/final-verification.json
34
+ 2ea6b7093dcac3ad96188725cd19cf8147511d96e70c0abd353e1baf6213816f provenance/original/minilm-l6-v2/MODEL_CARD.md
35
+ 5bbf390749bd573e2de766154ceb791e35c4b840ace6f7f7829939ce7f470ae5 provenance/original/minilm-l6-v2/model.json
36
+ fdd46960b5ad1b4dce94e3c05a4365efb631a947fa45e375bd34e5c47ee72cb4 provenance/original/protocol/PASSMARK-CLOVER-1.md
37
+ 756f4fda69a75ee9a777b6151b599c0456cf9bc35bd0a928c1c85fd09c5e793f provenance/original/protocol/plan.json
38
+ 3bcb85e89881c9e6c8d58503e169fd69ae55488ea1d1c4459d090c97f785644e provenance/original/results.md
39
+ 270b5ab0ea3ad33cec13803f4ccb4ee2ecdd5f8c7152780712546d3e94c8e798 provenance/original/source/ariadne_bench/clover.py
40
+ 2d08a3d37c4c171250e5e2bcf1ad572d23ce420fff7d37e61fcccda08e5cca8c provenance/original/source/ariadne_bench/clover_models.py
41
+ 19700fb8170b2460401900cb96ebdff22bd7bf778ca5132e98d56ba68f344187 provenance/original/source/ariadne_bench/interfaces.py
42
+ 2aef90fc4b04c759d11dc900d4ab565980c1e071fa56b492628aa5b8e4a8d46e provenance/original/source/scripts/package_clover_minilm.py
43
+ 07ba1f84b4bed51072f943c663835b350ab2afa0f50e31e6b12e0abfe36e203c provenance/original/source/scripts/predict_clover.py
44
+ df8b0c3c79c627618a2ae2a12e02cb861d1369ffbbe86f5c60cd3112836c3af5 provenance/original/source/scripts/run_clover_experiments.py
45
+ c7ea877b7e68e2dcb986b7a92d1026191eec06fff933eae220d6af0b47a21378 requirements.txt
46
+ 2ababfd7813d8cb42bc8f886d03e8dbd8e1da64a62471cfd2210ef0114856052 results/baselines/embedding-class_centroids.json
47
+ a826d8825ade3d1e02988393369e972c6a652105ab1ec96db27c8466c9666feb results/baselines/embedding-kmeans-seed-0.json
48
+ e1c2415e94febcb80754e59b13fd52e28a0d4f9147ee8e5fd39a4a193eb31ac8 results/baselines/embedding-kmeans-seed-1.json
49
+ 1289a225b0df372e2a4615e4552b194e007b735db0e84d47c1d44f66f5f5e495 results/baselines/embedding-kmeans-seed-2.json
50
+ 60824d591a2f7171054e4cca12608f2b65fe5aad1eb9543dad978524e2e97013 results/baselines/embedding-knn.json
51
+ 03b4ac1dcab65ab3791f8bad5173c17de566badc3f49e74c8314bd80e8b50abc results/baselines/embedding-linear_head.json
52
+ d397fb275880b44b4603873a6587307dee19e04887dc52f82d68bce28d51a82f results/baselines/frozen-baseline.json
53
+ 37c39a34166869f9c88de21fce9af9616b6494e124598e1449a2864203260b55 results/baselines/head_only-seed-0.json
54
+ 6fc13826c6f8a77c09aab46bbaffdef874b20b9473285a861013728f62241242 results/baselines/head_only-seed-1.json
55
+ 72b1edc8ffe38d518fdffd50f35d6e72318fe2df8045bab591a5f1701decc5b7 results/baselines/head_only-seed-2.json
56
+ 97e439ec22246473a9d4224ba1fe3a8ea52835c3fa151930749ec77afb402c35 results/cpu-latency.json
57
+ 7455dc220c877d297c483f3279de4dc74f76f49cfc4d069f50ebc7d747ea5fc5 results/inference-comparison.json
58
+ 13c27fe6e6eab4ef650f6a323ea652ee1f750a1039fa8a3b3b14298a53d8a841 results/inference-smoke.json
59
+ 4c0d7a9d360ad04ee82b1fed7348cb471c73bf9f3cb10778970dfc55a376d91b results/seed-summary-minilm.json
60
+ ca9c373b4135ab7f7912d728367f5873035a2b236e0d4ef5bb47504163c3ac0f results/seeds/seed-0/complete.json
61
+ 74cbae8b24326b53fe7917f5b943a0d4a4e026682018d9ec963f876a835a1eaa results/seeds/seed-0/history.json
62
+ 358d3baed5a1ad6cd0ca2e8794ed60b80677450e379ce18bf0ea4f9d38ae5827 results/seeds/seed-0/model.json
63
+ 4dfaafbe8ae351664edb49cb3a5aae7b292fe0a65a37f157f84503023e39da52 results/seeds/seed-0/test-predictions.jsonl
64
+ 1c4f65c5d4e649bdd18d2178f532a2eed7744590461b8a7a8757766e23f3177f results/seeds/seed-0/test-report.json
65
+ 81d3aeb360106df074020edf128a1e340bf118a8203fed9b64c9eb2b6e272fc9 results/seeds/seed-0/test-uncertainty.jsonl
66
+ 2529ad5cfeeaaf836a6fb902e3039b8caa7b6e4eb3baf599b501b2d4df4c863f results/seeds/seed-1/complete.json
67
+ 3409df997aa986ca7f80c01bdb5fcb1d89f4993f82e9e23a42d577ee06165cad results/seeds/seed-1/history.json
68
+ 358d3baed5a1ad6cd0ca2e8794ed60b80677450e379ce18bf0ea4f9d38ae5827 results/seeds/seed-1/model.json
69
+ 83b0153d08a6e957942931166fa2729c898fa482807e4a3b67da1eddfe9ca65e results/seeds/seed-1/test-predictions.jsonl
70
+ 3773cd70da2c750b9617c8bc8068ec88ca61c4202e646f950590a00683a17036 results/seeds/seed-1/test-report.json
71
+ c9b586afa3e639932579183e25a6e0367299c7b373915a89780698c2e07ce230 results/seeds/seed-1/test-uncertainty.jsonl
72
+ f533898126d28bd3364b71f12eaa6b2093470492273ccca104be3905b821ff80 results/seeds/seed-2/complete.json
73
+ e6b741fd3fa57e2c51106cf6d5897342dfe36c4c2164190a37af63887e24279d results/seeds/seed-2/history.json
74
+ 358d3baed5a1ad6cd0ca2e8794ed60b80677450e379ce18bf0ea4f9d38ae5827 results/seeds/seed-2/model.json
75
+ 05b3e3bb67e8973fd614fcdf52249e322c2adc10b9d7758c6638574bd1e8bf9e results/seeds/seed-2/test-predictions.jsonl
76
+ 5dbf729da994049108220bb81213934e81265fece8019d264e6f1aa0f332f58e results/seeds/seed-2/test-report.json
77
+ 72508270db2dbcd5a84415242a638c0fe92bb4b16810023249616a6f0f671f1f results/seeds/seed-2/test-uncertainty.jsonl
78
+ 05b3e3bb67e8973fd614fcdf52249e322c2adc10b9d7758c6638574bd1e8bf9e results/test-predictions.jsonl
79
+ 5dbf729da994049108220bb81213934e81265fece8019d264e6f1aa0f332f58e results/test-report.json
80
+ 72508270db2dbcd5a84415242a638c0fe92bb4b16810023249616a6f0f671f1f results/test-uncertainty.jsonl
adapter.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:37b5302e645423512b6fcd6328a4f371ab8f5220457514dcd8bf2d27bdbc5a8d
3
+ size 601008
base_model/1_Pooling/config.json ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ {
2
+ "word_embedding_dimension": 384,
3
+ "pooling_mode_cls_token": false,
4
+ "pooling_mode_mean_tokens": true,
5
+ "pooling_mode_max_tokens": false,
6
+ "pooling_mode_mean_sqrt_len_tokens": false
7
+ }
base_model/README.md ADDED
@@ -0,0 +1,175 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ base_model:
3
+ - nreimers/MiniLM-L6-H384-uncased
4
+ language: en
5
+ license: apache-2.0
6
+ library_name: sentence-transformers
7
+ tags:
8
+ - sentence-transformers
9
+ - feature-extraction
10
+ - sentence-similarity
11
+ - transformers
12
+ datasets:
13
+ - s2orc
14
+ - flax-sentence-embeddings/stackexchange_xml
15
+ - ms_marco
16
+ - gooaq
17
+ - yahoo_answers_topics
18
+ - code_search_net
19
+ - search_qa
20
+ - eli5
21
+ - snli
22
+ - multi_nli
23
+ - wikihow
24
+ - natural_questions
25
+ - trivia_qa
26
+ - embedding-data/sentence-compression
27
+ - embedding-data/flickr30k-captions
28
+ - embedding-data/altlex
29
+ - embedding-data/simple-wiki
30
+ - embedding-data/QQP
31
+ - embedding-data/SPECTER
32
+ - embedding-data/PAQ_pairs
33
+ - embedding-data/WikiAnswers
34
+ pipeline_tag: sentence-similarity
35
+ ---
36
+
37
+
38
+ # all-MiniLM-L6-v2
39
+ This is a [sentence-transformers](https://www.SBERT.net) model: It maps sentences & paragraphs to a 384 dimensional dense vector space and can be used for tasks like clustering or semantic search.
40
+
41
+ ## Usage (Sentence-Transformers)
42
+ Using this model becomes easy when you have [sentence-transformers](https://www.SBERT.net) installed:
43
+
44
+ ```
45
+ pip install -U sentence-transformers
46
+ ```
47
+
48
+ Then you can use the model like this:
49
+ ```python
50
+ from sentence_transformers import SentenceTransformer
51
+ sentences = ["This is an example sentence", "Each sentence is converted"]
52
+
53
+ model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2')
54
+ embeddings = model.encode(sentences)
55
+ print(embeddings)
56
+ ```
57
+
58
+ ## Usage (HuggingFace Transformers)
59
+ Without [sentence-transformers](https://www.SBERT.net), you can use the model like this: First, you pass your input through the transformer model, then you have to apply the right pooling-operation on-top of the contextualized word embeddings.
60
+
61
+ ```python
62
+ from transformers import AutoTokenizer, AutoModel
63
+ import torch
64
+ import torch.nn.functional as F
65
+
66
+ #Mean Pooling - Take attention mask into account for correct averaging
67
+ def mean_pooling(model_output, attention_mask):
68
+ token_embeddings = model_output[0] #First element of model_output contains all token embeddings
69
+ input_mask_expanded = attention_mask.unsqueeze(-1).expand(token_embeddings.size()).float()
70
+ return torch.sum(token_embeddings * input_mask_expanded, 1) / torch.clamp(input_mask_expanded.sum(1), min=1e-9)
71
+
72
+
73
+ # Sentences we want sentence embeddings for
74
+ sentences = ['This is an example sentence', 'Each sentence is converted']
75
+
76
+ # Load model from HuggingFace Hub
77
+ tokenizer = AutoTokenizer.from_pretrained('sentence-transformers/all-MiniLM-L6-v2')
78
+ model = AutoModel.from_pretrained('sentence-transformers/all-MiniLM-L6-v2')
79
+
80
+ # Tokenize sentences
81
+ encoded_input = tokenizer(sentences, padding=True, truncation=True, return_tensors='pt')
82
+
83
+ # Compute token embeddings
84
+ with torch.no_grad():
85
+ model_output = model(**encoded_input)
86
+
87
+ # Perform pooling
88
+ sentence_embeddings = mean_pooling(model_output, encoded_input['attention_mask'])
89
+
90
+ # Normalize embeddings
91
+ sentence_embeddings = F.normalize(sentence_embeddings, p=2, dim=1)
92
+
93
+ print("Sentence embeddings:")
94
+ print(sentence_embeddings)
95
+ ```
96
+
97
+ ------
98
+
99
+ ## Background
100
+
101
+ The project aims to train sentence embedding models on very large sentence level datasets using a self-supervised
102
+ contrastive learning objective. We used the pretrained [`nreimers/MiniLM-L6-H384-uncased`](https://huggingface.co/nreimers/MiniLM-L6-H384-uncased) model and fine-tuned in on a
103
+ 1B sentence pairs dataset. We use a contrastive learning objective: given a sentence from the pair, the model should predict which out of a set of randomly sampled other sentences, was actually paired with it in our dataset.
104
+
105
+ We developed this model during the
106
+ [Community week using JAX/Flax for NLP & CV](https://discuss.huggingface.co/t/open-to-the-community-community-week-using-jax-flax-for-nlp-cv/7104),
107
+ organized by Hugging Face. We developed this model as part of the project:
108
+ [Train the Best Sentence Embedding Model Ever with 1B Training Pairs](https://discuss.huggingface.co/t/train-the-best-sentence-embedding-model-ever-with-1b-training-pairs/7354). We benefited from efficient hardware infrastructure to run the project: 7 TPUs v3-8, as well as intervention from Googles Flax, JAX, and Cloud team member about efficient deep learning frameworks.
109
+
110
+ ## Intended uses
111
+
112
+ Our model is intended to be used as a sentence and short paragraph encoder. Given an input text, it outputs a vector which captures
113
+ the semantic information. The sentence vector may be used for information retrieval, clustering or sentence similarity tasks.
114
+
115
+ By default, input text longer than 256 word pieces is truncated.
116
+
117
+
118
+ ## Training procedure
119
+
120
+ ### Pre-training
121
+
122
+ We use the pretrained [`nreimers/MiniLM-L6-H384-uncased`](https://huggingface.co/nreimers/MiniLM-L6-H384-uncased) model. Please refer to the model card for more detailed information about the pre-training procedure.
123
+
124
+ ### Fine-tuning
125
+
126
+ We fine-tune the model using a contrastive objective. Formally, we compute the cosine similarity from each possible sentence pairs from the batch.
127
+ We then apply the cross entropy loss by comparing with true pairs.
128
+
129
+ #### Hyper parameters
130
+
131
+ We trained our model on a TPU v3-8. We train the model during 100k steps using a batch size of 1024 (128 per TPU core).
132
+ We use a learning rate warm up of 500. The sequence length was limited to 128 tokens. We used the AdamW optimizer with
133
+ a 2e-5 learning rate. The full training script is accessible in this current repository: `train_script.py`.
134
+
135
+ #### Training data
136
+
137
+ We use the concatenation from multiple datasets to fine-tune our model. The total number of sentence pairs is above 1 billion sentences.
138
+ We sampled each dataset given a weighted probability which configuration is detailed in the `data_config.json` file.
139
+
140
+
141
+ | Dataset | Paper | Number of training tuples |
142
+ |--------------------------------------------------------|:----------------------------------------:|:--------------------------:|
143
+ | [Reddit comments (2015-2018)](https://github.com/PolyAI-LDN/conversational-datasets/tree/master/reddit) | [paper](https://arxiv.org/abs/1904.06472) | 726,484,430 |
144
+ | [S2ORC](https://github.com/allenai/s2orc) Citation pairs (Abstracts) | [paper](https://aclanthology.org/2020.acl-main.447/) | 116,288,806 |
145
+ | [WikiAnswers](https://github.com/afader/oqa#wikianswers-corpus) Duplicate question pairs | [paper](https://doi.org/10.1145/2623330.2623677) | 77,427,422 |
146
+ | [PAQ](https://github.com/facebookresearch/PAQ) (Question, Answer) pairs | [paper](https://arxiv.org/abs/2102.07033) | 64,371,441 |
147
+ | [S2ORC](https://github.com/allenai/s2orc) Citation pairs (Titles) | [paper](https://aclanthology.org/2020.acl-main.447/) | 52,603,982 |
148
+ | [S2ORC](https://github.com/allenai/s2orc) (Title, Abstract) | [paper](https://aclanthology.org/2020.acl-main.447/) | 41,769,185 |
149
+ | [Stack Exchange](https://huggingface.co/datasets/flax-sentence-embeddings/stackexchange_xml) (Title, Body) pairs | - | 25,316,456 |
150
+ | [Stack Exchange](https://huggingface.co/datasets/flax-sentence-embeddings/stackexchange_xml) (Title+Body, Answer) pairs | - | 21,396,559 |
151
+ | [Stack Exchange](https://huggingface.co/datasets/flax-sentence-embeddings/stackexchange_xml) (Title, Answer) pairs | - | 21,396,559 |
152
+ | [MS MARCO](https://microsoft.github.io/msmarco/) triplets | [paper](https://doi.org/10.1145/3404835.3462804) | 9,144,553 |
153
+ | [GOOAQ: Open Question Answering with Diverse Answer Types](https://github.com/allenai/gooaq) | [paper](https://arxiv.org/pdf/2104.08727.pdf) | 3,012,496 |
154
+ | [Yahoo Answers](https://www.kaggle.com/soumikrakshit/yahoo-answers-dataset) (Title, Answer) | [paper](https://proceedings.neurips.cc/paper/2015/hash/250cf8b51c773f3f8dc8b4be867a9a02-Abstract.html) | 1,198,260 |
155
+ | [Code Search](https://huggingface.co/datasets/code_search_net) | - | 1,151,414 |
156
+ | [COCO](https://cocodataset.org/#home) Image captions | [paper](https://link.springer.com/chapter/10.1007%2F978-3-319-10602-1_48) | 828,395|
157
+ | [SPECTER](https://github.com/allenai/specter) citation triplets | [paper](https://doi.org/10.18653/v1/2020.acl-main.207) | 684,100 |
158
+ | [Yahoo Answers](https://www.kaggle.com/soumikrakshit/yahoo-answers-dataset) (Question, Answer) | [paper](https://proceedings.neurips.cc/paper/2015/hash/250cf8b51c773f3f8dc8b4be867a9a02-Abstract.html) | 681,164 |
159
+ | [Yahoo Answers](https://www.kaggle.com/soumikrakshit/yahoo-answers-dataset) (Title, Question) | [paper](https://proceedings.neurips.cc/paper/2015/hash/250cf8b51c773f3f8dc8b4be867a9a02-Abstract.html) | 659,896 |
160
+ | [SearchQA](https://huggingface.co/datasets/search_qa) | [paper](https://arxiv.org/abs/1704.05179) | 582,261 |
161
+ | [Eli5](https://huggingface.co/datasets/eli5) | [paper](https://doi.org/10.18653/v1/p19-1346) | 325,475 |
162
+ | [Flickr 30k](https://shannon.cs.illinois.edu/DenotationGraph/) | [paper](https://transacl.org/ojs/index.php/tacl/article/view/229/33) | 317,695 |
163
+ | [Stack Exchange](https://huggingface.co/datasets/flax-sentence-embeddings/stackexchange_xml) Duplicate questions (titles) | | 304,525 |
164
+ | AllNLI ([SNLI](https://nlp.stanford.edu/projects/snli/) and [MultiNLI](https://cims.nyu.edu/~sbowman/multinli/) | [paper SNLI](https://doi.org/10.18653/v1/d15-1075), [paper MultiNLI](https://doi.org/10.18653/v1/n18-1101) | 277,230 |
165
+ | [Stack Exchange](https://huggingface.co/datasets/flax-sentence-embeddings/stackexchange_xml) Duplicate questions (bodies) | | 250,519 |
166
+ | [Stack Exchange](https://huggingface.co/datasets/flax-sentence-embeddings/stackexchange_xml) Duplicate questions (titles+bodies) | | 250,460 |
167
+ | [Sentence Compression](https://github.com/google-research-datasets/sentence-compression) | [paper](https://www.aclweb.org/anthology/D13-1155/) | 180,000 |
168
+ | [Wikihow](https://github.com/pvl/wikihow_pairs_dataset) | [paper](https://arxiv.org/abs/1810.09305) | 128,542 |
169
+ | [Altlex](https://github.com/chridey/altlex/) | [paper](https://aclanthology.org/P16-1135.pdf) | 112,696 |
170
+ | [Quora Question Triplets](https://quoradata.quora.com/First-Quora-Dataset-Release-Question-Pairs) | - | 103,663 |
171
+ | [Simple Wikipedia](https://cs.pomona.edu/~dkauchak/simplification/) | [paper](https://www.aclweb.org/anthology/P11-2117/) | 102,225 |
172
+ | [Natural Questions (NQ)](https://ai.google.com/research/NaturalQuestions) | [paper](https://transacl.org/ojs/index.php/tacl/article/view/1455) | 100,231 |
173
+ | [SQuAD2.0](https://rajpurkar.github.io/SQuAD-explorer/) | [paper](https://aclanthology.org/P18-2124.pdf) | 87,599 |
174
+ | [TriviaQA](https://huggingface.co/datasets/trivia_qa) | - | 73,346 |
175
+ | **Total** | | **1,170,060,424** |
base_model/config.json ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_name_or_path": "nreimers/MiniLM-L6-H384-uncased",
3
+ "architectures": [
4
+ "BertModel"
5
+ ],
6
+ "attention_probs_dropout_prob": 0.1,
7
+ "gradient_checkpointing": false,
8
+ "hidden_act": "gelu",
9
+ "hidden_dropout_prob": 0.1,
10
+ "hidden_size": 384,
11
+ "initializer_range": 0.02,
12
+ "intermediate_size": 1536,
13
+ "layer_norm_eps": 1e-12,
14
+ "max_position_embeddings": 512,
15
+ "model_type": "bert",
16
+ "num_attention_heads": 12,
17
+ "num_hidden_layers": 6,
18
+ "pad_token_id": 0,
19
+ "position_embedding_type": "absolute",
20
+ "transformers_version": "4.8.2",
21
+ "type_vocab_size": 2,
22
+ "use_cache": true,
23
+ "vocab_size": 30522
24
+ }
base_model/config_sentence_transformers.json ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ {
2
+ "__version__": {
3
+ "sentence_transformers": "2.0.0",
4
+ "transformers": "4.6.1",
5
+ "pytorch": "1.8.1"
6
+ }
7
+ }
base_model/model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:53aa51172d142c89d9012cce15ae4d6cc0ca6895895114379cacb4fab128d9db
3
+ size 90868376
base_model/modules.json ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "idx": 0,
4
+ "name": "0",
5
+ "path": "",
6
+ "type": "sentence_transformers.models.Transformer"
7
+ },
8
+ {
9
+ "idx": 1,
10
+ "name": "1",
11
+ "path": "1_Pooling",
12
+ "type": "sentence_transformers.models.Pooling"
13
+ },
14
+ {
15
+ "idx": 2,
16
+ "name": "2",
17
+ "path": "2_Normalize",
18
+ "type": "sentence_transformers.models.Normalize"
19
+ }
20
+ ]
base_model/sentence_bert_config.json ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ {
2
+ "max_seq_length": 256,
3
+ "do_lower_case": false
4
+ }
base_model/special_tokens_map.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"unk_token": "[UNK]", "sep_token": "[SEP]", "pad_token": "[PAD]", "cls_token": "[CLS]", "mask_token": "[MASK]"}
base_model/tokenizer.json ADDED
The diff for this file is too large to render. See raw diff
 
base_model/tokenizer_config.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"do_lower_case": true, "unk_token": "[UNK]", "sep_token": "[SEP]", "pad_token": "[PAD]", "cls_token": "[CLS]", "mask_token": "[MASK]", "tokenize_chinese_chars": true, "strip_accents": null, "name_or_path": "nreimers/MiniLM-L6-H384-uncased", "do_basic_tokenize": true, "never_split": null, "tokenizer_class": "BertTokenizer", "model_max_length": 512}
base_model/vocab.txt ADDED
The diff for this file is too large to render. See raw diff
 
checkpoints/seed-0.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:5c38aa73b22d91591d644829259c9c6a790e76380fb49ff947d52fee4f6fd40a
3
+ size 601008
checkpoints/seed-1.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1b74e3473191677c943d3f36b9437213be23ab5e3cf2cf0300773c489f0fafd8
3
+ size 601008
checkpoints/seed-2.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:37b5302e645423512b6fcd6328a4f371ab8f5220457514dcd8bf2d27bdbc5a8d
3
+ size 601008
checks/packaged-inference-verification.json ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "device": "cpu",
3
+ "torch": "2.13.0+cu130",
4
+ "released_seed": 2,
5
+ "selection": {
6
+ "0": {
7
+ "epoch": 8,
8
+ "validation_nll": 0.14147035955480516,
9
+ "validation_accuracy": 0.9547383309759547
10
+ },
11
+ "1": {
12
+ "epoch": 7,
13
+ "validation_nll": 0.1305078952452114,
14
+ "validation_accuracy": 0.9519094766619519
15
+ },
16
+ "2": {
17
+ "epoch": 8,
18
+ "validation_nll": 0.12104468951391349,
19
+ "validation_accuracy": 0.9561527581329562
20
+ }
21
+ },
22
+ "seed-0": {
23
+ "frozen_backbone_sha256_matches": true,
24
+ "test_max_abs_probability_difference": 3.7550926208496094e-06,
25
+ "test_predicted_labels_match": true,
26
+ "test_accuracy": 0.9663865546218487,
27
+ "test_accuracy_recorded": 0.9663865546218487,
28
+ "validation_accuracy": 0.9547383309759547,
29
+ "validation_accuracy_recorded": 0.9547383309759547,
30
+ "validation_nll": 0.14147038757801056,
31
+ "validation_nll_recorded": 0.14147035955480516
32
+ },
33
+ "seed-1": {
34
+ "frozen_backbone_sha256_matches": true,
35
+ "test_max_abs_probability_difference": 3.933906555175781e-06,
36
+ "test_predicted_labels_match": true,
37
+ "test_accuracy": 0.9593837535014006,
38
+ "test_accuracy_recorded": 0.9593837535014006,
39
+ "validation_accuracy": 0.9519094766619519,
40
+ "validation_accuracy_recorded": 0.9519094766619519,
41
+ "validation_nll": 0.13050784170627594,
42
+ "validation_nll_recorded": 0.1305078952452114
43
+ },
44
+ "seed-2": {
45
+ "frozen_backbone_sha256_matches": true,
46
+ "test_max_abs_probability_difference": 5.334615707397461e-06,
47
+ "test_predicted_labels_match": true,
48
+ "test_accuracy": 0.9719887955182073,
49
+ "test_accuracy_recorded": 0.9719887955182073,
50
+ "validation_accuracy": 0.9561527581329562,
51
+ "validation_accuracy_recorded": 0.9561527581329562,
52
+ "validation_nll": 0.12104469537734985,
53
+ "validation_nll_recorded": 0.12104468951391349
54
+ },
55
+ "examples": {
56
+ "Restart my web server.": "task",
57
+ "yes after a restart offer": "task",
58
+ "yes after a backup-check offer": "question"
59
+ }
60
+ }
data/README.md ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Clover English intent dataset
2
+
3
+ Developed by AKIKI.AI.
4
+
5
+ Six labels: chat, question, build, task, fix, unclear. English only. Class IDs A–F follow that order.
6
+
7
+ Model inputs are only `message` and `context` (earlier turns containing `role` and `text`). `label` is the target. Difficulty, domain, review reasons and all provenance fields are annotations and are excluded from the model input. The supplied renderer enforces this separation.
8
+
9
+ Examples were generated locally with cached Qwen3.8-27B-FP8, independently classified by cached Qwen3.5-9B, and checked again in a fresh label-blind 27B request. Target labels and earlier votes are hidden, and input order is shuffled. Disagreements are rejected. The extra 27B vote reuses the generator checkpoint, so it is not a third distinct model. For hard examples, both models must recover the intended route from context and classify the same message without context as unclear. Hard unclear examples instead require both to find multiple unresolved referents. Decorative context is insufficient. These are synthetic, model-reviewed labels. Human review remains pending.
10
+
11
+ | Split | Examples | Easy | Medium | Hard |
12
+ |---|---:|---:|---:|---:|
13
+ | train | 9913 | 3228 | 3325 | 3360 |
14
+ | validation | 707 | 229 | 238 | 240 |
15
+ | test | 714 | 235 | 239 | 240 |
16
+
17
+ Scenario groups and all scenarios sharing a generation output remain in one split. Exact full-input duplicates are removed. Character n-gram similarity ≥0.92 removes lower-priority cross-split examples, protecting test first, then validation. Every retained input fits both encoder tokenizers without truncation.
18
+
19
+ The longest rendered input is 126 MiniLM tokens and 127 ModernBERT tokens, including tokenizer special tokens. The experiment's 512-token encoder input cap is therefore not approached; these results do not establish long-context routing performance.
20
+
21
+ Audit removed 186 examples. File hashes and label/difficulty counts are in manifest.json; drops and reasons are in audit-drops.jsonl. review-sample.jsonl is a stratified sample prepared for inspection, not evidence that human inspection has occurred.
22
+
23
+ Difficulty is assigned before backbone evaluation. No backbone results were used to label difficulty or select examples. Hard current messages use a class-neutral follow-up bank, with phrase families separated between train, validation and test; the generator invents the contexts. This is a controlled contextual routing test, not an unrestricted natural-conversation sample. Model agreement and lexical filtering do not prove correctness or semantic independence.
data/audit-drops.jsonl ADDED
@@ -0,0 +1,186 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {"id": "test-00042-unclear", "reason": "exact_duplicate"}
2
+ {"id": "test-00069-unclear", "reason": "exact_duplicate"}
3
+ {"id": "test-00075-unclear", "reason": "exact_duplicate"}
4
+ {"id": "test-00096-unclear", "reason": "exact_duplicate"}
5
+ {"id": "test-00112-unclear", "reason": "exact_duplicate"}
6
+ {"id": "test-00114-unclear", "reason": "exact_duplicate"}
7
+ {"id": "validation-00003-unclear", "reason": "exact_duplicate"}
8
+ {"id": "validation-00006-unclear", "reason": "exact_duplicate"}
9
+ {"id": "validation-00012-unclear", "reason": "exact_duplicate"}
10
+ {"id": "validation-00021-unclear", "reason": "exact_duplicate"}
11
+ {"id": "validation-00033-unclear", "reason": "exact_duplicate"}
12
+ {"id": "validation-00037-unclear", "reason": "exact_duplicate"}
13
+ {"id": "validation-00039-unclear", "reason": "exact_duplicate"}
14
+ {"id": "validation-00040-unclear", "reason": "exact_duplicate"}
15
+ {"id": "validation-00048-unclear", "reason": "exact_duplicate"}
16
+ {"id": "validation-00063-unclear", "reason": "exact_duplicate"}
17
+ {"id": "validation-00075-unclear", "reason": "exact_duplicate"}
18
+ {"id": "validation-00093-unclear", "reason": "exact_duplicate"}
19
+ {"id": "validation-00117-unclear", "reason": "exact_duplicate"}
20
+ {"id": "train-00012-unclear", "reason": "exact_duplicate"}
21
+ {"id": "train-00045-unclear", "reason": "exact_duplicate"}
22
+ {"id": "train-00054-unclear", "reason": "exact_duplicate"}
23
+ {"id": "train-00072-unclear", "reason": "exact_duplicate"}
24
+ {"id": "train-00075-unclear", "reason": "exact_duplicate"}
25
+ {"id": "train-00123-unclear", "reason": "exact_duplicate"}
26
+ {"id": "train-00127-unclear", "reason": "exact_duplicate"}
27
+ {"id": "train-00129-unclear", "reason": "exact_duplicate"}
28
+ {"id": "train-00168-unclear", "reason": "exact_duplicate"}
29
+ {"id": "train-00177-unclear", "reason": "exact_duplicate"}
30
+ {"id": "train-00204-unclear", "reason": "exact_duplicate"}
31
+ {"id": "train-00213-unclear", "reason": "exact_duplicate"}
32
+ {"id": "train-00225-unclear", "reason": "exact_duplicate"}
33
+ {"id": "train-00234-unclear", "reason": "exact_duplicate"}
34
+ {"id": "train-00243-unclear", "reason": "exact_duplicate"}
35
+ {"id": "train-00252-unclear", "reason": "exact_duplicate"}
36
+ {"id": "train-00258-unclear", "reason": "exact_duplicate"}
37
+ {"id": "train-00264-unclear", "reason": "exact_duplicate"}
38
+ {"id": "train-00279-unclear", "reason": "exact_duplicate"}
39
+ {"id": "train-00288-unclear", "reason": "exact_duplicate"}
40
+ {"id": "train-00289-unclear", "reason": "exact_duplicate"}
41
+ {"id": "train-00304-unclear", "reason": "exact_duplicate"}
42
+ {"id": "train-00310-unclear", "reason": "exact_duplicate"}
43
+ {"id": "train-00315-unclear", "reason": "exact_duplicate"}
44
+ {"id": "train-00321-unclear", "reason": "exact_duplicate"}
45
+ {"id": "train-00325-unclear", "reason": "exact_duplicate"}
46
+ {"id": "train-00328-unclear", "reason": "exact_duplicate"}
47
+ {"id": "train-00334-unclear", "reason": "exact_duplicate"}
48
+ {"id": "train-00354-unclear", "reason": "exact_duplicate"}
49
+ {"id": "train-00366-unclear", "reason": "exact_duplicate"}
50
+ {"id": "train-00372-unclear", "reason": "exact_duplicate"}
51
+ {"id": "train-00375-chat", "reason": "exact_duplicate"}
52
+ {"id": "train-00378-unclear", "reason": "exact_duplicate"}
53
+ {"id": "train-00381-unclear", "reason": "exact_duplicate"}
54
+ {"id": "train-00387-unclear", "reason": "exact_duplicate"}
55
+ {"id": "train-00396-unclear", "reason": "exact_duplicate"}
56
+ {"id": "train-00408-unclear", "reason": "exact_duplicate"}
57
+ {"id": "train-00420-unclear", "reason": "exact_duplicate"}
58
+ {"id": "train-00430-chat", "reason": "exact_duplicate"}
59
+ {"id": "train-00438-unclear", "reason": "exact_duplicate"}
60
+ {"id": "train-00441-unclear", "reason": "exact_duplicate"}
61
+ {"id": "train-00445-unclear", "reason": "exact_duplicate"}
62
+ {"id": "train-00451-unclear", "reason": "exact_duplicate"}
63
+ {"id": "train-00474-unclear", "reason": "exact_duplicate"}
64
+ {"id": "train-00477-unclear", "reason": "exact_duplicate"}
65
+ {"id": "train-00480-unclear", "reason": "exact_duplicate"}
66
+ {"id": "train-00501-unclear", "reason": "exact_duplicate"}
67
+ {"id": "train-00516-unclear", "reason": "exact_duplicate"}
68
+ {"id": "train-00525-unclear", "reason": "exact_duplicate"}
69
+ {"id": "train-00534-unclear", "reason": "exact_duplicate"}
70
+ {"id": "train-00543-unclear", "reason": "exact_duplicate"}
71
+ {"id": "train-00549-unclear", "reason": "exact_duplicate"}
72
+ {"id": "train-00552-unclear", "reason": "exact_duplicate"}
73
+ {"id": "train-00564-unclear", "reason": "exact_duplicate"}
74
+ {"id": "train-00576-unclear", "reason": "exact_duplicate"}
75
+ {"id": "train-00588-unclear", "reason": "exact_duplicate"}
76
+ {"id": "train-00591-unclear", "reason": "exact_duplicate"}
77
+ {"id": "train-00600-unclear", "reason": "exact_duplicate"}
78
+ {"id": "train-00606-unclear", "reason": "exact_duplicate"}
79
+ {"id": "train-00609-unclear", "reason": "exact_duplicate"}
80
+ {"id": "train-00615-unclear", "reason": "exact_duplicate"}
81
+ {"id": "train-00630-unclear", "reason": "exact_duplicate"}
82
+ {"id": "train-00636-unclear", "reason": "exact_duplicate"}
83
+ {"id": "train-00643-unclear", "reason": "exact_duplicate"}
84
+ {"id": "train-00648-unclear", "reason": "exact_duplicate"}
85
+ {"id": "train-00660-unclear", "reason": "exact_duplicate"}
86
+ {"id": "train-00666-unclear", "reason": "exact_duplicate"}
87
+ {"id": "train-00669-unclear", "reason": "exact_duplicate"}
88
+ {"id": "train-00690-unclear", "reason": "exact_duplicate"}
89
+ {"id": "train-00696-unclear", "reason": "exact_duplicate"}
90
+ {"id": "train-00711-unclear", "reason": "exact_duplicate"}
91
+ {"id": "train-00723-unclear", "reason": "exact_duplicate"}
92
+ {"id": "train-00732-unclear", "reason": "exact_duplicate"}
93
+ {"id": "train-00738-unclear", "reason": "exact_duplicate"}
94
+ {"id": "train-00741-unclear", "reason": "exact_duplicate"}
95
+ {"id": "train-00753-unclear", "reason": "exact_duplicate"}
96
+ {"id": "train-00765-unclear", "reason": "exact_duplicate"}
97
+ {"id": "train-00787-unclear", "reason": "exact_duplicate"}
98
+ {"id": "train-00807-unclear", "reason": "exact_duplicate"}
99
+ {"id": "train-00816-chat", "reason": "exact_duplicate"}
100
+ {"id": "train-00816-unclear", "reason": "exact_duplicate"}
101
+ {"id": "train-00855-task", "reason": "exact_duplicate"}
102
+ {"id": "train-00856-unclear", "reason": "exact_duplicate"}
103
+ {"id": "train-00876-unclear", "reason": "exact_duplicate"}
104
+ {"id": "train-00879-unclear", "reason": "exact_duplicate"}
105
+ {"id": "train-00891-unclear", "reason": "exact_duplicate"}
106
+ {"id": "train-00895-unclear", "reason": "exact_duplicate"}
107
+ {"id": "train-00907-unclear", "reason": "exact_duplicate"}
108
+ {"id": "train-00921-unclear", "reason": "exact_duplicate"}
109
+ {"id": "train-00973-unclear", "reason": "exact_duplicate"}
110
+ {"id": "train-00984-chat", "reason": "exact_duplicate"}
111
+ {"id": "train-00999-unclear", "reason": "exact_duplicate"}
112
+ {"id": "train-01011-unclear", "reason": "exact_duplicate"}
113
+ {"id": "train-01014-unclear", "reason": "exact_duplicate"}
114
+ {"id": "train-01017-unclear", "reason": "exact_duplicate"}
115
+ {"id": "train-01047-unclear", "reason": "exact_duplicate"}
116
+ {"id": "train-01050-unclear", "reason": "exact_duplicate"}
117
+ {"id": "train-01060-unclear", "reason": "exact_duplicate"}
118
+ {"id": "train-01071-unclear", "reason": "exact_duplicate"}
119
+ {"id": "train-01074-unclear", "reason": "exact_duplicate"}
120
+ {"id": "train-01095-unclear", "reason": "exact_duplicate"}
121
+ {"id": "train-01108-unclear", "reason": "exact_duplicate"}
122
+ {"id": "train-01140-unclear", "reason": "exact_duplicate"}
123
+ {"id": "train-01143-unclear", "reason": "exact_duplicate"}
124
+ {"id": "train-01146-unclear", "reason": "exact_duplicate"}
125
+ {"id": "train-01158-unclear", "reason": "exact_duplicate"}
126
+ {"id": "train-01165-chat", "reason": "exact_duplicate"}
127
+ {"id": "train-01179-unclear", "reason": "exact_duplicate"}
128
+ {"id": "train-01191-unclear", "reason": "exact_duplicate"}
129
+ {"id": "train-01194-unclear", "reason": "exact_duplicate"}
130
+ {"id": "train-01206-unclear", "reason": "exact_duplicate"}
131
+ {"id": "train-01216-unclear", "reason": "exact_duplicate"}
132
+ {"id": "train-01221-chat", "reason": "exact_duplicate"}
133
+ {"id": "train-01233-unclear", "reason": "exact_duplicate"}
134
+ {"id": "train-01239-unclear", "reason": "exact_duplicate"}
135
+ {"id": "train-01260-unclear", "reason": "exact_duplicate"}
136
+ {"id": "train-01267-unclear", "reason": "exact_duplicate"}
137
+ {"id": "train-01269-unclear", "reason": "exact_duplicate"}
138
+ {"id": "train-01278-unclear", "reason": "exact_duplicate"}
139
+ {"id": "train-01315-unclear", "reason": "exact_duplicate"}
140
+ {"id": "train-01327-chat", "reason": "exact_duplicate"}
141
+ {"id": "train-01335-unclear", "reason": "exact_duplicate"}
142
+ {"id": "train-01338-chat", "reason": "exact_duplicate"}
143
+ {"id": "train-01339-unclear", "reason": "exact_duplicate"}
144
+ {"id": "train-01348-unclear", "reason": "exact_duplicate"}
145
+ {"id": "train-01362-unclear", "reason": "exact_duplicate"}
146
+ {"id": "train-01374-unclear", "reason": "exact_duplicate"}
147
+ {"id": "train-01377-unclear", "reason": "exact_duplicate"}
148
+ {"id": "train-01416-unclear", "reason": "exact_duplicate"}
149
+ {"id": "train-01434-unclear", "reason": "exact_duplicate"}
150
+ {"id": "train-01437-unclear", "reason": "exact_duplicate"}
151
+ {"id": "train-01443-unclear", "reason": "exact_duplicate"}
152
+ {"id": "train-01452-chat", "reason": "exact_duplicate"}
153
+ {"id": "train-01455-chat", "reason": "exact_duplicate"}
154
+ {"id": "train-01467-unclear", "reason": "exact_duplicate"}
155
+ {"id": "train-01473-unclear", "reason": "exact_duplicate"}
156
+ {"id": "train-01494-task", "reason": "exact_duplicate"}
157
+ {"id": "train-01518-unclear", "reason": "exact_duplicate"}
158
+ {"id": "train-01534-unclear", "reason": "exact_duplicate"}
159
+ {"id": "train-01536-unclear", "reason": "exact_duplicate"}
160
+ {"id": "train-01545-unclear", "reason": "exact_duplicate"}
161
+ {"id": "train-01593-unclear", "reason": "exact_duplicate"}
162
+ {"id": "train-01596-unclear", "reason": "exact_duplicate"}
163
+ {"id": "train-01603-unclear", "reason": "exact_duplicate"}
164
+ {"id": "train-01617-unclear", "reason": "exact_duplicate"}
165
+ {"id": "train-01626-chat", "reason": "exact_duplicate"}
166
+ {"id": "train-01641-unclear", "reason": "exact_duplicate"}
167
+ {"id": "train-01656-unclear", "reason": "exact_duplicate"}
168
+ {"id": "train-01662-unclear", "reason": "exact_duplicate"}
169
+ {"id": "train-01674-unclear", "reason": "exact_duplicate"}
170
+ {"id": "train-00003-unclear", "reason": "cross_split_near_duplicate", "similarity": 0.9422524571418762, "protected_split": "test"}
171
+ {"id": "train-00024-unclear", "reason": "cross_split_near_duplicate", "similarity": 0.9288095831871033, "protected_split": "test"}
172
+ {"id": "train-00192-unclear", "reason": "cross_split_near_duplicate", "similarity": 0.9634224772453308, "protected_split": "test"}
173
+ {"id": "train-00397-unclear", "reason": "cross_split_near_duplicate", "similarity": 0.9594231843948364, "protected_split": "test"}
174
+ {"id": "train-00520-unclear", "reason": "cross_split_near_duplicate", "similarity": 0.9355655908584595, "protected_split": "test"}
175
+ {"id": "train-00532-unclear", "reason": "cross_split_near_duplicate", "similarity": 0.952883780002594, "protected_split": "test"}
176
+ {"id": "train-00541-unclear", "reason": "cross_split_near_duplicate", "similarity": 0.9207755923271179, "protected_split": "test"}
177
+ {"id": "train-00546-unclear", "reason": "cross_split_near_duplicate", "similarity": 0.9416508674621582, "protected_split": "test"}
178
+ {"id": "train-01137-unclear", "reason": "cross_split_near_duplicate", "similarity": 0.9582526683807373, "protected_split": "test"}
179
+ {"id": "train-01584-question", "reason": "cross_split_near_duplicate", "similarity": 0.9418998956680298, "protected_split": "test"}
180
+ {"id": "train-00604-unclear", "reason": "cross_split_near_duplicate", "similarity": 0.9394984245300293, "protected_split": "validation"}
181
+ {"id": "train-00963-unclear", "reason": "cross_split_near_duplicate", "similarity": 0.9514755010604858, "protected_split": "validation"}
182
+ {"id": "train-00985-unclear", "reason": "cross_split_near_duplicate", "similarity": 0.9511113166809082, "protected_split": "validation"}
183
+ {"id": "train-01117-task", "reason": "cross_split_near_duplicate", "similarity": 0.9571490287780762, "protected_split": "validation"}
184
+ {"id": "train-01212-unclear", "reason": "cross_split_near_duplicate", "similarity": 0.9307024478912354, "protected_split": "validation"}
185
+ {"id": "train-01290-unclear", "reason": "cross_split_near_duplicate", "similarity": 0.9405972957611084, "protected_split": "validation"}
186
+ {"id": "train-01390-task", "reason": "cross_split_near_duplicate", "similarity": 0.9359763860702515, "protected_split": "validation"}
data/audit.json ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "passed": true,
3
+ "scenario_groups_cross_splits": 0,
4
+ "exact_full_input_duplicates": 0,
5
+ "cross_split_similarity_threshold": 0.92,
6
+ "pre_filter_max_similarities": {
7
+ "test/validation": 0.9049872756004333,
8
+ "test/train": 0.9634224772453308,
9
+ "validation/train": 0.9571490287780762
10
+ },
11
+ "dropped": 186,
12
+ "synthetic_only": true,
13
+ "human_reviewed": false,
14
+ "difficulty": "preassigned generation constraints, independent of evaluated backbone scores",
15
+ "encoder_input_audit": {
16
+ "minilm-l6-v2": {
17
+ "maximum_before_filter": 126,
18
+ "over_512": 0
19
+ },
20
+ "modernbert-base": {
21
+ "maximum_before_filter": 127,
22
+ "over_512": 0
23
+ }
24
+ },
25
+ "limitations": [
26
+ "Model agreement is not ground truth; human review required for release-quality claims.",
27
+ "Lexical near-duplicate filtering does not prove semantic or template independence.",
28
+ "Difficulty labels reflect the requested construction, not a human difficulty rating."
29
+ ]
30
+ }
data/manifest.json ADDED
@@ -0,0 +1,186 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "version": 1,
3
+ "language": "en",
4
+ "labels": [
5
+ "chat",
6
+ "question",
7
+ "build",
8
+ "task",
9
+ "fix",
10
+ "unclear"
11
+ ],
12
+ "difficulty_levels": [
13
+ "easy",
14
+ "medium",
15
+ "hard"
16
+ ],
17
+ "rubric_sha256": "6ff2b88f9dfd69573c07a8629fb51977c6b2c72d7e33cbf3978cf209d659f4f3",
18
+ "splits": {
19
+ "train": {
20
+ "file": "train.jsonl",
21
+ "sha256": "2e3edef9182471d0fcd3738fdf886fdbe78fac5e6f3855373ab92a6ad0f1ca72",
22
+ "rows": 9913,
23
+ "label_counts": {
24
+ "task": 1676,
25
+ "fix": 1680,
26
+ "build": 1680,
27
+ "chat": 1669,
28
+ "unclear": 1529,
29
+ "question": 1679
30
+ },
31
+ "difficulty_counts": {
32
+ "medium": 3325,
33
+ "hard": 3360,
34
+ "easy": 3228
35
+ },
36
+ "label_difficulty_counts": {
37
+ "chat": {
38
+ "easy": 552,
39
+ "medium": 557,
40
+ "hard": 560
41
+ },
42
+ "question": {
43
+ "easy": 559,
44
+ "medium": 560,
45
+ "hard": 560
46
+ },
47
+ "build": {
48
+ "easy": 560,
49
+ "medium": 560,
50
+ "hard": 560
51
+ },
52
+ "task": {
53
+ "easy": 558,
54
+ "medium": 558,
55
+ "hard": 560
56
+ },
57
+ "fix": {
58
+ "easy": 560,
59
+ "medium": 560,
60
+ "hard": 560
61
+ },
62
+ "unclear": {
63
+ "easy": 439,
64
+ "medium": 530,
65
+ "hard": 560
66
+ }
67
+ }
68
+ },
69
+ "validation": {
70
+ "file": "validation.jsonl",
71
+ "sha256": "40759974effb15fe000589d5e9082ae94c7c760a9dfef40cb364d95bc74c953b",
72
+ "rows": 707,
73
+ "label_counts": {
74
+ "question": 120,
75
+ "task": 120,
76
+ "fix": 120,
77
+ "build": 120,
78
+ "unclear": 107,
79
+ "chat": 120
80
+ },
81
+ "difficulty_counts": {
82
+ "easy": 229,
83
+ "hard": 240,
84
+ "medium": 238
85
+ },
86
+ "label_difficulty_counts": {
87
+ "chat": {
88
+ "easy": 40,
89
+ "medium": 40,
90
+ "hard": 40
91
+ },
92
+ "question": {
93
+ "easy": 40,
94
+ "medium": 40,
95
+ "hard": 40
96
+ },
97
+ "build": {
98
+ "easy": 40,
99
+ "medium": 40,
100
+ "hard": 40
101
+ },
102
+ "task": {
103
+ "easy": 40,
104
+ "medium": 40,
105
+ "hard": 40
106
+ },
107
+ "fix": {
108
+ "easy": 40,
109
+ "medium": 40,
110
+ "hard": 40
111
+ },
112
+ "unclear": {
113
+ "easy": 29,
114
+ "medium": 38,
115
+ "hard": 40
116
+ }
117
+ }
118
+ },
119
+ "test": {
120
+ "file": "test.jsonl",
121
+ "sha256": "8e1fde3f1074fb216e73b879fe3905d4448faf1c7a83d1fef6b3078dc1560c28",
122
+ "rows": 714,
123
+ "label_counts": {
124
+ "unclear": 114,
125
+ "chat": 120,
126
+ "build": 120,
127
+ "task": 120,
128
+ "question": 120,
129
+ "fix": 120
130
+ },
131
+ "difficulty_counts": {
132
+ "medium": 239,
133
+ "hard": 240,
134
+ "easy": 235
135
+ },
136
+ "label_difficulty_counts": {
137
+ "chat": {
138
+ "easy": 40,
139
+ "medium": 40,
140
+ "hard": 40
141
+ },
142
+ "question": {
143
+ "easy": 40,
144
+ "medium": 40,
145
+ "hard": 40
146
+ },
147
+ "build": {
148
+ "easy": 40,
149
+ "medium": 40,
150
+ "hard": 40
151
+ },
152
+ "task": {
153
+ "easy": 40,
154
+ "medium": 40,
155
+ "hard": 40
156
+ },
157
+ "fix": {
158
+ "easy": 40,
159
+ "medium": 40,
160
+ "hard": 40
161
+ },
162
+ "unclear": {
163
+ "easy": 35,
164
+ "medium": 39,
165
+ "hard": 40
166
+ }
167
+ }
168
+ }
169
+ },
170
+ "audit_sha256": "3ed02c8fb676df20988b89adb1e04ed4fcb99565e3f6bab1e0eabc5bd2778607",
171
+ "generator": "clover-teacher-27b",
172
+ "reviewer": "akiki-qwen35-9b",
173
+ "local_checkpoints": {
174
+ "generator": "Qwen/Qwen3.8-27B-FP8@017b9c7af6b5689d5dd426a76e0bc077eb5ca20a",
175
+ "reviewer": "Qwen/Qwen3.5-9B@c202236235762e1c871ad0ccb60c8ee5ba337b9a"
176
+ },
177
+ "generation_sources_sha256": {
178
+ "/mnt/storage/ariadne/scripts/build_clover_dataset.py": "35580bb3da8d9099d3a4f28c7366b498b1da26dc890307861720569636d65af5",
179
+ "scripts/build_clover_native_batch.py": "ab92d1c1a34e59fccfbe7d17564a0277223ce43ae5fdefe0102c7c1d9c9f816f",
180
+ "scripts/repair_clover_batch.py": "902630e11625ad04d3e9bf87f7301e8d59b03e80f1fc3ccf2412fb5bfd0b10b4",
181
+ "scripts/benchmark_clover_generation.py": "a368567a6f364c9dc1cf284fb49f67809aad1ce22de001c2c2f710c123e44144",
182
+ "ariadne_bench/clover.py": "270b5ab0ea3ad33cec13803f4ccb4ee2ecdd5f8c7152780712546d3e94c8e798",
183
+ "data/clover-intent-v1/generation-overrides.json": "bdf8a0179a856387ed16807d4f1f141390ed636747fc1476c476ec1f998a721a"
184
+ },
185
+ "complete": true
186
+ }
data/test.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
data/train.jsonl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:2e3edef9182471d0fcd3738fdf886fdbe78fac5e6f3855373ab92a6ad0f1ca72
3
+ size 13057269
data/validation.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
model.py ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Akiki MiniLM-L6-v2 Clover intent classifier.
2
+
3
+ A frozen sentence-transformers/all-MiniLM-L6-v2 encoder, an identity-initialized
4
+ 384 x 384 Akiki input affine on its word embeddings, and a six-class head.
5
+ Classes, in order: A=chat, B=question, C=build, D=task, E=fix, F=unclear.
6
+
7
+ from model import CloverIntent
8
+ clf = CloverIntent.from_pretrained(".")
9
+ clf.predict("Restart my web server.")
10
+ clf.predict("yes", context=[{"role": "assistant", "text": "Shall I restart nginx?"}])
11
+
12
+ Command line:
13
+
14
+ python model.py 'Restart my web server.'
15
+ python model.py --context-file context.json --output json 'yes'
16
+ """
17
+
18
+ import argparse
19
+ import json
20
+ from pathlib import Path
21
+
22
+ import torch
23
+ from safetensors.torch import load_file
24
+ from torch import nn
25
+ from torch.nn import functional as F
26
+
27
+ LABELS = ("chat", "question", "build", "task", "fix", "unclear")
28
+ MAX_LEN = 512
29
+ HERE = Path(__file__).resolve().parent
30
+
31
+
32
+ def render(message, context=()):
33
+ """The exact text seen in training: earlier turns, then the current message."""
34
+ prior = "\n".join(f"{turn['role']}: {turn['text']}" for turn in context)
35
+ return ("Conversation context:\n" + prior + "\n\n" if prior else "") + "Current user message: " + message
36
+
37
+
38
+ class IdentityAffine(nn.Module):
39
+ """Akiki input affine, kept in FP32 regardless of autocast."""
40
+
41
+ def __init__(self, width):
42
+ super().__init__()
43
+ self.proj = nn.Linear(width, width)
44
+ nn.init.eye_(self.proj.weight)
45
+ nn.init.zeros_(self.proj.bias)
46
+
47
+ def forward(self, x):
48
+ with torch.autocast(device_type=x.device.type, enabled=False):
49
+ value = F.linear(x.float(), self.proj.weight.float(), self.proj.bias.float())
50
+ return value.to(x.dtype)
51
+
52
+
53
+ class FrozenEncoderClassifier(nn.Module):
54
+ def __init__(self, encoder):
55
+ super().__init__()
56
+ width = encoder.config.hidden_size
57
+ self.pretrained = encoder.requires_grad_(False).eval()
58
+ self.interface = IdentityAffine(width)
59
+ self.head = nn.Linear(width, len(LABELS))
60
+ # The affine transforms word embeddings before position and type embeddings are added.
61
+ encoder.get_input_embeddings().register_forward_hook(lambda module, args, output: self.interface(output))
62
+
63
+ def features(self, input_ids, attention_mask):
64
+ hidden = self.pretrained(input_ids=input_ids, attention_mask=attention_mask, return_dict=True).last_hidden_state
65
+ mask = attention_mask.unsqueeze(-1).to(hidden.dtype)
66
+ return F.normalize(((hidden * mask).sum(1) / mask.sum(1).clamp_min(1)).float(), dim=-1)
67
+
68
+ def forward(self, input_ids, attention_mask):
69
+ return self.head(self.features(input_ids, attention_mask))
70
+
71
+
72
+ class CloverIntent:
73
+ def __init__(self, tokenizer, model, device):
74
+ self.tokenizer, self.model, self.device = tokenizer, model, device
75
+
76
+ @classmethod
77
+ def from_pretrained(cls, path=HERE, adapter="adapter.safetensors", device="cpu"):
78
+ from transformers import AutoModel, AutoTokenizer
79
+ path = Path(path)
80
+ tokenizer = AutoTokenizer.from_pretrained(path / "base_model", local_files_only=True)
81
+ encoder = AutoModel.from_pretrained(path / "base_model", local_files_only=True,
82
+ dtype=torch.float32, attn_implementation="sdpa")
83
+ model = FrozenEncoderClassifier(encoder)
84
+ missing, unexpected = model.load_state_dict(load_file(path / adapter), strict=False)
85
+ if unexpected or any(not k.startswith("pretrained.") for k in missing):
86
+ raise ValueError(f"Adapter does not match the model: missing={missing}, unexpected={unexpected}")
87
+ return cls(tokenizer, model.to(device).eval(), torch.device(device))
88
+
89
+ def tokenize(self, texts):
90
+ batch = self.tokenizer(list(texts), padding=True, truncation=False, return_tensors="pt")
91
+ if batch["input_ids"].shape[1] > MAX_LEN:
92
+ raise ValueError(f"Input exceeds {MAX_LEN} tokens; truncation is disabled")
93
+ return {k: batch[k].to(self.device) for k in ("input_ids", "attention_mask")}
94
+
95
+ @torch.inference_mode()
96
+ def probabilities(self, rows):
97
+ """rows: dicts with 'message' and optional 'context'. Returns an (n, 6) tensor."""
98
+ texts = [render(r["message"], r.get("context") or ()) for r in rows]
99
+ return self.model(**self.tokenize(texts)).float().softmax(-1).cpu()
100
+
101
+ def predict(self, message, context=()):
102
+ p = self.probabilities([{"message": message, "context": context}])[0]
103
+ index = int(p.argmax())
104
+ return {"label": LABELS[index], "token": chr(65 + index),
105
+ "probabilities": dict(zip(LABELS, p.tolist()))}
106
+
107
+
108
+ def main():
109
+ parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
110
+ parser.add_argument("message")
111
+ parser.add_argument("--context-file", type=Path, help="JSON array of earlier {role, text} turns")
112
+ parser.add_argument("--model", type=Path, default=HERE)
113
+ parser.add_argument("--device", default="cpu")
114
+ parser.add_argument("--output", choices=["token", "label", "json"], default="token")
115
+ args = parser.parse_args()
116
+ context = json.loads(args.context_file.read_text()) if args.context_file else []
117
+ result = CloverIntent.from_pretrained(args.model, device=args.device).predict(args.message, context)
118
+ print(json.dumps(result, indent=2) if args.output == "json" else result[args.output])
119
+
120
+
121
+ if __name__ == "__main__":
122
+ main()
model_config.json ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "model": "Akiki MiniLM-L6-v2 Clover intent",
3
+ "repo_id": "Akiki-AI/Akiki-MiniLM-L6-v2-clover-intent",
4
+ "labels": [
5
+ "chat",
6
+ "question",
7
+ "build",
8
+ "task",
9
+ "fix",
10
+ "unclear"
11
+ ],
12
+ "tokens": {
13
+ "A": "chat",
14
+ "B": "question",
15
+ "C": "build",
16
+ "D": "task",
17
+ "E": "fix",
18
+ "F": "unclear"
19
+ },
20
+ "base_model": "sentence-transformers/all-MiniLM-L6-v2",
21
+ "base_revision": "1110a243fdf4706b3f48f1d95db1a4f5529b4d41",
22
+ "frozen_backbone_sha256": "11ac3c0bba90239eddece3b7eb97f85d85e1107b1bf82b19e2d32fc98a101aa2",
23
+ "base_parameters": 22713216,
24
+ "trainable_parameters": {
25
+ "input_affine": 147840,
26
+ "head": 2310,
27
+ "total": 150150
28
+ },
29
+ "adapter": "adapter.safetensors",
30
+ "released_seed": 2,
31
+ "best_epoch": 8,
32
+ "pooling": "attention-masked mean followed by L2 normalization",
33
+ "max_tokens": 512,
34
+ "truncation": false,
35
+ "input": "Conversation context:\\n<role>: <text>...\\n\\nCurrent user message: <message> (context block omitted when empty)",
36
+ "probabilities": "softmax of head logits; no fitted calibration"
37
+ }
provenance/original/CREDITS.md ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Clover experiment credits
2
+
3
+ Developed by AKIKI.AI.
4
+
5
+ This is an English, six-category intent-classification experiment. The small input
6
+ interfaces and classification readouts are experiment artifacts; the pretrained
7
+ backbones remain frozen.
8
+
9
+ | Cached backbone | Provider | Local revision | Cached licence metadata |
10
+ |---|---|---|---|
11
+ | all-MiniLM-L6-v2 | sentence-transformers | 1110a243fdf4706b3f48f1d95db1a4f5529b4d41 | Apache-2.0 in cached model card |
12
+ | ModernBERT-base | answerdotai | 8949b909ec900327062f0ebf497f51aef5e6f0c8 | Apache-2.0 in cached model card |
13
+ | Laya | convaiinnovations | 55cf4c4ebb4ebe31b2550e8bdf3bd21b99753851 | No model card/licence file in this local snapshot; unverified |
14
+ | Qwen3.5-0.8B | Qwen | 2fc06364715b967f1860aea9cf38778875588b17 | Apache-2.0 in cached model card |
15
+
16
+ Synthetic data uses the existing local Qwen3.8-27B-FP8 checkpoint at revision
17
+ 017b9c7af6b5689d5dd426a76e0bc077eb5ca20a and Qwen3.5-9B at revision
18
+ c202236235762e1c871ad0ccb60c8ee5ba337b9a for independent model review.
19
+
20
+ Tools: the existing Ariadne native adapters and identity input interfaces,
21
+ PyTorch, Hugging Face Transformers, vLLM, NumPy, SciPy, scikit-learn, optimized
22
+ causal-conv1d and FLA kernels, Docker and Git. Model paths and runtime/kernel
23
+ metadata are recorded with the experiment. No model artifacts are downloaded.
24
+
25
+ The local cached licence metadata above is attribution information. This file
26
+ does not assert a separate patent grant or replace the original licence texts.
provenance/original/README.md ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Clover English intent experiment
2
+
3
+ Developed by AKIKI.AI.
4
+
5
+ The dataset is in `data/clover-intent-v1`. It contains six intents: chat,
6
+ question, build, task, fix and unclear. Training, validation and test keep
7
+ originating scenarios and generation outputs together. Each split covers easy,
8
+ medium and hard inputs. Difficulty is defined before backbone evaluation.
9
+
10
+ `generation-benchmark/README.md` records the measured batching, shared prefix,
11
+ sample packing and MTP-three comparison. `dataset-generation.log` and
12
+ `dataset-export.log` record the final build and audit. Model-reviewed labels are
13
+ synthetic and require human review before release-quality acceptance claims.
14
+
15
+ The comparison uses only the exact local cached MiniLM-L6-v2, ModernBERT-base,
16
+ Laya and Qwen3.5-0.8B checkpoints. Every backbone is evaluated before fitting.
17
+ The encoder zero-shot readout uses fixed label-description similarity; the two
18
+ native decision models use their original frozen heads. Encoder alternatives
19
+ include centroid similarity, k-nearest neighbours, k-means and a regularized
20
+ linear classifier. All supervised or cluster-label fitting uses training labels;
21
+ validation selects hyperparameters and checkpoints.
22
+
23
+ Each encoder then compares head-only training with Ariadne input-affine plus
24
+ head training. Laya and Qwen train only their input affine maps, preserving their
25
+ native heads. Three seeds are used. All original tensors remain frozen and are
26
+ hashed throughout. `protocol/` records the pre-training commit, data hashes,
27
+ model paths, seeds, optimization settings and stopping rules.
28
+
29
+ Run the comparison with the existing local runtime:
30
+
31
+ ```bash
32
+ PYTHONPATH=.deps-causal-opt:.deps-decisions:.:scripts \
33
+ .venv-blackwell/bin/python -u scripts/run_clover_experiments.py
34
+ ```
35
+
36
+ Live progress is in `status.json`, `progress.jsonl` and `experiment.log`.
37
+ `results.md`, `results.json` and `seed-summary.json` collect holdout results,
38
+ including the three difficulty tiers, confusion matrices and false actions on
39
+ chat/question. Individual run directories contain histories, small trained
40
+ checkpoints and per-example predictions. A completed epoch can be resumed.
41
+
42
+ Inference prints one class token, with A=chat, B=question, C=build, D=task,
43
+ E=fix and F=unclear:
44
+
45
+ ```bash
46
+ PYTHONPATH=.deps-causal-opt:.deps-decisions:.:scripts \
47
+ .venv-blackwell/bin/python scripts/predict_clover.py \
48
+ --run runs/clover-intent-v1/minilm-l6-v2/ariadne-seed-0 \
49
+ 'Restart my web server.'
50
+ ```
51
+
52
+ Use `--context-file` for prior role/text turns, and `--output label` to print
53
+ the category name instead. All model loading is offline. This experiment does
54
+ not change a served model.
55
+
56
+ `inference-smoke.json` records a contextual inference check and a warm CPU
57
+ measurement for MiniLM Ariadne seed 0. The same message, `yes`, returned task
58
+ after an offer to restart the web server and question after an offer to check
59
+ a backup. With eight CPU threads, FP32 PyTorch/Transformers, batch size one,
60
+ five warm-up calls and 100 measured calls, latency was 2.0 ms median and 3.3 ms
61
+ p95. This includes tokenization and classification, and excludes process start
62
+ and model loading. It measures this server CPU, not a laptop or a Rust runtime.
63
+
64
+ `inference-comparison.json` compares head-only and Ariadne seed 0 on the same
65
+ 22-token context/message input, with the same eight-thread FP32 runtime.
66
+ Across 12 paired blocks with randomized method order, 600 measured calls per
67
+ method gave median latency of 2.40 ms for head-only and 2.47 ms for Ariadne
68
+ (p95 2.57 ms and 2.62 ms). The input affine has 147,840 parameters, or 0.59 MB
69
+ of FP32 weights; the shared backbone has 22,713,216 parameters and the
70
+ six-class head has 2,310. These parameter counts describe potential weight
71
+ storage savings, not measured process RAM: the shared benchmark wrapper
72
+ allocates the affine for both methods and disables it for head-only.
73
+
74
+ The final uniform CPU comparison is in `cpu-latency.json`. It measures all
75
+ readouts on the same contextual request using eight threads, FP32, batch size
76
+ one, five warm-up calls and 100 measured calls, including preparation and
77
+ tokenization. Native choice prompts are longer than encoder inputs. Qwen uses
78
+ the installed Transformers Torch reference functions on CPU; its CUDA-only
79
+ causal/FLA dispatch is bypassed only in that measurement process. The accuracy
80
+ axis in the figures uses the original GPU holdout scores, with BF16 native
81
+ backbones. CPU latency uses seed 0 and is not a re-evaluation of CPU accuracy.
82
+
83
+ `figures/` contains PNG, SVG and PDF exports of:
84
+
85
+ - `frozen-to-trained`: frozen readout to Ariadne mean, with sample SD across
86
+ three seeds. Frozen encoder and native readouts are explicitly distinguished.
87
+ - `latency-accuracy`: Ariadne, head-only and regularized linear classifiers.
88
+ - `latency-accuracy-all-readouts`: additionally includes similarity, nearest
89
+ neighbours, clustering and untrained readouts.
90
+ - `accuracy-by-difficulty`: easy, medium and hard means and sample SD.
91
+
92
+ `figures/chart-data.csv` and `figures/chart-data.json` retain the exact plotted
93
+ data and timing specification. Accuracy error bars represent variation across
94
+ seeds; latency whiskers show the 5th–95th percentiles of warm calls. Neither is
95
+ a confidence interval on human-labelled generalization.
96
+
97
+ Reproduce the charts with the existing plotting environment:
98
+
99
+ ```bash
100
+ .venv-monitor/bin/python scripts/plot_clover_results.py
101
+ ```
102
+
103
+ `final-verification.json` records all 18 completed fits, frozen source/weight
104
+ checks, dataset split hashes and each numerical pass mark. `error-overlap.json`
105
+ compares errors for matched seeds across all four backbones. These analyses
106
+ do not change fitting, data or checkpoint selection. Each model directory
107
+ also contains a `MODEL_CARD.md`.
108
+
109
+ Every evaluation's `predictions.jsonl` stores the six class probabilities.
110
+ `scripts/analyze_clover_uncertainty.py` derives a neighbouring
111
+ `uncertainty.jsonl` with entropy in nats, normalized entropy (0–1), maximum
112
+ class probability and the top-two probability margin. `uncertainty-summary.json`
113
+ aggregates these by run, difficulty and correctness. This analysis uses the
114
+ saved probabilities, preserves original prediction files/hashes, and does not
115
+ rerun models. Entropy measures probability spread; it is not calibrated error
116
+ risk, and the differing readout scales make direct cross-model interpretation
117
+ tentative. The default prediction CLI continues to print a single class token.
provenance/original/final-verification.json ADDED
@@ -0,0 +1,197 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "experiment_complete": true,
3
+ "completed_fits": 18,
4
+ "expected_fits": 18,
5
+ "frozen_sources_match": true,
6
+ "source_files": 55,
7
+ "manifest_matches_protocol": true,
8
+ "split_hashes_match": {
9
+ "train": true,
10
+ "validation": true,
11
+ "test": true
12
+ },
13
+ "all_frozen_weights_verified": true,
14
+ "human_reviewed": false,
15
+ "runs": [
16
+ {
17
+ "run": "laya/ariadne-seed-0",
18
+ "accuracy": 0.957983193277311,
19
+ "false_actions_on_chat_question": 4,
20
+ "actions_on_unclear": 3,
21
+ "accuracy_pass": true,
22
+ "zero_actions_pass": false,
23
+ "both_numerical_passmarks": false,
24
+ "frozen_verified": true
25
+ },
26
+ {
27
+ "run": "laya/ariadne-seed-1",
28
+ "accuracy": 0.9677871148459384,
29
+ "false_actions_on_chat_question": 2,
30
+ "actions_on_unclear": 3,
31
+ "accuracy_pass": true,
32
+ "zero_actions_pass": false,
33
+ "both_numerical_passmarks": false,
34
+ "frozen_verified": true
35
+ },
36
+ {
37
+ "run": "laya/ariadne-seed-2",
38
+ "accuracy": 0.9509803921568627,
39
+ "false_actions_on_chat_question": 3,
40
+ "actions_on_unclear": 2,
41
+ "accuracy_pass": true,
42
+ "zero_actions_pass": false,
43
+ "both_numerical_passmarks": false,
44
+ "frozen_verified": true
45
+ },
46
+ {
47
+ "run": "minilm-l6-v2/ariadne-seed-0",
48
+ "accuracy": 0.9663865546218487,
49
+ "false_actions_on_chat_question": 1,
50
+ "actions_on_unclear": 6,
51
+ "accuracy_pass": true,
52
+ "zero_actions_pass": false,
53
+ "both_numerical_passmarks": false,
54
+ "frozen_verified": true
55
+ },
56
+ {
57
+ "run": "minilm-l6-v2/ariadne-seed-1",
58
+ "accuracy": 0.9593837535014006,
59
+ "false_actions_on_chat_question": 2,
60
+ "actions_on_unclear": 8,
61
+ "accuracy_pass": true,
62
+ "zero_actions_pass": false,
63
+ "both_numerical_passmarks": false,
64
+ "frozen_verified": true
65
+ },
66
+ {
67
+ "run": "minilm-l6-v2/ariadne-seed-2",
68
+ "accuracy": 0.9719887955182073,
69
+ "false_actions_on_chat_question": 1,
70
+ "actions_on_unclear": 3,
71
+ "accuracy_pass": true,
72
+ "zero_actions_pass": false,
73
+ "both_numerical_passmarks": false,
74
+ "frozen_verified": true
75
+ },
76
+ {
77
+ "run": "minilm-l6-v2/head_only-seed-0",
78
+ "accuracy": 0.9145658263305322,
79
+ "false_actions_on_chat_question": 13,
80
+ "actions_on_unclear": 7,
81
+ "accuracy_pass": false,
82
+ "zero_actions_pass": false,
83
+ "both_numerical_passmarks": false,
84
+ "frozen_verified": true
85
+ },
86
+ {
87
+ "run": "minilm-l6-v2/head_only-seed-1",
88
+ "accuracy": 0.9201680672268907,
89
+ "false_actions_on_chat_question": 12,
90
+ "actions_on_unclear": 6,
91
+ "accuracy_pass": false,
92
+ "zero_actions_pass": false,
93
+ "both_numerical_passmarks": false,
94
+ "frozen_verified": true
95
+ },
96
+ {
97
+ "run": "minilm-l6-v2/head_only-seed-2",
98
+ "accuracy": 0.9159663865546218,
99
+ "false_actions_on_chat_question": 14,
100
+ "actions_on_unclear": 7,
101
+ "accuracy_pass": false,
102
+ "zero_actions_pass": false,
103
+ "both_numerical_passmarks": false,
104
+ "frozen_verified": true
105
+ },
106
+ {
107
+ "run": "modernbert-base/ariadne-seed-0",
108
+ "accuracy": 0.9663865546218487,
109
+ "false_actions_on_chat_question": 3,
110
+ "actions_on_unclear": 4,
111
+ "accuracy_pass": true,
112
+ "zero_actions_pass": false,
113
+ "both_numerical_passmarks": false,
114
+ "frozen_verified": true
115
+ },
116
+ {
117
+ "run": "modernbert-base/ariadne-seed-1",
118
+ "accuracy": 0.9607843137254902,
119
+ "false_actions_on_chat_question": 4,
120
+ "actions_on_unclear": 4,
121
+ "accuracy_pass": true,
122
+ "zero_actions_pass": false,
123
+ "both_numerical_passmarks": false,
124
+ "frozen_verified": true
125
+ },
126
+ {
127
+ "run": "modernbert-base/ariadne-seed-2",
128
+ "accuracy": 0.9635854341736695,
129
+ "false_actions_on_chat_question": 2,
130
+ "actions_on_unclear": 1,
131
+ "accuracy_pass": true,
132
+ "zero_actions_pass": false,
133
+ "both_numerical_passmarks": false,
134
+ "frozen_verified": true
135
+ },
136
+ {
137
+ "run": "modernbert-base/head_only-seed-0",
138
+ "accuracy": 0.9621848739495799,
139
+ "false_actions_on_chat_question": 5,
140
+ "actions_on_unclear": 3,
141
+ "accuracy_pass": true,
142
+ "zero_actions_pass": false,
143
+ "both_numerical_passmarks": false,
144
+ "frozen_verified": true
145
+ },
146
+ {
147
+ "run": "modernbert-base/head_only-seed-1",
148
+ "accuracy": 0.9565826330532213,
149
+ "false_actions_on_chat_question": 5,
150
+ "actions_on_unclear": 3,
151
+ "accuracy_pass": true,
152
+ "zero_actions_pass": false,
153
+ "both_numerical_passmarks": false,
154
+ "frozen_verified": true
155
+ },
156
+ {
157
+ "run": "modernbert-base/head_only-seed-2",
158
+ "accuracy": 0.9537815126050421,
159
+ "false_actions_on_chat_question": 5,
160
+ "actions_on_unclear": 4,
161
+ "accuracy_pass": true,
162
+ "zero_actions_pass": false,
163
+ "both_numerical_passmarks": false,
164
+ "frozen_verified": true
165
+ },
166
+ {
167
+ "run": "qwen3.5-0.8B/ariadne-seed-0",
168
+ "accuracy": 0.9705882352941176,
169
+ "false_actions_on_chat_question": 1,
170
+ "actions_on_unclear": 4,
171
+ "accuracy_pass": true,
172
+ "zero_actions_pass": false,
173
+ "both_numerical_passmarks": false,
174
+ "frozen_verified": true
175
+ },
176
+ {
177
+ "run": "qwen3.5-0.8B/ariadne-seed-1",
178
+ "accuracy": 0.9761904761904762,
179
+ "false_actions_on_chat_question": 0,
180
+ "actions_on_unclear": 4,
181
+ "accuracy_pass": true,
182
+ "zero_actions_pass": true,
183
+ "both_numerical_passmarks": true,
184
+ "frozen_verified": true
185
+ },
186
+ {
187
+ "run": "qwen3.5-0.8B/ariadne-seed-2",
188
+ "accuracy": 0.969187675070028,
189
+ "false_actions_on_chat_question": 1,
190
+ "actions_on_unclear": 12,
191
+ "accuracy_pass": true,
192
+ "zero_actions_pass": false,
193
+ "both_numerical_passmarks": false,
194
+ "frozen_verified": true
195
+ }
196
+ ]
197
+ }
provenance/original/minilm-l6-v2/MODEL_CARD.md ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Clover English intent: MiniLM-L6-v2
2
+
3
+ Developed by AKIKI.AI.
4
+
5
+ Experimental six-category routing specialist. The cached
6
+ `sentence-transformers/all-MiniLM-L6-v2` backbone (revision
7
+ `1110a243fdf4706b3f48f1d95db1a4f5529b4d41`) stays frozen. Ariadne learns
8
+ an identity-initialized input affine and a six-class readout: 150,150 trainable
9
+ parameters, alongside 22,713,216 original backbone parameters. Original tensors
10
+ are hashed and checked throughout training. Cached base licence: Apache-2.0;
11
+ see `../CREDITS.md` for attribution.
12
+
13
+ Inputs are an English `message` and optional earlier `context` turns with
14
+ `role` and `text`. Output is one token: A=chat, B=question, C=build, D=task,
15
+ E=fix, F=unclear. This specialist classifies intent; it does not generate
16
+ contracts, execute actions, or implement the broader Clover refusal policy.
17
+
18
+ The backbone and tokenizer support 512 tokens total, including rendered
19
+ context, message and special tokens. The cached Sentence Transformers
20
+ configuration defaults to 256; this experiment loads Transformers directly
21
+ and explicitly allows 512. Oversized inputs raise an error; they are not
22
+ silently truncated. The dataset's longest input is 126 tokens, so the reported
23
+ scores do not establish performance on long briefings or full chat histories.
24
+
25
+ Training uses 9,913 synthetic examples, with 707 validation and 714 test
26
+ examples. The dataset card and files are under `data/clover-intent-v1` in
27
+ the workspace root. Labels
28
+ have two-model agreement; human review remains pending. Hard cases are a
29
+ controlled context-resolution test with split-separated follow-up families.
30
+
31
+ All three seeds (0, 1, 2) are retained. Validation NLL selects each checkpoint;
32
+ test results do not select epochs or settings. See `../protocol/plan.json`
33
+ and the committed source snapshot for the exact recipe.
34
+
35
+ | Method | Test accuracy | Hard accuracy |
36
+ |---|---:|---:|
37
+ | Frozen description similarity, no fitted classifier | 34.9% | 36.7% |
38
+ | Frozen embeddings + regularized linear classifier | 92.3% | 91.7% |
39
+ | Head-only Adam training, three-seed mean | 91.7% | 91.1% |
40
+ | Ariadne, three-seed mean | **96.6%** | **95.6%** |
41
+
42
+ Ariadne accuracy is 96.6% with sample SD 0.6 percentage points across seeds;
43
+ easy/medium/hard means are 99.4% / 94.8% / 95.6%. The three seeds make 1, 2,
44
+ and 1 action predictions on 240 chat/question examples, and 6, 8, and 3 action
45
+ predictions on 114 unclear examples. Thus none meets the experiment's zero
46
+ observed actions on chat/question requirement, despite exceeding 95% accuracy.
47
+
48
+ Each Ariadne fit took 28–31 seconds on the assigned RTX PRO 6000. Warm
49
+ PyTorch/Transformers FP32 CPU inference with eight threads measured 2.47 ms
50
+ median and 2.62 ms p95 for seed 0 on a short contextual input, including
51
+ tokenization and excluding model loading. Head-only measured 2.40 ms median
52
+ under the paired benchmark. See `../inference-comparison.json`; these are
53
+ server measurements, not a laptop or Rust runtime claim.
54
+
55
+ Checkpoints contain the small learned affine and head, not a copy of the
56
+ backbone. Use the existing local cache and `scripts/predict_clover.py`:
57
+
58
+ ```bash
59
+ PYTHONPATH=.deps-causal-opt:.deps-decisions:.:scripts \
60
+ .venv-blackwell/bin/python scripts/predict_clover.py \
61
+ --run runs/clover-intent-v1/minilm-l6-v2/ariadne-seed-0 \
62
+ --device cpu 'Restart my web server.'
63
+ ```
64
+
65
+ Model loading is offline. No serving change or release has been made.
provenance/original/minilm-l6-v2/model.json ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "minilm-l6-v2",
3
+ "path": "/mnt/models/hub/models--sentence-transformers--all-MiniLM-L6-v2/snapshots/1110a243fdf4706b3f48f1d95db1a4f5529b4d41",
4
+ "revision": "1110a243fdf4706b3f48f1d95db1a4f5529b4d41",
5
+ "frozen_sha256": "11ac3c0bba90239eddece3b7eb97f85d85e1107b1bf82b19e2d32fc98a101aa2",
6
+ "base_parameters": 22713216,
7
+ "readout": "six-class head; label-description cosine prototypes before any training",
8
+ "input": "rendered conversation context and current user message; no metadata or labels",
9
+ "torch_version": "2.13.0+cu130",
10
+ "transformers_version": "5.17.0",
11
+ "cuda_runtime": "13.0",
12
+ "device": "cuda:1",
13
+ "max_len": 512,
14
+ "pooling": "attention-masked mean followed by L2 normalization"
15
+ }
provenance/original/protocol/PASSMARK-CLOVER-1.md ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ # Clover English intent experiment
2
+
3
+ Developed by AKIKI.AI.
4
+
5
+ Six categories: chat, question, build, task, fix, unclear. Output is a single class ID.
6
+
7
+ Targets: at least 95% accuracy and zero observed build/task/fix classifications on pure chat/question. Report easy, medium and hard separately. These are experimental measurements on model-reviewed synthetic data, not a human-verified acceptance exam. No release or serving change is authorized.
8
+
9
+ All dataset hashes, seeds, methods and stopping rules are in plan.json. Select hyperparameters and checkpoints on validation only. Holdout never enters training. Frozen backbone and original native heads remain unchanged. No model downloads.
provenance/original/protocol/plan.json ADDED
@@ -0,0 +1,291 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "dataset": "/mnt/storage/ariadne/data/clover-intent-v1",
3
+ "dataset_manifest_sha256": "857d674c7b0cf9bc9ab112fce5b6db2cdead4055c8e9c9b2901f2706bc8f7c59",
4
+ "splits": {
5
+ "train": {
6
+ "file": "train.jsonl",
7
+ "sha256": "2e3edef9182471d0fcd3738fdf886fdbe78fac5e6f3855373ab92a6ad0f1ca72",
8
+ "rows": 9913,
9
+ "label_counts": {
10
+ "task": 1676,
11
+ "fix": 1680,
12
+ "build": 1680,
13
+ "chat": 1669,
14
+ "unclear": 1529,
15
+ "question": 1679
16
+ },
17
+ "difficulty_counts": {
18
+ "medium": 3325,
19
+ "hard": 3360,
20
+ "easy": 3228
21
+ },
22
+ "label_difficulty_counts": {
23
+ "chat": {
24
+ "easy": 552,
25
+ "medium": 557,
26
+ "hard": 560
27
+ },
28
+ "question": {
29
+ "easy": 559,
30
+ "medium": 560,
31
+ "hard": 560
32
+ },
33
+ "build": {
34
+ "easy": 560,
35
+ "medium": 560,
36
+ "hard": 560
37
+ },
38
+ "task": {
39
+ "easy": 558,
40
+ "medium": 558,
41
+ "hard": 560
42
+ },
43
+ "fix": {
44
+ "easy": 560,
45
+ "medium": 560,
46
+ "hard": 560
47
+ },
48
+ "unclear": {
49
+ "easy": 439,
50
+ "medium": 530,
51
+ "hard": 560
52
+ }
53
+ }
54
+ },
55
+ "validation": {
56
+ "file": "validation.jsonl",
57
+ "sha256": "40759974effb15fe000589d5e9082ae94c7c760a9dfef40cb364d95bc74c953b",
58
+ "rows": 707,
59
+ "label_counts": {
60
+ "question": 120,
61
+ "task": 120,
62
+ "fix": 120,
63
+ "build": 120,
64
+ "unclear": 107,
65
+ "chat": 120
66
+ },
67
+ "difficulty_counts": {
68
+ "easy": 229,
69
+ "hard": 240,
70
+ "medium": 238
71
+ },
72
+ "label_difficulty_counts": {
73
+ "chat": {
74
+ "easy": 40,
75
+ "medium": 40,
76
+ "hard": 40
77
+ },
78
+ "question": {
79
+ "easy": 40,
80
+ "medium": 40,
81
+ "hard": 40
82
+ },
83
+ "build": {
84
+ "easy": 40,
85
+ "medium": 40,
86
+ "hard": 40
87
+ },
88
+ "task": {
89
+ "easy": 40,
90
+ "medium": 40,
91
+ "hard": 40
92
+ },
93
+ "fix": {
94
+ "easy": 40,
95
+ "medium": 40,
96
+ "hard": 40
97
+ },
98
+ "unclear": {
99
+ "easy": 29,
100
+ "medium": 38,
101
+ "hard": 40
102
+ }
103
+ }
104
+ },
105
+ "test": {
106
+ "file": "test.jsonl",
107
+ "sha256": "8e1fde3f1074fb216e73b879fe3905d4448faf1c7a83d1fef6b3078dc1560c28",
108
+ "rows": 714,
109
+ "label_counts": {
110
+ "unclear": 114,
111
+ "chat": 120,
112
+ "build": 120,
113
+ "task": 120,
114
+ "question": 120,
115
+ "fix": 120
116
+ },
117
+ "difficulty_counts": {
118
+ "medium": 239,
119
+ "hard": 240,
120
+ "easy": 235
121
+ },
122
+ "label_difficulty_counts": {
123
+ "chat": {
124
+ "easy": 40,
125
+ "medium": 40,
126
+ "hard": 40
127
+ },
128
+ "question": {
129
+ "easy": 40,
130
+ "medium": 40,
131
+ "hard": 40
132
+ },
133
+ "build": {
134
+ "easy": 40,
135
+ "medium": 40,
136
+ "hard": 40
137
+ },
138
+ "task": {
139
+ "easy": 40,
140
+ "medium": 40,
141
+ "hard": 40
142
+ },
143
+ "fix": {
144
+ "easy": 40,
145
+ "medium": 40,
146
+ "hard": 40
147
+ },
148
+ "unclear": {
149
+ "easy": 35,
150
+ "medium": 39,
151
+ "hard": 40
152
+ }
153
+ }
154
+ }
155
+ },
156
+ "models": {
157
+ "minilm-l6-v2": {
158
+ "path": "/mnt/models/hub/models--sentence-transformers--all-MiniLM-L6-v2/snapshots/1110a243fdf4706b3f48f1d95db1a4f5529b4d41",
159
+ "kind": "encoder",
160
+ "width": 384
161
+ },
162
+ "modernbert-base": {
163
+ "path": "/mnt/models/hub/models--answerdotai--ModernBERT-base/snapshots/8949b909ec900327062f0ebf497f51aef5e6f0c8",
164
+ "kind": "encoder",
165
+ "width": 768
166
+ },
167
+ "laya": {
168
+ "path": "/mnt/storage/ariadne/.cache/huggingface/hub/models--convaiinnovations--laya/snapshots/55cf4c4ebb4ebe31b2550e8bdf3bd21b99753851",
169
+ "kind": "native"
170
+ },
171
+ "qwen3.5-0.8B": {
172
+ "path": "/mnt/models/hub/models--Qwen--Qwen3.5-0.8B/snapshots/2fc06364715b967f1860aea9cf38778875588b17",
173
+ "kind": "native"
174
+ }
175
+ },
176
+ "seeds": [
177
+ 0,
178
+ 1,
179
+ 2
180
+ ],
181
+ "methods": {
182
+ "encoders": [
183
+ "description_similarity",
184
+ "class_centroids",
185
+ "knn",
186
+ "kmeans",
187
+ "linear_head",
188
+ "head_only",
189
+ "ariadne"
190
+ ],
191
+ "native": [
192
+ "native_frozen",
193
+ "ariadne"
194
+ ]
195
+ },
196
+ "stopping": {
197
+ "minimum_epochs": 10,
198
+ "patience": 3,
199
+ "selection": "lowest validation NLL; no test-based choices"
200
+ },
201
+ "optimization": {
202
+ "batch": 32,
203
+ "microbatch": 32,
204
+ "head_lr": 0.001,
205
+ "interface_lr": 0.0001,
206
+ "weight_decay": 0.0,
207
+ "clip": 1.0,
208
+ "head_only_feature_cache": true,
209
+ "feature_cache_validation": "live frozen features must match within 2e-5"
210
+ },
211
+ "seed_summary": "mean and sample standard deviation; all individual runs retained",
212
+ "reported_metrics": [
213
+ "accuracy",
214
+ "macro_f1",
215
+ "nll",
216
+ "brier",
217
+ "confusion_matrix",
218
+ "difficulty_tiers",
219
+ "actions_on_chat_question",
220
+ "actions_on_unclear"
221
+ ],
222
+ "passmarks": {
223
+ "accuracy": 0.95,
224
+ "false_actions_on_chat_question": 0,
225
+ "difficulty_tiers": [
226
+ "easy",
227
+ "medium",
228
+ "hard"
229
+ ]
230
+ },
231
+ "baseline_caveat": "Description similarity is an explicitly constructed zero-shot readout, not a native semantic head on MiniLM/ModernBERT.",
232
+ "label_quality": "synthetic, two-model agreement; no claim of human-labelled ground truth",
233
+ "output": "single class ID; Qwen uses one native letter token; JSON is artifact storage only",
234
+ "sources": {
235
+ "ariadne_bench/__init__.py": "a73c9fdf21413382cb93b523bfb3925aa3fd354e18faeead4650e86a30645411",
236
+ "ariadne_bench/__main__.py": "935a1c1166b0c1ea35a82256345000bf2c73ded718d77773bc27a71ecce28f7d",
237
+ "ariadne_bench/adapters.py": "3bd4820165be077b3b98fe83ac23e649e1ad69186ad5f2a4f5ee7addf1427cf5",
238
+ "ariadne_bench/arguana_monitor.py": "40702d8f1cfc6ecadd779235918c2eabfc92bf60c540136a63ec6aa651d4f415",
239
+ "ariadne_bench/causal_selector.py": "0b7b1c2662e13734f21ffeec5cf875c9f5733dc17e08ae05a8352e724cf46a8f",
240
+ "ariadne_bench/cli.py": "de267c0502489eb4bb37e4b8f6faa8da8be37a56ced270f754424a40404d1af6",
241
+ "ariadne_bench/clover.py": "270b5ab0ea3ad33cec13803f4ccb4ee2ecdd5f8c7152780712546d3e94c8e798",
242
+ "ariadne_bench/clover_models.py": "2d08a3d37c4c171250e5e2bcf1ad572d23ce420fff7d37e61fcccda08e5cca8c",
243
+ "ariadne_bench/datasets.py": "31c722c64895519a4635b501da88862b446384682e3e8ee884495941d6990912",
244
+ "ariadne_bench/decider_interface.py": "1ff921ea8c3bfe33d06dd091317fa698c8052557466b3f0d0da400d3e1340e08",
245
+ "ariadne_bench/embeddinggemma2_td.py": "d39dd9aa9bbfa7766f3cc7a4753c0a305fb63e13de2ac96f1f00a573357cac88",
246
+ "ariadne_bench/extraction_monitor.py": "218e0f3ec738a9c89ab5c2830e546c35381420aa8adda41bdd369837c5dd40a1",
247
+ "ariadne_bench/frozen_fp8_linear.py": "f044798c66ac93d446a77dc7e04f461730d56a6bf4daf99dc20544935c78dbdc",
248
+ "ariadne_bench/frozen_input_interface.py": "253f0186dac6e4a7f4b0fcf3c33449c3b3882cf8be538dca6eeca8d9e4ce9b83",
249
+ "ariadne_bench/full_finetune.py": "6067be8cf837d254b919c841c9a9851e1546a413dbf6324ff242e5d2f56c9734",
250
+ "ariadne_bench/full_input_interface.py": "a8f440a2185085c64896300a243ac52a9619c4d05a1b4e43c50c2c32aa1da996",
251
+ "ariadne_bench/hybrid.py": "90fbbdab9b8157a32854d27c2d93089be6dc88dfe9320426f102eae4e03d9ffd",
252
+ "ariadne_bench/hybrid_control.py": "1b53678bea73fe7608570b78d7215d1dff2e38d6ad3627615f26c06ae74d8b4c",
253
+ "ariadne_bench/interfaces.py": "19700fb8170b2460401900cb96ebdff22bd7bf778ca5132e98d56ba68f344187",
254
+ "ariadne_bench/metrics.py": "fc6fde20c95d5052de52d05d6fb9b6eb69b780c46966f5bf1e517738b276a4b4",
255
+ "ariadne_bench/minilm_fusion_td.py": "02911ff0ffbe59258bbd2ba26d11a66adbe383c59d968b18053dc33c13bc9531",
256
+ "ariadne_bench/minilm_retrieval.py": "b7e5eec2d9b471ee86162fb1f77ff662ebb12948a6b7bf14a527e392f3a54651",
257
+ "ariadne_bench/minilm_second_affine_head_td.py": "adfbfbfcec2736a75c149acab4ffd2f06880087d375e9e91fd44cb881aade36b",
258
+ "ariadne_bench/minilm_second_affine_td.py": "30520235f801857975cd34e37e095949d5c4b61ede155e982e2497689b4cb97d",
259
+ "ariadne_bench/minilm_td.py": "6bd5d04dfea12cb74005369a483bacf4beb036d5acf2f21c369765e4d36c2baa",
260
+ "ariadne_bench/minilm_three_pass_td.py": "5e94d643ffb7b2c02fea2e323d0a6ce90f08039587a22455eab03f5b0ce31335",
261
+ "ariadne_bench/minilm_two_pass_post_mean_td.py": "c34692cb6cbe6bf596d3e4c9dbc9cbd94e7c208706a0909c1bf37172c9ada924",
262
+ "ariadne_bench/minilm_two_pass_post_weighted_mean_td.py": "59711d070660b76494cd0f8e5d9ed19e16e49f16f783578fe1a595bc5c262a8c",
263
+ "ariadne_bench/minilm_two_pass_td.py": "db737ec3f55d22ed60de5ad1c078d04a4dff26ad192065e30e9b982ef861e2e9",
264
+ "ariadne_bench/modernbert_td.py": "d34de2ba4413fec74a0701c446b68d9c8c50dcfaf4c69cb49d750f170530a48e",
265
+ "ariadne_bench/portable.py": "259f633a8bb6663d0594d9639ea8d80ef493f5a63d4b11444a4003f2f9a318e8",
266
+ "ariadne_bench/pythia_selector.py": "cc5f46794a0cc07ae7e14731eb022d0eeed970be7b0b7c885d7b1b6f07860ad5",
267
+ "ariadne_bench/qwen35_moe_fast.py": "4e40340ebeb2eefb39ad58b6ff738f7190e3336ce6a85208a6cbf812b7f02b6b",
268
+ "ariadne_bench/qwen35_moe_fast_selector.py": "303457ed725e748cc512e3c64ba8c9f2fb1ec6744d8e9629e0f39e4668d51e83",
269
+ "ariadne_bench/qwen35_moe_scaling_selector.py": "1b86e32817aff48e3c54d25d9878ddc34841065a1f9bb9503adf2576d1ce645b",
270
+ "ariadne_bench/qwen35_scaling_selector.py": "a807f53c03cee3ba3e0d19a594d9ed9c5c078cbed141925550ff816e1c100724",
271
+ "ariadne_bench/qwen38_fp8_native_selector.py": "d8871ee965ef500988b147aa86b9c9beaa0566ffeafa322b2c510e670027a3e9",
272
+ "ariadne_bench/qwen38_fp8_scaling_selector.py": "cc7a64e814942ed3c6a6f2a1bdc1c33dfe078ca9a9524459aadb1b3ee0553bba",
273
+ "ariadne_bench/qwen_comparison_monitor.py": "b546c4c64ddf53e91a7b07a5753b7e81c8c3a318ba9e67f20d43263785b24531",
274
+ "ariadne_bench/raw_extraction.py": "e36dca0644fdf9b90262b0071a719f86a8f75d12f189ee0cba6f6d1bd51fa578",
275
+ "ariadne_bench/reproducibility.py": "5b0c161c596f25277b3326c645df53d5d1f2dc0272da9e77bc4a4c0d56188b6e",
276
+ "ariadne_bench/rotary_selector.py": "2b7a80a20688170fe7680b5d8f2e3a8b279638ccebe442ba473db12e920251c9",
277
+ "ariadne_bench/runner.py": "91c934177113c34052d0560938cd0ab40804339349591ce515ee1a055d986c58",
278
+ "ariadne_bench/scaling_selector.py": "0489fb0bab0e627595bc22fb8cec2524f1633f48d632d095860a35c35d474805",
279
+ "ariadne_bench/schema.py": "e4f60c57ada82b964bfbbb3e2d4b122416ab01b480484d99b3850e7c185f08c4",
280
+ "ariadne_bench/specializations.py": "25eada26991e9c43e3d0f5b383bbe67975ff6b7495a9d5aa81d76644b7dde010",
281
+ "ariadne_bench/td_monitor.py": "78766de89adb42fa8e7dafb22190ed7cd62a9a3d99399db6f37143437e5d3c5c",
282
+ "scripts/run_clover_experiments.py": "df8b0c3c79c627618a2ae2a12e02cb861d1369ffbbe86f5c60cd3112836c3af5",
283
+ "scripts/build_clover_dataset.py": "35580bb3da8d9099d3a4f28c7366b498b1da26dc890307861720569636d65af5",
284
+ "scripts/build_clover_native_batch.py": "ab92d1c1a34e59fccfbe7d17564a0277223ce43ae5fdefe0102c7c1d9c9f816f",
285
+ "scripts/repair_clover_batch.py": "902630e11625ad04d3e9bf87f7301e8d59b03e80f1fc3ccf2412fb5bfd0b10b4",
286
+ "scripts/benchmark_clover_generation.py": "a368567a6f364c9dc1cf284fb49f67809aad1ce22de001c2c2f710c123e44144",
287
+ "scripts/finish_clover_dataset.py": "bb44d35eea6939434fa7cfc541c05a20692768905e52e9aed68771f1ec0b97e9",
288
+ "scripts/predict_clover.py": "07ba1f84b4bed51072f943c663835b350ab2afa0f50e31e6b12e0abfe36e203c",
289
+ "data/clover-intent-v1/generation-overrides.json": "bdf8a0179a856387ed16807d4f1f141390ed636747fc1476c476ec1f998a721a"
290
+ }
291
+ }
provenance/original/results.md ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Clover English intent comparison
2
+
3
+ Developed by AKIKI.AI. Synthetic, model-reviewed labels; human review pending.
4
+
5
+ All original backbone weights remain frozen. Validation alone chooses training settings and checkpoints.
6
+
7
+ Results across seeds (mean ± sample standard deviation where repeated):
8
+
9
+ | Model / method | Runs | Accuracy | Macro F1 | Hard accuracy |
10
+ |---|---:|---:|---:|---:|
11
+ | laya / ariadne | 3 | 95.9% ± 0.8 | 0.959 ± 0.008 | 94.9% ± 2.4 |
12
+ | laya / native_frozen | 1 | 52.4% | 0.474 | 55.8% |
13
+ | minilm-l6-v2 / ariadne | 3 | 96.6% ± 0.6 | 0.966 ± 0.006 | 95.6% ± 0.6 |
14
+ | minilm-l6-v2 / cosine nearest labelled examples | 1 | 78.9% | 0.786 | 79.2% |
15
+ | minilm-l6-v2 / description_similarity | 1 | 34.9% | 0.313 | 36.7% |
16
+ | minilm-l6-v2 / frozen embeddings + regularized linear classifier | 1 | 92.3% | 0.923 | 91.7% |
17
+ | minilm-l6-v2 / head_only | 3 | 91.7% ± 0.3 | 0.917 ± 0.003 | 91.1% ± 0.6 |
18
+ | minilm-l6-v2 / k-means on training embeddings; training-majority cluster labels | 3 | 51.2% ± 0.5 | 0.514 ± 0.008 | 54.7% ± 2.7 |
19
+ | minilm-l6-v2 / training-class-centroid cosine similarity | 1 | 80.5% | 0.804 | 81.2% |
20
+ | modernbert-base / ariadne | 3 | 96.4% ± 0.3 | 0.964 ± 0.003 | 96.0% ± 0.9 |
21
+ | modernbert-base / cosine nearest labelled examples | 1 | 90.1% | 0.901 | 88.8% |
22
+ | modernbert-base / description_similarity | 1 | 28.6% | 0.218 | 30.4% |
23
+ | modernbert-base / frozen embeddings + regularized linear classifier | 1 | 95.7% | 0.956 | 95.0% |
24
+ | modernbert-base / head_only | 3 | 95.8% ± 0.4 | 0.958 ± 0.004 | 94.9% ± 0.9 |
25
+ | modernbert-base / k-means on training embeddings; training-majority cluster labels | 3 | 72.0% ± 3.7 | 0.724 ± 0.040 | 54.9% ± 2.1 |
26
+ | modernbert-base / training-class-centroid cosine similarity | 1 | 80.5% | 0.802 | 61.7% |
27
+ | qwen3.5-0.8B / ariadne | 3 | 97.2% ± 0.4 | 0.972 ± 0.004 | 96.1% ± 1.3 |
28
+ | qwen3.5-0.8B / native_frozen | 1 | 30.5% | 0.255 | 14.6% |
29
+
30
+ Individual runs:
31
+
32
+ | Model / method | Accuracy | Macro F1 | Easy | Medium | Hard | Actions on chat/question | Actions on unclear |
33
+ |---|---:|---:|---:|---:|---:|---:|---:|
34
+ | laya/ariadne-seed-0/holdout | 95.8% | 0.958 | 98.7% | 92.9% | 95.8% | 4/240 | 3/114 |
35
+ | laya/ariadne-seed-1/holdout | 96.8% | 0.968 | 98.7% | 95.0% | 96.7% | 2/240 | 3/114 |
36
+ | laya/ariadne-seed-2/holdout | 95.1% | 0.951 | 99.6% | 93.7% | 92.1% | 3/240 | 2/114 |
37
+ | laya/frozen-baseline | 52.4% | 0.474 | 54.9% | 46.4% | 55.8% | 18/240 | 76/114 |
38
+ | minilm-l6-v2/ariadne-seed-0/holdout | 96.6% | 0.966 | 99.6% | 95.0% | 95.4% | 1/240 | 6/114 |
39
+ | minilm-l6-v2/ariadne-seed-1/holdout | 95.9% | 0.960 | 99.1% | 93.7% | 95.0% | 2/240 | 8/114 |
40
+ | minilm-l6-v2/ariadne-seed-2/holdout | 97.2% | 0.972 | 99.6% | 95.8% | 96.2% | 1/240 | 3/114 |
41
+ | minilm-l6-v2/embedding-baselines/class_centroids | 80.5% | 0.804 | 81.3% | 79.1% | 81.2% | 29/240 | 20/114 |
42
+ | minilm-l6-v2/embedding-baselines/kmeans-seed-0 | 51.7% | 0.523 | 48.5% | 49.0% | 57.5% | 105/240 | 34/114 |
43
+ | minilm-l6-v2/embedding-baselines/kmeans-seed-1 | 50.8% | 0.512 | 49.4% | 48.5% | 54.6% | 98/240 | 34/114 |
44
+ | minilm-l6-v2/embedding-baselines/kmeans-seed-2 | 51.0% | 0.508 | 51.5% | 49.4% | 52.1% | 85/240 | 20/114 |
45
+ | minilm-l6-v2/embedding-baselines/knn | 78.9% | 0.786 | 81.7% | 75.7% | 79.2% | 32/240 | 12/114 |
46
+ | minilm-l6-v2/embedding-baselines/linear_head | 92.3% | 0.923 | 94.5% | 90.8% | 91.7% | 10/240 | 5/114 |
47
+ | minilm-l6-v2/frozen-baseline | 34.9% | 0.313 | 31.5% | 36.4% | 36.7% | 58/240 | 23/114 |
48
+ | minilm-l6-v2/head_only-seed-0/holdout | 91.5% | 0.914 | 94.9% | 89.1% | 90.4% | 13/240 | 7/114 |
49
+ | minilm-l6-v2/head_only-seed-1/holdout | 92.0% | 0.920 | 94.9% | 89.5% | 91.7% | 12/240 | 6/114 |
50
+ | minilm-l6-v2/head_only-seed-2/holdout | 91.6% | 0.916 | 94.5% | 89.1% | 91.2% | 14/240 | 7/114 |
51
+ | modernbert-base/ariadne-seed-0/holdout | 96.6% | 0.966 | 98.7% | 96.2% | 95.0% | 3/240 | 4/114 |
52
+ | modernbert-base/ariadne-seed-1/holdout | 96.1% | 0.961 | 97.9% | 93.7% | 96.7% | 4/240 | 4/114 |
53
+ | modernbert-base/ariadne-seed-2/holdout | 96.4% | 0.964 | 98.7% | 94.1% | 96.2% | 2/240 | 1/114 |
54
+ | modernbert-base/embedding-baselines/class_centroids | 80.5% | 0.802 | 96.2% | 84.1% | 61.7% | 14/240 | 9/114 |
55
+ | modernbert-base/embedding-baselines/kmeans-seed-0 | 67.8% | 0.679 | 86.0% | 65.3% | 52.5% | 78/240 | 6/114 |
56
+ | modernbert-base/embedding-baselines/kmeans-seed-1 | 74.6% | 0.754 | 91.1% | 77.8% | 55.4% | 32/240 | 11/114 |
57
+ | modernbert-base/embedding-baselines/kmeans-seed-2 | 73.7% | 0.740 | 88.5% | 76.2% | 56.7% | 33/240 | 9/114 |
58
+ | modernbert-base/embedding-baselines/knn | 90.1% | 0.901 | 97.0% | 84.5% | 88.8% | 19/240 | 3/114 |
59
+ | modernbert-base/embedding-baselines/linear_head | 95.7% | 0.956 | 98.3% | 93.7% | 95.0% | 5/240 | 4/114 |
60
+ | modernbert-base/frozen-baseline | 28.6% | 0.218 | 23.4% | 31.8% | 30.4% | 30/240 | 3/114 |
61
+ | modernbert-base/head_only-seed-0/holdout | 96.2% | 0.962 | 99.1% | 93.7% | 95.8% | 5/240 | 3/114 |
62
+ | modernbert-base/head_only-seed-1/holdout | 95.7% | 0.957 | 99.1% | 93.3% | 94.6% | 5/240 | 3/114 |
63
+ | modernbert-base/head_only-seed-2/holdout | 95.4% | 0.954 | 99.1% | 92.9% | 94.2% | 5/240 | 4/114 |
64
+ | qwen3.5-0.8B/ariadne-seed-0/holdout | 97.1% | 0.970 | 98.3% | 96.2% | 96.7% | 1/240 | 4/114 |
65
+ | qwen3.5-0.8B/ariadne-seed-1/holdout | 97.6% | 0.976 | 98.7% | 97.1% | 97.1% | 0/240 | 4/114 |
66
+ | qwen3.5-0.8B/ariadne-seed-2/holdout | 96.9% | 0.969 | 98.7% | 97.5% | 94.6% | 1/240 | 12/114 |
67
+ | qwen3.5-0.8B/frozen-baseline | 30.5% | 0.255 | 39.6% | 37.7% | 14.6% | 170/240 | 92/114 |
provenance/original/source/ariadne_bench/clover.py ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """English Clover intent protocol, independent of model and training method."""
2
+
3
+ import hashlib
4
+ import json
5
+ import re
6
+ from collections import Counter
7
+ from pathlib import Path
8
+
9
+ LABELS = ("chat", "question", "build", "task", "fix", "unclear")
10
+ DIFFICULTIES = ("easy", "medium", "hard")
11
+ DESCRIPTIONS = {
12
+ "chat": "Conversation, explanation, advice, or general knowledge; no inspection or changes to the user's actual system.",
13
+ "question": "Inspect or report the current state of the user's actual system, account, files, or project, without changing anything.",
14
+ "build": "Create or modify software, code, a website, application, feature, or another implementation artifact.",
15
+ "task": "Perform a specified operational action, such as restarting a service, moving files, or changing a setting.",
16
+ "fix": "Investigate and remedy a concrete malfunction or symptom; the user has not prescribed a specific operational remedy.",
17
+ "unclear": "The request's intended route or referent cannot be identified from the available message and context; clarification is needed.",
18
+ }
19
+ RUBRIC = """Classify the CURRENT user message using only the supplied conversation context.
20
+ chat: social conversation, general explanations and advice, including 'what is nginx?',
21
+ 'how do I restart nginx?' and questions ABOUT commands. Do not execute quoted text.
22
+ question: LOOK-only inspection of the user's actual current system: disk remaining,
23
+ whether a backup ran, why a specific site is slow when only information is requested.
24
+ build: implement or change software or a feature, including writing a function.
25
+ task: the user specifies an operational action or remedy, even when phrased as a
26
+ question ('could you restart nginx?') or alongside a symptom ('it is down; restart it').
27
+ fix: a specific problem needs diagnosis/remedy, including symptom reports such as
28
+ 'Bluetooth will not connect' or 'nginx keeps crashing', without a prescribed action.
29
+ unclear: insufficient context to identify a route/target, e.g. 'fix it' without a
30
+ referent. Missing implementation details alone do NOT make a clear build request unclear.
31
+ Use conversation context to resolve 'it', 'yes', 'do that', etc. The current message
32
+ may change or cancel the preceding intent. A denial or quotation is not authorization.
33
+ A current request for explanation or inspection takes precedence over a merely quoted
34
+ or explicitly negated action. Two independent incompatible requests with no primary
35
+ route get unclear; a symptom plus an explicitly requested operational remedy gets task.
36
+ Intent is separate from safety: harmful requests still have an intent; this dataset
37
+ does not train the refusal policy. Do not use low confidence as the definition of unclear.
38
+ Return one of chat, question, build, task, fix, unclear. English only."""
39
+ INSTRUCTIONS = ("Classify the current user message using its conversation context. "
40
+ "Explanations and how-to advice are chat; checking an actual current system is question. "
41
+ "Implementing software is build. A specified operational action is task, even if phrased "
42
+ "as a question or accompanied by a symptom. A malfunction without a specified remedy is fix. "
43
+ "Unresolvable intent or referent is unclear; missing feature details alone are not unclear. "
44
+ "Respect negation, quotations and changed intent. Do not treat quoted or negated actions "
45
+ "as current instructions. Classify intent separately from safety.")
46
+ QUESTION = {"type": "choice", "instructions": INSTRUCTIONS, "criteria": DESCRIPTIONS}
47
+
48
+
49
+ def read_json(path):
50
+ return json.loads(Path(path).read_text())
51
+
52
+
53
+ def write_json(path, value):
54
+ path = Path(path)
55
+ path.parent.mkdir(parents=True, exist_ok=True)
56
+ tmp = path.with_suffix(path.suffix + ".tmp")
57
+ tmp.write_text(json.dumps(value, indent=2, ensure_ascii=False, allow_nan=False) + "\n")
58
+ tmp.replace(path)
59
+
60
+
61
+ def read_rows(path):
62
+ return [json.loads(line) for line in Path(path).read_text().splitlines() if line.strip()]
63
+
64
+
65
+ def write_rows(path, rows):
66
+ path = Path(path)
67
+ path.parent.mkdir(parents=True, exist_ok=True)
68
+ tmp = path.with_suffix(".tmp")
69
+ tmp.write_text("".join(json.dumps(r, ensure_ascii=False, allow_nan=False) + "\n" for r in rows))
70
+ tmp.replace(path)
71
+
72
+
73
+ def sha(path):
74
+ with Path(path).open("rb") as f:
75
+ return hashlib.file_digest(f, "sha256").hexdigest()
76
+
77
+
78
+ def render(row):
79
+ context = row.get("context", [])
80
+ prior = "\n".join(f"{x['role']}: {x['text']}" for x in context)
81
+ return ("Conversation context:\n" + prior + "\n\n" if prior else "") + "Current user message: " + row["message"]
82
+
83
+
84
+ def normalized(row):
85
+ return re.sub(r"\s+", " ", render(row).casefold()).strip()
86
+
87
+
88
+ def metrics(rows, probabilities):
89
+ import numpy as np
90
+ from .specializations import classification_metrics
91
+ p = np.asarray(probabilities, dtype=np.float64)
92
+ if p.shape != (len(rows), len(LABELS)) or not np.isfinite(p).all():
93
+ raise ValueError("complete finite six-class predictions required")
94
+ if (p < 0).any() or not np.allclose(p.sum(1), 1, atol=1e-4):
95
+ raise ValueError("normalized probability distributions required")
96
+ gold = [r["label"] for r in rows]
97
+ pred = [LABELS[i] for i in p.argmax(1)]
98
+ result = classification_metrics(gold, pred, list(LABELS))
99
+ y = np.array([LABELS.index(g) for g in gold])
100
+ result["nll"] = float(-np.log(np.maximum(p[np.arange(len(y)), y], 1e-12)).mean())
101
+ result["brier"] = float(((p - np.eye(6)[y]) ** 2).sum(1).mean())
102
+ passive = [i for i,g in enumerate(gold) if g in ("chat", "question")]
103
+ result["false_actions"] = sum(pred[i] in ("build", "task", "fix") for i in passive)
104
+ result["passive_cases"] = len(passive)
105
+ result["false_action_rate"] = result["false_actions"] / len(passive) if passive else None
106
+ unresolved=[i for i,g in enumerate(gold) if g=='unclear']
107
+ result['unclear_cases']=len(unresolved)
108
+ result['actions_on_unclear']=sum(pred[i] in ('build','task','fix') for i in unresolved)
109
+ result['action_rate_on_unclear']=result['actions_on_unclear']/len(unresolved) if unresolved else None
110
+ result["by_difficulty"] = {}
111
+ for level in DIFFICULTIES:
112
+ indices = [i for i,r in enumerate(rows) if r["difficulty"] == level]
113
+ if indices:
114
+ result["by_difficulty"][level] = classification_metrics(
115
+ [gold[i] for i in indices], [pred[i] for i in indices], list(LABELS))
116
+ result["difficulty_counts"] = dict(Counter(r["difficulty"] for r in rows))
117
+ return result
provenance/original/source/ariadne_bench/clover_models.py ADDED
@@ -0,0 +1,210 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Local-only Clover encoder classifier and native Laya/Qwen decision adapters."""
2
+
3
+ import os
4
+ os.environ.update(HF_HUB_OFFLINE="1", TRANSFORMERS_OFFLINE="1", HF_DATASETS_OFFLINE="1")
5
+
6
+ import copy
7
+ import hashlib
8
+ from pathlib import Path
9
+
10
+ import torch
11
+ from torch import nn
12
+ from torch.nn import functional as F
13
+
14
+ from .clover import DESCRIPTIONS, INSTRUCTIONS, LABELS, QUESTION, render
15
+ from .interfaces import IdentityAffine
16
+
17
+ ROOT = Path(__file__).resolve().parents[1]
18
+ MODELS = {
19
+ "minilm-l6-v2": {"path": "/mnt/models/hub/models--sentence-transformers--all-MiniLM-L6-v2/snapshots/1110a243fdf4706b3f48f1d95db1a4f5529b4d41", "kind":"encoder", "width":384},
20
+ "modernbert-base": {"path": "/mnt/models/hub/models--answerdotai--ModernBERT-base/snapshots/8949b909ec900327062f0ebf497f51aef5e6f0c8", "kind":"encoder", "width":768},
21
+ "laya": {"path": str(ROOT / ".cache/huggingface/hub/models--convaiinnovations--laya/snapshots/55cf4c4ebb4ebe31b2550e8bdf3bd21b99753851"), "kind":"native"},
22
+ "qwen3.5-0.8B": {"path":"/mnt/models/hub/models--Qwen--Qwen3.5-0.8B/snapshots/2fc06364715b967f1860aea9cf38778875588b17", "kind":"native"},
23
+ }
24
+
25
+
26
+ def frozen_hash(module):
27
+ digest = hashlib.sha256()
28
+ for name,value in sorted(module.state_dict().items()):
29
+ digest.update(name.encode());digest.update(str((tuple(value.shape),value.dtype)).encode())
30
+ digest.update(value.detach().cpu().contiguous().view(torch.uint8).numpy().tobytes())
31
+ return digest.hexdigest()
32
+
33
+
34
+ class FrozenEncoderClassifier(nn.Module):
35
+ def __init__(self, pretrained, width, modernbert=False):
36
+ super().__init__()
37
+ self.pretrained = pretrained.requires_grad_(False).eval()
38
+ self.modernbert = modernbert
39
+ self.interface = IdentityAffine(width)
40
+ self.head = nn.Linear(width, len(LABELS))
41
+ self.interface_enabled = False
42
+ self.hook = pretrained.get_input_embeddings().register_forward_hook(self._transform)
43
+ self.eval()
44
+
45
+ def _transform(self, module, args, output):
46
+ return self.interface(output) if self.interface_enabled else output
47
+
48
+ def train(self, mode=True):
49
+ super().train(mode)
50
+ self.pretrained.eval()
51
+ return self
52
+
53
+ def features(self, **batch):
54
+ backbone = self.pretrained.model if self.modernbert else self.pretrained
55
+ hidden = backbone(**batch, return_dict=True).last_hidden_state
56
+ mask = batch["attention_mask"].unsqueeze(-1).to(hidden.dtype)
57
+ return F.normalize(((hidden * mask).sum(1) / mask.sum(1).clamp_min(1)).float(), dim=-1)
58
+
59
+ def forward(self, **batch):
60
+ return self.head(self.features(**batch))
61
+
62
+
63
+ class Encoder:
64
+ def __init__(self, name, device="cuda:1", seed=0):
65
+ import transformers
66
+ from transformers import AutoModel, AutoModelForMaskedLM, AutoTokenizer
67
+ torch.manual_seed(seed)
68
+ self.name,self.device = name,torch.device(device)
69
+ self.path = Path(MODELS[name]["path"]).resolve(strict=True)
70
+ self.tokenizer = AutoTokenizer.from_pretrained(self.path,local_files_only=True)
71
+ cls = AutoModelForMaskedLM if name=="modernbert-base" else AutoModel
72
+ pretrained = cls.from_pretrained(self.path,local_files_only=True,dtype=torch.float32,attn_implementation="sdpa")
73
+ self.model = FrozenEncoderClassifier(pretrained,MODELS[name]["width"],name=="modernbert-base").to(self.device)
74
+ self.initial_hash = frozen_hash(self.model.pretrained)
75
+ self.metadata = {"name":name,"path":str(self.path),"revision":self.path.name,
76
+ "frozen_sha256":self.initial_hash,"base_parameters":sum(p.numel() for p in pretrained.parameters()),
77
+ "readout":"six-class head; label-description cosine prototypes before any training",
78
+ "input":"rendered conversation context and current user message; no metadata or labels",
79
+ "torch_version":str(torch.__version__),"transformers_version":transformers.__version__,
80
+ "cuda_runtime":torch.version.cuda,"device":str(self.device),
81
+ "max_len":512,"pooling":"attention-masked mean followed by L2 normalization"}
82
+ with torch.no_grad():
83
+ self.prototypes = self.model.features(**self.tokenize(["Current user message: " + DESCRIPTIONS[l] for l in LABELS]))
84
+ self.model.head.weight.copy_(10 * self.prototypes)
85
+ self.model.head.bias.zero_()
86
+
87
+ def tokenize(self, texts):
88
+ result = self.tokenizer(texts,padding=True,truncation=False,return_tensors="pt")
89
+ if result["input_ids"].shape[1] > 512:
90
+ raise ValueError("Clover input exceeds 512 tokens; truncation is disabled")
91
+ return {k:v.to(self.device) for k,v in result.items() if k in ('input_ids','attention_mask')}
92
+
93
+ def batch(self,rows):
94
+ return self.tokenize([render(r) for r in rows])
95
+
96
+ def logits(self, rows):
97
+ return self.model(**self.batch(rows))
98
+
99
+ def configure(self, method):
100
+ self.model.interface_enabled = method=="ariadne"
101
+ self.model.interface.requires_grad_(method=="ariadne")
102
+ self.model.head.requires_grad_(True)
103
+ self.model.pretrained.requires_grad_(False).eval()
104
+ return [{"params":self.model.head.parameters(),"lr":1e-3}] + (
105
+ [{"params":self.model.interface.parameters(),"lr":1e-4}] if method=="ariadne" else [])
106
+
107
+ def state(self):
108
+ return {k:v.detach().cpu().clone() for k,v in self.model.state_dict().items() if k.startswith(("interface.","head."))}
109
+
110
+ def load(self,state):
111
+ self.model.load_state_dict(state,strict=False)
112
+
113
+ def verify_frozen(self):
114
+ assert all(not p.requires_grad and p.grad is None for p in self.model.pretrained.parameters())
115
+ assert frozen_hash(self.model.pretrained)==self.initial_hash
116
+
117
+ @torch.no_grad()
118
+ def verify_identity(self,rows):
119
+ self.model.interface_enabled=False;native=self.logits(rows).clone()
120
+ self.model.interface_enabled=True;identity=self.logits(rows).clone()
121
+ self.model.interface_enabled=False
122
+ assert torch.equal(native,identity),'identity affine changed pretrained encoder logits'
123
+
124
+
125
+ class Native:
126
+ def __init__(self,name,device="cuda:1",seed=0):
127
+ from .adapters import create_adapter
128
+ self.name,self.device = name,torch.device(device)
129
+ path=Path(MODELS[name]["path"]).resolve(strict=True)
130
+ options={"device":device,"seed":seed,"max_len":2048,"batch_size":8,"add_interface":True}
131
+ if name=="laya":
132
+ options.update(laya_model=str(path),head_max_len=1024,training_scope="bridge",deterministic=True)
133
+ factory="ariadne_bench.frozen_input_interface:create"
134
+ else:
135
+ options.update(llm_model=str(path),base_model="Qwen/Qwen3.5-0.8B",base_revision=path.name)
136
+ factory="ariadne_bench.qwen35_scaling_selector:create"
137
+ self.adapter=create_adapter({"adapter":"python","factory":factory,"options":options})
138
+ self.model=self.adapter.model
139
+ self.initial_hash=self.adapter.frozen_state_sha256()
140
+ self.metadata={**self.adapter.metadata,"clover_model":name,"training":"input affine only; native decision/vocabulary head frozen",
141
+ "clover_scoring_temperature":1.0,"probabilities":"softmax of raw native logits; no fitted calibration"}
142
+ if name=='qwen3.5-0.8B':
143
+ self.metadata.update(chat_template_applied=True,prompt_format='clover-native-chat-letter-v1')
144
+
145
+ def items(self,rows):
146
+ if self.name=="qwen3.5-0.8B":
147
+ # Apply the instruction checkpoint's native chat template, then gather
148
+ # single-letter scores from its frozen vocabulary head. No generation.
149
+ tokenizer=self.adapter.tokenizer
150
+ letters=[x[0] for x in self.adapter.candidates[:6]]
151
+ rubric=INSTRUCTIONS+"\n"+"\n".join(f"({letter}) {label}: {DESCRIPTIONS[label]}" for letter,label in zip(letters,LABELS))
152
+ items=[]
153
+ for row in rows:
154
+ prompt=tokenizer.apply_chat_template(
155
+ [{"role":"system","content":rubric+"\nReturn only the answer letter."},
156
+ {"role":"user","content":render(row)}], tokenize=False,add_generation_prompt=True,enable_thinking=False)
157
+ ids=tokenizer.encode(prompt,add_special_tokens=False)
158
+ if len(ids)>2048:raise ValueError("Complete Qwen prompt exceeds 2048 tokens")
159
+ items.append({"ids":ids,"slot":len(ids)-1,"keys":list(LABELS)})
160
+ return items
161
+ result=[]
162
+ for row in rows:
163
+ item=self.adapter.prepare(render(row),{"intent":copy.deepcopy(QUESTION)})[0]
164
+ if item["keys"]!=list(LABELS):raise ValueError("native label order changed")
165
+ if item.get("state_tokens_used")!=item.get("state_tokens_original"):
166
+ raise ValueError("Laya truncated the current message or context")
167
+ result.append(item)
168
+ return result
169
+
170
+ def logits(self,rows):
171
+ from .hybrid import collate
172
+ items=self.items(rows)
173
+ batch=self.adapter.collate(items) if hasattr(self.adapter,"collate") else collate(items,self.adapter.pad_id,self.device)
174
+ with self.adapter.autocast():
175
+ logits,_=self.model(**batch)
176
+ return logits.float()
177
+
178
+ def configure(self,method):
179
+ if method!="ariadne":raise ValueError("Native models train only their input affine")
180
+ return [{"params":[p for p in self.model.parameters() if p.requires_grad],"lr":1e-4}]
181
+
182
+ def state(self):
183
+ names=self.adapter.checkpoint_tensor_names()
184
+ return {k:v.detach().cpu().clone() for k,v in self.model.state_dict().items() if k in names}
185
+
186
+ def load(self,state):
187
+ self.model.load_state_dict(state,strict=False)
188
+
189
+ def verify_frozen(self):
190
+ assert self.adapter.frozen_state_sha256()==self.initial_hash
191
+ trained=set(self.adapter.checkpoint_tensor_names())
192
+ assert all(not p.requires_grad and p.grad is None for n,p in self.model.named_parameters() if n not in trained)
193
+
194
+ @torch.no_grad()
195
+ def verify_identity(self,rows):
196
+ identity=self.logits(rows).clone()
197
+ if self.name=='qwen3.5-0.8B':
198
+ self.model.disable_interface()
199
+ try:native=self.logits(rows).clone()
200
+ finally:self.model.enable_interface()
201
+ else:
202
+ embeddings=self.model.encoder.embeddings;saved=embeddings.interface
203
+ embeddings.interface=nn.Identity()
204
+ try:native=self.logits(rows).clone()
205
+ finally:embeddings.interface=saved
206
+ assert torch.equal(native,identity),'identity affine changed native decision logits'
207
+
208
+
209
+ def load(name,device="cuda:1",seed=0):
210
+ return Encoder(name,device,seed) if MODELS[name]["kind"]=="encoder" else Native(name,device,seed)
provenance/original/source/ariadne_bench/interfaces.py ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Input transformations with explicit initialization and low-rank factors."""
2
+
3
+ import math
4
+
5
+ import torch
6
+ from torch import nn
7
+ from torch.nn import functional as F
8
+
9
+
10
+ class IdentityAffine(nn.Module):
11
+ """Affine map initialized as identity, preserving input precision under AMP.
12
+
13
+ Autocasting an identity GEMM to BF16 would round FP32 embeddings before
14
+ BERT sees them. Keep this small interface in FP32 and return the input dtype.
15
+ CUDA callers must use highest float32 matmul precision (no TF32 rounding).
16
+ """
17
+
18
+ def __init__(self, width, residual=False):
19
+ super().__init__()
20
+ self.residual = residual
21
+ self.proj = nn.Linear(width, width)
22
+ if residual:
23
+ nn.init.zeros_(self.proj.weight)
24
+ else:
25
+ nn.init.eye_(self.proj.weight)
26
+ nn.init.zeros_(self.proj.bias)
27
+
28
+ def forward(self, x):
29
+ with torch.autocast(device_type=x.device.type, enabled=False):
30
+ value = F.linear(x.float(), self.proj.weight.float(), self.proj.bias.float())
31
+ if self.residual:
32
+ value = x.float() + value
33
+ return value.to(x.dtype)
34
+
35
+
36
+ class LowRankLinear(nn.Module):
37
+ def __init__(self, width, rank, residual=False):
38
+ super().__init__()
39
+ if not 1 <= rank <= width:
40
+ raise ValueError("rank must be between one and the hidden width")
41
+ self.rank, self.residual = rank, residual
42
+ self.a = nn.Parameter(torch.empty(rank, width))
43
+ self.b = nn.Parameter(torch.empty(width, rank))
44
+ self.bias = nn.Parameter(torch.zeros(width))
45
+ if residual:
46
+ nn.init.kaiming_uniform_(self.a, a=math.sqrt(5))
47
+ nn.init.zeros_(self.b)
48
+ else:
49
+ # A pure rank-r map cannot start at identity. Start as an orthogonal
50
+ # rank-r projection instead, and record this in experiment metadata.
51
+ q, _ = torch.linalg.qr(torch.randn(width, rank), mode="reduced")
52
+ with torch.no_grad():
53
+ self.a.copy_(q.T)
54
+ self.b.copy_(q)
55
+
56
+ def forward(self, x):
57
+ value = F.linear(F.linear(x, self.a), self.b, self.bias)
58
+ return x + value if self.residual else value
59
+
60
+ def dense_weight(self):
61
+ weight = self.b @ self.a
62
+ if self.residual:
63
+ weight = weight + torch.eye(weight.shape[0], device=weight.device, dtype=weight.dtype)
64
+ return weight
65
+
66
+ @classmethod
67
+ def from_svd(cls, u, s, vh, bias, rank, residual=False):
68
+ layer = cls(u.shape[0], rank, residual=residual)
69
+ with torch.no_grad():
70
+ root = s[:rank].sqrt()
71
+ layer.a.copy_(root[:, None] * vh[:rank])
72
+ layer.b.copy_(u[:, :rank] * root[None, :])
73
+ layer.bias.copy_(bias)
74
+ return layer
75
+
76
+
77
+ class Diagonal(nn.Module):
78
+ def __init__(self, width):
79
+ super().__init__()
80
+ self.scale = nn.Parameter(torch.ones(width))
81
+ self.bias = nn.Parameter(torch.zeros(width))
82
+
83
+ def forward(self, x):
84
+ return x * self.scale + self.bias
85
+
86
+
87
+ class ResidualInput(nn.Module):
88
+ def __init__(self, width):
89
+ super().__init__()
90
+ self.norm = nn.LayerNorm(width)
91
+ self.linear = nn.Linear(width, width)
92
+ nn.init.zeros_(self.linear.weight)
93
+ nn.init.zeros_(self.linear.bias)
94
+
95
+ def forward(self, x):
96
+ return x + self.linear(self.norm(x))
97
+
98
+
99
+ def make_interface(width, specification):
100
+ kind = specification.get("kind", "norm_linear")
101
+ if kind in ("exact_linear", "exact_linear_residual"):
102
+ return IdentityAffine(width, residual=kind == "exact_linear_residual")
103
+ if kind == "identity":
104
+ return nn.Identity()
105
+ if kind == "norm":
106
+ return nn.LayerNorm(width)
107
+ if kind == "diagonal":
108
+ return Diagonal(width)
109
+ if kind == "residual":
110
+ return ResidualInput(width)
111
+ if kind in ("low_rank", "low_rank_delta"):
112
+ return nn.Sequential(
113
+ nn.LayerNorm(width),
114
+ LowRankLinear(width, specification["rank"], residual=kind == "low_rank_delta"),
115
+ )
116
+ if kind in ("linear", "norm_linear"):
117
+ linear = nn.Linear(width, width)
118
+ nn.init.eye_(linear.weight)
119
+ nn.init.zeros_(linear.bias)
120
+ return linear if kind == "linear" else nn.Sequential(nn.LayerNorm(width), linear)
121
+ raise ValueError(f"unknown interface kind: {kind}")
provenance/original/source/scripts/package_clover_minilm.py ADDED
@@ -0,0 +1,154 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Assemble the private Hugging Face package for the Clover MiniLM-L6-v2 intent model.
2
+
3
+ The released adapter is Ariadne seed 2, chosen on validation NLL (the experiment's
4
+ checkpoint criterion); test results played no part. Seeds 0 and 1 ship alongside.
5
+ The packaged model.py is re-run on CPU and checked against the recorded predictions.
6
+
7
+ .venv-blackwell/bin/python scripts/package_clover_minilm.py
8
+ """
9
+
10
+ import os
11
+ os.environ.update(HF_HUB_OFFLINE='1',TRANSFORMERS_OFFLINE='1',HF_DATASETS_OFFLINE='1')
12
+
13
+ import hashlib
14
+ import importlib.util
15
+ import json
16
+ import shutil
17
+ import sys
18
+ from pathlib import Path
19
+
20
+ import numpy as np
21
+ import torch
22
+ from safetensors.torch import save_file
23
+
24
+ ROOT=Path(__file__).resolve().parents[1]
25
+ sys.path.insert(0,str(ROOT))
26
+ from ariadne_bench.clover import read_json,read_rows,sha,write_json
27
+ from ariadne_bench.clover_models import MODELS,frozen_hash
28
+
29
+ RUN=ROOT/'runs/clover-intent-v1';MINILM=RUN/'minilm-l6-v2';DATA=ROOT/'data/clover-intent-v1'
30
+ OUT=ROOT/'releases/akiki-minilm-l6-v2-clover-intent'
31
+ SEEDS=(0,1,2);RELEASED=2
32
+ REPO_ID='Akiki-AI/Akiki-MiniLM-L6-v2-clover-intent'
33
+
34
+
35
+ def copy(src,dst):
36
+ dst=OUT/dst;dst.parent.mkdir(parents=True,exist_ok=True);shutil.copy2(Path(src).resolve(strict=True),dst)
37
+
38
+
39
+ def select_seed():
40
+ best={}
41
+ for s in SEEDS:
42
+ h=read_json(MINILM/f'ariadne-seed-{s}/history.json')
43
+ e=min(h,key=lambda x:x['validation']['nll'])
44
+ best[s]={'epoch':e['epoch'],'validation_nll':e['validation']['nll'],'validation_accuracy':e['validation']['accuracy']}
45
+ assert e['epoch']==read_json(MINILM/f'ariadne-seed-{s}/complete.json')['best_epoch']
46
+ chosen=min(best,key=lambda s:best[s]['validation_nll'])
47
+ assert chosen==RELEASED,best
48
+ return best
49
+
50
+
51
+ def assemble():
52
+ for d in ('base_model','checkpoints','results','data','provenance','checks'):shutil.rmtree(OUT/d,ignore_errors=True)
53
+ base=Path(MODELS['minilm-l6-v2']['path'])
54
+ for f in base.rglob('*'):
55
+ if f.is_file():copy(f,Path('base_model')/f.relative_to(base))
56
+ (OUT/'checkpoints').mkdir()
57
+ for s in SEEDS:
58
+ state=torch.load(MINILM/f'ariadne-seed-{s}/best.pt',map_location='cpu',weights_only=True)
59
+ assert set(state)=={'interface.proj.weight','interface.proj.bias','head.weight','head.bias'}
60
+ save_file({k:v.contiguous() for k,v in state.items()},OUT/f'checkpoints/seed-{s}.safetensors',
61
+ metadata={'seed':str(s),'source':f'runs/clover-intent-v1/minilm-l6-v2/ariadne-seed-{s}/best.pt'})
62
+ shutil.copy2(OUT/f'checkpoints/seed-{RELEASED}.safetensors',OUT/'adapter.safetensors')
63
+ for s in SEEDS:
64
+ src=MINILM/f'ariadne-seed-{s}'
65
+ for f in ('holdout/report.json','holdout/predictions.jsonl','holdout/uncertainty.jsonl','history.json','model.json','complete.json'):
66
+ copy(src/f,Path('results/seeds')/f'seed-{s}'/f.replace('holdout/','test-'))
67
+ for f in ('report.json','predictions.jsonl','uncertainty.jsonl'):copy(MINILM/f'ariadne-seed-{RELEASED}/holdout/{f}',f'results/test-{f}')
68
+ for f in ('frozen-baseline','head_only-seed-0','head_only-seed-1','head_only-seed-2'):
69
+ rep=MINILM/f/('report.json' if f=='frozen-baseline' else 'holdout/report.json');copy(rep,f'results/baselines/{f}.json')
70
+ for f in ('class_centroids','knn','linear_head','kmeans-seed-0','kmeans-seed-1','kmeans-seed-2'):
71
+ copy(MINILM/'embedding-baselines'/f/'report.json',f'results/baselines/embedding-{f}.json')
72
+ summary=read_json(RUN/'seed-summary.json')
73
+ write_json(OUT/'results/seed-summary-minilm.json',[r for r in summary if r['model']=='minilm-l6-v2'])
74
+ for f in ('cpu-latency.json','inference-comparison.json','inference-smoke.json'):copy(RUN/f,f'results/{f}')
75
+ for f in ('train.jsonl','validation.jsonl','test.jsonl','README.md','manifest.json','audit.json','audit-drops.jsonl'):copy(DATA/f,f'data/{f}')
76
+ for f in ('protocol/plan.json','protocol/PASSMARK-CLOVER-1.md','CREDITS.md','README.md','results.md','final-verification.json','minilm-l6-v2/MODEL_CARD.md','minilm-l6-v2/model.json'):
77
+ copy(RUN/f,Path('provenance/original')/f)
78
+ for f in ('ariadne_bench/clover.py','ariadne_bench/clover_models.py','ariadne_bench/interfaces.py','scripts/run_clover_experiments.py','scripts/predict_clover.py','scripts/package_clover_minilm.py'):
79
+ copy(ROOT/f,Path('provenance/original/source')/f)
80
+ copy(ROOT/'LICENSE','LICENSE')
81
+
82
+
83
+ def verify(selection):
84
+ torch.set_num_threads(8);torch.set_float32_matmul_precision('highest')
85
+ spec=importlib.util.spec_from_file_location('akiki_clover_model',OUT/'model.py');module=importlib.util.module_from_spec(spec);spec.loader.exec_module(module)
86
+ info=read_json(MINILM/'model.json');result={'device':'cpu','torch':torch.__version__,'released_seed':RELEASED,'selection':selection}
87
+ test=read_rows(DATA/'test.jsonl');validation=read_rows(DATA/'validation.jsonl')
88
+ for s in SEEDS:
89
+ clf=module.CloverIntent.from_pretrained(OUT,adapter=f'checkpoints/seed-{s}.safetensors')
90
+ assert frozen_hash(clf.model.pretrained)==info['frozen_sha256'],'packaged backbone differs from the frozen training backbone'
91
+ probs=lambda rows:torch.cat([clf.probabilities(rows[i:i+64]) for i in range(0,len(rows),64)]).numpy()
92
+ recorded={r['id']:r for r in read_rows(MINILM/f'ariadne-seed-{s}/holdout/predictions.jsonl')}
93
+ p=probs(test);ref=np.array([[recorded[r['id']]['probabilities'][l] for l in module.LABELS] for r in test])
94
+ pred=[module.LABELS[i] for i in p.argmax(1)]
95
+ v=probs(validation);y=np.array([module.LABELS.index(r['label']) for r in validation])
96
+ best=selection[s]
97
+ result[f'seed-{s}']={
98
+ 'frozen_backbone_sha256_matches':True,
99
+ 'test_max_abs_probability_difference':float(np.abs(p-ref).max()),
100
+ 'test_predicted_labels_match':pred==[recorded[r['id']]['predicted'] for r in test],
101
+ 'test_accuracy':float(np.mean([a==r['label'] for a,r in zip(pred,test)])),
102
+ 'test_accuracy_recorded':read_json(MINILM/f'ariadne-seed-{s}/holdout/report.json')['accuracy'],
103
+ 'validation_accuracy':float((v.argmax(1)==y).mean()),'validation_accuracy_recorded':best['validation_accuracy'],
104
+ 'validation_nll':float(-np.log(np.maximum(v[np.arange(len(y)),y],1e-12)).mean()),'validation_nll_recorded':best['validation_nll']}
105
+ r=result[f'seed-{s}']
106
+ assert r['test_predicted_labels_match'] and r['test_max_abs_probability_difference']<1e-4,r
107
+ assert abs(r['validation_accuracy']-best['validation_accuracy'])<1e-9 and abs(r['validation_nll']-best['validation_nll'])<1e-4,r
108
+ smoke=module.CloverIntent.from_pretrained(OUT)
109
+ result['examples']={
110
+ 'Restart my web server.':smoke.predict('Restart my web server.')['label'],
111
+ 'yes after a restart offer':smoke.predict('yes',[{'role':'assistant','text':'Would you like me to restart the web server?'}])['label'],
112
+ 'yes after a backup-check offer':smoke.predict('yes',[{'role':'assistant','text':'Would you like me to check whether last night\'s backup ran?'}])['label']}
113
+ write_json(OUT/'checks/packaged-inference-verification.json',result)
114
+ return result
115
+
116
+
117
+ def finish(check):
118
+ report=read_json(OUT/'results/test-report.json')
119
+ write_json(OUT/'model_config.json',{
120
+ 'model':'Akiki MiniLM-L6-v2 Clover intent','repo_id':REPO_ID,'labels':list(read_json(DATA/'manifest.json')['labels']),
121
+ 'tokens':{chr(65+i):l for i,l in enumerate(read_json(DATA/'manifest.json')['labels'])},
122
+ 'base_model':'sentence-transformers/all-MiniLM-L6-v2','base_revision':MODELS['minilm-l6-v2']['path'].rsplit('/',1)[1],
123
+ 'frozen_backbone_sha256':read_json(MINILM/'model.json')['frozen_sha256'],'base_parameters':22713216,
124
+ 'trainable_parameters':{'input_affine':384*384+384,'head':6*384+6,'total':150150},
125
+ 'adapter':'adapter.safetensors','released_seed':RELEASED,'best_epoch':report['best_epoch'],
126
+ 'pooling':'attention-masked mean followed by L2 normalization','max_tokens':512,'truncation':False,
127
+ 'input':'Conversation context:\\n<role>: <text>...\\n\\nCurrent user message: <message> (context block omitted when empty)',
128
+ 'probabilities':'softmax of head logits; no fitted calibration'})
129
+ (OUT/'NOTICE').write_text(
130
+ 'Akiki MiniLM-L6-v2 Clover intent classifier\nDeveloped by AKIKI.AI.\n\n'
131
+ 'Project code is supplied under the Apache License, Version 2.0 (see LICENSE).\n'
132
+ 'Base model: sentence-transformers/all-MiniLM-L6-v2, revision\n'
133
+ f"{MODELS['minilm-l6-v2']['path'].rsplit('/',1)[1]}, Apache-2.0.\n"
134
+ 'Original base-model card and attribution: base_model/README.md.\n'
135
+ 'https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2\n\n'
136
+ 'Clover intent data (data/) is synthetic, generated and reviewed locally by AKIKI.AI with\n'
137
+ 'cached Qwen checkpoints; see data/README.md and provenance/original/CREDITS.md.\n'
138
+ 'Labels are model-reviewed; human review is pending.\n\n'
139
+ 'provenance/original/source/ preserves the original experiment implementation for audit,\n'
140
+ 'under its internal project names. The root-level model.py is portable and needs no\n'
141
+ 'original project files. Result and manifest files copied verbatim from the experiment\n'
142
+ "keep the internal method name 'ariadne', which is the Akiki input affine.\n")
143
+ files=sorted(p for p in OUT.rglob('*') if p.is_file() and p.name!='SHA256SUMS' and '__pycache__' not in p.parts)
144
+ (OUT/'SHA256SUMS').write_text(''.join(f'{sha(p)} {p.relative_to(OUT).as_posix()}\n' for p in files))
145
+ write_json(ROOT/'releases/akiki-minilm-l6-v2-clover-intent-package.json',{
146
+ 'folder':OUT.name,'repo_id':REPO_ID,'files':len(files)+1,'bytes':sum(p.stat().st_size for p in files),
147
+ 'adapter_sha256':sha(OUT/'adapter.safetensors'),'released_seed':RELEASED,
148
+ 'test_accuracy':report['accuracy'],'test_macro_f1':report['macro_f1'],
149
+ 'inference_verification':{k:v for k,v in check.items() if k.startswith('seed-')},'upload_performed':False})
150
+
151
+
152
+ if __name__=='__main__':
153
+ selection=select_seed();assemble();check=verify(selection);finish(check)
154
+ print(json.dumps(check,indent=2))
provenance/original/source/scripts/predict_clover.py ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Print one Clover class token from a local experiment artifact.
2
+
3
+ A=chat, B=question, C=build, D=task, E=fix, F=unclear.
4
+ Use --output label to print the category name instead.
5
+ """
6
+
7
+ import os
8
+ os.environ.update(HF_HUB_OFFLINE='1',TRANSFORMERS_OFFLINE='1',HF_DATASETS_OFFLINE='1')
9
+
10
+ import argparse
11
+ from pathlib import Path
12
+
13
+ import numpy as np
14
+ import torch
15
+
16
+ from ariadne_bench.clover import LABELS,read_json
17
+ from ariadne_bench.clover_models import Encoder,load
18
+
19
+
20
+ def main():
21
+ p=argparse.ArgumentParser(description=__doc__)
22
+ p.add_argument('--run',type=Path,required=True,help='A training-run directory or baseline report directory')
23
+ p.add_argument('message')
24
+ p.add_argument('--context-file',type=Path,help='JSON array of prior role/text conversation turns')
25
+ p.add_argument('--device',default='cuda:1')
26
+ p.add_argument('--output',choices=['token','id','label'],default='token')
27
+ args=p.parse_args();folder=args.run.resolve(strict=True)
28
+ row={'message':args.message,'context':read_json(args.context_file) if args.context_file else []}
29
+ if (folder/'best.pt').exists():
30
+ info=read_json(folder/'model.json');name=info.get('name',info.get('clover_model'))
31
+ model=load(name,args.device,0)
32
+ expected=info.get('frozen_sha256',info.get('frozen_state_sha256'))
33
+ if expected!=model.initial_hash:raise ValueError('Frozen backbone differs from the training artifact')
34
+ method='head_only' if folder.name.startswith('head_only-') else 'ariadne'
35
+ model.configure(method);model.load(torch.load(folder/'best.pt',map_location='cpu',weights_only=True))
36
+ with torch.inference_mode():index=int(model.logits([row]).argmax(-1).item())
37
+ else:
38
+ info=read_json(folder/'report.json');model=load(info['model'],args.device,0)
39
+ with torch.inference_mode():
40
+ if not isinstance(model,Encoder) or folder.name=='frozen-baseline':
41
+ index=int(model.logits([row]).argmax(-1).item())
42
+ else:
43
+ feature=model.model.features(**model.batch([row])).cpu().numpy()[0]
44
+ root=folder.parent
45
+ if folder.name=='class_centroids':
46
+ index=int((np.load(folder/'centroids.npy')@feature).argmax())
47
+ elif folder.name=='knn':
48
+ x=np.load(root/'train-embeddings.npy');y=np.load(root/'train-labels.npy');k=info['k']
49
+ neighbors=np.argpartition(-(x@feature),k-1)[:k]
50
+ index=int(np.bincount(y[neighbors],minlength=6).argmax())
51
+ elif folder.name=='linear_head':
52
+ weights=np.load(root/'linear-head.npz');index=int((weights['weight']@feature+weights['bias']).argmax())
53
+ elif folder.name.startswith('kmeans-seed-'):
54
+ saved=np.load(root/(folder.name+'.npz'))
55
+ cluster=int(((saved['centers']-feature)**2).sum(1).argmin())
56
+ index=int(saved['probabilities'][cluster].argmax())
57
+ else:raise ValueError('Unrecognized baseline directory')
58
+ print(chr(65+index) if args.output=='token' else index if args.output=='id' else LABELS[index])
59
+
60
+
61
+ if __name__=='__main__':main()
provenance/original/source/scripts/run_clover_experiments.py ADDED
@@ -0,0 +1,373 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Run Clover baselines and frozen-backbone specialization, entirely offline.
2
+
3
+ Validation selects hyperparameters/checkpoints; holdout results never control
4
+ training. All pretrained weights are hashed before and after each training run.
5
+ """
6
+
7
+ import os
8
+ os.environ.update(HF_HUB_OFFLINE="1", TRANSFORMERS_OFFLINE="1", HF_DATASETS_OFFLINE="1",
9
+ CUBLAS_WORKSPACE_CONFIG=":4096:8", TOKENIZERS_PARALLELISM="false")
10
+
11
+ import argparse
12
+ import fcntl
13
+ import gc
14
+ import json
15
+ import math
16
+ import random
17
+ import shutil
18
+ import subprocess
19
+ import sys
20
+ import time
21
+ from pathlib import Path
22
+
23
+ # Reuse local CPU analysis dependencies while keeping the selected environment's
24
+ # PyTorch/Transformers first. Qwen's installed CUDA kernels require PyTorch 2.13.
25
+ sys.path.append(str(Path(__file__).resolve().parents[1]/'.deps-specializations'))
26
+
27
+ import numpy as np
28
+ import torch
29
+ from torch.nn import functional as F
30
+
31
+ from ariadne_bench.clover import (
32
+ DESCRIPTIONS, DIFFICULTIES, LABELS, RUBRIC, metrics, read_json, read_rows, render,
33
+ sha, write_json, write_rows,
34
+ )
35
+ from ariadne_bench.clover_models import MODELS, Encoder, load
36
+
37
+ ROOT=Path(__file__).resolve().parents[1]
38
+ os.environ.setdefault('TRITON_CACHE_DIR',str(ROOT/'.cache/triton-clover'))
39
+ os.environ.setdefault('TORCHINDUCTOR_CACHE_DIR',str(ROOT/'.cache/inductor-clover'))
40
+
41
+
42
+ def emit(out,event,**fields):
43
+ record={"event":event,"utc":time.strftime("%Y-%m-%dT%H:%M:%SZ",time.gmtime()),**fields}
44
+ with (out/"progress.jsonl").open("a") as f:f.write(json.dumps(record)+"\n")
45
+ write_json(out/"status.json",record)
46
+ print(json.dumps(record),flush=True)
47
+
48
+
49
+ def softmax(x):
50
+ x=x-x.max(1,keepdims=True);p=np.exp(x);return p/p.sum(1,keepdims=True)
51
+
52
+
53
+ def save_score(directory,rows,probabilities,metadata):
54
+ directory.mkdir(parents=True,exist_ok=True)
55
+ report={**metadata,**metrics(rows,probabilities)}
56
+ predictions=[{"id":r["id"],"label":r["label"],"difficulty":r["difficulty"],
57
+ "predicted":LABELS[int(np.argmax(p))],"probabilities":dict(zip(LABELS,map(float,p)))}
58
+ for r,p in zip(rows,probabilities)]
59
+ write_rows(directory/"predictions.jsonl",predictions)
60
+ report["predictions_sha256"]=sha(directory/"predictions.jsonl")
61
+ write_json(directory/"report.json",report)
62
+ return report
63
+
64
+
65
+ @torch.no_grad()
66
+ def evaluate(model,rows,batch_size):
67
+ model.model.eval();probabilities=[]
68
+ for start in range(0,len(rows),batch_size):
69
+ probabilities.extend(model.logits(rows[start:start+batch_size]).float().softmax(-1).cpu().tolist())
70
+ return np.array(probabilities)
71
+
72
+
73
+ def protocol(args,manifest):
74
+ folder=args.out/"protocol";folder.mkdir(parents=True,exist_ok=True)
75
+ source_files=sorted((ROOT/'ariadne_bench').glob('*.py'))+[
76
+ ROOT/'scripts'/name for name in ['run_clover_experiments.py','build_clover_dataset.py',
77
+ 'build_clover_native_batch.py','repair_clover_batch.py','benchmark_clover_generation.py',
78
+ 'finish_clover_dataset.py','predict_clover.py']]
79
+ guidance=ROOT/'data/clover-intent-v1/generation-overrides.json'
80
+ if guidance.exists():source_files.append(guidance)
81
+ plan={"dataset":str(args.data.resolve()),"dataset_manifest_sha256":sha(args.data/"manifest.json"),
82
+ "splits":manifest["splits"],"models":MODELS,"seeds":args.seeds,
83
+ "methods":{"encoders":["description_similarity","class_centroids","knn","kmeans","linear_head","head_only","ariadne"],
84
+ "native":["native_frozen","ariadne"]},
85
+ "stopping":{"minimum_epochs":10,"patience":3,"selection":"lowest validation NLL; no test-based choices"},
86
+ "optimization":{"batch":32,"microbatch":args.microbatch,"head_lr":1e-3,"interface_lr":1e-4,"weight_decay":0.0,"clip":1.0,
87
+ "head_only_feature_cache":True,"feature_cache_validation":"live frozen features must match within 2e-5"},
88
+ "seed_summary":"mean and sample standard deviation; all individual runs retained",
89
+ "reported_metrics":["accuracy","macro_f1","nll","brier","confusion_matrix","difficulty_tiers",
90
+ "actions_on_chat_question","actions_on_unclear"],
91
+ "passmarks":{"accuracy":.95,"false_actions_on_chat_question":0,"difficulty_tiers":list(DIFFICULTIES)},
92
+ "baseline_caveat":"Description similarity is an explicitly constructed zero-shot readout, not a native semantic head on MiniLM/ModernBERT.",
93
+ "label_quality":"synthetic, two-model agreement; no claim of human-labelled ground truth",
94
+ "output":"single class ID; Qwen uses one native letter token; JSON is artifact storage only",
95
+ "sources":{str(p.relative_to(ROOT)):sha(p) for p in source_files}}
96
+ path=folder/"plan.json"
97
+ if path.exists():
98
+ previous=read_json(path)
99
+ assert previous==plan,"Protocol changed after freeze; create a new experiment version"
100
+ else:
101
+ write_json(path,plan)
102
+ for source in source_files:
103
+ snapshot=folder/'sources'/source.relative_to(ROOT)
104
+ snapshot.parent.mkdir(parents=True,exist_ok=True)
105
+ shutil.copyfile(source,snapshot)
106
+ (folder/"PASSMARK-CLOVER-1.md").write_text(
107
+ "# Clover English intent experiment\n\nDeveloped by AKIKI.AI.\n\n"
108
+ "Six categories: chat, question, build, task, fix, unclear. Output is a single class ID.\n\n"
109
+ "Targets: at least 95% accuracy and zero observed build/task/fix classifications on pure chat/question. "
110
+ "Report easy, medium and hard separately. These are experimental measurements on model-reviewed "
111
+ "synthetic data, not a human-verified acceptance exam. No release or serving change is authorized.\n\n"
112
+ "All dataset hashes, seeds, methods and stopping rules are in plan.json. "
113
+ "Select hyperparameters and checkpoints on validation only. Holdout never enters training. "
114
+ "Frozen backbone and original native heads remain unchanged. No model downloads.\n")
115
+ # The workspace has no parent Git checkout. Keep the required pre-training
116
+ # protocol commit in a separate, self-contained experiment repository.
117
+ subprocess.run(["git","init","-q",str(folder)],check=True)
118
+ subprocess.run(["git","-C",str(folder),"add","plan.json","PASSMARK-CLOVER-1.md","sources"],check=True)
119
+ subprocess.run(["git","-C",str(folder),"-c","user.name=Codex","-c","user.email=codex@localhost", "commit","-qm","Freeze Clover English data hashes and comparison protocol before training"],check=True)
120
+ commit=subprocess.check_output(["git","-C",str(folder),"rev-parse","HEAD"],text=True).strip()
121
+ emit(args.out,"protocol_frozen",commit=commit,dataset=manifest["splits"])
122
+ return sha(path)
123
+
124
+
125
+ def embedding_baselines(args,name,model,rows):
126
+ from sklearn.cluster import KMeans
127
+ from sklearn.linear_model import LogisticRegression
128
+ from sklearn.metrics import adjusted_rand_score
129
+ folder=args.out/name/"embedding-baselines"
130
+ if (folder/"complete.json").exists():return
131
+ folder.mkdir(parents=True,exist_ok=True)
132
+ vectors={}
133
+ for split,items in rows.items():
134
+ path=folder/(split+"-embeddings.npy")
135
+ if path.exists():vectors[split]=np.load(path)
136
+ else:
137
+ data=[];t=time.monotonic()
138
+ with torch.no_grad():
139
+ for start in range(0,len(items),args.eval_batch):
140
+ data.append(model.model.features(**model.batch(items[start:start+args.eval_batch])).cpu().numpy())
141
+ vectors[split]=np.concatenate(data);np.save(path,vectors[split])
142
+ emit(args.out,"embeddings_cached",model=name,split=split,rows=len(items),seconds=round(time.monotonic()-t,1))
143
+ assert len(vectors[split])==len(items)
144
+ x=vectors["train"];v=vectors["validation"];z=vectors["test"]
145
+ y=np.array([LABELS.index(r["label"]) for r in rows["train"]])
146
+ vy=np.array([LABELS.index(r["label"]) for r in rows["validation"]])
147
+ ty=np.array([LABELS.index(r["label"]) for r in rows["test"]])
148
+ centroids=np.stack([x[y==i].mean(0) for i in range(6)])
149
+ centroids/=np.maximum(np.linalg.norm(centroids,axis=1,keepdims=True),1e-12)
150
+ (folder/'class_centroids').mkdir(parents=True,exist_ok=True)
151
+ np.save(folder/'class_centroids'/'centroids.npy',centroids)
152
+ np.save(folder/'train-labels.npy',y)
153
+ save_score(folder/"class_centroids",rows["test"],softmax(10*z@centroids.T),{"model":name,"method":"training-class-centroid cosine similarity","train_labels_used":True})
154
+ # Tune k and C on development data only; all labels are canonical indices.
155
+ def neighbor_prob(query,k):
156
+ result=[]
157
+ for start in range(0,len(query),128):
158
+ sim=query[start:start+128]@x.T
159
+ indices=np.argpartition(-sim,k-1,axis=1)[:,:k]
160
+ p=np.stack([np.bincount(y[idx],minlength=6) for idx in indices]).astype(float)
161
+ result.extend((p+.001)/(k+.006))
162
+ return np.array(result)
163
+ options=[]
164
+ for k in [1,3,5,11]:
165
+ p=neighbor_prob(v,k);options.append((metrics(rows["validation"],p)["macro_f1"],k))
166
+ _,k=max(options)
167
+ save_score(folder/"knn",rows["test"],neighbor_prob(z,k),{"model":name,"method":"cosine nearest labelled examples","k":k,"validation_candidates":options})
168
+ options=[];best=None
169
+ for c in [.1,1.,10.,100.]:
170
+ classifier=LogisticRegression(C=c,max_iter=2000,class_weight="balanced",random_state=0)
171
+ classifier.fit(x,y);p=classifier.predict_proba(v)
172
+ score=metrics(rows["validation"],p)["nll"]
173
+ options.append({"C":c,"validation_nll":score})
174
+ if best is None or score<best[0]:best=(score,c,classifier)
175
+ _,c,classifier=best
176
+ np.savez(folder/"linear-head.npz",weight=classifier.coef_,bias=classifier.intercept_)
177
+ save_score(folder/"linear_head",rows["test"],classifier.predict_proba(z),{"model":name,"method":"frozen embeddings + regularized linear classifier","C":c,"validation_candidates":options})
178
+ for seed in args.seeds:
179
+ candidates=[];best=None
180
+ for n in [6,12,24,48]:
181
+ km=KMeans(n_clusters=n,random_state=seed,n_init=10).fit(x)
182
+ # Fit clusters with no labels, then label each using TRAIN labels only.
183
+ count=np.stack([np.bincount(y[km.labels_==i],minlength=6) for i in range(n)]).astype(float)
184
+ pcluster=(count+.01)/(count.sum(1,keepdims=True)+.06)
185
+ p=pcluster[km.predict(v)];score=metrics(rows["validation"],p)["macro_f1"]
186
+ candidates.append({"clusters":n,"validation_macro_f1":score})
187
+ if best is None or score>best[0]:best=(score,n,km,pcluster)
188
+ _,n,km,pcluster=best
189
+ assigned=km.predict(z)
190
+ np.savez(folder/(f'kmeans-seed-{seed}.npz'),centers=km.cluster_centers_,probabilities=pcluster)
191
+ save_score(folder/("kmeans-seed-"+str(seed)),rows["test"],pcluster[assigned],{
192
+ "model":name,"method":"k-means on training embeddings; training-majority cluster labels",
193
+ "seed":seed,"clusters":n,"adjusted_rand_index":float(adjusted_rand_score(ty,assigned)),"validation_candidates":candidates})
194
+ write_json(folder/"complete.json",{"complete":True,"embedding_rows":{s:len(v) for s,v in vectors.items()}})
195
+ emit(args.out,"embedding_baselines_complete",model=name)
196
+
197
+
198
+ def train(args,name,method,seed,rows,plan_sha):
199
+ folder=args.out/name/(method+"-seed-"+str(seed));folder.mkdir(parents=True,exist_ok=True)
200
+ if (folder/"complete.json").exists():return
201
+ torch.manual_seed(seed);random.seed(seed);np.random.seed(seed)
202
+ model=load(name,args.device,seed)
203
+ groups=model.configure(method)
204
+ optimizer=torch.optim.AdamW(groups,weight_decay=0.)
205
+ parameters=[p for p in model.model.parameters() if p.requires_grad]
206
+ feature_cache=None;cache_metadata={}
207
+ if method=='head_only' and isinstance(model,Encoder):
208
+ cache_path=args.out/name/'embedding-baselines/train-embeddings.npy'
209
+ values=np.load(cache_path)
210
+ assert values.shape==(len(rows['train']),model.model.head.in_features) and np.isfinite(values).all()
211
+ feature_cache=torch.from_numpy(values).to(model.device)
212
+ with torch.no_grad():
213
+ live=model.model.features(**model.batch(rows['train'][:5]))
214
+ torch.testing.assert_close(feature_cache[:5],live,rtol=2e-5,atol=2e-5)
215
+ cache_metadata={'frozen_feature_cache_sha256':sha(cache_path),
216
+ 'training_forward':'cached unchanged frozen features, live trainable head; validation uses full model'}
217
+ write_json(folder/"model.json",{**model.metadata,**cache_metadata,"trainable_parameters":sum(p.numel() for p in parameters)})
218
+ # Real gradient/frozen-parameter preflight, plus identity equivalence for encoders.
219
+ first=rows["train"][:args.microbatch]
220
+ initial=model.state()
221
+ native=model.logits(first).detach().clone()
222
+ loss=F.cross_entropy(model.logits(first),torch.tensor([LABELS.index(r["label"]) for r in first],device=model.device))
223
+ loss.backward()
224
+ assert all(p.grad is not None and torch.isfinite(p.grad).all() for p in parameters)
225
+ optimizer.step();model.verify_frozen();model.load(initial);optimizer.zero_grad(set_to_none=True)
226
+ assert torch.equal(native,model.logits(first).detach()),"identity restore failed"
227
+ optimizer=torch.optim.AdamW(groups,weight_decay=0.)
228
+ history=[];best=float("inf");stale=0;epoch=0
229
+ resume=folder/"resume.pt"
230
+ if resume.exists():
231
+ saved=torch.load(resume,map_location="cpu",weights_only=True)
232
+ assert saved["plan_sha256"]==plan_sha
233
+ model.load(saved["parameters"]);optimizer.load_state_dict(saved["optimizer"])
234
+ history=saved["history"];epoch=saved["epoch"];best=saved["best"];stale=saved["stale"]
235
+ emit(args.out,"training_started",model=name,method=method,seed=seed,trainable_parameters=sum(p.numel() for p in parameters),resumed_epoch=epoch)
236
+ while not (epoch>=10 and stale>=3):
237
+ epoch+=1;t=time.monotonic();model.model.eval()
238
+ order=list(range(len(rows["train"])));random.Random(seed*10000+epoch).shuffle(order)
239
+ train_loss=0.;train_correct=0;total=0;last_emit=time.monotonic()
240
+ for start in range(0,len(order),32):
241
+ indices=order[start:start+32];optimizer.zero_grad(set_to_none=True)
242
+ for micro in range(0,len(indices),args.microbatch):
243
+ selected=[rows["train"][i] for i in indices[micro:micro+args.microbatch]]
244
+ y=torch.tensor([LABELS.index(r["label"]) for r in selected],device=model.device)
245
+ if feature_cache is None:logits=model.logits(selected)
246
+ else:
247
+ take=torch.tensor(indices[micro:micro+args.microbatch],device=model.device)
248
+ logits=model.model.head(feature_cache.index_select(0,take))
249
+ loss=F.cross_entropy(logits,y)
250
+ (loss*len(selected)/len(indices)).backward()
251
+ train_loss+=loss.item()*len(selected);train_correct+=(logits.argmax(-1)==y).sum().item();total+=len(selected)
252
+ norm=torch.nn.utils.clip_grad_norm_(parameters,1.,error_if_nonfinite=True)
253
+ optimizer.step()
254
+ if time.monotonic()-last_emit>=45:
255
+ emit(args.out,"training_progress",model=name,method=method,seed=seed,epoch=epoch,examples=total,total_examples=len(order),train_loss=train_loss/total)
256
+ last_emit=time.monotonic()
257
+ model.verify_frozen()
258
+ p=evaluate(model,rows["validation"],args.eval_batch if isinstance(model,Encoder) else args.microbatch)
259
+ report=metrics(rows["validation"],p);improved=report["nll"]<best
260
+ if improved:
261
+ best=report["nll"];stale=0;torch.save(model.state(),folder/"best.pt")
262
+ else:stale+=1
263
+ row={"epoch":epoch,"train_loss":train_loss/total,"train_accuracy":train_correct/total,
264
+ "validation":report,"seconds":time.monotonic()-t,"improved":improved,"stale":stale}
265
+ history.append(row);write_json(folder/"history.json",history)
266
+ tmp=resume.with_suffix(".tmp")
267
+ torch.save({"plan_sha256":plan_sha,"parameters":model.state(),"optimizer":optimizer.state_dict(),
268
+ "history":history,"epoch":epoch,"best":best,"stale":stale},tmp);tmp.replace(resume)
269
+ emit(args.out,"epoch_complete",model=name,method=method,seed=seed,epoch=epoch,validation_accuracy=report["accuracy"],validation_nll=report["nll"],seconds=round(row["seconds"],1),stale=stale)
270
+ model.load(torch.load(folder/"best.pt",map_location="cpu",weights_only=True));model.verify_frozen()
271
+ best_epoch=min(history,key=lambda r:r["validation"]["nll"])["epoch"]
272
+ p=evaluate(model,rows["test"],args.eval_batch if isinstance(model,Encoder) else args.microbatch)
273
+ report=save_score(folder/"holdout",rows["test"],p,{"model":name,"method":method,"seed":seed,"best_epoch":best_epoch,"epochs_completed":epoch,"frozen_weights_unchanged":True,"frozen_sha256":model.initial_hash})
274
+ write_json(folder/"complete.json",{"complete":True,"best_epoch":best_epoch,"holdout_accuracy":report["accuracy"],"frozen_verified":True})
275
+ emit(args.out,"training_complete",model=name,method=method,seed=seed,best_epoch=best_epoch,holdout_accuracy=report["accuracy"],false_actions=report["false_actions"])
276
+ if hasattr(model,"adapter"):model.adapter.close()
277
+ del model,optimizer;gc.collect();torch.cuda.empty_cache()
278
+
279
+
280
+ def refresh_report(out):
281
+ reports=[]
282
+ for path in out.rglob("report.json"):
283
+ if path.is_relative_to(out/"protocol"):continue
284
+ report=read_json(path)
285
+ if "accuracy" in report:reports.append({"artifact":str(path.relative_to(out)),**report})
286
+ write_json(out/"results.json",reports)
287
+ grouped={}
288
+ for report in reports:
289
+ key=(report.get('model'),report.get('method'))
290
+ grouped.setdefault(key,[]).append(report)
291
+ summaries=[]
292
+ for (name,method),group in sorted(grouped.items()):
293
+ summary={'model':name,'method':method,'runs':len(group),'seeds':[r.get('seed') for r in group]}
294
+ for field in ('accuracy','macro_f1','nll','brier'):
295
+ values=np.array([r[field] for r in group],dtype=float)
296
+ summary[field]={'mean':float(values.mean()),'sample_sd':float(values.std(ddof=1)) if len(values)>1 else None}
297
+ summary['by_difficulty']={}
298
+ for level in DIFFICULTIES:
299
+ values=np.array([r['by_difficulty'][level]['accuracy'] for r in group],dtype=float)
300
+ summary['by_difficulty'][level]={'mean':float(values.mean()),'sample_sd':float(values.std(ddof=1)) if len(values)>1 else None}
301
+ summary['false_actions']=[r['false_actions'] for r in group]
302
+ summary['actions_on_unclear']=[r['actions_on_unclear'] for r in group]
303
+ summaries.append(summary)
304
+ write_json(out/'seed-summary.json',summaries)
305
+ lines=["# Clover English intent comparison","","Developed by AKIKI.AI. Synthetic, model-reviewed labels; human review pending.","",
306
+ "All original backbone weights remain frozen. Validation alone chooses training settings and checkpoints.","",
307
+ "Results across seeds (mean ± sample standard deviation where repeated):","",
308
+ "| Model / method | Runs | Accuracy | Macro F1 | Hard accuracy |",
309
+ "|---|---:|---:|---:|---:|"]
310
+ def percent(cell):
311
+ return f"{100*cell['mean']:.1f}%"+(f" ± {100*cell['sample_sd']:.1f}" if cell['sample_sd'] is not None else '')
312
+ for summary in summaries:
313
+ f1=summary['macro_f1']
314
+ f1_text=f"{f1['mean']:.3f}"+(f" ± {f1['sample_sd']:.3f}" if f1['sample_sd'] is not None else '')
315
+ lines.append(f"| {summary['model']} / {summary['method']} | {summary['runs']} | {percent(summary['accuracy'])} | {f1_text} | {percent(summary['by_difficulty']['hard'])} |")
316
+ lines.extend(["","Individual runs:","",
317
+ "| Model / method | Accuracy | Macro F1 | Easy | Medium | Hard | Actions on chat/question | Actions on unclear |",
318
+ "|---|---:|---:|---:|---:|---:|---:|---:|"])
319
+ for r in sorted(reports,key=lambda r:r["artifact"]):
320
+ levels=r["by_difficulty"]
321
+ cells=[f"{100*levels[d]['accuracy']:.1f}%" if d in levels else "—" for d in DIFFICULTIES]
322
+ lines.append(f"| {r['artifact'].replace('/report.json','')} | {100*r['accuracy']:.1f}% | {r['macro_f1']:.3f} | {' | '.join(cells)} | {r['false_actions']}/{r['passive_cases']} | {r['actions_on_unclear']}/{r['unclear_cases']} |")
323
+ (out/"results.md").write_text("\n".join(lines)+"\n")
324
+
325
+
326
+ def main():
327
+ p=argparse.ArgumentParser(description=__doc__)
328
+ p.add_argument("--data",type=Path,default=ROOT/"data/clover-intent-v1")
329
+ p.add_argument("--out",type=Path,default=ROOT/"runs/clover-intent-v1")
330
+ p.add_argument("--models",nargs="+",default=list(MODELS),choices=list(MODELS))
331
+ p.add_argument("--seeds",nargs="+",type=int,default=[0,1,2])
332
+ p.add_argument("--device",default="cuda:1")
333
+ p.add_argument("--microbatch",type=int,default=32)
334
+ p.add_argument("--eval-batch",type=int,default=64)
335
+ args=p.parse_args();args.out.mkdir(parents=True,exist_ok=True)
336
+ torch.set_num_threads(8);torch.set_float32_matmul_precision("highest")
337
+ torch.backends.cuda.matmul.allow_tf32=False;torch.backends.cudnn.allow_tf32=False
338
+ from ariadne_bench.reproducibility import configure_determinism
339
+ configure_determinism(0)
340
+ with (args.out/"experiment.lock").open("a") as lock:
341
+ fcntl.flock(lock,fcntl.LOCK_EX|fcntl.LOCK_NB)
342
+ manifest=read_json(args.data/"manifest.json");assert manifest["complete"] and read_json(args.data/"audit.json")["passed"]
343
+ assert sha(args.data/'audit.json')==manifest['audit_sha256']
344
+ rows={}
345
+ for split,spec in manifest["splits"].items():
346
+ assert sha(args.data/spec["file"])==spec["sha256"]
347
+ rows[split]=read_rows(args.data/spec["file"])
348
+ plan_sha=protocol(args,manifest)
349
+ # Complete all requested pre-training baselines before any specialization.
350
+ for name in args.models:
351
+ folder=args.out/name/"frozen-baseline"
352
+ if (folder/"report.json").exists():continue
353
+ emit(args.out,"baseline_started",model=name)
354
+ model=load(name,args.device,0);write_json(args.out/name/"model.json",model.metadata)
355
+ model.verify_identity(rows['validation'][:3]);model.verify_frozen()
356
+ probabilities=evaluate(model,rows["test"],args.eval_batch if isinstance(model,Encoder) else args.microbatch)
357
+ report=save_score(folder,rows["test"],probabilities,{"model":name,"method":"description_similarity" if isinstance(model,Encoder) else "native_frozen","training_examples_used":0,"identity_matches_native_logits":True})
358
+ emit(args.out,"baseline_complete",model=name,accuracy=report["accuracy"],by_difficulty={d:r["accuracy"] for d,r in report["by_difficulty"].items()})
359
+ if hasattr(model,"adapter"):model.adapter.close()
360
+ del model;gc.collect();torch.cuda.empty_cache();refresh_report(args.out)
361
+ for name in args.models:
362
+ if MODELS[name]["kind"]=="encoder":
363
+ model=load(name,args.device,0);embedding_baselines(args,name,model,rows)
364
+ del model;gc.collect();torch.cuda.empty_cache();refresh_report(args.out)
365
+ for name in args.models:
366
+ methods=["head_only","ariadne"] if MODELS[name]["kind"]=="encoder" else ["ariadne"]
367
+ for method in methods:
368
+ for seed in args.seeds:
369
+ train(args,name,method,seed,rows,plan_sha);refresh_report(args.out)
370
+ refresh_report(args.out);emit(args.out,"experiment_complete",report=str(args.out/"results.md"))
371
+
372
+
373
+ if __name__=="__main__":main()
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ torch==2.13.0
2
+ transformers==5.17.0
3
+ safetensors==0.8.0
4
+ tokenizers==0.23.2
results/baselines/embedding-class_centroids.json ADDED
@@ -0,0 +1,419 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "model": "minilm-l6-v2",
3
+ "method": "training-class-centroid cosine similarity",
4
+ "train_labels_used": true,
5
+ "cases": 714,
6
+ "accuracy": 0.8053221288515406,
7
+ "macro_f1": 0.8039270413110179,
8
+ "per_class": {
9
+ "chat": {
10
+ "precision": 0.8791208791208791,
11
+ "recall": 0.6666666666666666,
12
+ "f1": 0.7582938388625592,
13
+ "support": 120
14
+ },
15
+ "question": {
16
+ "precision": 0.8833333333333333,
17
+ "recall": 0.8833333333333333,
18
+ "f1": 0.8833333333333333,
19
+ "support": 120
20
+ },
21
+ "build": {
22
+ "precision": 0.8515625,
23
+ "recall": 0.9083333333333333,
24
+ "f1": 0.8790322580645161,
25
+ "support": 120
26
+ },
27
+ "task": {
28
+ "precision": 0.8469387755102041,
29
+ "recall": 0.6916666666666667,
30
+ "f1": 0.7614678899082569,
31
+ "support": 120
32
+ },
33
+ "fix": {
34
+ "precision": 0.6792452830188679,
35
+ "recall": 0.9,
36
+ "f1": 0.7741935483870968,
37
+ "support": 120
38
+ },
39
+ "unclear": {
40
+ "precision": 0.7542372881355932,
41
+ "recall": 0.7807017543859649,
42
+ "f1": 0.7672413793103449,
43
+ "support": 114
44
+ }
45
+ },
46
+ "confusion": {
47
+ "chat": {
48
+ "chat": 80,
49
+ "question": 7,
50
+ "build": 15,
51
+ "task": 2,
52
+ "fix": 7,
53
+ "unclear": 9,
54
+ "INVALID": 0
55
+ },
56
+ "question": {
57
+ "chat": 2,
58
+ "question": 106,
59
+ "build": 0,
60
+ "task": 0,
61
+ "fix": 5,
62
+ "unclear": 7,
63
+ "INVALID": 0
64
+ },
65
+ "build": {
66
+ "chat": 5,
67
+ "question": 0,
68
+ "build": 109,
69
+ "task": 3,
70
+ "fix": 0,
71
+ "unclear": 3,
72
+ "INVALID": 0
73
+ },
74
+ "task": {
75
+ "chat": 0,
76
+ "question": 1,
77
+ "build": 4,
78
+ "task": 83,
79
+ "fix": 27,
80
+ "unclear": 5,
81
+ "INVALID": 0
82
+ },
83
+ "fix": {
84
+ "chat": 0,
85
+ "question": 5,
86
+ "build": 0,
87
+ "task": 2,
88
+ "fix": 108,
89
+ "unclear": 5,
90
+ "INVALID": 0
91
+ },
92
+ "unclear": {
93
+ "chat": 4,
94
+ "question": 1,
95
+ "build": 0,
96
+ "task": 8,
97
+ "fix": 12,
98
+ "unclear": 89,
99
+ "INVALID": 0
100
+ }
101
+ },
102
+ "invalid": 0,
103
+ "nll": 0.9776460491478228,
104
+ "brier": 0.4748579251724496,
105
+ "false_actions": 29,
106
+ "passive_cases": 240,
107
+ "false_action_rate": 0.12083333333333333,
108
+ "unclear_cases": 114,
109
+ "actions_on_unclear": 20,
110
+ "action_rate_on_unclear": 0.17543859649122806,
111
+ "by_difficulty": {
112
+ "easy": {
113
+ "cases": 235,
114
+ "accuracy": 0.8127659574468085,
115
+ "macro_f1": 0.8068940909578335,
116
+ "per_class": {
117
+ "chat": {
118
+ "precision": 0.9545454545454546,
119
+ "recall": 0.525,
120
+ "f1": 0.6774193548387096,
121
+ "support": 40
122
+ },
123
+ "question": {
124
+ "precision": 0.8571428571428571,
125
+ "recall": 0.9,
126
+ "f1": 0.8780487804878049,
127
+ "support": 40
128
+ },
129
+ "build": {
130
+ "precision": 0.7647058823529411,
131
+ "recall": 0.975,
132
+ "f1": 0.8571428571428571,
133
+ "support": 40
134
+ },
135
+ "task": {
136
+ "precision": 0.8333333333333334,
137
+ "recall": 0.75,
138
+ "f1": 0.7894736842105263,
139
+ "support": 40
140
+ },
141
+ "fix": {
142
+ "precision": 0.7037037037037037,
143
+ "recall": 0.95,
144
+ "f1": 0.8085106382978723,
145
+ "support": 40
146
+ },
147
+ "unclear": {
148
+ "precision": 0.9,
149
+ "recall": 0.7714285714285715,
150
+ "f1": 0.8307692307692308,
151
+ "support": 35
152
+ }
153
+ },
154
+ "confusion": {
155
+ "chat": {
156
+ "chat": 21,
157
+ "question": 4,
158
+ "build": 9,
159
+ "task": 1,
160
+ "fix": 3,
161
+ "unclear": 2,
162
+ "INVALID": 0
163
+ },
164
+ "question": {
165
+ "chat": 1,
166
+ "question": 36,
167
+ "build": 0,
168
+ "task": 0,
169
+ "fix": 3,
170
+ "unclear": 0,
171
+ "INVALID": 0
172
+ },
173
+ "build": {
174
+ "chat": 0,
175
+ "question": 0,
176
+ "build": 39,
177
+ "task": 1,
178
+ "fix": 0,
179
+ "unclear": 0,
180
+ "INVALID": 0
181
+ },
182
+ "task": {
183
+ "chat": 0,
184
+ "question": 0,
185
+ "build": 3,
186
+ "task": 30,
187
+ "fix": 6,
188
+ "unclear": 1,
189
+ "INVALID": 0
190
+ },
191
+ "fix": {
192
+ "chat": 0,
193
+ "question": 1,
194
+ "build": 0,
195
+ "task": 1,
196
+ "fix": 38,
197
+ "unclear": 0,
198
+ "INVALID": 0
199
+ },
200
+ "unclear": {
201
+ "chat": 0,
202
+ "question": 1,
203
+ "build": 0,
204
+ "task": 3,
205
+ "fix": 4,
206
+ "unclear": 27,
207
+ "INVALID": 0
208
+ }
209
+ },
210
+ "invalid": 0
211
+ },
212
+ "medium": {
213
+ "cases": 239,
214
+ "accuracy": 0.7907949790794979,
215
+ "macro_f1": 0.7804472677829759,
216
+ "per_class": {
217
+ "chat": {
218
+ "precision": 1.0,
219
+ "recall": 0.525,
220
+ "f1": 0.6885245901639344,
221
+ "support": 40
222
+ },
223
+ "question": {
224
+ "precision": 0.8837209302325582,
225
+ "recall": 0.95,
226
+ "f1": 0.9156626506024096,
227
+ "support": 40
228
+ },
229
+ "build": {
230
+ "precision": 0.8809523809523809,
231
+ "recall": 0.925,
232
+ "f1": 0.9024390243902439,
233
+ "support": 40
234
+ },
235
+ "task": {
236
+ "precision": 0.7916666666666666,
237
+ "recall": 0.475,
238
+ "f1": 0.59375,
239
+ "support": 40
240
+ },
241
+ "fix": {
242
+ "precision": 0.6129032258064516,
243
+ "recall": 0.95,
244
+ "f1": 0.7450980392156863,
245
+ "support": 40
246
+ },
247
+ "unclear": {
248
+ "precision": 0.7659574468085106,
249
+ "recall": 0.9230769230769231,
250
+ "f1": 0.8372093023255814,
251
+ "support": 39
252
+ }
253
+ },
254
+ "confusion": {
255
+ "chat": {
256
+ "chat": 21,
257
+ "question": 3,
258
+ "build": 5,
259
+ "task": 1,
260
+ "fix": 3,
261
+ "unclear": 7,
262
+ "INVALID": 0
263
+ },
264
+ "question": {
265
+ "chat": 0,
266
+ "question": 38,
267
+ "build": 0,
268
+ "task": 0,
269
+ "fix": 0,
270
+ "unclear": 2,
271
+ "INVALID": 0
272
+ },
273
+ "build": {
274
+ "chat": 0,
275
+ "question": 0,
276
+ "build": 37,
277
+ "task": 2,
278
+ "fix": 0,
279
+ "unclear": 1,
280
+ "INVALID": 0
281
+ },
282
+ "task": {
283
+ "chat": 0,
284
+ "question": 1,
285
+ "build": 0,
286
+ "task": 19,
287
+ "fix": 20,
288
+ "unclear": 0,
289
+ "INVALID": 0
290
+ },
291
+ "fix": {
292
+ "chat": 0,
293
+ "question": 1,
294
+ "build": 0,
295
+ "task": 0,
296
+ "fix": 38,
297
+ "unclear": 1,
298
+ "INVALID": 0
299
+ },
300
+ "unclear": {
301
+ "chat": 0,
302
+ "question": 0,
303
+ "build": 0,
304
+ "task": 2,
305
+ "fix": 1,
306
+ "unclear": 36,
307
+ "INVALID": 0
308
+ }
309
+ },
310
+ "invalid": 0
311
+ },
312
+ "hard": {
313
+ "cases": 240,
314
+ "accuracy": 0.8125,
315
+ "macro_f1": 0.8136373691259903,
316
+ "per_class": {
317
+ "chat": {
318
+ "precision": 0.7916666666666666,
319
+ "recall": 0.95,
320
+ "f1": 0.8636363636363636,
321
+ "support": 40
322
+ },
323
+ "question": {
324
+ "precision": 0.9142857142857143,
325
+ "recall": 0.8,
326
+ "f1": 0.8533333333333334,
327
+ "support": 40
328
+ },
329
+ "build": {
330
+ "precision": 0.9428571428571428,
331
+ "recall": 0.825,
332
+ "f1": 0.88,
333
+ "support": 40
334
+ },
335
+ "task": {
336
+ "precision": 0.8947368421052632,
337
+ "recall": 0.85,
338
+ "f1": 0.8717948717948718,
339
+ "support": 40
340
+ },
341
+ "fix": {
342
+ "precision": 0.7441860465116279,
343
+ "recall": 0.8,
344
+ "f1": 0.7710843373493976,
345
+ "support": 40
346
+ },
347
+ "unclear": {
348
+ "precision": 0.6341463414634146,
349
+ "recall": 0.65,
350
+ "f1": 0.6419753086419753,
351
+ "support": 40
352
+ }
353
+ },
354
+ "confusion": {
355
+ "chat": {
356
+ "chat": 38,
357
+ "question": 0,
358
+ "build": 1,
359
+ "task": 0,
360
+ "fix": 1,
361
+ "unclear": 0,
362
+ "INVALID": 0
363
+ },
364
+ "question": {
365
+ "chat": 1,
366
+ "question": 32,
367
+ "build": 0,
368
+ "task": 0,
369
+ "fix": 2,
370
+ "unclear": 5,
371
+ "INVALID": 0
372
+ },
373
+ "build": {
374
+ "chat": 5,
375
+ "question": 0,
376
+ "build": 33,
377
+ "task": 0,
378
+ "fix": 0,
379
+ "unclear": 2,
380
+ "INVALID": 0
381
+ },
382
+ "task": {
383
+ "chat": 0,
384
+ "question": 0,
385
+ "build": 1,
386
+ "task": 34,
387
+ "fix": 1,
388
+ "unclear": 4,
389
+ "INVALID": 0
390
+ },
391
+ "fix": {
392
+ "chat": 0,
393
+ "question": 3,
394
+ "build": 0,
395
+ "task": 1,
396
+ "fix": 32,
397
+ "unclear": 4,
398
+ "INVALID": 0
399
+ },
400
+ "unclear": {
401
+ "chat": 4,
402
+ "question": 0,
403
+ "build": 0,
404
+ "task": 3,
405
+ "fix": 7,
406
+ "unclear": 26,
407
+ "INVALID": 0
408
+ }
409
+ },
410
+ "invalid": 0
411
+ }
412
+ },
413
+ "difficulty_counts": {
414
+ "medium": 239,
415
+ "hard": 240,
416
+ "easy": 235
417
+ },
418
+ "predictions_sha256": "8dc7acfec189471f677a86bf5e19e35655ba2f1e1bf77afe9678a65e1d0dbf61"
419
+ }
results/baselines/embedding-kmeans-seed-0.json ADDED
@@ -0,0 +1,439 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "model": "minilm-l6-v2",
3
+ "method": "k-means on training embeddings; training-majority cluster labels",
4
+ "seed": 0,
5
+ "clusters": 48,
6
+ "adjusted_rand_index": 0.07325460529021985,
7
+ "validation_candidates": [
8
+ {
9
+ "clusters": 6,
10
+ "validation_macro_f1": 0.4448239498166639
11
+ },
12
+ {
13
+ "clusters": 12,
14
+ "validation_macro_f1": 0.5387143732224868
15
+ },
16
+ {
17
+ "clusters": 24,
18
+ "validation_macro_f1": 0.4966756931300707
19
+ },
20
+ {
21
+ "clusters": 48,
22
+ "validation_macro_f1": 0.5649193348918948
23
+ }
24
+ ],
25
+ "cases": 714,
26
+ "accuracy": 0.5168067226890757,
27
+ "macro_f1": 0.5227685117233037,
28
+ "per_class": {
29
+ "chat": {
30
+ "precision": 0.5595238095238095,
31
+ "recall": 0.39166666666666666,
32
+ "f1": 0.46078431372549017,
33
+ "support": 120
34
+ },
35
+ "question": {
36
+ "precision": 0.45255474452554745,
37
+ "recall": 0.5166666666666667,
38
+ "f1": 0.48249027237354086,
39
+ "support": 120
40
+ },
41
+ "build": {
42
+ "precision": 0.48148148148148145,
43
+ "recall": 0.65,
44
+ "f1": 0.5531914893617021,
45
+ "support": 120
46
+ },
47
+ "task": {
48
+ "precision": 0.4406779661016949,
49
+ "recall": 0.43333333333333335,
50
+ "f1": 0.4369747899159664,
51
+ "support": 120
52
+ },
53
+ "fix": {
54
+ "precision": 0.42857142857142855,
55
+ "recall": 0.475,
56
+ "f1": 0.4505928853754941,
57
+ "support": 120
58
+ },
59
+ "unclear": {
60
+ "precision": 0.9125,
61
+ "recall": 0.6403508771929824,
62
+ "f1": 0.7525773195876289,
63
+ "support": 114
64
+ }
65
+ },
66
+ "confusion": {
67
+ "chat": {
68
+ "chat": 47,
69
+ "question": 14,
70
+ "build": 34,
71
+ "task": 9,
72
+ "fix": 14,
73
+ "unclear": 2,
74
+ "INVALID": 0
75
+ },
76
+ "question": {
77
+ "chat": 10,
78
+ "question": 62,
79
+ "build": 13,
80
+ "task": 11,
81
+ "fix": 24,
82
+ "unclear": 0,
83
+ "INVALID": 0
84
+ },
85
+ "build": {
86
+ "chat": 12,
87
+ "question": 11,
88
+ "build": 78,
89
+ "task": 10,
90
+ "fix": 9,
91
+ "unclear": 0,
92
+ "INVALID": 0
93
+ },
94
+ "task": {
95
+ "chat": 6,
96
+ "question": 23,
97
+ "build": 16,
98
+ "task": 52,
99
+ "fix": 19,
100
+ "unclear": 4,
101
+ "INVALID": 0
102
+ },
103
+ "fix": {
104
+ "chat": 5,
105
+ "question": 24,
106
+ "build": 13,
107
+ "task": 20,
108
+ "fix": 57,
109
+ "unclear": 1,
110
+ "INVALID": 0
111
+ },
112
+ "unclear": {
113
+ "chat": 4,
114
+ "question": 3,
115
+ "build": 8,
116
+ "task": 16,
117
+ "fix": 10,
118
+ "unclear": 73,
119
+ "INVALID": 0
120
+ }
121
+ },
122
+ "invalid": 0,
123
+ "nll": 1.2672067322258014,
124
+ "brier": 0.5938426790677706,
125
+ "false_actions": 105,
126
+ "passive_cases": 240,
127
+ "false_action_rate": 0.4375,
128
+ "unclear_cases": 114,
129
+ "actions_on_unclear": 34,
130
+ "action_rate_on_unclear": 0.2982456140350877,
131
+ "by_difficulty": {
132
+ "easy": {
133
+ "cases": 235,
134
+ "accuracy": 0.4851063829787234,
135
+ "macro_f1": 0.4885814014063359,
136
+ "per_class": {
137
+ "chat": {
138
+ "precision": 0.631578947368421,
139
+ "recall": 0.3,
140
+ "f1": 0.4067796610169492,
141
+ "support": 40
142
+ },
143
+ "question": {
144
+ "precision": 0.39655172413793105,
145
+ "recall": 0.575,
146
+ "f1": 0.46938775510204084,
147
+ "support": 40
148
+ },
149
+ "build": {
150
+ "precision": 0.42105263157894735,
151
+ "recall": 0.6,
152
+ "f1": 0.4948453608247423,
153
+ "support": 40
154
+ },
155
+ "task": {
156
+ "precision": 0.4642857142857143,
157
+ "recall": 0.325,
158
+ "f1": 0.38235294117647056,
159
+ "support": 40
160
+ },
161
+ "fix": {
162
+ "precision": 0.38095238095238093,
163
+ "recall": 0.4,
164
+ "f1": 0.3902439024390244,
165
+ "support": 40
166
+ },
167
+ "unclear": {
168
+ "precision": 0.8387096774193549,
169
+ "recall": 0.7428571428571429,
170
+ "f1": 0.7878787878787878,
171
+ "support": 35
172
+ }
173
+ },
174
+ "confusion": {
175
+ "chat": {
176
+ "chat": 12,
177
+ "question": 7,
178
+ "build": 14,
179
+ "task": 1,
180
+ "fix": 5,
181
+ "unclear": 1,
182
+ "INVALID": 0
183
+ },
184
+ "question": {
185
+ "chat": 2,
186
+ "question": 23,
187
+ "build": 6,
188
+ "task": 1,
189
+ "fix": 8,
190
+ "unclear": 0,
191
+ "INVALID": 0
192
+ },
193
+ "build": {
194
+ "chat": 2,
195
+ "question": 5,
196
+ "build": 24,
197
+ "task": 6,
198
+ "fix": 3,
199
+ "unclear": 0,
200
+ "INVALID": 0
201
+ },
202
+ "task": {
203
+ "chat": 1,
204
+ "question": 10,
205
+ "build": 7,
206
+ "task": 13,
207
+ "fix": 6,
208
+ "unclear": 3,
209
+ "INVALID": 0
210
+ },
211
+ "fix": {
212
+ "chat": 2,
213
+ "question": 12,
214
+ "build": 5,
215
+ "task": 4,
216
+ "fix": 16,
217
+ "unclear": 1,
218
+ "INVALID": 0
219
+ },
220
+ "unclear": {
221
+ "chat": 0,
222
+ "question": 1,
223
+ "build": 1,
224
+ "task": 3,
225
+ "fix": 4,
226
+ "unclear": 26,
227
+ "INVALID": 0
228
+ }
229
+ },
230
+ "invalid": 0
231
+ },
232
+ "medium": {
233
+ "cases": 239,
234
+ "accuracy": 0.4895397489539749,
235
+ "macro_f1": 0.49673073454605987,
236
+ "per_class": {
237
+ "chat": {
238
+ "precision": 0.42857142857142855,
239
+ "recall": 0.375,
240
+ "f1": 0.4,
241
+ "support": 40
242
+ },
243
+ "question": {
244
+ "precision": 0.41304347826086957,
245
+ "recall": 0.475,
246
+ "f1": 0.4418604651162791,
247
+ "support": 40
248
+ },
249
+ "build": {
250
+ "precision": 0.5897435897435898,
251
+ "recall": 0.575,
252
+ "f1": 0.5822784810126582,
253
+ "support": 40
254
+ },
255
+ "task": {
256
+ "precision": 0.2682926829268293,
257
+ "recall": 0.275,
258
+ "f1": 0.2716049382716049,
259
+ "support": 40
260
+ },
261
+ "fix": {
262
+ "precision": 0.4,
263
+ "recall": 0.45,
264
+ "f1": 0.4235294117647059,
265
+ "support": 40
266
+ },
267
+ "unclear": {
268
+ "precision": 0.9393939393939394,
269
+ "recall": 0.7948717948717948,
270
+ "f1": 0.8611111111111112,
271
+ "support": 39
272
+ }
273
+ },
274
+ "confusion": {
275
+ "chat": {
276
+ "chat": 15,
277
+ "question": 6,
278
+ "build": 7,
279
+ "task": 6,
280
+ "fix": 5,
281
+ "unclear": 1,
282
+ "INVALID": 0
283
+ },
284
+ "question": {
285
+ "chat": 4,
286
+ "question": 19,
287
+ "build": 2,
288
+ "task": 7,
289
+ "fix": 8,
290
+ "unclear": 0,
291
+ "INVALID": 0
292
+ },
293
+ "build": {
294
+ "chat": 8,
295
+ "question": 4,
296
+ "build": 23,
297
+ "task": 1,
298
+ "fix": 4,
299
+ "unclear": 0,
300
+ "INVALID": 0
301
+ },
302
+ "task": {
303
+ "chat": 4,
304
+ "question": 11,
305
+ "build": 3,
306
+ "task": 11,
307
+ "fix": 10,
308
+ "unclear": 1,
309
+ "INVALID": 0
310
+ },
311
+ "fix": {
312
+ "chat": 2,
313
+ "question": 6,
314
+ "build": 4,
315
+ "task": 10,
316
+ "fix": 18,
317
+ "unclear": 0,
318
+ "INVALID": 0
319
+ },
320
+ "unclear": {
321
+ "chat": 2,
322
+ "question": 0,
323
+ "build": 0,
324
+ "task": 6,
325
+ "fix": 0,
326
+ "unclear": 31,
327
+ "INVALID": 0
328
+ }
329
+ },
330
+ "invalid": 0
331
+ },
332
+ "hard": {
333
+ "cases": 240,
334
+ "accuracy": 0.575,
335
+ "macro_f1": 0.5733008687983755,
336
+ "per_class": {
337
+ "chat": {
338
+ "precision": 0.6666666666666666,
339
+ "recall": 0.5,
340
+ "f1": 0.5714285714285714,
341
+ "support": 40
342
+ },
343
+ "question": {
344
+ "precision": 0.6060606060606061,
345
+ "recall": 0.5,
346
+ "f1": 0.547945205479452,
347
+ "support": 40
348
+ },
349
+ "build": {
350
+ "precision": 0.4696969696969697,
351
+ "recall": 0.775,
352
+ "f1": 0.5849056603773585,
353
+ "support": 40
354
+ },
355
+ "task": {
356
+ "precision": 0.5714285714285714,
357
+ "recall": 0.7,
358
+ "f1": 0.6292134831460674,
359
+ "support": 40
360
+ },
361
+ "fix": {
362
+ "precision": 0.5,
363
+ "recall": 0.575,
364
+ "f1": 0.5348837209302325,
365
+ "support": 40
366
+ },
367
+ "unclear": {
368
+ "precision": 1.0,
369
+ "recall": 0.4,
370
+ "f1": 0.5714285714285714,
371
+ "support": 40
372
+ }
373
+ },
374
+ "confusion": {
375
+ "chat": {
376
+ "chat": 20,
377
+ "question": 1,
378
+ "build": 13,
379
+ "task": 2,
380
+ "fix": 4,
381
+ "unclear": 0,
382
+ "INVALID": 0
383
+ },
384
+ "question": {
385
+ "chat": 4,
386
+ "question": 20,
387
+ "build": 5,
388
+ "task": 3,
389
+ "fix": 8,
390
+ "unclear": 0,
391
+ "INVALID": 0
392
+ },
393
+ "build": {
394
+ "chat": 2,
395
+ "question": 2,
396
+ "build": 31,
397
+ "task": 3,
398
+ "fix": 2,
399
+ "unclear": 0,
400
+ "INVALID": 0
401
+ },
402
+ "task": {
403
+ "chat": 1,
404
+ "question": 2,
405
+ "build": 6,
406
+ "task": 28,
407
+ "fix": 3,
408
+ "unclear": 0,
409
+ "INVALID": 0
410
+ },
411
+ "fix": {
412
+ "chat": 1,
413
+ "question": 6,
414
+ "build": 4,
415
+ "task": 6,
416
+ "fix": 23,
417
+ "unclear": 0,
418
+ "INVALID": 0
419
+ },
420
+ "unclear": {
421
+ "chat": 2,
422
+ "question": 2,
423
+ "build": 7,
424
+ "task": 7,
425
+ "fix": 6,
426
+ "unclear": 16,
427
+ "INVALID": 0
428
+ }
429
+ },
430
+ "invalid": 0
431
+ }
432
+ },
433
+ "difficulty_counts": {
434
+ "medium": 239,
435
+ "hard": 240,
436
+ "easy": 235
437
+ },
438
+ "predictions_sha256": "daae1546df7b9abb147ca9b14879d08dba597b76853ed3abdd1ca7571917f32a"
439
+ }
results/baselines/embedding-kmeans-seed-1.json ADDED
@@ -0,0 +1,439 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "model": "minilm-l6-v2",
3
+ "method": "k-means on training embeddings; training-majority cluster labels",
4
+ "seed": 1,
5
+ "clusters": 48,
6
+ "adjusted_rand_index": 0.09704067858483406,
7
+ "validation_candidates": [
8
+ {
9
+ "clusters": 6,
10
+ "validation_macro_f1": 0.44619204513246435
11
+ },
12
+ {
13
+ "clusters": 12,
14
+ "validation_macro_f1": 0.5151510674513514
15
+ },
16
+ {
17
+ "clusters": 24,
18
+ "validation_macro_f1": 0.49806823313168463
19
+ },
20
+ {
21
+ "clusters": 48,
22
+ "validation_macro_f1": 0.5281206697704389
23
+ }
24
+ ],
25
+ "cases": 714,
26
+ "accuracy": 0.5084033613445378,
27
+ "macro_f1": 0.512370530501952,
28
+ "per_class": {
29
+ "chat": {
30
+ "precision": 0.46601941747572817,
31
+ "recall": 0.4,
32
+ "f1": 0.4304932735426009,
33
+ "support": 120
34
+ },
35
+ "question": {
36
+ "precision": 0.44696969696969696,
37
+ "recall": 0.49166666666666664,
38
+ "f1": 0.46825396825396826,
39
+ "support": 120
40
+ },
41
+ "build": {
42
+ "precision": 0.5851851851851851,
43
+ "recall": 0.6583333333333333,
44
+ "f1": 0.6196078431372549,
45
+ "support": 120
46
+ },
47
+ "task": {
48
+ "precision": 0.4017857142857143,
49
+ "recall": 0.375,
50
+ "f1": 0.3879310344827586,
51
+ "support": 120
52
+ },
53
+ "fix": {
54
+ "precision": 0.4217687074829932,
55
+ "recall": 0.5166666666666667,
56
+ "f1": 0.46441947565543074,
57
+ "support": 120
58
+ },
59
+ "unclear": {
60
+ "precision": 0.8235294117647058,
61
+ "recall": 0.6140350877192983,
62
+ "f1": 0.7035175879396985,
63
+ "support": 114
64
+ }
65
+ },
66
+ "confusion": {
67
+ "chat": {
68
+ "chat": 48,
69
+ "question": 16,
70
+ "build": 25,
71
+ "task": 8,
72
+ "fix": 20,
73
+ "unclear": 3,
74
+ "INVALID": 0
75
+ },
76
+ "question": {
77
+ "chat": 15,
78
+ "question": 59,
79
+ "build": 7,
80
+ "task": 18,
81
+ "fix": 20,
82
+ "unclear": 1,
83
+ "INVALID": 0
84
+ },
85
+ "build": {
86
+ "chat": 13,
87
+ "question": 12,
88
+ "build": 79,
89
+ "task": 7,
90
+ "fix": 9,
91
+ "unclear": 0,
92
+ "INVALID": 0
93
+ },
94
+ "task": {
95
+ "chat": 8,
96
+ "question": 23,
97
+ "build": 13,
98
+ "task": 45,
99
+ "fix": 28,
100
+ "unclear": 3,
101
+ "INVALID": 0
102
+ },
103
+ "fix": {
104
+ "chat": 13,
105
+ "question": 18,
106
+ "build": 6,
107
+ "task": 13,
108
+ "fix": 62,
109
+ "unclear": 8,
110
+ "INVALID": 0
111
+ },
112
+ "unclear": {
113
+ "chat": 6,
114
+ "question": 4,
115
+ "build": 5,
116
+ "task": 21,
117
+ "fix": 8,
118
+ "unclear": 70,
119
+ "INVALID": 0
120
+ }
121
+ },
122
+ "invalid": 0,
123
+ "nll": 1.2304312893348386,
124
+ "brier": 0.5813902944293567,
125
+ "false_actions": 98,
126
+ "passive_cases": 240,
127
+ "false_action_rate": 0.4083333333333333,
128
+ "unclear_cases": 114,
129
+ "actions_on_unclear": 34,
130
+ "action_rate_on_unclear": 0.2982456140350877,
131
+ "by_difficulty": {
132
+ "easy": {
133
+ "cases": 235,
134
+ "accuracy": 0.49361702127659574,
135
+ "macro_f1": 0.49739800245611443,
136
+ "per_class": {
137
+ "chat": {
138
+ "precision": 0.5384615384615384,
139
+ "recall": 0.35,
140
+ "f1": 0.42424242424242425,
141
+ "support": 40
142
+ },
143
+ "question": {
144
+ "precision": 0.3620689655172414,
145
+ "recall": 0.525,
146
+ "f1": 0.42857142857142855,
147
+ "support": 40
148
+ },
149
+ "build": {
150
+ "precision": 0.5333333333333333,
151
+ "recall": 0.6,
152
+ "f1": 0.5647058823529412,
153
+ "support": 40
154
+ },
155
+ "task": {
156
+ "precision": 0.4166666666666667,
157
+ "recall": 0.25,
158
+ "f1": 0.3125,
159
+ "support": 40
160
+ },
161
+ "fix": {
162
+ "precision": 0.41509433962264153,
163
+ "recall": 0.55,
164
+ "f1": 0.4731182795698925,
165
+ "support": 40
166
+ },
167
+ "unclear": {
168
+ "precision": 0.8620689655172413,
169
+ "recall": 0.7142857142857143,
170
+ "f1": 0.78125,
171
+ "support": 35
172
+ }
173
+ },
174
+ "confusion": {
175
+ "chat": {
176
+ "chat": 14,
177
+ "question": 8,
178
+ "build": 9,
179
+ "task": 3,
180
+ "fix": 6,
181
+ "unclear": 0,
182
+ "INVALID": 0
183
+ },
184
+ "question": {
185
+ "chat": 4,
186
+ "question": 21,
187
+ "build": 3,
188
+ "task": 4,
189
+ "fix": 7,
190
+ "unclear": 1,
191
+ "INVALID": 0
192
+ },
193
+ "build": {
194
+ "chat": 4,
195
+ "question": 5,
196
+ "build": 24,
197
+ "task": 3,
198
+ "fix": 4,
199
+ "unclear": 0,
200
+ "INVALID": 0
201
+ },
202
+ "task": {
203
+ "chat": 1,
204
+ "question": 12,
205
+ "build": 4,
206
+ "task": 10,
207
+ "fix": 12,
208
+ "unclear": 1,
209
+ "INVALID": 0
210
+ },
211
+ "fix": {
212
+ "chat": 3,
213
+ "question": 9,
214
+ "build": 3,
215
+ "task": 1,
216
+ "fix": 22,
217
+ "unclear": 2,
218
+ "INVALID": 0
219
+ },
220
+ "unclear": {
221
+ "chat": 0,
222
+ "question": 3,
223
+ "build": 2,
224
+ "task": 3,
225
+ "fix": 2,
226
+ "unclear": 25,
227
+ "INVALID": 0
228
+ }
229
+ },
230
+ "invalid": 0
231
+ },
232
+ "medium": {
233
+ "cases": 239,
234
+ "accuracy": 0.48535564853556484,
235
+ "macro_f1": 0.48565144203591504,
236
+ "per_class": {
237
+ "chat": {
238
+ "precision": 0.325,
239
+ "recall": 0.325,
240
+ "f1": 0.325,
241
+ "support": 40
242
+ },
243
+ "question": {
244
+ "precision": 0.4186046511627907,
245
+ "recall": 0.45,
246
+ "f1": 0.43373493975903615,
247
+ "support": 40
248
+ },
249
+ "build": {
250
+ "precision": 0.6388888888888888,
251
+ "recall": 0.575,
252
+ "f1": 0.6052631578947368,
253
+ "support": 40
254
+ },
255
+ "task": {
256
+ "precision": 0.2857142857142857,
257
+ "recall": 0.25,
258
+ "f1": 0.26666666666666666,
259
+ "support": 40
260
+ },
261
+ "fix": {
262
+ "precision": 0.45652173913043476,
263
+ "recall": 0.525,
264
+ "f1": 0.4883720930232558,
265
+ "support": 40
266
+ },
267
+ "unclear": {
268
+ "precision": 0.7948717948717948,
269
+ "recall": 0.7948717948717948,
270
+ "f1": 0.7948717948717948,
271
+ "support": 39
272
+ }
273
+ },
274
+ "confusion": {
275
+ "chat": {
276
+ "chat": 13,
277
+ "question": 7,
278
+ "build": 6,
279
+ "task": 5,
280
+ "fix": 6,
281
+ "unclear": 3,
282
+ "INVALID": 0
283
+ },
284
+ "question": {
285
+ "chat": 6,
286
+ "question": 18,
287
+ "build": 2,
288
+ "task": 8,
289
+ "fix": 6,
290
+ "unclear": 0,
291
+ "INVALID": 0
292
+ },
293
+ "build": {
294
+ "chat": 7,
295
+ "question": 5,
296
+ "build": 23,
297
+ "task": 3,
298
+ "fix": 2,
299
+ "unclear": 0,
300
+ "INVALID": 0
301
+ },
302
+ "task": {
303
+ "chat": 6,
304
+ "question": 9,
305
+ "build": 2,
306
+ "task": 10,
307
+ "fix": 11,
308
+ "unclear": 2,
309
+ "INVALID": 0
310
+ },
311
+ "fix": {
312
+ "chat": 6,
313
+ "question": 4,
314
+ "build": 2,
315
+ "task": 4,
316
+ "fix": 21,
317
+ "unclear": 3,
318
+ "INVALID": 0
319
+ },
320
+ "unclear": {
321
+ "chat": 2,
322
+ "question": 0,
323
+ "build": 1,
324
+ "task": 5,
325
+ "fix": 0,
326
+ "unclear": 31,
327
+ "INVALID": 0
328
+ }
329
+ },
330
+ "invalid": 0
331
+ },
332
+ "hard": {
333
+ "cases": 240,
334
+ "accuracy": 0.5458333333333333,
335
+ "macro_f1": 0.5417277585950407,
336
+ "per_class": {
337
+ "chat": {
338
+ "precision": 0.5675675675675675,
339
+ "recall": 0.525,
340
+ "f1": 0.5454545454545454,
341
+ "support": 40
342
+ },
343
+ "question": {
344
+ "precision": 0.6451612903225806,
345
+ "recall": 0.5,
346
+ "f1": 0.5633802816901409,
347
+ "support": 40
348
+ },
349
+ "build": {
350
+ "precision": 0.5925925925925926,
351
+ "recall": 0.8,
352
+ "f1": 0.6808510638297872,
353
+ "support": 40
354
+ },
355
+ "task": {
356
+ "precision": 0.4716981132075472,
357
+ "recall": 0.625,
358
+ "f1": 0.5376344086021505,
359
+ "support": 40
360
+ },
361
+ "fix": {
362
+ "precision": 0.3958333333333333,
363
+ "recall": 0.475,
364
+ "f1": 0.4318181818181818,
365
+ "support": 40
366
+ },
367
+ "unclear": {
368
+ "precision": 0.8235294117647058,
369
+ "recall": 0.35,
370
+ "f1": 0.49122807017543857,
371
+ "support": 40
372
+ }
373
+ },
374
+ "confusion": {
375
+ "chat": {
376
+ "chat": 21,
377
+ "question": 1,
378
+ "build": 10,
379
+ "task": 0,
380
+ "fix": 8,
381
+ "unclear": 0,
382
+ "INVALID": 0
383
+ },
384
+ "question": {
385
+ "chat": 5,
386
+ "question": 20,
387
+ "build": 2,
388
+ "task": 6,
389
+ "fix": 7,
390
+ "unclear": 0,
391
+ "INVALID": 0
392
+ },
393
+ "build": {
394
+ "chat": 2,
395
+ "question": 2,
396
+ "build": 32,
397
+ "task": 1,
398
+ "fix": 3,
399
+ "unclear": 0,
400
+ "INVALID": 0
401
+ },
402
+ "task": {
403
+ "chat": 1,
404
+ "question": 2,
405
+ "build": 7,
406
+ "task": 25,
407
+ "fix": 5,
408
+ "unclear": 0,
409
+ "INVALID": 0
410
+ },
411
+ "fix": {
412
+ "chat": 4,
413
+ "question": 5,
414
+ "build": 1,
415
+ "task": 8,
416
+ "fix": 19,
417
+ "unclear": 3,
418
+ "INVALID": 0
419
+ },
420
+ "unclear": {
421
+ "chat": 4,
422
+ "question": 1,
423
+ "build": 2,
424
+ "task": 13,
425
+ "fix": 6,
426
+ "unclear": 14,
427
+ "INVALID": 0
428
+ }
429
+ },
430
+ "invalid": 0
431
+ }
432
+ },
433
+ "difficulty_counts": {
434
+ "medium": 239,
435
+ "hard": 240,
436
+ "easy": 235
437
+ },
438
+ "predictions_sha256": "1ba3d3f923ef3ca3d7c9457518467c77480715331c0bf09efe97ff9beba42463"
439
+ }
results/baselines/embedding-kmeans-seed-2.json ADDED
@@ -0,0 +1,439 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "model": "minilm-l6-v2",
3
+ "method": "k-means on training embeddings; training-majority cluster labels",
4
+ "seed": 2,
5
+ "clusters": 48,
6
+ "adjusted_rand_index": 0.08624731089370681,
7
+ "validation_candidates": [
8
+ {
9
+ "clusters": 6,
10
+ "validation_macro_f1": 0.44224637568678826
11
+ },
12
+ {
13
+ "clusters": 12,
14
+ "validation_macro_f1": 0.47702334836973365
15
+ },
16
+ {
17
+ "clusters": 24,
18
+ "validation_macro_f1": 0.5096566658977267
19
+ },
20
+ {
21
+ "clusters": 48,
22
+ "validation_macro_f1": 0.534471064892484
23
+ }
24
+ ],
25
+ "cases": 714,
26
+ "accuracy": 0.5098039215686274,
27
+ "macro_f1": 0.5078508804654348,
28
+ "per_class": {
29
+ "chat": {
30
+ "precision": 0.45794392523364486,
31
+ "recall": 0.4083333333333333,
32
+ "f1": 0.43171806167400884,
33
+ "support": 120
34
+ },
35
+ "question": {
36
+ "precision": 0.4460431654676259,
37
+ "recall": 0.5166666666666667,
38
+ "f1": 0.47876447876447875,
39
+ "support": 120
40
+ },
41
+ "build": {
42
+ "precision": 0.5572519083969466,
43
+ "recall": 0.6083333333333333,
44
+ "f1": 0.5816733067729084,
45
+ "support": 120
46
+ },
47
+ "task": {
48
+ "precision": 0.43373493975903615,
49
+ "recall": 0.3,
50
+ "f1": 0.35467980295566504,
51
+ "support": 120
52
+ },
53
+ "fix": {
54
+ "precision": 0.39855072463768115,
55
+ "recall": 0.4583333333333333,
56
+ "f1": 0.4263565891472868,
57
+ "support": 120
58
+ },
59
+ "unclear": {
60
+ "precision": 0.7672413793103449,
61
+ "recall": 0.7807017543859649,
62
+ "f1": 0.7739130434782608,
63
+ "support": 114
64
+ }
65
+ },
66
+ "confusion": {
67
+ "chat": {
68
+ "chat": 49,
69
+ "question": 21,
70
+ "build": 27,
71
+ "task": 6,
72
+ "fix": 15,
73
+ "unclear": 2,
74
+ "INVALID": 0
75
+ },
76
+ "question": {
77
+ "chat": 17,
78
+ "question": 62,
79
+ "build": 7,
80
+ "task": 11,
81
+ "fix": 19,
82
+ "unclear": 4,
83
+ "INVALID": 0
84
+ },
85
+ "build": {
86
+ "chat": 14,
87
+ "question": 15,
88
+ "build": 73,
89
+ "task": 11,
90
+ "fix": 7,
91
+ "unclear": 0,
92
+ "INVALID": 0
93
+ },
94
+ "task": {
95
+ "chat": 9,
96
+ "question": 18,
97
+ "build": 14,
98
+ "task": 36,
99
+ "fix": 34,
100
+ "unclear": 9,
101
+ "INVALID": 0
102
+ },
103
+ "fix": {
104
+ "chat": 16,
105
+ "question": 20,
106
+ "build": 6,
107
+ "task": 11,
108
+ "fix": 55,
109
+ "unclear": 12,
110
+ "INVALID": 0
111
+ },
112
+ "unclear": {
113
+ "chat": 2,
114
+ "question": 3,
115
+ "build": 4,
116
+ "task": 8,
117
+ "fix": 8,
118
+ "unclear": 89,
119
+ "INVALID": 0
120
+ }
121
+ },
122
+ "invalid": 0,
123
+ "nll": 1.229046056763782,
124
+ "brier": 0.5827884372993704,
125
+ "false_actions": 85,
126
+ "passive_cases": 240,
127
+ "false_action_rate": 0.3541666666666667,
128
+ "unclear_cases": 114,
129
+ "actions_on_unclear": 20,
130
+ "action_rate_on_unclear": 0.17543859649122806,
131
+ "by_difficulty": {
132
+ "easy": {
133
+ "cases": 235,
134
+ "accuracy": 0.5148936170212766,
135
+ "macro_f1": 0.5112951342836657,
136
+ "per_class": {
137
+ "chat": {
138
+ "precision": 0.5277777777777778,
139
+ "recall": 0.475,
140
+ "f1": 0.5,
141
+ "support": 40
142
+ },
143
+ "question": {
144
+ "precision": 0.4583333333333333,
145
+ "recall": 0.55,
146
+ "f1": 0.5,
147
+ "support": 40
148
+ },
149
+ "build": {
150
+ "precision": 0.5116279069767442,
151
+ "recall": 0.55,
152
+ "f1": 0.5301204819277109,
153
+ "support": 40
154
+ },
155
+ "task": {
156
+ "precision": 0.3,
157
+ "recall": 0.15,
158
+ "f1": 0.2,
159
+ "support": 40
160
+ },
161
+ "fix": {
162
+ "precision": 0.4074074074074074,
163
+ "recall": 0.55,
164
+ "f1": 0.46808510638297873,
165
+ "support": 40
166
+ },
167
+ "unclear": {
168
+ "precision": 0.8823529411764706,
169
+ "recall": 0.8571428571428571,
170
+ "f1": 0.8695652173913043,
171
+ "support": 35
172
+ }
173
+ },
174
+ "confusion": {
175
+ "chat": {
176
+ "chat": 19,
177
+ "question": 6,
178
+ "build": 10,
179
+ "task": 0,
180
+ "fix": 4,
181
+ "unclear": 1,
182
+ "INVALID": 0
183
+ },
184
+ "question": {
185
+ "chat": 5,
186
+ "question": 22,
187
+ "build": 3,
188
+ "task": 3,
189
+ "fix": 7,
190
+ "unclear": 0,
191
+ "INVALID": 0
192
+ },
193
+ "build": {
194
+ "chat": 3,
195
+ "question": 5,
196
+ "build": 22,
197
+ "task": 7,
198
+ "fix": 3,
199
+ "unclear": 0,
200
+ "INVALID": 0
201
+ },
202
+ "task": {
203
+ "chat": 3,
204
+ "question": 8,
205
+ "build": 4,
206
+ "task": 6,
207
+ "fix": 16,
208
+ "unclear": 3,
209
+ "INVALID": 0
210
+ },
211
+ "fix": {
212
+ "chat": 6,
213
+ "question": 7,
214
+ "build": 3,
215
+ "task": 2,
216
+ "fix": 22,
217
+ "unclear": 0,
218
+ "INVALID": 0
219
+ },
220
+ "unclear": {
221
+ "chat": 0,
222
+ "question": 0,
223
+ "build": 1,
224
+ "task": 2,
225
+ "fix": 2,
226
+ "unclear": 30,
227
+ "INVALID": 0
228
+ }
229
+ },
230
+ "invalid": 0
231
+ },
232
+ "medium": {
233
+ "cases": 239,
234
+ "accuracy": 0.49372384937238495,
235
+ "macro_f1": 0.48830145932976254,
236
+ "per_class": {
237
+ "chat": {
238
+ "precision": 0.35294117647058826,
239
+ "recall": 0.3,
240
+ "f1": 0.32432432432432434,
241
+ "support": 40
242
+ },
243
+ "question": {
244
+ "precision": 0.40816326530612246,
245
+ "recall": 0.5,
246
+ "f1": 0.449438202247191,
247
+ "support": 40
248
+ },
249
+ "build": {
250
+ "precision": 0.6486486486486487,
251
+ "recall": 0.6,
252
+ "f1": 0.6233766233766234,
253
+ "support": 40
254
+ },
255
+ "task": {
256
+ "precision": 0.23333333333333334,
257
+ "recall": 0.175,
258
+ "f1": 0.2,
259
+ "support": 40
260
+ },
261
+ "fix": {
262
+ "precision": 0.42857142857142855,
263
+ "recall": 0.525,
264
+ "f1": 0.47191011235955055,
265
+ "support": 40
266
+ },
267
+ "unclear": {
268
+ "precision": 0.85,
269
+ "recall": 0.8717948717948718,
270
+ "f1": 0.8607594936708861,
271
+ "support": 39
272
+ }
273
+ },
274
+ "confusion": {
275
+ "chat": {
276
+ "chat": 12,
277
+ "question": 11,
278
+ "build": 5,
279
+ "task": 6,
280
+ "fix": 5,
281
+ "unclear": 1,
282
+ "INVALID": 0
283
+ },
284
+ "question": {
285
+ "chat": 5,
286
+ "question": 20,
287
+ "build": 2,
288
+ "task": 7,
289
+ "fix": 5,
290
+ "unclear": 1,
291
+ "INVALID": 0
292
+ },
293
+ "build": {
294
+ "chat": 6,
295
+ "question": 6,
296
+ "build": 24,
297
+ "task": 2,
298
+ "fix": 2,
299
+ "unclear": 0,
300
+ "INVALID": 0
301
+ },
302
+ "task": {
303
+ "chat": 6,
304
+ "question": 5,
305
+ "build": 3,
306
+ "task": 7,
307
+ "fix": 16,
308
+ "unclear": 3,
309
+ "INVALID": 0
310
+ },
311
+ "fix": {
312
+ "chat": 5,
313
+ "question": 6,
314
+ "build": 3,
315
+ "task": 4,
316
+ "fix": 21,
317
+ "unclear": 1,
318
+ "INVALID": 0
319
+ },
320
+ "unclear": {
321
+ "chat": 0,
322
+ "question": 1,
323
+ "build": 0,
324
+ "task": 4,
325
+ "fix": 0,
326
+ "unclear": 34,
327
+ "INVALID": 0
328
+ }
329
+ },
330
+ "invalid": 0
331
+ },
332
+ "hard": {
333
+ "cases": 240,
334
+ "accuracy": 0.5208333333333334,
335
+ "macro_f1": 0.5181061704750312,
336
+ "per_class": {
337
+ "chat": {
338
+ "precision": 0.4864864864864865,
339
+ "recall": 0.45,
340
+ "f1": 0.4675324675324675,
341
+ "support": 40
342
+ },
343
+ "question": {
344
+ "precision": 0.47619047619047616,
345
+ "recall": 0.5,
346
+ "f1": 0.4878048780487805,
347
+ "support": 40
348
+ },
349
+ "build": {
350
+ "precision": 0.5294117647058824,
351
+ "recall": 0.675,
352
+ "f1": 0.5934065934065934,
353
+ "support": 40
354
+ },
355
+ "task": {
356
+ "precision": 0.696969696969697,
357
+ "recall": 0.575,
358
+ "f1": 0.6301369863013698,
359
+ "support": 40
360
+ },
361
+ "fix": {
362
+ "precision": 0.34285714285714286,
363
+ "recall": 0.3,
364
+ "f1": 0.32,
365
+ "support": 40
366
+ },
367
+ "unclear": {
368
+ "precision": 0.5952380952380952,
369
+ "recall": 0.625,
370
+ "f1": 0.6097560975609756,
371
+ "support": 40
372
+ }
373
+ },
374
+ "confusion": {
375
+ "chat": {
376
+ "chat": 18,
377
+ "question": 4,
378
+ "build": 12,
379
+ "task": 0,
380
+ "fix": 6,
381
+ "unclear": 0,
382
+ "INVALID": 0
383
+ },
384
+ "question": {
385
+ "chat": 7,
386
+ "question": 20,
387
+ "build": 2,
388
+ "task": 1,
389
+ "fix": 7,
390
+ "unclear": 3,
391
+ "INVALID": 0
392
+ },
393
+ "build": {
394
+ "chat": 5,
395
+ "question": 4,
396
+ "build": 27,
397
+ "task": 2,
398
+ "fix": 2,
399
+ "unclear": 0,
400
+ "INVALID": 0
401
+ },
402
+ "task": {
403
+ "chat": 0,
404
+ "question": 5,
405
+ "build": 7,
406
+ "task": 23,
407
+ "fix": 2,
408
+ "unclear": 3,
409
+ "INVALID": 0
410
+ },
411
+ "fix": {
412
+ "chat": 5,
413
+ "question": 7,
414
+ "build": 0,
415
+ "task": 5,
416
+ "fix": 12,
417
+ "unclear": 11,
418
+ "INVALID": 0
419
+ },
420
+ "unclear": {
421
+ "chat": 2,
422
+ "question": 2,
423
+ "build": 3,
424
+ "task": 2,
425
+ "fix": 6,
426
+ "unclear": 25,
427
+ "INVALID": 0
428
+ }
429
+ },
430
+ "invalid": 0
431
+ }
432
+ },
433
+ "difficulty_counts": {
434
+ "medium": 239,
435
+ "hard": 240,
436
+ "easy": 235
437
+ },
438
+ "predictions_sha256": "6d6fce21c582abab8bf4fa4df51cdadc84ed2eca9c12fde94feb8ac25226e713"
439
+ }