Skip to content

Commit 9d1c79f

Browse files
authored
[Fix] Fix BBH freeform answer evaluation (#2548)
1 parent 1c386fe commit 9d1c79f

2 files changed

Lines changed: 70 additions & 4 deletions

File tree

opencompass/datasets/bbh.py

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,17 +47,29 @@ def bbh_mcq_postprocess(text: str) -> str:
4747
@TEXT_POSTPROCESSORS.register_module('bbh-freeform')
4848
def bbh_freeform_postprocess(text: str) -> str:
4949
ans = text
50-
ans_line = ans.split('answer is ')
50+
ans_line = re.split(r'answer is\s*:?\s*', ans, flags=re.IGNORECASE)
5151
if len(ans_line) != 1:
52-
ans = ans_line[1].strip()
52+
ans = ans_line[-1].strip()
5353
ans = ans.split('\n')[0].strip()
5454

5555
if ans.endswith('.'):
5656
ans = ans[:-1].strip()
5757

5858
match = re.search(r'\*\*(.*?)\*\*', ans)
5959
if match:
60-
return match.group(1)
60+
ans = match.group(1).strip()
61+
62+
match = re.match(r'^(yes|no)\b', ans, flags=re.IGNORECASE)
63+
if match:
64+
return match.group(1).capitalize()
65+
66+
match = re.match(r'^(true|false)\b', ans, flags=re.IGNORECASE)
67+
if match:
68+
return match.group(1).capitalize()
69+
70+
if not re.search(r'\d\s*,\s*\d', ans):
71+
ans = re.sub(r'\s*,\s*', ' ', ans)
72+
ans = re.sub(r'\s+', ' ', ans).strip()
6173

6274
return ans
6375

@@ -73,12 +85,13 @@ def score(self, predictions, references):
7385
}
7486

7587
predictions = [bbh_freeform_postprocess(pred) for pred in predictions]
88+
references = [bbh_freeform_postprocess(ref) for ref in references]
7689

7790
details = []
7891
cnt = 0
7992
for pred, ref in zip(predictions, references):
8093
detail = {'pred': pred, 'answer': ref, 'correct': False}
81-
if pred == ref:
94+
if pred.casefold() == ref.casefold():
8295
cnt += 1
8396
detail['correct'] = True
8497
details.append(detail)

tests/datasets/test_bbh.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import unittest
2+
3+
from opencompass.datasets.bbh import BBHEvaluator, bbh_freeform_postprocess
4+
5+
6+
class TestBBHFreeform(unittest.TestCase):
7+
8+
def test_freeform_postprocess_extracts_short_answers(self):
9+
self.assertEqual(bbh_freeform_postprocess('no'), 'No')
10+
self.assertEqual(
11+
bbh_freeform_postprocess(
12+
'So the answer is No, because the last speaker lies.'),
13+
'No',
14+
)
15+
self.assertEqual(bbh_freeform_postprocess('Answer is **yes**.'),
16+
'Yes')
17+
18+
def test_freeform_postprocess_normalizes_word_sorting_commas(self):
19+
self.assertEqual(
20+
bbh_freeform_postprocess('apple, banana, cherry'),
21+
'apple banana cherry',
22+
)
23+
self.assertEqual(bbh_freeform_postprocess('1,000'), '1,000')
24+
25+
def test_freeform_evaluator_accepts_equivalent_formats(self):
26+
result = BBHEvaluator().score(
27+
predictions=[
28+
'no',
29+
'No, because the last speaker lies.',
30+
'apple, banana, cherry',
31+
],
32+
references=[
33+
'No',
34+
'No',
35+
'apple banana cherry',
36+
],
37+
)
38+
39+
self.assertEqual(result['score'], 100.0)
40+
self.assertTrue(all(item['correct'] for item in result['details']))
41+
42+
def test_freeform_evaluator_rejects_wrong_word_order(self):
43+
result = BBHEvaluator().score(
44+
predictions=['apple, cherry, banana'],
45+
references=['apple banana cherry'],
46+
)
47+
48+
self.assertEqual(result['score'], 0.0)
49+
self.assertFalse(result['details'][0]['correct'])
50+
51+
52+
if __name__ == '__main__':
53+
unittest.main()

0 commit comments

Comments
 (0)