diff --git a/nemo_skills/evaluation/math_grader.py b/nemo_skills/evaluation/math_grader.py index 77c7e26e7e..dd75529c4b 100644 --- a/nemo_skills/evaluation/math_grader.py +++ b/nemo_skills/evaluation/math_grader.py @@ -65,17 +65,24 @@ def math_equal(gt_answer, predicted_answer, take_modulo: int | None = None, **kw gt_answer = _additional_normalization(gt_answer) predicted_answer = _additional_normalization(predicted_answer) - # Try literal comparison - literal_pattern = r"[a-zA-Z ,]+|[0-9 ]+" normalized_gt = normalize_latex(gt_answer, NormalizationConfig) normalized_pred = normalize_latex(predicted_answer, NormalizationConfig) - is_literal = re.fullmatch(literal_pattern, normalized_gt) and re.fullmatch(literal_pattern, normalized_pred) is_normalized_equal = normalized_gt.replace(" ", "") == normalized_pred.replace(" ", "") - if is_literal or is_normalized_equal: - return is_normalized_equal + # Fast path: if normalized strings are equal, no need for symbolic comparison + if is_normalized_equal: + return True - # Fallback to symbolic comparison + # For TEXT literals (not numeric), use direct string comparison + text_literal_pattern = r"[a-zA-Z ,]+" + is_text_literal = re.fullmatch(text_literal_pattern, normalized_gt) and re.fullmatch( + text_literal_pattern, normalized_pred + ) + if is_text_literal: + return False # Already checked is_normalized_equal above + + # Fallback to symbolic comparison via math_verify + # This handles leading zeros ("016" == "16"), fractions, expressions, etc. current_gt_answer = gt_answer current_predicted_answer = predicted_answer diff --git a/tests/test_math_equal.py b/tests/test_math_equal.py index 9d773463db..972861df9c 100644 --- a/tests/test_math_equal.py +++ b/tests/test_math_equal.py @@ -34,6 +34,8 @@ ("185", "185\\"), ("185\\", "185\\"), (".185", "0.185"), + ("016", "16"), # Leading zeros handled by math_verify + ("007", "7"), # Multiple leading zeros handled by math_verify ("\\frac {1}{2}", 0.5), ("17\\text{ any text}", "17"), ("\$10", "10"),