42e commited on
Commit
b004725
·
verified ·
1 Parent(s): 2c31ee6

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. notes/project-report.md +190 -0
notes/project-report.md ADDED
@@ -0,0 +1,190 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Can a small model check math better than it can do math?
2
+
3
+ A write-up of what we tried, why, and what we found. It builds on the two research
4
+ notes in this folder (`brainlift.md` and `research-small-vs-large-math.md`) and the
5
+ runs saved under `results/`.
6
+
7
+ ## The question
8
+
9
+ We wanted to take a small open model, fine-tune it on data we generate, and get it to
10
+ reliably do one narrow thing that a plain prompt cannot: read a step-by-step math
11
+ solution and point to the first step that is wrong. This is usually called process
12
+ verification. We chose it because the background reading suggested it is one of the few
13
+ math tasks where a small specialist has a real chance against a much larger model.
14
+
15
+ The reason is the generator-verifier asymmetry. Checking a solution is generally easier
16
+ than producing one, so a model that is weak at solving competition problems can still be
17
+ useful at catching mistakes in someone else's work. If that holds, a small verifier is a
18
+ sensible bet.
19
+
20
+ We wrote the target as a spec so that a stranger could grade any output. Given a problem
21
+ and a numbered solution, the model returns the index of the first incorrect step, or -1
22
+ if every step is correct. We score this on ProcessBench, which reports the harmonic mean
23
+ of accuracy on erroneous solutions and accuracy on correct ones. GPT-4o scores about
24
+ 61.9 there, so that was the number to have in mind.
25
+
26
+ ## What the reading told us going in
27
+
28
+ Three findings from the research notes shaped the plan.
29
+
30
+ Data matters more than the training run. Results like LIMA and s1 come mostly from a
31
+ small, carefully chosen set of examples, so we put our effort into generating and
32
+ filtering data rather than tuning hyperparameters.
33
+
34
+ You should distill the process, not the style. Orca points out that copying a teacher's
35
+ final answers teaches surface imitation while copying the reasoning teaches the actual
36
+ skill. We ended up learning this the hard way.
37
+
38
+ Scale is a real constraint. The math-specific note was blunt that most "small beats
39
+ large" results live at 7B, and that genuine sub-4B wins are thin and usually need extra
40
+ machinery. The clearest sub-4B verifier, GenPRM at 1.5B, only beats GPT-4o when it also
41
+ runs generated Python to check arithmetic and votes over several samples. We noted this
42
+ and started at 1.5B anyway, partly to see the ceiling ourselves.
43
+
44
+ ## How we built it
45
+
46
+ The pipeline has three parts, and we reused all three across every experiment.
47
+
48
+ Data. We took step-level labels from PRM800K, which are human judgments of where a
49
+ solution first goes wrong. For each solution a frontier model (Claude, through a company
50
+ gateway) wrote a paragraph-by-paragraph critique. We removed any training problem that
51
+ also appears in ProcessBench or MATH-500, so we were not training on the test set.
52
+
53
+ Training. QLoRA on Qwen2.5-Math, first the 1.5B instruct model and later the 7B. We
54
+ trained the verifier as an ordinary generative model with supervised fine-tuning. The
55
+ version of TRL we used has no dedicated process-reward trainer, and a generative verifier
56
+ is what the GenPRM result used, so this was both the practical and the principled choice.
57
+
58
+ Evaluation. ProcessBench for the main number and PRMBench as a harder, adversarial check.
59
+ Both use exact, objective scoring, so there is no model acting as judge and no judge bias
60
+ to worry about.
61
+
62
+ ## What happened
63
+
64
+ ### The first data recipe did not work
65
+
66
+ Our first version told the teacher the correct answer and asked for a matching critique.
67
+ This was a mistake. The critiques read well, but they were written backward from the
68
+ answer, so they contained no real error-finding. The 1.5B model trained on them picked up
69
+ the format and not the skill. On ProcessBench it caught errors about as often as the
70
+ untuned base, and the only thing it clearly improved at was confidently declaring
71
+ solutions correct. It learned to say "looks fine." That is the failure Orca describes.
72
+
73
+ ### The second recipe was honest but hit a wall
74
+
75
+ We rebuilt the data so the teacher critiqued each solution without seeing the answer, and
76
+ we kept a critique only when its predicted error index matched the PRM800K label. This is
77
+ rejection sampling, and it gave us critiques that actually located the error. The keep
78
+ rate was about 77 percent, and the kept set came out roughly balanced between erroneous
79
+ and correct examples on its own. We also raised the LoRA rank, since a genuinely hard
80
+ skill should need more capacity than a small low-rank update.
81
+
82
+ It still did not move the score. At 1.5B the model kept defaulting to "all correct,"
83
+ predicting -1 about 90 percent of the time on the gsm8k subset. More data and more
84
+ capacity did not help, which usually means the problem is capability rather than data.
85
+
86
+ ### Why it was stuck
87
+
88
+ The failure was not uniform across the test set, and that was the useful part. On
89
+ PRMBench the same model flagged an error about 41 percent of the time, much more often
90
+ than on gsm8k. The difference is the kind of error each set contains. PRMBench's injected
91
+ errors are often structural, like circular reasoning or a step that contradicts an
92
+ earlier one, and those can be caught by reading carefully. The gsm8k errors are
93
+ arithmetic, and a 1.5B model cannot reliably redo the arithmetic, so it falls back on
94
+ "looks fine." This matches GenPRM, which needed a Python interpreter for exactly this
95
+ reason.
96
+
97
+ ### Two things that helped
98
+
99
+ We tried the code-execution idea first, because it can be run at inference on a model we
100
+ already had. We let the verifier write short Python snippets, ran them, and fed the
101
+ output back before it committed to an answer. On the 7B base this roughly doubled
102
+ error-localization on gsm8k, from about 11 to 21 (accuracy on erroneous steps), which is
103
+ the arithmetic-heavy split where we expected it to matter.
104
+
105
+ Moving from 1.5B to 7B helped on its own. The untuned 7B stopped collapsing to "all
106
+ correct" on the harder subsets and localized errors at a real rate, where the 1.5B could
107
+ not. This is the plainest evidence we have for the "wins live at 7B" point from the note.
108
+
109
+ ### Results so far
110
+
111
+ Numbers are ProcessBench F1 on a 100-example sample per subset, greedy decoding, on the
112
+ 0-100 scale (so GPT-4o's 61.9 is the reference). These are sensitive to decoding
113
+ settings; we say more about that below.
114
+
115
+ | model | gsm8k | math | olympiad | omnimath | avg | notes |
116
+ |---|---|---|---|---|---|---|
117
+ | 1.5B base | ~16 | | | | | prompt alone is weak |
118
+ | 1.5B tuned (v2) | ~16 | | | | | collapses to -1 (~90%) |
119
+ | 7B base | 12-21 | ~14 | ~13 | ~9 | ~12-21 | stops collapsing on hard subsets |
120
+ | 7B base + code-exec | ~32 | ~33 | | | | gsm8k acc-error ~11 to ~21 |
121
+ | 7B tuned | pending | | | | | final eval to fill in |
122
+
123
+ The gsm8k -1 rate tells the story cleanly: 1.5B tuned sits around 0.90, while the 7B base
124
+ is 0.83 on gsm8k but drops to about 0.21-0.25 on olympiad and omnimath, meaning it
125
+ actually attempts to localize on the harder problems.
126
+
127
+ ## What we take from this
128
+
129
+ The honest headline is narrower than "small model beats big model," and that is fine. A
130
+ small fine-tuned model can help on the easy side of the generator-verifier asymmetry, but
131
+ only where the check is cheap for the model to run. For structural reasoning errors a
132
+ 1.5B model can contribute. For arithmetic it cannot, at least not without a calculator,
133
+ and adding the calculator is what closes most of the gap. Capability (7B) and tools (code
134
+ execution) push in the same direction, which is the direction GenPRM already pointed.
135
+
136
+ On the project's own framing, the dataset really was the deliverable, but not the way we
137
+ first assumed. The first dataset was large and clean and still taught the wrong thing,
138
+ because the examples encoded justification instead of detection. Fixing what the examples
139
+ taught mattered more than making more of them.
140
+
141
+ We also spent more time on plumbing than expected. Getting QLoRA, the eval harness, and
142
+ the Colab setup to behave took several rounds of debugging, and a few of our early numbers
143
+ were held down by eval bugs rather than by the model (a repetition penalty that fought the
144
+ verifier's own format, a token budget that cut long critiques before they finished, and a
145
+ scale mix-up where our fractions were sitting next to a percentage). We mention this
146
+ because it changes how much to trust any single run.
147
+
148
+ ## Evaluations
149
+
150
+ We ran these:
151
+
152
+ - ProcessBench, base versus tuned, on all four subsets. This is the main number and the
153
+ base-versus-tuned comparison the assignment asks for.
154
+ - PRMBench, which injects errors of specific types. This is the robustness check, and it
155
+ is where we found that the model does better on structural errors than arithmetic ones.
156
+ - A prediction-distribution readout (how often the model says -1, gives an index, or
157
+ fails to parse). This is a calibration check, and it is what exposed the "collapse to
158
+ all-correct" failure that a single F1 number hides.
159
+ - A code-execution ablation, the same model with and without the Python tool. This
160
+ isolates the arithmetic-verification effect.
161
+
162
+ Others that fit the assignment's rubric and are worth running:
163
+
164
+ - Test-time scaling with majority voting (Maj@k). GenPRM's headline needs it. Our harness
165
+ supports it, but it only helps once the base verdicts are decent, so it is a later step.
166
+ - The composition eval, where the verifier reranks a separate generator's samples and we
167
+ measure the lift in final-answer accuracy. This is the most direct "why does this
168
+ matter" test, since a verifier is only useful if it improves a downstream result. We
169
+ have the pieces but have not built the generator half yet.
170
+ - Consistency under perturbation. Take a solution the model handles, rename variables or
171
+ reorder independent steps, and check that the verdict does not change. This targets the
172
+ consistency dimension of the rubric and the fragilities the brainlift lists.
173
+ - A contamination-controlled held-out set. We already deduplicate training against the
174
+ eval sets, but a fresh set would make the numbers harder to argue with.
175
+
176
+ ## What we would do next
177
+
178
+ The verifier is only half of the original plan. The other half is a generator, and the
179
+ point of having both was to measure the asymmetry directly by having the verifier rerank
180
+ the generator's samples. We have the code for this but have not run it.
181
+
182
+ After that, the clear next steps are the full GenPRM recipe on the 7B, meaning code
183
+ execution together with majority voting, and a held-out set to rule out contamination.
184
+
185
+ ## Artifacts
186
+
187
+ - Datasets and model on Hugging Face: `42e/mathcompose-verifier` (data),
188
+ `42e/mathcompose-verifier-7b` (the tuned adapter), `42e/mathcompose` (code snapshot).
189
+ - Eval outputs in `results/`, and the earlier detailed failure analysis in
190
+ `results/M1_verifier_findings.md`.