Skip to content

Commit 3ce3c94

Browse files
committed
[Bugfix] Add pred and choices parsing to fix the issue of score=0 for mmstar datasets
1 parent 9c023bc commit 3ce3c94

4 files changed

Lines changed: 95 additions & 55 deletions

File tree

.gitignore

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,9 @@ __pycache__
55
test_reports
66
.venv
77
.eggs
8-
ais_bench_benchmark.egg-info
8+
ais_bench_benchmark.egg-info
9+
10+
ais_bench/datasets/**/*/*
11+
!ais_bench/datasets/**/*/*.py
12+
outputs
13+
tmp

ais_bench/benchmark/configs/datasets/mmstar/mmstar_gen.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from ais_bench.benchmark.openicl.icl_retriever import ZeroRetriever
33
from ais_bench.benchmark.openicl.icl_inferencer import GenInferencer
44
from ais_bench.benchmark.datasets import MMStarDataset, MMStarEvaluator
5+
from ais_bench.benchmark.utils.postprocess.text_postprocessors import last_option_postprocess
56

67

78
mmstar_reader_cfg = dict(
@@ -26,7 +27,8 @@
2627
)
2728

2829
mmstar_eval_cfg = dict(
29-
evaluator=dict(type=MMStarEvaluator)
30+
evaluator=dict(type=MMStarEvaluator),
31+
pred_postprocessor=dict(type=last_option_postprocess, options="ABCD"),
3032
)
3133

3234
mmstar_datasets = [

ais_bench/benchmark/configs/datasets/mmstar/mmstar_gen_cot.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from ais_bench.benchmark.openicl.icl_retriever import ZeroRetriever
33
from ais_bench.benchmark.openicl.icl_inferencer import GenInferencer
44
from ais_bench.benchmark.datasets import MMStarDataset, MMStarEvaluator
5+
from ais_bench.benchmark.utils.postprocess.text_postprocessors import last_option_postprocess
56

67

78
mmstar_reader_cfg = dict(
@@ -29,7 +30,8 @@
2930
)
3031

3132
mmstar_eval_cfg = dict(
32-
evaluator=dict(type=MMStarEvaluator)
33+
evaluator=dict(type=MMStarEvaluator),
34+
pred_postprocessor=dict(type=last_option_postprocess, options="ABCD"),
3335
)
3436

3537
mmstar_datasets = [

ais_bench/benchmark/datasets/mmstar.py

Lines changed: 83 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,76 @@
11
import json
22
import os
3+
import re
34
import string
4-
import pandas as pd
5-
import numpy as np
65

6+
import numpy as np
7+
import pandas as pd
78
from datasets import Dataset, DatasetDict
89

10+
from ais_bench.benchmark.datasets import build_choices, can_infer, dump_image, split_MMMU
11+
from ais_bench.benchmark.datasets.utils.datasets import get_data_path, toliststr
912
from ais_bench.benchmark.openicl import BaseEvaluator
1013
from ais_bench.benchmark.registry import LOAD_DATASET
11-
from ais_bench.benchmark.datasets.utils.datasets import get_data_path, toliststr
1214
from ais_bench.benchmark.utils.logging import AISLogger
13-
from ais_bench.benchmark.datasets import dump_image, split_MMMU, build_choices, can_infer
14-
from ais_bench.benchmark.utils.prompt import AIS_CONTENT_TAG, AIS_TEXT_START, AIS_IMAGE_START
15+
from ais_bench.benchmark.utils.prompt import AIS_CONTENT_TAG, AIS_IMAGE_START, AIS_TEXT_START
1516

1617
from .base import BaseDataset
1718

1819
IMAGE_MAP_LEN = 64
1920
logger = AISLogger()
2021

22+
23+
def extract_options_from_question(question_text):
24+
options = {}
25+
26+
# 查找"Options:"部分
27+
if "Options:" in question_text:
28+
# 获取Options部分
29+
options_part = question_text.split("Options:")[1].strip()
30+
31+
# 使用正则表达式匹配所有A-Z的选项
32+
pattern = r"([A-Z]):\s*([^,]+(?:,\s*[^,]+)*?)(?=(?:,\s*[A-Z]:|$))"
33+
34+
matches = re.findall(pattern, options_part)
35+
for letter, content in matches:
36+
# 清理内容:移除末尾的句点(如果存在)
37+
content = content.strip()
38+
if content.endswith("."):
39+
content = content[:-1]
40+
options[letter] = content
41+
42+
return options
43+
44+
2145
@LOAD_DATASET.register_module()
2246
class MMStarDataset(BaseDataset):
23-
2447
@staticmethod
2548
def load(path):
2649
path = get_data_path(path)
2750
image_root_path = os.path.join(os.path.dirname(path), "MMStar_images")
2851
logger.info(f"Convert base64 to image and save it in {image_root_path}")
2952
skip_noimg = True
30-
31-
data = pd.read_csv(path, sep='\t')
32-
if skip_noimg and 'image' in data:
33-
data = data[~pd.isna(data['image'])]
53+
54+
data = pd.read_csv(path, sep="\t")
55+
if skip_noimg and "image" in data:
56+
data = data[~pd.isna(data["image"])]
3457
# The image field can store the base64 encoded image or another question index (for saving space)
35-
if 'image' in data:
36-
data['image'] = [str(x) for x in data['image']]
37-
image_map = {x: y for x, y in zip(data['index'], data['image'])}
58+
if "image" in data:
59+
data["image"] = [str(x) for x in data["image"]]
60+
image_map = {x: y for x, y in zip(data["index"], data["image"])}
3861
for k in image_map:
3962
if len(image_map[k]) <= IMAGE_MAP_LEN:
4063
idx = image_map[k]
4164
image_map[k] = image_map[idx]
4265

43-
images = [toliststr(image_map[k]) for k in data['index']]
44-
data['image'] = [x[0] if len(x) == 1 else x for x in images]
45-
if 'image_path' in data:
46-
paths = [toliststr(x) for x in data['image_path']]
47-
data['image_path'] = [x[0] if len(x) == 1 else x for x in paths]
66+
images = [toliststr(image_map[k]) for k in data["index"]]
67+
data["image"] = [x[0] if len(x) == 1 else x for x in images]
68+
if "image_path" in data:
69+
paths = [toliststr(x) for x in data["image_path"]]
70+
data["image_path"] = [x[0] if len(x) == 1 else x for x in paths]
4871

49-
if np.all([isinstance(x, int) for x in data['index']]):
50-
data['index'] = [int(x) for x in data['index']]
72+
if np.all([isinstance(x, int) for x in data["index"]]):
73+
data["index"] = [int(x) for x in data["index"]]
5174

5275
sheet_indices = list(range(0, len(data), 1))
5376
data = data.iloc[sheet_indices]
@@ -61,59 +84,67 @@ def load(path):
6184
for cand in string.ascii_uppercase
6285
if cand in line and not pd.isna(line[cand])
6386
}
64-
options_prompt = 'Options:\n'
87+
options_prompt = "Options:\n"
6588
for key, item in options.items():
66-
options_prompt += f'{key}. {item}\n'
67-
68-
hint = line['hint'] if ('hint' in line and not pd.isna(line['hint'])) else None
69-
# get text prompt
70-
prompt = ''
89+
options_prompt += f"{key}. {item}\n"
90+
91+
hint = line["hint"] if ("hint" in line and not pd.isna(line["hint"])) else None
92+
# get text prompt
93+
prompt = ""
7194
if hint is not None:
72-
prompt += f'Hint: {hint}\n'
95+
prompt += f"Hint: {hint}\n"
7396
prompt += line["question"]
7497
if len(options):
7598
prompt += options_prompt
76-
prompt += 'Please select the correct answer from the options above. \n'
99+
prompt += "Please select the correct answer from the options above. \n"
77100
# add image info
78101
if isinstance(tgt_path, list):
79102
tgt_path = tgt_path[0]
80-
81-
content = AIS_IMAGE_START + tgt_path + AIS_CONTENT_TAG \
82-
+ AIS_TEXT_START + prompt + AIS_CONTENT_TAG
83-
choices = build_choices(line)
84-
dataset.append({"content": content,
85-
"answer": {'choices': json.dumps(choices),
86-
'answer': line['answer'],
87-
'split': line.get('split'),
88-
'l2-category': line.get('l2-category'),
89-
'category': line.get('category')}})
103+
104+
content = (
105+
AIS_IMAGE_START
106+
+ tgt_path
107+
+ AIS_CONTENT_TAG
108+
+ AIS_TEXT_START
109+
+ prompt
110+
+ AIS_CONTENT_TAG
111+
)
112+
choices = build_choices(extract_options_from_question(line['question']))
113+
dataset.append(
114+
{
115+
"content": content,
116+
"answer": {
117+
"choices": json.dumps(choices),
118+
"answer": line["answer"],
119+
"split": line.get("split"),
120+
"l2-category": line.get("l2-category"),
121+
"category": line.get("category"),
122+
},
123+
}
124+
)
90125
return Dataset.from_list(dataset)
91126

92-
class MMStarEvaluator(BaseEvaluator):
93127

128+
class MMStarEvaluator(BaseEvaluator):
94129
def score(self, predictions, references):
95130
result = {}
96131
if len(predictions) != len(references):
97-
return {
98-
'error': 'predictions and references have different '
99-
'length'
100-
}
132+
return {"error": "predictions and references have different length"}
101133
details = []
102-
overall_key = 'Overall'
134+
overall_key = "Overall"
103135
for pred, refer in zip(predictions, references):
104-
detail = {'pred': pred, 'answer': refer, 'correct': False}
105-
choices = json.loads(refer['choices'])
136+
detail = {"pred": pred, "answer": refer, "correct": False}
137+
choices = json.loads(refer["choices"])
106138
infer_res = can_infer(pred, choices)
107-
108-
key_category = refer['category']
109-
score = 1 if infer_res == refer['answer'] else 0
139+
140+
key_category = refer["category"]
141+
score = 1 if infer_res == refer["answer"] else 0
110142
if score == 1:
111-
detail['correct'] = True
143+
detail["correct"] = True
112144
details.append(detail)
113145
result.setdefault(overall_key, []).append(score)
114146
result.setdefault(key_category, []).append(score)
115147
for key in result:
116148
result[key] = 100 * sum(result[key]) / len(result[key])
117-
result['details'] = details
149+
result["details"] = details
118150
return result
119-

0 commit comments

Comments
 (0)