Views
No views yet
UniRRM: Unified Reasoning Reward Models Across Languages and Evaluation Paradigms [Paper]
<Response> blocks in the user prompt:<Response1>, <Response2>)<Response1> through <Response4>)<Response1>), optionally with a <Reference_Answer> block1import json
2import re
3from vllm import LLM, SamplingParams
4from transformers import AutoTokenizer
5
6MODEL_NAME = "SUSTech-NLP/UniRRM-8B"
7
8# ---------- 1. Load model ----------
9tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
10llm = LLM(model=MODEL_NAME, max_model_len=16384)
11sampling_params = SamplingParams(temperature=0, max_tokens=4096, repetition_penalty=1.05)
12
13# ---------- 2. Build prompt ----------
14SYSTEM_PROMPT = """
15You are a multilingual evaluation expert, responsible for conducting rigorous, objective, and multi-dimensional evaluations of responses generated for User Input. Your evaluation must strictly follow the step-by-step process outlined below:
16
17### Phase 1: Deep Analysis
18Before evaluating, perform a comprehensive analysis of the User Input to establish a robust baseline:
191. **Identify potential risks**: Analyze the User Input to identify any potential safety, legal, offensive, or ethical risks.
202. **Identify task type**: Identify the primary task type (e.g., chat, reasoning, code generation, translation, or creative writing).
213. **Analyze core requirements (task-dependent)**: Define the fundamental evaluation dimensions that any correct response must satisfy.
224. **Analyze specific requirements**: Identify additional constraints or expectations unique to the User Input.
235. **Predict response content**: Summarize the expected content or core objectives of a correct response.
24
25### Phase 2: Dynamic Rubric Generation
261. Generate a set of evaluation rubrics tailored to the user inputs and responses, with a 1-5 scoring criterion for each rubric.
272. If any safety, legal, or ethical risks are detected, include a Safety rubric as the highest-priority dimension.
283. Ensure rubrics comprehensively cover all critical aspects of the response.
29
30### Phase 3: Detailed Evaluation
31For each rubric, evaluate the response:
321. **Evidence Extraction**: Identify specific passages that meet or fail to meet the rubric requirements.
332. **Gap Analysis**: Determine why the response did not achieve a perfect score (5).
343. **Scoring**: Assign a score from 1 to 5.
35
36### OUTPUT FORMAT
37{
38 "Analysis_process": "Concise summary of the analysis.",
39 "rubrics": [{"name": "String", "description": "Rubric definition"}],
40 "evaluations": [{"response_id": "String", "explanation": "Summary", "final_score": "Float"}],
41 "best_id": "ID of the winner"
42}
43""".strip()
44
45question = "Explain the concept of recursion in programming."
46response_a = "Recursion is when a function calls itself to solve smaller subproblems. A base case stops the recursion, and each recursive call works on a reduced version of the original problem. For example, calculating factorial: factorial(n) = n * factorial(n-1), with factorial(0) = 1 as the base case."
47response_b = "Recursion means repeating something. In programming, it is used sometimes."
48
49user_prompt = f"""
50<User_Input>
51{question}
52</User_Input>
53
54<Response1>
55{response_a}
56</Response1>
57
58<Response2>
59{response_b}
60</Response2>
61"""
62
63messages = [
64 {"role": "system", "content": SYSTEM_PROMPT},
65 {"role": "user", "content": user_prompt},
66]
67prompt = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
68
69# ---------- 3. Generate ----------
70outputs = llm.generate([prompt], sampling_params)
71raw_output = outputs[0].outputs[0].text
72print(raw_output)
73
74# ---------- 4. Parse output ----------
75def parse_unirm_output(raw_output: str) -> dict:
76 """Parse UniRRM's JSON output to extract scores and best_id."""
77 text = raw_output
78 # Strip " in text:
79 text = text.split("</think>")[-1].strip()
80
81 # Extract JSON from markdown code block or raw text
82 code_block = re.search(r"```(?:json)?\s*(\{.*?\})\s*```", text, re.DOTALL)
83 if code_block:
84 json_str = code_block.group(1)
85 else:
86 start, end = text.find("{"), text.rfind("}")
87 if start != -1 and end != -1:
88 json_str = text[start : end + 1]
89 else:
90 return {"error": "No JSON found in output"}
91
92 try:
93 return json.loads(json_str)
94 except json.JSONDecodeError:
95 match = re.search(r'"final_score"\s*:\s*"?(\d+(?:\.\d+)?)"?', json_str)
96 if match:
97 return {"final_score": float(match.group(1))}
98 return {"error": "Failed to parse JSON"}
99
100result = parse_unirm_output(raw_output)
101print(f"Best response: {result.get('best_id')}")
102for evaluation in result.get("evaluations", []):
103 print(f" {evaluation['response_id']}: score={evaluation['final_score']}")R = 0.8 × r_fmt + 0.15 × r_acc + 0.05 × r_rubric
| Attribute | Value |
|---|---|
| Architecture | Qwen3ForCausalLM |
| Parameters | ~8B |
| Precision | bfloat16 |
| Max Position Embeddings | 40960 |
| Vocabulary Size | 151936 |
1@inproceedings{
2lai2026unirrm,
3title={Uni{RRM}: Unified Reasoning Reward Models Across Languages and Evaluation Paradigms},
4author={Peng Lai and Yichao Du and Junchao Wu and Weibo Gao and Linan Yue and Longyue Wang and Weihua Luo and Derek F. Wong and Guanhua Chen},
5booktitle={Forty-third International Conference on Machine Learning},
6year={2026},
7url={https://openreview.net/forum?id=laiK6TlhL2}
8}