Files
2026-07-13 13:24:13 +08:00

176 lines
5.4 KiB
Python

import json
import argparse
import os.path
from glob import glob
from tqdm import tqdm
import collections
from multiprocessing import Pool
from functools import partial
import torch
import sys
sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
from post_processors.openai_api_callback import majority_voting_predict
from data.deepseek_math_utils import eval_script
def load_rewards(reward_file):
if os.path.exists(reward_file):
rewards = json.load(open(reward_file))
else:
rewards = []
for file in glob(reward_file):
print(file)
rewards.extend(json.load(open(file)))
return rewards
def _init(id2reward):
global _id2reward
_id2reward = id2reward
def _worker(item, sc_top_k=None):
sorted_results = []
if not item["response"] or not item["pred"] or not item["res"]:
return {
"missing": 1,
"reward_missing": 0,
"pred_missing": 0,
"seq_too_long": 0,
"sorted_results": [],
"sc_res": False
}
reward_missing = 0
pred_missing = 0
seq_too_long = 0
for i, (resp, pred, r) in enumerate(zip(item["response"], item["pred"], item["res"])):
resp_id = f"{item['id']}_{i}"
if resp_id not in _id2reward:
reward_missing += 1
continue
if not pred:
pred_missing += 1
continue
reward = _id2reward[resp_id]
sorted_results.append((resp, pred, r, reward))
sorted_results = sorted(sorted_results, key=lambda x: x[-1], reverse=True)
sc_top_k_res = {}
if sc_top_k and sorted_results:
for k in sc_top_k:
preds = [r[1] for r in sorted_results[:k]]
sc_pred = majority_voting_predict(preds)
if sc_pred != "":
sc_res = eval_script.eval_math({"prediction": sc_pred, "answer": item["label"]})
else:
sc_res = False
sc_top_k_res[k] = sc_res
return {
"missing": 0,
"reward_missing": reward_missing,
"pred_missing": pred_missing,
"seq_too_long": seq_too_long,
"sorted_results": sorted_results,
"sc_res": item["sc_res"],
"sc_top_k_res": sc_top_k_res,
}
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--response_file", type=str, required=True)
parser.add_argument("--reward_file", type=str, required=True)
parser.add_argument("--num_workers", type=int, default=8)
args = parser.parse_args()
if os.path.exists(args.response_file):
responses = json.load(open(args.response_file))
else:
responses = []
for file in glob(args.response_file):
print(file)
responses.extend(json.load(open(file)))
rewards = load_rewards(args.reward_file)
id2reward = {item["index"]: item["reward"][1] for item in rewards}
_k = [1, 3, 5]
orm_pass_at_k = {k: 0 for k in _k}
missing = 0
missing_reward = 0
pred_missing = 0
seq_too_long = 0
sc_cnt = 0
# for item in tqdm(responses):
# sorted_results = []
# if not item["response"] or not item["pred"] or not item["res"]:
# missing += 1
# continue
# for i, (resp, pred, r) in enumerate(zip(item["response"], item["pred"], item["res"])):
# resp_id = f"{item['id']}_{i}"
# if resp_id not in id2reward:
# missing_reward += 1
# continue
#
# reward = id2reward[resp_id]
# sorted_results.append((resp, pred, r, reward))
#
# if not sorted_results:
# continue
# sorted_results = sorted(sorted_results, key=lambda x: x[-1], reverse=True)
# for k in _k:
# if any([r[2] for r in sorted_results[:k]]):
# orm_pass_at_k[k] += 1
#
# if item["sc_res"]:
# sc_cnt += 1
with Pool(args.num_workers, initializer=_init, initargs=(id2reward,)) as pool:
annotate = partial(_worker, sc_top_k=(5, 10))
results = list(tqdm(pool.imap_unordered(annotate, responses), total=len(responses)))
sc_top_k = {k: 0 for k in (5, 10)}
for item in results:
missing += item["missing"]
missing_reward += item["reward_missing"]
pred_missing += item["pred_missing"]
seq_too_long += item["seq_too_long"]
sorted_results = item["sorted_results"]
if item["sc_res"]:
sc_cnt += 1
if not sorted_results:
continue
# ultimate_results.append(sorted_results)
for k in _k:
if any([r[2] for r in sorted_results[:k]]):
orm_pass_at_k[k] += 1
for k, v in item["sc_top_k_res"].items():
if v:
sc_top_k[k] += 1
print(f"Total: {len(responses)}")
print(f"Missing: {missing}")
print(f"Missing reward: {missing_reward}")
print(f"Missing pred: {pred_missing}")
print(f"Seq too long: {seq_too_long}")
print(f"SC: {sc_cnt}")
for k, v in orm_pass_at_k.items():
print(f"PRM pass at {k}: {v}")
print(f"PRM pass at {k} rate: {v / len(responses) * 100:.2f}%")
for k, v in sc_top_k.items():
print(f"SC pass at {k}: {v}")
print(f"SC pass at {k} rate: {v / len(responses) * 100:.2f}%")
print(f"SC rate: {sc_cnt / len(responses) * 100:.2f}%")
if __name__ == '__main__':
main()