The problem
A reasoning solution is a list of steps. An outcome reward model judges only the end result. A PRM (process reward model) judges every step: it gives each step the probability that the step is correct. To rank whole solutions, Lightman et al. (2023) score a solution as the probability that every step is correct, the product of its step probabilities. A solution with one wrong step and a lucky final answer gets a low score, as it should.
Three ways to score
For the step probabilities of one solution:
"product": , the PRM score of Lightman et al.;"min": the weakest step, , a common alternative;"last": only the last step's probability, : an outcome-style score, which sees only how the solution ended.
Example. Solution A has steps and solution B has .
method A B best "product"A "min"A "last"B The outcome-style score prefers B, whose last step looks perfect even though one step in the middle was probably wrong. The product and the minimum see the weak step.
Picking the best solution
pick_best(solutions, method): solutions is a list of step-probability arrays; return the index of the best one under method (the first one on a tie). In the example, pick_best([A, B], "product") is 0 and pick_best([A, B], "last") is 1.
Long products
A product of many probabilities shrinks fast: 1,000 steps of give , and 2,000 steps of give a number below the smallest a float64 can store: exactly 0. In practice such products are computed as a sum of logarithms, which stays well-behaved ( for the second case). Both np.prod and np.exp(np.sum(np.log(p))) are fine for the tests here, but remember why log-space exists.
What to implement
solution_score(step_probs, method):step_probsis a 1-D array, one probability per step;methodis"product","min"or"last". RaiseValueErrorfor any other method.pick_best(solutions, method): the index of the best solution.