j2ampn commited on
Commit
4631c41
·
verified ·
1 Parent(s): 665cb4b

Publish verified v8 diagnostic distractor adapter

Browse files

Verified recovery artifact with pinned Qwen3-8B base revision, truthful model card, and aggregate frozen benchmark summary. No raw Eedi data, predictions, checkpoints, optimizer state, or credentials.

.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ tokenizer.json filter=lfs diff=lfs merge=lfs -text
README.md ADDED
@@ -0,0 +1,268 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ base_model: unsloth/Qwen3-8B-bnb-4bit
3
+ library_name: peft
4
+ pipeline_tag: text-generation
5
+ license: apache-2.0
6
+ language:
7
+ - en
8
+ tags:
9
+ - qwen3
10
+ - peft
11
+ - lora
12
+ - qlora
13
+ - education
14
+ - mathematics
15
+ - middle-school
16
+ - diagnostic-assessment
17
+ ---
18
+
19
+ # Qwen3-8B Diagnostic Distractor LoRA v8
20
+
21
+ This is a PEFT LoRA adapter trained to propose diagnostic wrong answers for
22
+ sixth-grade and middle-school **Number** mathematics questions. Given a trusted
23
+ question, correct answer, and topic, it is trained to return exactly three
24
+ different distractors. Each distractor names a distinct student misconception,
25
+ shows the question-specific arithmetic that misconception would produce, and
26
+ reports the resulting answer.
27
+
28
+ The outputs are hypotheses for assessment authors, not diagnoses of learners.
29
+ Generated content must be parsed and independently checked before it reaches a
30
+ student.
31
+
32
+ ## Model and artifact identity
33
+
34
+ - Base model: [`unsloth/Qwen3-8B-bnb-4bit`](https://huggingface.co/unsloth/Qwen3-8B-bnb-4bit)
35
+ - Immutable base revision: `1deaf68f694c40dbce295da300851729d759b21a`
36
+ - Adapter type: causal-LM LoRA, rank 32, alpha 32, dropout 0
37
+ - Target modules: `q_proj`, `k_proj`, `v_proj`, `o_proj`, `gate_proj`,
38
+ `up_proj`, and `down_proj`
39
+ - PEFT version recorded by the artifact: 0.19.1
40
+ - Recovered ZIP: 325,882,649 bytes; SHA-256
41
+ `e00dcb7653e9baa19fb103bbe0712b419fccb281724b487847de7f03a960c7fb`
42
+ - `adapter_model.safetensors`: 349,243,752 bytes; SHA-256
43
+ `e949ee36800f429ba5dc02b761aa54bf8037af6d406fac9e5a04c7b68cce4a12`
44
+
45
+ The recovered ZIP named the correct base model but stored `revision: null` in
46
+ `adapter_config.json`. For this publication, that metadata field was set to the
47
+ immutable revision in the training receipt. Adapter weights and tokenizer files
48
+ were not changed.
49
+
50
+ ## Output contract
51
+
52
+ The model was supervised to emit only one JSON object with this shape:
53
+
54
+ ```json
55
+ {
56
+ "distractors": [
57
+ {
58
+ "misconception": "<short misconception>",
59
+ "computation": "<arithmetic> = <value>",
60
+ "answer": "<value>"
61
+ },
62
+ {
63
+ "misconception": "...",
64
+ "computation": "...",
65
+ "answer": "..."
66
+ },
67
+ {
68
+ "misconception": "...",
69
+ "computation": "...",
70
+ "answer": "..."
71
+ }
72
+ ]
73
+ }
74
+ ```
75
+
76
+ The intended constraints are:
77
+
78
+ 1. exactly three distractors;
79
+ 2. three distinct, specific misconceptions;
80
+ 3. three distinct wrong answers, none equal to the key; and
81
+ 4. each `computation` evaluates to its paired `answer` for the supplied
82
+ question.
83
+
84
+ These are generation targets, not guarantees. Enforce them in trusted code.
85
+
86
+ ## Usage
87
+
88
+ Qwen3 support requires a current Transformers release. The base is a
89
+ bitsandbytes 4-bit checkpoint, so use a compatible CUDA environment.
90
+
91
+ ```python
92
+ import json
93
+ import torch
94
+ from peft import PeftModel
95
+ from transformers import AutoModelForCausalLM, AutoTokenizer
96
+
97
+ ADAPTER = "j2ampn/qwen3-8b-distractor-lora-v8"
98
+ BASE = "unsloth/Qwen3-8B-bnb-4bit"
99
+ BASE_REVISION = "1deaf68f694c40dbce295da300851729d759b21a"
100
+
101
+ SYSTEM_PROMPT = """You are an expert middle-school mathematics assessment writer. Given a "Number" strand math question and its correct answer, produce exactly three diagnostic distractors (wrong answers) for a multiple-choice version.
102
+
103
+ For each distractor provide, in this order:
104
+ - misconception: the specific student misconception or procedural error.
105
+ - computation: the exact arithmetic a student with THAT misconception performs on THIS question, written as a plain expression that ends in '= <answer>' (e.g. "0.4 ÷ 0.2 = 2"). Use only digits, + - × ÷, parentheses, decimals, and fractions a/b.
106
+ - answer: the value the computation evaluates to. It MUST equal the computation's result.
107
+
108
+ Rules:
109
+ - Exactly 3 distractors, each tagged to a distinct misconception.
110
+ - Each answer is exactly what a student making that misconception would compute (numerically consistent with the misconception and its shown computation).
111
+ - The three answers must all be different, and none may equal the correct answer.
112
+
113
+ Respond with ONLY a JSON object, no prose, in this exact schema:
114
+ {"distractors": [{"misconception": "<short misconception>", "computation": "<arithmetic> = <value>", "answer": "<value>"}, {"misconception": "...", "computation": "...", "answer": "..."}, {"misconception": "...", "computation": "...", "answer": "..."}]}"""
115
+
116
+ tokenizer = AutoTokenizer.from_pretrained(ADAPTER)
117
+ base = AutoModelForCausalLM.from_pretrained(
118
+ BASE,
119
+ revision=BASE_REVISION,
120
+ torch_dtype="auto",
121
+ device_map="auto",
122
+ )
123
+ model = PeftModel.from_pretrained(base, ADAPTER)
124
+ model.eval()
125
+
126
+ messages = [
127
+ {"role": "system", "content": SYSTEM_PROMPT},
128
+ {
129
+ "role": "user",
130
+ "content": (
131
+ "Question: What is 3/4 of 20?\n"
132
+ "Correct answer: 15\n"
133
+ "Topic: Fractions"
134
+ ),
135
+ },
136
+ ]
137
+ input_ids = tokenizer.apply_chat_template(
138
+ messages,
139
+ tokenize=True,
140
+ add_generation_prompt=True,
141
+ enable_thinking=False,
142
+ return_tensors="pt",
143
+ ).to(model.device)
144
+
145
+ with torch.inference_mode():
146
+ output_ids = model.generate(
147
+ input_ids=input_ids,
148
+ max_new_tokens=512,
149
+ do_sample=False,
150
+ )
151
+
152
+ text = tokenizer.decode(
153
+ output_ids[0, input_ids.shape[1]:],
154
+ skip_special_tokens=True,
155
+ )
156
+ payload = json.loads(text)
157
+ print(payload)
158
+ ```
159
+
160
+ The registered **model-only** track uses greedy generation as shown above. The
161
+ separate best-of-N result below does not come from this single call.
162
+
163
+ ## Training
164
+
165
+ “One-shot” means one planned training invocation, not one training example. The
166
+ run used QLoRA SFT against the pinned 4-bit base for three planned epochs with:
167
+
168
+ - 3,572 verified training rows and a deterministic prompt-grouped train/validation
169
+ split;
170
+ - response-only loss, maximum sequence length 2,048;
171
+ - batch size 1, gradient accumulation 8;
172
+ - learning rate `1.5e-4`, cosine schedule, 5% warmup;
173
+ - 8-bit AdamW, weight decay 0.01, seed 42; and
174
+ - automatic restoration of the checkpoint with lowest validation loss.
175
+
176
+ The selected checkpoint was `outputs_v8/checkpoint-403`, with validation loss
177
+ `0.051324423402547836`. The frozen 140-item benchmark was not used for training,
178
+ validation, checkpoint selection, or tuning.
179
+
180
+ Training combined programmatically generated misconception procedures with
181
+ filtered real-question targets. No raw training dataset is included in this
182
+ model repository.
183
+
184
+ ## Evaluation
185
+
186
+ The following are the final deterministic hard-gate results from
187
+ [`TABLE_V8_RESULTS.md`](https://github.com/jsonjj/diagnostic-distractor-slm/blob/5aa7146b0fa7fc71efbd10feac4e57c2839e05a4/TABLE_V8_RESULTS.md).
188
+ Brackets are 95% intervals.
189
+
190
+ | Metric | Opus generator baseline | v8 model-only | v8 verifier-guided best-of-4 |
191
+ |---|---:|---:|---:|
192
+ | Valid exactly-3 output | 97.1% (136/140) [92.9, 98.9] | 100.0% (140/140) [97.3, 100.0] | 100.0% (140/140) [97.3, 100.0] |
193
+ | No answer equals key | 94.3% (132/140) [89.1, 97.1] | 94.3% (132/140) [89.1, 97.1] | 96.4% (135/140) [91.9, 98.5] |
194
+ | Three distinct answers | 85.0% (119/140) [78.2, 90.0] | 80.7% (113/140) [73.4, 86.4] | 96.4% (135/140) [91.9, 98.5] |
195
+ | Three distinct misconceptions | 97.1% (136/140) [92.9, 98.9] | 100.0% (140/140) [97.3, 100.0] | 100.0% (140/140) [97.3, 100.0] |
196
+ | Hardened computation validity | 40.3% (170/422) [34.2, 47.4] | 79.3% (333/420) [73.3, 84.5] | 84.8% (356/420) [79.0, 89.3] |
197
+
198
+ **Model-only** is deterministic greedy output from the adapter. **Best-of-4** is
199
+ a system track: it adds three seeded sampled candidates to the greedy candidate,
200
+ then uses trusted local code to select by structure, key safety, distinctness,
201
+ and hardened computation checks. It must not be described as model-only
202
+ performance.
203
+
204
+ Good Distractor Rate (GDR), Good@3, holistic diagnostic-quality/plausibility,
205
+ and the registered overall win rule are **unavailable / not demonstrated**.
206
+ There is no accepted independent judge or completed human review for those
207
+ holistic measures. There are also no observed student option-pick frequencies;
208
+ the evaluation cannot establish that any distractor is frequently selected by
209
+ students.
210
+
211
+ Aggregate machine-readable results are in
212
+ [`benchmark_summary.json`](benchmark_summary.json). No protected benchmark
213
+ questions, raw Eedi records, or prediction rows are distributed here.
214
+
215
+ ## Limitations
216
+
217
+ - The model can emit malformed JSON, a correct answer as a distractor, duplicate
218
+ answers, invalid arithmetic, or a misconception label that does not explain
219
+ its answer.
220
+ - Deterministic arithmetic checks do not establish student plausibility,
221
+ diagnostic usefulness, or misconception-to-answer validity in every case.
222
+ - The benchmark covers English middle-school Number content and should not be
223
+ generalized to other subjects, languages, ages, or high-stakes decisions.
224
+ - A generated misconception is a content-design hypothesis. It must not be used
225
+ as an automated diagnosis of a learner.
226
+ - Results do not measure observed student choice frequency.
227
+ - The best-of-4 figures require the repository verifier and additional
228
+ generation; loading this adapter alone reproduces only the model-only track.
229
+
230
+ ## Safety, privacy, and local game use
231
+
232
+ The intended Wayline game path runs inference locally. Trusted code supplies
233
+ only the question, correct answer, topic, and fixed prompt. It does not send a
234
+ learner's name, profile/session ID, answer selection, confidence, or progress to
235
+ the model. No Hugging Face or provider credential is embedded in these files or
236
+ required after local download.
237
+
238
+ Treat raw model text as untrusted. Parse exact JSON, reject key collisions and
239
+ duplicates, evaluate arithmetic, apply curriculum constraints, and use human
240
+ review for released content. The model should not directly grade students,
241
+ change progression, or present unverified material to children.
242
+
243
+ For a local `llama.cpp` game runtime, the base and adapter must first be merged
244
+ and exported to a separately validated GGUF. This repository does not claim that
245
+ the adapter by itself is a production-ready game package.
246
+
247
+ ## License and data terms
248
+
249
+ The adapter is released under Apache-2.0, matching the pinned base model's
250
+ declared license and the owner's prior adapter release. The source repository
251
+ describes raw Eedi Kaggle inputs under separate CC BY-NC 4.0 terms. No raw Eedi
252
+ data is included here, and the model license does not replace any source-data
253
+ terms that apply when reproducing the training pipeline.
254
+
255
+ ## Source and frozen evidence
256
+
257
+ - Source repository:
258
+ <https://github.com/jsonjj/diagnostic-distractor-slm>
259
+ - Frozen source revision:
260
+ [`5aa7146b0fa7fc71efbd10feac4e57c2839e05a4`](https://github.com/jsonjj/diagnostic-distractor-slm/tree/5aa7146b0fa7fc71efbd10feac4e57c2839e05a4)
261
+ - Final results:
262
+ [`TABLE_V8_RESULTS.md`](https://github.com/jsonjj/diagnostic-distractor-slm/blob/5aa7146b0fa7fc71efbd10feac4e57c2839e05a4/TABLE_V8_RESULTS.md)
263
+ - Artifact validation:
264
+ [`v8_artifact_validation.json`](https://github.com/jsonjj/diagnostic-distractor-slm/blob/5aa7146b0fa7fc71efbd10feac4e57c2839e05a4/data/eval_out/v8_artifact_validation.json)
265
+ - Final benchmark record:
266
+ [`benchmark_v8_final.json`](https://github.com/jsonjj/diagnostic-distractor-slm/blob/5aa7146b0fa7fc71efbd10feac4e57c2839e05a4/data/eval_out/benchmark_v8_final.json)
267
+ - Training receipt:
268
+ [`v8_training_receipt.json`](https://github.com/jsonjj/diagnostic-distractor-slm/blob/5aa7146b0fa7fc71efbd10feac4e57c2839e05a4/v8_training_receipt.json)
adapter_config.json ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "alora_invocation_tokens": null,
3
+ "alpha_pattern": {},
4
+ "arrow_config": null,
5
+ "auto_mapping": {
6
+ "base_model_class": "Qwen3ForCausalLM",
7
+ "parent_library": "transformers.models.qwen3.modeling_qwen3",
8
+ "unsloth_fixed": true
9
+ },
10
+ "base_model_name_or_path": "unsloth/Qwen3-8B-bnb-4bit",
11
+ "bias": "none",
12
+ "corda_config": null,
13
+ "ensure_weight_tying": false,
14
+ "eva_config": null,
15
+ "exclude_modules": null,
16
+ "fan_in_fan_out": false,
17
+ "inference_mode": true,
18
+ "init_lora_weights": true,
19
+ "layer_replication": null,
20
+ "layers_pattern": null,
21
+ "layers_to_transform": null,
22
+ "loftq_config": {},
23
+ "lora_alpha": 32,
24
+ "lora_bias": false,
25
+ "lora_dropout": 0.0,
26
+ "lora_ga_config": null,
27
+ "megatron_config": null,
28
+ "megatron_core": "megatron.core",
29
+ "modules_to_save": null,
30
+ "peft_type": "LORA",
31
+ "peft_version": "0.19.1",
32
+ "qalora_group_size": 16,
33
+ "r": 32,
34
+ "rank_pattern": {},
35
+ "revision": "1deaf68f694c40dbce295da300851729d759b21a",
36
+ "target_modules": [
37
+ "q_proj",
38
+ "gate_proj",
39
+ "v_proj",
40
+ "o_proj",
41
+ "up_proj",
42
+ "down_proj",
43
+ "k_proj"
44
+ ],
45
+ "target_parameters": null,
46
+ "task_type": "CAUSAL_LM",
47
+ "trainable_token_indices": null,
48
+ "use_bdlora": null,
49
+ "use_dora": false,
50
+ "use_qalora": false,
51
+ "use_rslora": false
52
+ }
adapter_model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e949ee36800f429ba5dc02b761aa54bf8037af6d406fac9e5a04c7b68cce4a12
3
+ size 349243752
benchmark_summary.json ADDED
@@ -0,0 +1,219 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "adapter_artifact": {
3
+ "adapter_model": {
4
+ "bytes": 349243752,
5
+ "sha256": "e949ee36800f429ba5dc02b761aa54bf8037af6d406fac9e5a04c7b68cce4a12",
6
+ "tensor_count": 504
7
+ },
8
+ "published_adapter_config_sha256": "a1036d4a3bf1ded9718ad7a3c555ab989243bf8ce0aec8949d5ca2a79e2b06be",
9
+ "published_metadata_change": "Set adapter_config.json revision from null to the immutable base revision in the training receipt; weights and tokenizer artifacts are unchanged.",
10
+ "source_zip": {
11
+ "bytes": 325882649,
12
+ "crc_test_passed": true,
13
+ "duplicates_present": false,
14
+ "sha256": "e00dcb7653e9baa19fb103bbe0712b419fccb281724b487847de7f03a960c7fb",
15
+ "symlinks_present": false,
16
+ "unsafe_paths_present": false
17
+ }
18
+ },
19
+ "base_model": {
20
+ "repo_id": "unsloth/Qwen3-8B-bnb-4bit",
21
+ "revision": "1deaf68f694c40dbce295da300851729d759b21a"
22
+ },
23
+ "benchmark": {
24
+ "frozen_items": 140,
25
+ "frozen_sha256": "546c14f03707ce098146dac5e0c6e99c0a4619d6d4e32193a9fff4e3b9bfd1b1",
26
+ "measured_metrics": {
27
+ "opus_generator_baseline": {
28
+ "hardened_computation_validity": {
29
+ "ci95_percent": [
30
+ 34.2,
31
+ 47.4
32
+ ],
33
+ "denominator": 422,
34
+ "numerator": 170,
35
+ "score_percent": 40.3
36
+ },
37
+ "no_answer_equals_key": {
38
+ "ci95_percent": [
39
+ 89.1,
40
+ 97.1
41
+ ],
42
+ "denominator": 140,
43
+ "numerator": 132,
44
+ "score_percent": 94.3
45
+ },
46
+ "three_distinct_answers": {
47
+ "ci95_percent": [
48
+ 78.2,
49
+ 90.0
50
+ ],
51
+ "denominator": 140,
52
+ "numerator": 119,
53
+ "score_percent": 85.0
54
+ },
55
+ "three_distinct_misconceptions": {
56
+ "ci95_percent": [
57
+ 92.9,
58
+ 98.9
59
+ ],
60
+ "denominator": 140,
61
+ "numerator": 136,
62
+ "score_percent": 97.1
63
+ },
64
+ "valid_exactly_three": {
65
+ "ci95_percent": [
66
+ 92.9,
67
+ 98.9
68
+ ],
69
+ "denominator": 140,
70
+ "numerator": 136,
71
+ "score_percent": 97.1
72
+ }
73
+ },
74
+ "v8_model_only": {
75
+ "generation": "deterministic greedy",
76
+ "hardened_computation_validity": {
77
+ "ci95_percent": [
78
+ 73.3,
79
+ 84.5
80
+ ],
81
+ "denominator": 420,
82
+ "numerator": 333,
83
+ "score_percent": 79.3
84
+ },
85
+ "no_answer_equals_key": {
86
+ "ci95_percent": [
87
+ 89.1,
88
+ 97.1
89
+ ],
90
+ "denominator": 140,
91
+ "numerator": 132,
92
+ "score_percent": 94.3
93
+ },
94
+ "three_distinct_answers": {
95
+ "ci95_percent": [
96
+ 73.4,
97
+ 86.4
98
+ ],
99
+ "denominator": 140,
100
+ "numerator": 113,
101
+ "score_percent": 80.7
102
+ },
103
+ "three_distinct_misconceptions": {
104
+ "ci95_percent": [
105
+ 97.3,
106
+ 100.0
107
+ ],
108
+ "denominator": 140,
109
+ "numerator": 140,
110
+ "score_percent": 100.0
111
+ },
112
+ "track_type": "model_only",
113
+ "valid_exactly_three": {
114
+ "ci95_percent": [
115
+ 97.3,
116
+ 100.0
117
+ ],
118
+ "denominator": 140,
119
+ "numerator": 140,
120
+ "score_percent": 100.0
121
+ }
122
+ },
123
+ "v8_verifier_guided_best_of_4": {
124
+ "candidate_count": 4,
125
+ "generation": "one greedy candidate plus three seeded sampled candidates, selected by a deterministic local verifier",
126
+ "hardened_computation_validity": {
127
+ "ci95_percent": [
128
+ 79.0,
129
+ 89.3
130
+ ],
131
+ "denominator": 420,
132
+ "numerator": 356,
133
+ "score_percent": 84.8
134
+ },
135
+ "no_answer_equals_key": {
136
+ "ci95_percent": [
137
+ 91.9,
138
+ 98.5
139
+ ],
140
+ "denominator": 140,
141
+ "numerator": 135,
142
+ "score_percent": 96.4
143
+ },
144
+ "three_distinct_answers": {
145
+ "ci95_percent": [
146
+ 91.9,
147
+ 98.5
148
+ ],
149
+ "denominator": 140,
150
+ "numerator": 135,
151
+ "score_percent": 96.4
152
+ },
153
+ "three_distinct_misconceptions": {
154
+ "ci95_percent": [
155
+ 97.3,
156
+ 100.0
157
+ ],
158
+ "denominator": 140,
159
+ "numerator": 140,
160
+ "score_percent": 100.0
161
+ },
162
+ "track_type": "system",
163
+ "valid_exactly_three": {
164
+ "ci95_percent": [
165
+ 97.3,
166
+ 100.0
167
+ ],
168
+ "denominator": 140,
169
+ "numerator": 140,
170
+ "score_percent": 100.0
171
+ }
172
+ }
173
+ },
174
+ "method": "Deterministic local hard gates on the sealed v8 Number benchmark; intervals are 95%.",
175
+ "registered_verdict": {
176
+ "v8_model_only": "NOT DEMONSTRATED",
177
+ "v8_verifier_guided_best_of_4": "NOT DEMONSTRATED"
178
+ },
179
+ "unavailable_metrics": {
180
+ "diagnostic_quality_or_plausibility": "No accepted independent judge or completed human review.",
181
+ "good_at_3": "GDR is unavailable.",
182
+ "good_distractor_rate": "No accepted independent judge for holistic misconception mapping, specificity, plausibility, and diagnostic usefulness.",
183
+ "observed_student_pick_frequency": "No student option-selection frequency data exists for this benchmark."
184
+ }
185
+ },
186
+ "model_id": "j2ampn/qwen3-8b-distractor-lora-v8",
187
+ "schema_version": "diagnostic-distractor-v8-benchmark-summary-v1",
188
+ "source_evidence": {
189
+ "artifact_validation": {
190
+ "sha256": "6accd30757d0023eed252c45ba8f02a1e3499372782e6fbb7daeda53a13b7f7c",
191
+ "url": "https://github.com/jsonjj/diagnostic-distractor-slm/blob/5aa7146b0fa7fc71efbd10feac4e57c2839e05a4/data/eval_out/v8_artifact_validation.json"
192
+ },
193
+ "final_benchmark": {
194
+ "sha256": "419ec4a7f9b8c3e4baef1830582b0c54225be315d0cc740d517575aa208c1368",
195
+ "url": "https://github.com/jsonjj/diagnostic-distractor-slm/blob/5aa7146b0fa7fc71efbd10feac4e57c2839e05a4/data/eval_out/benchmark_v8_final.json"
196
+ },
197
+ "final_results": {
198
+ "sha256": "388b9d28267d9fc25aeef4bb885816b9764dfa94cba3c43c7475b0aa19b4ae9e",
199
+ "url": "https://github.com/jsonjj/diagnostic-distractor-slm/blob/5aa7146b0fa7fc71efbd10feac4e57c2839e05a4/TABLE_V8_RESULTS.md"
200
+ },
201
+ "repository": "https://github.com/jsonjj/diagnostic-distractor-slm",
202
+ "source_revision": "5aa7146b0fa7fc71efbd10feac4e57c2839e05a4",
203
+ "training_receipt": {
204
+ "sha256": "a88a1ca6dae5611ee64e34f7ecb236a17c82809f1a4f053c5daaa701c7e00571",
205
+ "url": "https://github.com/jsonjj/diagnostic-distractor-slm/blob/5aa7146b0fa7fc71efbd10feac4e57c2839e05a4/v8_training_receipt.json"
206
+ }
207
+ },
208
+ "training": {
209
+ "best_checkpoint": "outputs_v8/checkpoint-403",
210
+ "best_eval_loss": 0.051324423402547836,
211
+ "epochs_planned": 3,
212
+ "learning_rate": 0.00015,
213
+ "lora_alpha": 32,
214
+ "lora_rank": 32,
215
+ "seed": 42,
216
+ "train_rows": 3572,
217
+ "train_sha256": "babe071e310a389b8a0fb2d3a5b6414f1275129f3cad8c15be5ff175e098a5ad"
218
+ }
219
+ }
chat_template.jinja ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {%- if tools %}
2
+ {{- '<|im_start|>system\n' }}
3
+ {%- if messages[0].role == 'system' %}
4
+ {{- messages[0].content + '\n\n' }}
5
+ {%- endif %}
6
+ {{- "# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within <tools></tools> XML tags:\n<tools>" }}
7
+ {%- for tool in tools %}
8
+ {{- "\n" }}
9
+ {{- tool | tojson }}
10
+ {%- endfor %}
11
+ {{- "\n</tools>\n\nFor each function call, return a json object with function name and arguments within <tool_call></tool_call> XML tags:\n<tool_call>\n{\"name\": <function-name>, \"arguments\": <args-json-object>}\n</tool_call><|im_end|>\n" }}
12
+ {%- else %}
13
+ {%- if messages[0].role == 'system' %}
14
+ {{- '<|im_start|>system\n' + messages[0].content + '<|im_end|>\n' }}
15
+ {%- endif %}
16
+ {%- endif %}
17
+ {%- set ns = namespace(multi_step_tool=true, last_query_index=messages|length - 1) %}
18
+ {%- for forward_message in messages %}
19
+ {%- set index = (messages|length - 1) - loop.index0 %}
20
+ {%- set message = messages[index] %}
21
+ {%- set tool_start = '<tool_response>' %}
22
+ {%- set tool_start_length = tool_start|length %}
23
+ {%- set start_of_message = message.content[:tool_start_length] %}
24
+ {%- set tool_end = '</tool_response>' %}
25
+ {%- set tool_end_length = tool_end|length %}
26
+ {%- set start_pos = (message.content|length) - tool_end_length %}
27
+ {%- if start_pos < 0 %}
28
+ {%- set start_pos = 0 %}
29
+ {%- endif %}
30
+ {%- set end_of_message = message.content[start_pos:] %}
31
+ {%- if ns.multi_step_tool and message.role == "user" and not(start_of_message == tool_start and end_of_message == tool_end) %}
32
+ {%- set ns.multi_step_tool = false %}
33
+ {%- set ns.last_query_index = index %}
34
+ {%- endif %}
35
+ {%- endfor %}
36
+ {%- for message in messages %}
37
+ {%- if (message.role == "user") or (message.role == "system" and not loop.first) %}
38
+ {{- '<|im_start|>' + message.role + '\n' + message.content + '<|im_end|>' + '\n' }}
39
+ {%- elif message.role == "assistant" %}
40
+ {%- set content = message.content %}
41
+ {%- set reasoning_content = '' %}
42
+ {%- if message.reasoning_content is defined and message.reasoning_content is not none %}
43
+ {%- set reasoning_content = message.reasoning_content %}
44
+ {%- else %}
45
+ {%- if '</think>' in message.content %}
46
+ {%- set content = (message.content.split('</think>')|last).lstrip('\n') %}
47
+ {%- set reasoning_content = (message.content.split('</think>')|first).rstrip('\n') %}
48
+ {%- set reasoning_content = (reasoning_content.split('<think>')|last).lstrip('\n') %}
49
+ {%- endif %}
50
+ {%- endif %}
51
+ {%- if loop.index0 > ns.last_query_index %}
52
+ {%- if loop.last or (not loop.last and reasoning_content) %}
53
+ {{- '<|im_start|>' + message.role + '\n<think>\n' + reasoning_content.strip('\n') + '\n</think>\n\n' + content.lstrip('\n') }}
54
+ {%- else %}
55
+ {{- '<|im_start|>' + message.role + '\n' + content }}
56
+ {%- endif %}
57
+ {%- else %}
58
+ {{- '<|im_start|>' + message.role + '\n' + content }}
59
+ {%- endif %}
60
+ {%- if message.tool_calls %}
61
+ {%- for tool_call in message.tool_calls %}
62
+ {%- if (loop.first and content) or (not loop.first) %}
63
+ {{- '\n' }}
64
+ {%- endif %}
65
+ {%- if tool_call.function %}
66
+ {%- set tool_call = tool_call.function %}
67
+ {%- endif %}
68
+ {{- '<tool_call>\n{"name": "' }}
69
+ {{- tool_call.name }}
70
+ {{- '", "arguments": ' }}
71
+ {%- if tool_call.arguments is string %}
72
+ {{- tool_call.arguments }}
73
+ {%- else %}
74
+ {{- tool_call.arguments | tojson }}
75
+ {%- endif %}
76
+ {{- '}\n</tool_call>' }}
77
+ {%- endfor %}
78
+ {%- endif %}
79
+ {{- '<|im_end|>\n' }}
80
+ {%- elif message.role == "tool" %}
81
+ {%- if loop.first or (messages[loop.index0 - 1].role != "tool") %}
82
+ {{- '<|im_start|>user' }}
83
+ {%- endif %}
84
+ {{- '\n<tool_response>\n' }}
85
+ {{- message.content }}
86
+ {{- '\n</tool_response>' }}
87
+ {%- if loop.last or (messages[loop.index0 + 1].role != "tool") %}
88
+ {{- '<|im_end|>\n' }}
89
+ {%- endif %}
90
+ {%- endif %}
91
+ {%- endfor %}
92
+ {%- if add_generation_prompt %}
93
+ {{- '<|im_start|>assistant\n' }}
94
+ {%- if enable_thinking is defined and enable_thinking is false %}
95
+ {{- '<think>\n\n</think>\n\n' }}
96
+ {%- endif %}
97
+ {%- endif %}
tokenizer.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:476870a1f2fb6f6a2759a6ede2383bf9d5d738f17844563b65c91965b722ae09
3
+ size 11422924
tokenizer_config.json ADDED
@@ -0,0 +1,225 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "add_prefix_space": false,
3
+ "backend": "tokenizers",
4
+ "bos_token": null,
5
+ "clean_up_tokenization_spaces": false,
6
+ "eos_token": "<|im_end|>",
7
+ "errors": "replace",
8
+ "is_local": false,
9
+ "model_max_length": 40960,
10
+ "pad_token": "<|vision_pad|>",
11
+ "padding_side": "left",
12
+ "split_special_tokens": false,
13
+ "tokenizer_class": "Qwen2Tokenizer",
14
+ "unk_token": null,
15
+ "added_tokens_decoder": {
16
+ "151643": {
17
+ "content": "<|endoftext|>",
18
+ "single_word": false,
19
+ "lstrip": false,
20
+ "rstrip": false,
21
+ "normalized": false,
22
+ "special": true
23
+ },
24
+ "151644": {
25
+ "content": "<|im_start|>",
26
+ "single_word": false,
27
+ "lstrip": false,
28
+ "rstrip": false,
29
+ "normalized": false,
30
+ "special": true
31
+ },
32
+ "151645": {
33
+ "content": "<|im_end|>",
34
+ "single_word": false,
35
+ "lstrip": false,
36
+ "rstrip": false,
37
+ "normalized": false,
38
+ "special": true
39
+ },
40
+ "151646": {
41
+ "content": "<|object_ref_start|>",
42
+ "single_word": false,
43
+ "lstrip": false,
44
+ "rstrip": false,
45
+ "normalized": false,
46
+ "special": true
47
+ },
48
+ "151647": {
49
+ "content": "<|object_ref_end|>",
50
+ "single_word": false,
51
+ "lstrip": false,
52
+ "rstrip": false,
53
+ "normalized": false,
54
+ "special": true
55
+ },
56
+ "151648": {
57
+ "content": "<|box_start|>",
58
+ "single_word": false,
59
+ "lstrip": false,
60
+ "rstrip": false,
61
+ "normalized": false,
62
+ "special": true
63
+ },
64
+ "151649": {
65
+ "content": "<|box_end|>",
66
+ "single_word": false,
67
+ "lstrip": false,
68
+ "rstrip": false,
69
+ "normalized": false,
70
+ "special": true
71
+ },
72
+ "151650": {
73
+ "content": "<|quad_start|>",
74
+ "single_word": false,
75
+ "lstrip": false,
76
+ "rstrip": false,
77
+ "normalized": false,
78
+ "special": true
79
+ },
80
+ "151651": {
81
+ "content": "<|quad_end|>",
82
+ "single_word": false,
83
+ "lstrip": false,
84
+ "rstrip": false,
85
+ "normalized": false,
86
+ "special": true
87
+ },
88
+ "151652": {
89
+ "content": "<|vision_start|>",
90
+ "single_word": false,
91
+ "lstrip": false,
92
+ "rstrip": false,
93
+ "normalized": false,
94
+ "special": true
95
+ },
96
+ "151653": {
97
+ "content": "<|vision_end|>",
98
+ "single_word": false,
99
+ "lstrip": false,
100
+ "rstrip": false,
101
+ "normalized": false,
102
+ "special": true
103
+ },
104
+ "151654": {
105
+ "content": "<|vision_pad|>",
106
+ "single_word": false,
107
+ "lstrip": false,
108
+ "rstrip": false,
109
+ "normalized": false,
110
+ "special": true
111
+ },
112
+ "151655": {
113
+ "content": "<|image_pad|>",
114
+ "single_word": false,
115
+ "lstrip": false,
116
+ "rstrip": false,
117
+ "normalized": false,
118
+ "special": true
119
+ },
120
+ "151656": {
121
+ "content": "<|video_pad|>",
122
+ "single_word": false,
123
+ "lstrip": false,
124
+ "rstrip": false,
125
+ "normalized": false,
126
+ "special": true
127
+ },
128
+ "151657": {
129
+ "content": "<tool_call>",
130
+ "single_word": false,
131
+ "lstrip": false,
132
+ "rstrip": false,
133
+ "normalized": false,
134
+ "special": false
135
+ },
136
+ "151658": {
137
+ "content": "</tool_call>",
138
+ "single_word": false,
139
+ "lstrip": false,
140
+ "rstrip": false,
141
+ "normalized": false,
142
+ "special": false
143
+ },
144
+ "151659": {
145
+ "content": "<|fim_prefix|>",
146
+ "single_word": false,
147
+ "lstrip": false,
148
+ "rstrip": false,
149
+ "normalized": false,
150
+ "special": false
151
+ },
152
+ "151660": {
153
+ "content": "<|fim_middle|>",
154
+ "single_word": false,
155
+ "lstrip": false,
156
+ "rstrip": false,
157
+ "normalized": false,
158
+ "special": false
159
+ },
160
+ "151661": {
161
+ "content": "<|fim_suffix|>",
162
+ "single_word": false,
163
+ "lstrip": false,
164
+ "rstrip": false,
165
+ "normalized": false,
166
+ "special": false
167
+ },
168
+ "151662": {
169
+ "content": "<|fim_pad|>",
170
+ "single_word": false,
171
+ "lstrip": false,
172
+ "rstrip": false,
173
+ "normalized": false,
174
+ "special": false
175
+ },
176
+ "151663": {
177
+ "content": "<|repo_name|>",
178
+ "single_word": false,
179
+ "lstrip": false,
180
+ "rstrip": false,
181
+ "normalized": false,
182
+ "special": false
183
+ },
184
+ "151664": {
185
+ "content": "<|file_sep|>",
186
+ "single_word": false,
187
+ "lstrip": false,
188
+ "rstrip": false,
189
+ "normalized": false,
190
+ "special": false
191
+ },
192
+ "151665": {
193
+ "content": "<tool_response>",
194
+ "single_word": false,
195
+ "lstrip": false,
196
+ "rstrip": false,
197
+ "normalized": false,
198
+ "special": false
199
+ },
200
+ "151666": {
201
+ "content": "</tool_response>",
202
+ "single_word": false,
203
+ "lstrip": false,
204
+ "rstrip": false,
205
+ "normalized": false,
206
+ "special": false
207
+ },
208
+ "151667": {
209
+ "content": "<think>",
210
+ "single_word": false,
211
+ "lstrip": false,
212
+ "rstrip": false,
213
+ "normalized": false,
214
+ "special": false
215
+ },
216
+ "151668": {
217
+ "content": "</think>",
218
+ "single_word": false,
219
+ "lstrip": false,
220
+ "rstrip": false,
221
+ "normalized": false,
222
+ "special": false
223
+ }
224
+ }
225
+ }