| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| import re |
| from typing import Any, Dict |
|
|
| from mathruler.grader import grade_answer |
|
|
|
|
| def format_reward(response: str) -> float: |
| pattern = re.compile(r"<think>.*?</think>\s*<answer>.*?</answer>", re.DOTALL) |
| format_match = re.fullmatch(pattern, response) |
| return 1.0 if format_match else 0.0 |
|
|
|
|
| def accuracy_reward(response: str, ground_truth: str) -> float: |
| try: |
| content_match = re.search(r"<answer>(.*?)</answer>", response) |
| given_answer = content_match.group(1).strip() if content_match else response.strip() |
| if grade_answer(given_answer, ground_truth.strip()): |
| return 1.0 |
|
|
| except Exception: |
| pass |
|
|
| return 0.0 |
|
|
|
|
| def compute_score(reward_input: Dict[str, Any], format_weight: float = 0.5) -> Dict[str, float]: |
| if not isinstance(reward_input, dict): |
| raise ValueError("Please use `reward_type=sequential` for r1v reward function.") |
|
|
| format_score = format_reward(reward_input["response"]) |
| accuracy_score = accuracy_reward(reward_input["response"], reward_input["ground_truth"]) |
| return { |
| "overall": (1 - format_weight) * accuracy_score + format_weight * format_score, |
| "format": format_score, |
| "accuracy": accuracy_score, |
| } |
|
|