Add files using upload-large-folder tool
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- LaViDa/eval/lmms_eval/tasks/ai2d/ai2d_no_mask.yaml +55 -0
- LaViDa/eval/lmms_eval/tasks/ai2d/upload_ai2d.py +117 -0
- LaViDa/eval/lmms_eval/tasks/ai2d/utils.py +80 -0
- LaViDa/eval/lmms_eval/tasks/cmmmu/_cmmmu.yaml +4 -0
- LaViDa/eval/lmms_eval/tasks/cmmmu/_default_template_cmmmu_yaml +8 -0
- LaViDa/eval/lmms_eval/tasks/cmmmu/cmmmu_test.yaml +12 -0
- LaViDa/eval/lmms_eval/tasks/cmmmu/cmmmu_val.yaml +15 -0
- LaViDa/eval/lmms_eval/tasks/cmmmu/utils.py +420 -0
- LaViDa/eval/lmms_eval/tasks/hrbench/hrbench.yaml +8 -0
- LaViDa/eval/lmms_eval/tasks/hrbench/hrbench4k.yaml +23 -0
- LaViDa/eval/lmms_eval/tasks/hrbench/hrbench8k.yaml +23 -0
- LaViDa/eval/lmms_eval/tasks/hrbench/hrbench_evals.py +153 -0
- LaViDa/eval/lmms_eval/tasks/hrbench/utils.py +103 -0
- LaViDa/eval/lmms_eval/tasks/livexiv_vqa/livexiv_vqa.yaml +9 -0
- LaViDa/eval/lmms_eval/tasks/livexiv_vqa/livexiv_vqa_template_yaml +26 -0
- LaViDa/eval/lmms_eval/tasks/livexiv_vqa/livexiv_vqa_v1.yaml +3 -0
- LaViDa/eval/lmms_eval/tasks/livexiv_vqa/livexiv_vqa_v2.yaml +3 -0
- LaViDa/eval/lmms_eval/tasks/livexiv_vqa/livexiv_vqa_v3.yaml +3 -0
- LaViDa/eval/lmms_eval/tasks/livexiv_vqa/livexiv_vqa_v4.yaml +3 -0
- LaViDa/eval/lmms_eval/tasks/livexiv_vqa/livexiv_vqa_v5.yaml +3 -0
- LaViDa/eval/lmms_eval/tasks/livexiv_vqa/livexiv_vqa_v6.yaml +3 -0
- LaViDa/eval/lmms_eval/tasks/livexiv_vqa/utils.py +74 -0
- LaViDa/eval/lmms_eval/tasks/mlvu/mlvu_dev.yaml +27 -0
- LaViDa/eval/lmms_eval/tasks/mlvu/mlvu_test.yaml +27 -0
- LaViDa/eval/lmms_eval/tasks/mlvu/utils.py +181 -0
- LaViDa/eval/lmms_eval/tasks/mmlu/default/_default_template_yaml +17 -0
- LaViDa/eval/lmms_eval/tasks/mmlu/default/_mmlu.yaml +11 -0
- LaViDa/eval/lmms_eval/tasks/mmlu/default/_mmlu_humanities.yaml +9 -0
- LaViDa/eval/lmms_eval/tasks/mmlu/default/_mmlu_other.yaml +9 -0
- LaViDa/eval/lmms_eval/tasks/mmlu/default/_mmlu_social_sciences.yaml +9 -0
- LaViDa/eval/lmms_eval/tasks/mmlu/default/_mmlu_stem.yaml +9 -0
- LaViDa/eval/lmms_eval/tasks/mmlu/default/mmlu_abstract_algebra.yaml +7 -0
- LaViDa/eval/lmms_eval/tasks/mmlu/default/mmlu_anatomy.yaml +7 -0
- LaViDa/eval/lmms_eval/tasks/mmlu/default/mmlu_astronomy.yaml +7 -0
- LaViDa/eval/lmms_eval/tasks/mmlu/default/mmlu_business_ethics.yaml +7 -0
- LaViDa/eval/lmms_eval/tasks/mmlu/default/mmlu_clinical_knowledge.yaml +7 -0
- LaViDa/eval/lmms_eval/tasks/mmlu/default/mmlu_college_biology.yaml +7 -0
- LaViDa/eval/lmms_eval/tasks/mmlu/default/mmlu_college_chemistry.yaml +7 -0
- LaViDa/eval/lmms_eval/tasks/mmlu/default/mmlu_college_computer_science.yaml +7 -0
- LaViDa/eval/lmms_eval/tasks/mmlu/default/mmlu_college_mathematics.yaml +7 -0
- LaViDa/eval/lmms_eval/tasks/mmlu/default/mmlu_college_medicine.yaml +7 -0
- LaViDa/eval/lmms_eval/tasks/mmlu/default/mmlu_college_physics.yaml +7 -0
- LaViDa/eval/lmms_eval/tasks/mmlu/default/mmlu_computer_security.yaml +7 -0
- LaViDa/eval/lmms_eval/tasks/mmlu/default/mmlu_conceptual_physics.yaml +7 -0
- LaViDa/eval/lmms_eval/tasks/mmlu/default/mmlu_econometrics.yaml +7 -0
- LaViDa/eval/lmms_eval/tasks/mmlu/default/mmlu_electrical_engineering.yaml +7 -0
- LaViDa/eval/lmms_eval/tasks/mmlu/default/mmlu_elementary_mathematics.yaml +7 -0
- LaViDa/eval/lmms_eval/tasks/mmlu/default/mmlu_formal_logic.yaml +7 -0
- LaViDa/eval/lmms_eval/tasks/mmlu/default/mmlu_global_facts.yaml +7 -0
- LaViDa/eval/lmms_eval/tasks/mmlu/default/mmlu_high_school_biology.yaml +7 -0
LaViDa/eval/lmms_eval/tasks/ai2d/ai2d_no_mask.yaml
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
dataset_path: Efficient-Large-Model/ai2d-no-mask
|
| 2 |
+
task: "ai2d_no_mask"
|
| 3 |
+
dataset_kwargs:
|
| 4 |
+
token: True
|
| 5 |
+
test_split: test
|
| 6 |
+
output_type: generate_until
|
| 7 |
+
doc_to_visual: !function utils.ai2d_doc_to_visual
|
| 8 |
+
doc_to_text: !function utils.ai2d_doc_to_text
|
| 9 |
+
doc_to_target: !function utils.ai2d_doc_to_target
|
| 10 |
+
|
| 11 |
+
lmms_eval_specific_kwargs:
|
| 12 |
+
default:
|
| 13 |
+
prompt_format: mcq
|
| 14 |
+
pre_prompt: ""
|
| 15 |
+
post_prompt: "\nAnswer with the option's letter from the given choices directly."
|
| 16 |
+
gpt4v:
|
| 17 |
+
prompt_format: mcq
|
| 18 |
+
pre_prompt: ""
|
| 19 |
+
post_prompt: "\nAbove choices are given in {option}. {content} format.\nPlease answer with the option letter from the given choices directly."
|
| 20 |
+
qwen_vl:
|
| 21 |
+
prompt_format: qa
|
| 22 |
+
pre_prompt: ""
|
| 23 |
+
post_prompt: " Answer:"
|
| 24 |
+
xcomposer2_4khd:
|
| 25 |
+
prompt_format: mcq_xcomposer
|
| 26 |
+
pre_prompt: "[UNUSED_TOKEN_146]user\nQuestion: "
|
| 27 |
+
post_prompt: "[UNUSED_TOKEN_145]\n[UNUSED_TOKEN_146]assistant\nThe answer is"
|
| 28 |
+
|
| 29 |
+
model_specific_target_kwargs:
|
| 30 |
+
default: "mcq"
|
| 31 |
+
qwen_vl: "qa"
|
| 32 |
+
|
| 33 |
+
generation_kwargs:
|
| 34 |
+
max_new_tokens: 16
|
| 35 |
+
temperature: 0
|
| 36 |
+
do_sample: False
|
| 37 |
+
|
| 38 |
+
filter_list:
|
| 39 |
+
- name: "flexible-extract"
|
| 40 |
+
filter:
|
| 41 |
+
- function: !function utils.MultiChoiceRegexFilter
|
| 42 |
+
group_select: 0
|
| 43 |
+
ignore_case: true
|
| 44 |
+
ignore_punctuation: true
|
| 45 |
+
regex_pattern: "([A-Z])\\."
|
| 46 |
+
|
| 47 |
+
metric_list:
|
| 48 |
+
- metric: exact_match
|
| 49 |
+
aggregation: mean
|
| 50 |
+
higher_is_better: true
|
| 51 |
+
ignore_case: true
|
| 52 |
+
ignore_punctuation: true
|
| 53 |
+
|
| 54 |
+
metadata:
|
| 55 |
+
- version: 0.0
|
LaViDa/eval/lmms_eval/tasks/ai2d/upload_ai2d.py
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2020 The HuggingFace Datasets Authors and the current dataset script contributor.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
import json
|
| 17 |
+
import os
|
| 18 |
+
|
| 19 |
+
import datasets
|
| 20 |
+
from PIL import Image
|
| 21 |
+
|
| 22 |
+
# Find for instance the citation on arxiv or on the dataset repo/website
|
| 23 |
+
_CITATION = """https://allenai.org/data/diagrams"""
|
| 24 |
+
_DESCRIPTION = "AI2D is a dataset of illustrative diagrams for research on diagram understanding and associated question answering."
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
def get_builder_config(VERSION):
|
| 28 |
+
builder_config = [
|
| 29 |
+
datasets.BuilderConfig(
|
| 30 |
+
name=f"ai2d",
|
| 31 |
+
version=VERSION,
|
| 32 |
+
description=f"ai2d",
|
| 33 |
+
)
|
| 34 |
+
]
|
| 35 |
+
return builder_config
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
dataset_features = {
|
| 39 |
+
"question": datasets.Value("string"),
|
| 40 |
+
"options": datasets.features.Sequence(datasets.Value("string")),
|
| 41 |
+
"answer": datasets.Value("string"),
|
| 42 |
+
"image": datasets.Image(),
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
class AI2D(datasets.GeneratorBasedBuilder):
|
| 47 |
+
VERSION = datasets.Version("1.0.0")
|
| 48 |
+
|
| 49 |
+
BUILDER_CONFIGS = get_builder_config(VERSION)
|
| 50 |
+
|
| 51 |
+
def _info(self):
|
| 52 |
+
features = datasets.Features(dataset_features)
|
| 53 |
+
return datasets.DatasetInfo(
|
| 54 |
+
# This is the description that will appear on the datasets page.
|
| 55 |
+
description=_DESCRIPTION,
|
| 56 |
+
# This defines the different columns of the dataset and their types
|
| 57 |
+
features=features, # Here we define them above because they are different between the two configurations
|
| 58 |
+
# If there's a common (input, target) tuple from the features, uncomment supervised_keys line below and
|
| 59 |
+
# specify them. They'll be used if as_supervised=True in builder.as_dataset.
|
| 60 |
+
# supervised_keys=("sentence", "label"),
|
| 61 |
+
# Homepage of the dataset for documentation
|
| 62 |
+
# Citation for the dataset
|
| 63 |
+
citation=_CITATION,
|
| 64 |
+
)
|
| 65 |
+
|
| 66 |
+
def _split_generators(self, dl_manager):
|
| 67 |
+
# If several configurations are possible (listed in BUILDER_CONFIGS), the configuration selected by the user is in self.config.name
|
| 68 |
+
|
| 69 |
+
# dl_manager is a datasets.download.DownloadManager that can be used to download and extract URLS
|
| 70 |
+
# It can accept any type or nested list/dict and will give back the same structure with the url replaced with path to local files.
|
| 71 |
+
# By default the archives will be extracted and a path to a cached folder where they are extracted is returned instead of the archive
|
| 72 |
+
image_path = "/path/to/ai2d/images"
|
| 73 |
+
annotation_path = "/path/to/ai2d/questions"
|
| 74 |
+
# wget https://ofasys-wlcb.oss-cn-wulanchabu.aliyuncs.com/Qwen-VL/evaluation/ai2diagram/test.jsonl
|
| 75 |
+
test_annotation_path = "/path/to/Qwen-VL/data/ai2diagram/test.jsonl"
|
| 76 |
+
return [
|
| 77 |
+
datasets.SplitGenerator(
|
| 78 |
+
name=datasets.Split.TEST,
|
| 79 |
+
gen_kwargs={"annotation": annotation_path, "images": image_path, "test_annotation": test_annotation_path},
|
| 80 |
+
),
|
| 81 |
+
]
|
| 82 |
+
|
| 83 |
+
# method parameters are unpacked from `gen_kwargs` as given in `_split_generators`
|
| 84 |
+
def _generate_examples(self, annotation, images, test_annotation):
|
| 85 |
+
# open test_annotation jsonl (note; not a json)
|
| 86 |
+
with open(test_annotation, encoding="utf-8") as f:
|
| 87 |
+
test_annotation = [json.loads(line) for line in f]
|
| 88 |
+
test_qn_ids = {x["question_id"] for x in test_annotation}
|
| 89 |
+
index = -1
|
| 90 |
+
# The `key` is for legacy reasons (tfds) and is not important in itself, but must be unique for each example.
|
| 91 |
+
for sub_annotation in os.listdir(annotation):
|
| 92 |
+
sub_annotation = os.path.join(annotation, sub_annotation)
|
| 93 |
+
with open(sub_annotation, encoding="utf-8") as f:
|
| 94 |
+
data = json.load(f)
|
| 95 |
+
image = data["imageName"]
|
| 96 |
+
image_path = os.path.join(images, image)
|
| 97 |
+
for question in data["questions"]:
|
| 98 |
+
if data["questions"]["questionId"] in test_qn_ids:
|
| 99 |
+
index += 1
|
| 100 |
+
options = data["questions"][question]["answerTexts"]
|
| 101 |
+
answer = data["questions"][question]["correctAnswer"]
|
| 102 |
+
|
| 103 |
+
now_data = {}
|
| 104 |
+
now_data["image"] = Image.open(image_path)
|
| 105 |
+
now_data["question"] = question
|
| 106 |
+
now_data["answer"] = answer
|
| 107 |
+
now_data["options"] = options
|
| 108 |
+
yield index, now_data
|
| 109 |
+
|
| 110 |
+
|
| 111 |
+
if __name__ == "__main__":
|
| 112 |
+
from datasets import load_dataset
|
| 113 |
+
|
| 114 |
+
data = load_dataset(
|
| 115 |
+
"/path/to/lmms-eval/lmms_eval/tasks/ai2d/upload_ai2d.py",
|
| 116 |
+
)
|
| 117 |
+
data.push_to_hub("lmms-lab/ai2d", private=True)
|
LaViDa/eval/lmms_eval/tasks/ai2d/utils.py
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import re
|
| 2 |
+
|
| 3 |
+
from lmms_eval.filters.extraction import ExtendedRegexFilter
|
| 4 |
+
from lmms_eval.filters.transformation import MapFilter
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
def ai2d_doc_to_text(doc, lmms_eval_specific_kwargs=None):
|
| 8 |
+
question, choices = doc["question"], doc["options"]
|
| 9 |
+
len_choices = len(choices)
|
| 10 |
+
post_prompt = lmms_eval_specific_kwargs["post_prompt"]
|
| 11 |
+
pre_prompt = lmms_eval_specific_kwargs["pre_prompt"]
|
| 12 |
+
if lmms_eval_specific_kwargs["prompt_format"] == "mcq":
|
| 13 |
+
options = [chr(ord("A") + i) for i in range(len_choices)]
|
| 14 |
+
choices_str = "\n".join([f"{option}. {choice}" for option, choice in zip(options, choices)])
|
| 15 |
+
return f"{pre_prompt}{question}\n{choices_str}{post_prompt}"
|
| 16 |
+
elif lmms_eval_specific_kwargs["prompt_format"] == "qa":
|
| 17 |
+
options = "\n".join(choices)
|
| 18 |
+
return f"{pre_prompt}{question}{options}{post_prompt}"
|
| 19 |
+
elif lmms_eval_specific_kwargs["prompt_format"] == "mcq_xcomposer":
|
| 20 |
+
options = [chr(ord("A") + i) for i in range(len_choices)]
|
| 21 |
+
choices_str = " ".join([f"{option}. {choice}" for option, choice in zip(options, choices)])
|
| 22 |
+
return f"{pre_prompt}{question}\nContext: N/A\n{choices_str}{post_prompt}"
|
| 23 |
+
else:
|
| 24 |
+
raise ValueError(f"Unknown prompt format: {lmms_eval_specific_kwargs['prompt_format']}")
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
def ai2d_doc_to_visual(doc):
|
| 28 |
+
return [doc["image"].convert("RGB")]
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
def ai2d_doc_to_target(doc, model_specific_target_kwargs):
|
| 32 |
+
if model_specific_target_kwargs == "mcq":
|
| 33 |
+
len_choices = len(doc["options"])
|
| 34 |
+
options = [chr(ord("A") + i) for i in range(len_choices)]
|
| 35 |
+
return options[int(doc["answer"])]
|
| 36 |
+
elif model_specific_target_kwargs == "qa":
|
| 37 |
+
return doc["options"][int(doc["answer"])]
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
class MultiChoiceRegexFilter(ExtendedRegexFilter):
|
| 41 |
+
def __init__(self, *args, **kwargs):
|
| 42 |
+
"""
|
| 43 |
+
regex_pattern: The basic regex pattern to use. If fails to match, we will use the customized match procedure
|
| 44 |
+
- step 1 : We parse the choices between ([A-Z])s then try to find these choices in the response.
|
| 45 |
+
- step 2 : We parse the choice with regex :[\s]*([A-?]), where ? varies by number of choices.
|
| 46 |
+
group_select: Selects the (group_select)th match from the findall result.
|
| 47 |
+
ignore_case: Ignores the case during step 1 matching
|
| 48 |
+
ignore_punctuation: Remove the punctuation during step 1 matching
|
| 49 |
+
regexes_to_ignore: Remove these regexes during step 1 matching
|
| 50 |
+
"""
|
| 51 |
+
super().__init__(*args, **kwargs)
|
| 52 |
+
|
| 53 |
+
def apply(self, resps, docs):
|
| 54 |
+
# here, we assume we have a list, in which each element is
|
| 55 |
+
# a list of model responses for some particular input/target pair.
|
| 56 |
+
# so we process each of these (same input/target response sets)
|
| 57 |
+
# independently (and keep them a list.)
|
| 58 |
+
|
| 59 |
+
filtered_resps = []
|
| 60 |
+
|
| 61 |
+
for r, doc in zip(resps, docs):
|
| 62 |
+
# Regex to directly extract the option letter from the model response
|
| 63 |
+
option_letter_regex = re.compile(r"^\s*([A-Z])\.")
|
| 64 |
+
|
| 65 |
+
# Process each response
|
| 66 |
+
filtered = []
|
| 67 |
+
for resp in r:
|
| 68 |
+
# Try to match the option letter at the start of the response
|
| 69 |
+
match = option_letter_regex.match(resp)
|
| 70 |
+
if match:
|
| 71 |
+
# If a match is found, append the matched letter
|
| 72 |
+
filtered.append(match.group(1))
|
| 73 |
+
else:
|
| 74 |
+
# If no match, return the original response
|
| 75 |
+
filtered.append(resp)
|
| 76 |
+
|
| 77 |
+
# Assuming we need the first response that matches or the original response
|
| 78 |
+
filtered_resps.append(filtered[0])
|
| 79 |
+
|
| 80 |
+
return filtered_resps
|
LaViDa/eval/lmms_eval/tasks/cmmmu/_cmmmu.yaml
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
group: cmmmu
|
| 2 |
+
task:
|
| 3 |
+
- cmmmu_val
|
| 4 |
+
- cmmmu_test
|
LaViDa/eval/lmms_eval/tasks/cmmmu/_default_template_cmmmu_yaml
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
dataset_path: lmms-lab/CMMMU
|
| 2 |
+
output_type: generate_until
|
| 3 |
+
doc_to_visual: !function utils.cmmmu_doc_to_visual
|
| 4 |
+
doc_to_text: !function utils.cmmmu_doc_to_text
|
| 5 |
+
doc_to_target: "answer"
|
| 6 |
+
generation_kwargs:
|
| 7 |
+
max_new_tokens: 16
|
| 8 |
+
image_aspect_ratio: original
|
LaViDa/eval/lmms_eval/tasks/cmmmu/cmmmu_test.yaml
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
task: "cmmmu_test"
|
| 2 |
+
test_split: test
|
| 3 |
+
# The return value of process_results will be used by metrics
|
| 4 |
+
process_results: !function utils.cmmmu_process_test_results_for_submission
|
| 5 |
+
# Note that the metric name can be either a registed metric function (such as the case for GQA) or a key name returned by process_results
|
| 6 |
+
metric_list:
|
| 7 |
+
- metric: submission
|
| 8 |
+
aggregation: !function utils.cmmmu_test_aggregate_results_for_submission
|
| 9 |
+
higher_is_better: false
|
| 10 |
+
metadata:
|
| 11 |
+
- version: 0.0
|
| 12 |
+
include: _default_template_cmmmu_yaml
|
LaViDa/eval/lmms_eval/tasks/cmmmu/cmmmu_val.yaml
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
task: "cmmmu_val"
|
| 2 |
+
test_split: val
|
| 3 |
+
# The return value of process_results will be used by metrics
|
| 4 |
+
process_results: !function utils.cmmmu_process_results
|
| 5 |
+
# Note that the metric name can be either a registed metric function (such as the case for GQA) or a key name returned by process_results
|
| 6 |
+
generation_kwargs:
|
| 7 |
+
max_new_tokens: 16
|
| 8 |
+
image_aspect_ratio: original
|
| 9 |
+
metric_list:
|
| 10 |
+
- metric: cmmmu_acc
|
| 11 |
+
aggregation: !function utils.cmmmu_aggregate_results
|
| 12 |
+
higher_is_better: true
|
| 13 |
+
metadata:
|
| 14 |
+
- version: 0.0
|
| 15 |
+
include: _default_template_cmmmu_yaml
|
LaViDa/eval/lmms_eval/tasks/cmmmu/utils.py
ADDED
|
@@ -0,0 +1,420 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import json
|
| 2 |
+
import os
|
| 3 |
+
import random
|
| 4 |
+
import re
|
| 5 |
+
from collections import Counter, defaultdict
|
| 6 |
+
|
| 7 |
+
from loguru import logger as eval_logger
|
| 8 |
+
|
| 9 |
+
from lmms_eval.tasks._task_utils.file_utils import generate_submission_file
|
| 10 |
+
|
| 11 |
+
PROMPT = {
|
| 12 |
+
"task_instructions": [
|
| 13 |
+
"请回答以下多项选择题,并选出正确选项。这些题目可能包括单选和多选题型。如果所提供的信息不足以确定一个明确的答案,那么请根据可用的数据和你的判断来选择最可能正确的选项。",
|
| 14 |
+
"请回答以下判断题,并根据题目描述和所给的信息来判断问题中陈述的对错。如果信息不完整或不足以作出绝对判断,请运用你的逻辑推理和现有信息来做出最可能的判断。",
|
| 15 |
+
"请回答以下填空题,并根据题目的要求和所提供的信息来给出最恰当的答案。如果信息不足以确切回答,那么请依据现有的数据和你的推理能力来填写最合理的答案。",
|
| 16 |
+
],
|
| 17 |
+
"multi_choice_example_format": ["问题:{}\n选项:\n{}\n正确答案:\n"],
|
| 18 |
+
"T/F_example_format": ["问题:{}\n正确答案:\n"],
|
| 19 |
+
"short_ans_example_format": ["问题:{}\n正确答案:\n"],
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
def construct_prompt(sample):
|
| 24 |
+
question = sample["question"]
|
| 25 |
+
task_instructions = PROMPT["task_instructions"]
|
| 26 |
+
|
| 27 |
+
if sample["type"] == "选择":
|
| 28 |
+
formatted_options = ""
|
| 29 |
+
start_chr = "A"
|
| 30 |
+
for i in range(1, 5):
|
| 31 |
+
formatted_options += f"({start_chr}) {sample[f'option{i}']}\n"
|
| 32 |
+
start_chr = chr(ord(start_chr) + 1)
|
| 33 |
+
|
| 34 |
+
current_example_template = PROMPT["multi_choice_example_format"][0]
|
| 35 |
+
current_example = current_example_template.format(question, formatted_options)
|
| 36 |
+
final_input_prompt = task_instructions[0] + "\n\n" + current_example
|
| 37 |
+
|
| 38 |
+
elif sample["type"] == "判断":
|
| 39 |
+
current_example_template = PROMPT["T/F_example_format"][0]
|
| 40 |
+
current_example = current_example_template.format(question)
|
| 41 |
+
final_input_prompt = task_instructions[1] + "\n\n" + current_example
|
| 42 |
+
|
| 43 |
+
else: # For fill in the blanks questions.
|
| 44 |
+
current_example_template = PROMPT["short_ans_example_format"][0]
|
| 45 |
+
current_example = current_example_template.format(question)
|
| 46 |
+
final_input_prompt = task_instructions[2] + "\n\n" + current_example
|
| 47 |
+
|
| 48 |
+
for i in range(1, 6):
|
| 49 |
+
final_input_prompt = final_input_prompt.replace(f'<img="{sample[f"image_{i}_filename"]}">', f"<图片 {i}>")
|
| 50 |
+
|
| 51 |
+
return final_input_prompt
|
| 52 |
+
|
| 53 |
+
|
| 54 |
+
def cmmmu_doc_to_text(doc):
|
| 55 |
+
return construct_prompt(doc)
|
| 56 |
+
|
| 57 |
+
|
| 58 |
+
def cmmmu_doc_to_visual(doc):
|
| 59 |
+
prompt = construct_prompt(doc)
|
| 60 |
+
image_tokens = re.findall(r"<图片 \d+>", prompt)
|
| 61 |
+
# Remove <> and swap space as _
|
| 62 |
+
image_tokens = [image_token.strip("<>").replace(" ", "_").replace("图片", "image") for image_token in image_tokens]
|
| 63 |
+
visual = [doc[image_token].convert("RGB") for image_token in image_tokens]
|
| 64 |
+
return visual
|
| 65 |
+
|
| 66 |
+
|
| 67 |
+
def cmmmu_process_results(doc, results):
|
| 68 |
+
pred = results[0]
|
| 69 |
+
if doc["type"] == "选择":
|
| 70 |
+
index2ans, all_choices = get_multi_choice_info([doc[f"option{i}"] for i in range(1, 5)])
|
| 71 |
+
parsed_pred = get_multi_choice_prediction(pred, all_choices, index2ans)
|
| 72 |
+
elif doc["type"] == "判断":
|
| 73 |
+
parsed_pred = get_TF_prediction(pred)
|
| 74 |
+
else:
|
| 75 |
+
parsed_pred = get_fill_blank_prediction(pred, doc["answer"])
|
| 76 |
+
return {"cmmmu_acc": {"id": doc["id"], "subdomain": doc["subcategory"], "question_type": doc["type"], "answer": doc["answer"], "parsed_pred": parsed_pred}}
|
| 77 |
+
|
| 78 |
+
|
| 79 |
+
def cmmmu_aggregate_results(results):
|
| 80 |
+
evaluation_result = {}
|
| 81 |
+
subset_to_eval_samples = defaultdict(list)
|
| 82 |
+
for result in results:
|
| 83 |
+
subset_to_eval_samples[result["subdomain"]].append(result)
|
| 84 |
+
for subset, sub_eval_samples in subset_to_eval_samples.items():
|
| 85 |
+
metric_dict = eval_cmmmu(sub_eval_samples)
|
| 86 |
+
evaluation_result[subset] = metric_dict
|
| 87 |
+
|
| 88 |
+
printable_results = {}
|
| 89 |
+
for domain, in_domain_cats in DOMAIN_CAT2SUB_CAT.items():
|
| 90 |
+
in_domain_cat_results = {}
|
| 91 |
+
for cat_name in in_domain_cats:
|
| 92 |
+
if cat_name in evaluation_result.keys():
|
| 93 |
+
in_domain_cat_results[cat_name] = evaluation_result[cat_name]
|
| 94 |
+
else:
|
| 95 |
+
pass
|
| 96 |
+
in_domain_ins_acc = calculate_ins_level_acc(in_domain_cat_results)
|
| 97 |
+
in_domain_data_num = sum([cat_results["entries_num"] for cat_results in in_domain_cat_results.values()])
|
| 98 |
+
printable_results["Overall-" + domain] = {
|
| 99 |
+
"num": int(in_domain_data_num),
|
| 100 |
+
"acc": round(in_domain_ins_acc, 3),
|
| 101 |
+
}
|
| 102 |
+
# add sub category
|
| 103 |
+
for cat_name, cat_results in in_domain_cat_results.items():
|
| 104 |
+
printable_results[cat_name] = {
|
| 105 |
+
"num": int(cat_results["entries_num"]),
|
| 106 |
+
"acc": round(cat_results["acc"], 3),
|
| 107 |
+
}
|
| 108 |
+
all_ins_acc = calculate_ins_level_acc(evaluation_result)
|
| 109 |
+
printable_results["Overall"] = {
|
| 110 |
+
"num": sum([cat_results["entries_num"] for cat_results in evaluation_result.values()]),
|
| 111 |
+
"acc": round(all_ins_acc, 3),
|
| 112 |
+
}
|
| 113 |
+
print(printable_results)
|
| 114 |
+
return printable_results["Overall"]["acc"]
|
| 115 |
+
|
| 116 |
+
|
| 117 |
+
def cmmmu_process_test_results_for_submission(doc, results):
|
| 118 |
+
response = results[0]
|
| 119 |
+
return {"submission": {"id": doc["id"], "type": doc["type"], "response": response}}
|
| 120 |
+
|
| 121 |
+
|
| 122 |
+
def cmmmu_test_aggregate_results_for_submission(results, args):
|
| 123 |
+
file = generate_submission_file("cmmmu_test_for_submission.jsonl", args)
|
| 124 |
+
with open(file, "w", encoding="utf8") as f:
|
| 125 |
+
for result in results:
|
| 126 |
+
json.dump(result, f, ensure_ascii=False)
|
| 127 |
+
f.write("\n")
|
| 128 |
+
eval_logger.info(f"Submission file saved to {file}")
|
| 129 |
+
|
| 130 |
+
|
| 131 |
+
##################
|
| 132 |
+
# Helper functions
|
| 133 |
+
##################
|
| 134 |
+
|
| 135 |
+
DOMAIN_CAT2SUB_CAT = {
|
| 136 |
+
"艺术与设计": ["艺术", "艺术理论", "设计", "音乐"],
|
| 137 |
+
"商业": ["会计", "经济", "金融", "管理", "营销"],
|
| 138 |
+
"科学": ["生物", "化学", "地理", "数学", "物理"],
|
| 139 |
+
"健康与医学": ["基础医学", "临床医学", "诊断学与实验室医学", "制药", "公共卫生"],
|
| 140 |
+
"人文社会科学": ["历史", "文献学", "社会学", "心理学"],
|
| 141 |
+
"技术与工程": ["农业", "建筑学", "计算机科学", "电子学", "能源和电力", "材料", "机械工程"],
|
| 142 |
+
}
|
| 143 |
+
|
| 144 |
+
|
| 145 |
+
def eval_cmmmu(entries):
|
| 146 |
+
correct_cnt = 0
|
| 147 |
+
for entry in entries:
|
| 148 |
+
parsed_pred = entry.get("parsed_pred", "")
|
| 149 |
+
correct = False
|
| 150 |
+
if entry.get("question_type") == "选择":
|
| 151 |
+
if parsed_pred == entry["answer"]:
|
| 152 |
+
correct_cnt += 1
|
| 153 |
+
correct = True
|
| 154 |
+
|
| 155 |
+
elif entry.get("question_type") == "填空":
|
| 156 |
+
norm_answers = normalize_str(entry["answer"], entry["answer"])
|
| 157 |
+
|
| 158 |
+
for pred in parsed_pred:
|
| 159 |
+
# already normalized
|
| 160 |
+
if isinstance(pred, str): # if it's a string, then find if ans in the pred_i
|
| 161 |
+
for norm_ans in norm_answers:
|
| 162 |
+
# only see if the string answer in the string pred
|
| 163 |
+
# print(norm_ans, pred)
|
| 164 |
+
if isinstance(norm_ans, str) and norm_ans in pred:
|
| 165 |
+
if not correct:
|
| 166 |
+
correct_cnt += 1
|
| 167 |
+
correct = True
|
| 168 |
+
break
|
| 169 |
+
else: # it's a number
|
| 170 |
+
if pred in norm_answers:
|
| 171 |
+
if not correct:
|
| 172 |
+
correct_cnt += 1
|
| 173 |
+
correct = True
|
| 174 |
+
break
|
| 175 |
+
|
| 176 |
+
else:
|
| 177 |
+
positive_keywords = ["正确", "对", "准确", "肯定", "对的"]
|
| 178 |
+
negative_keywords = ["不对", "错误", "不正确", "不准确", "不合适", "否定", "错的", "错"]
|
| 179 |
+
ambiguous_keywords = ["对错", "是否正确", "否正确", "或者", "是否", "正确性", "对不"]
|
| 180 |
+
|
| 181 |
+
def judge_similarity(pred_list, positive_keywords, negative_keywords):
|
| 182 |
+
positive_count = 0
|
| 183 |
+
negative_count = 0
|
| 184 |
+
|
| 185 |
+
for pred in pred_list:
|
| 186 |
+
if any(pos_word in pred for pos_word in positive_keywords):
|
| 187 |
+
positive_count += 1
|
| 188 |
+
elif any(neg_word in pred for neg_word in negative_keywords):
|
| 189 |
+
negative_count += 1
|
| 190 |
+
|
| 191 |
+
if positive_count > negative_count:
|
| 192 |
+
return "对"
|
| 193 |
+
elif negative_count > positive_count:
|
| 194 |
+
return "错"
|
| 195 |
+
else:
|
| 196 |
+
return random.choice(["对", "错"])
|
| 197 |
+
|
| 198 |
+
answer = entry["answer"]
|
| 199 |
+
parsed_pred = [word for word in parsed_pred if not any(ambiguous in word for ambiguous in ambiguous_keywords)]
|
| 200 |
+
result = judge_similarity(parsed_pred, positive_keywords, negative_keywords)
|
| 201 |
+
if result == answer:
|
| 202 |
+
correct_cnt += 1
|
| 203 |
+
correct = True
|
| 204 |
+
if correct:
|
| 205 |
+
entry["judge"] = "正确"
|
| 206 |
+
else:
|
| 207 |
+
entry["judge"] = "错误"
|
| 208 |
+
|
| 209 |
+
if len(entries) == 0:
|
| 210 |
+
print("entries_num == 0, please check your file")
|
| 211 |
+
results_count = {"correct_num": 0, "entries_num": 0, "acc": 0}
|
| 212 |
+
else:
|
| 213 |
+
results_count = {"correct_num": correct_cnt, "entries_num": len(entries), "acc": correct_cnt / len(entries)}
|
| 214 |
+
|
| 215 |
+
return results_count
|
| 216 |
+
|
| 217 |
+
|
| 218 |
+
def get_multi_choice_prediction(response, all_choices, index2ans):
|
| 219 |
+
for char in [",", ".", "!", "?", ";", ":", "'"]:
|
| 220 |
+
response = response.strip(char)
|
| 221 |
+
response = " " + response + " " # add space to avoid partial match
|
| 222 |
+
|
| 223 |
+
candidates = []
|
| 224 |
+
|
| 225 |
+
for choice in all_choices: # (A) (B) (C) (D)
|
| 226 |
+
# Add the choice to candidates each time it appears in the response
|
| 227 |
+
candidates.extend([choice for _ in range(response.count(f"({choice})"))])
|
| 228 |
+
|
| 229 |
+
if len(candidates) == 0:
|
| 230 |
+
for choice in all_choices: # A B C D
|
| 231 |
+
# Similarly, add the choice for each occurrence
|
| 232 |
+
candidates.extend([choice for _ in range(response.count(f"{choice}"))])
|
| 233 |
+
|
| 234 |
+
if len(candidates) == 0 and len(response.split()) >= 1:
|
| 235 |
+
for index, ans in index2ans.items():
|
| 236 |
+
# Add index for each occurrence of ans in response
|
| 237 |
+
candidates.extend([index for _ in range(response.count(ans))])
|
| 238 |
+
|
| 239 |
+
# if all above doesn't get candidates, check if the content is larger than 5 tokens and try to parse the example
|
| 240 |
+
if len(candidates) == 0 and len(response.split()) >= 1:
|
| 241 |
+
for index, ans in index2ans.items():
|
| 242 |
+
if ans in response:
|
| 243 |
+
candidates.append(index)
|
| 244 |
+
index_ans = False # it's content ans.
|
| 245 |
+
|
| 246 |
+
if len(candidates) == 0: # still not get answer, randomly choose one.
|
| 247 |
+
return random.choice(all_choices)
|
| 248 |
+
# return ''
|
| 249 |
+
else:
|
| 250 |
+
# Count the occurrence of each candidate
|
| 251 |
+
candidate_counts = Counter(candidates)
|
| 252 |
+
|
| 253 |
+
# Select the most frequent candidates
|
| 254 |
+
max_count = max(candidate_counts.values())
|
| 255 |
+
most_frequent_candidates = [c for c in all_choices if candidate_counts.get(c, 0) == max_count]
|
| 256 |
+
|
| 257 |
+
# Combine the most frequent candidates in ABCD order
|
| 258 |
+
return "".join(most_frequent_candidates)
|
| 259 |
+
|
| 260 |
+
|
| 261 |
+
def extract_numbers(string):
|
| 262 |
+
# Pattern for numbers with Chinese commas
|
| 263 |
+
pattern_commas = r"-?\d{1,3}(?:,\d{3})+"
|
| 264 |
+
# Pattern for scientific notation
|
| 265 |
+
pattern_scientific = r"-?\d+(?:\.\d+)?[eE][+-]?\d+"
|
| 266 |
+
# Pattern for simple numbers without Chinese commas
|
| 267 |
+
pattern_simple = r"-?(?:\d+\.\d+|\.\d+|\d+)(?![eE][+-]?\d+)(?!,\d)"
|
| 268 |
+
|
| 269 |
+
# Extract numbers with Chinese commas
|
| 270 |
+
numbers_with_commas = re.findall(pattern_commas, string)
|
| 271 |
+
# Extract numbers in scientific notation
|
| 272 |
+
numbers_scientific = re.findall(pattern_scientific, string)
|
| 273 |
+
# Extract simple numbers without Chinese commas
|
| 274 |
+
numbers_simple = re.findall(pattern_simple, string)
|
| 275 |
+
|
| 276 |
+
# Combine all extracted numbers
|
| 277 |
+
all_numbers = numbers_with_commas + numbers_scientific + numbers_simple
|
| 278 |
+
return all_numbers
|
| 279 |
+
|
| 280 |
+
|
| 281 |
+
def check_is_number(string):
|
| 282 |
+
try:
|
| 283 |
+
float(string.replace(",", ""))
|
| 284 |
+
return True
|
| 285 |
+
except ValueError:
|
| 286 |
+
# check if there's comma inside
|
| 287 |
+
return False
|
| 288 |
+
|
| 289 |
+
|
| 290 |
+
def count_letters(string):
|
| 291 |
+
return sum(c.isalpha() and "a" <= c <= "z" or "A" <= c <= "Z" for c in string)
|
| 292 |
+
|
| 293 |
+
|
| 294 |
+
def normalize_str(string, answer):
|
| 295 |
+
# check if characters in the string
|
| 296 |
+
|
| 297 |
+
# if number, numerize it.
|
| 298 |
+
if string == None:
|
| 299 |
+
return [string]
|
| 300 |
+
string = string.strip()
|
| 301 |
+
|
| 302 |
+
is_number = check_is_number(string)
|
| 303 |
+
|
| 304 |
+
if is_number:
|
| 305 |
+
string = string.replace(",", "")
|
| 306 |
+
string = float(string)
|
| 307 |
+
# leave 2 decimal
|
| 308 |
+
string = round(string, 2)
|
| 309 |
+
return [string]
|
| 310 |
+
else: # it's likely to be a string
|
| 311 |
+
if len(string) > len(answer) + 20 or count_letters(string) > count_letters(answer) + 2:
|
| 312 |
+
return []
|
| 313 |
+
return [string]
|
| 314 |
+
|
| 315 |
+
|
| 316 |
+
def get_fill_blank_prediction(response, answer):
|
| 317 |
+
"""get the prediction from the generated response,
|
| 318 |
+
return a list of predicted strings or numbers"""
|
| 319 |
+
|
| 320 |
+
def get_key_subresponses(response):
|
| 321 |
+
key_responses = []
|
| 322 |
+
response = response.strip("。").strip()
|
| 323 |
+
sub_responses = re.split(r"。|\n", response)
|
| 324 |
+
indicators_of_keys = ["是", "为", "所以", "等于", "方案", "选择", "正确答案", "因此", "最后", "答案", "结果"]
|
| 325 |
+
key_responses = []
|
| 326 |
+
for index, resp in enumerate(sub_responses):
|
| 327 |
+
# if last one, accept it's an equation (the entire response can be just one sentence with equation)
|
| 328 |
+
if index == len(sub_responses) - 1:
|
| 329 |
+
indicators_of_keys.extend(["="])
|
| 330 |
+
shortest_key_response = None # the shortest response that may contain the answer (tail part of the response)
|
| 331 |
+
for indicator in indicators_of_keys:
|
| 332 |
+
if indicator in resp:
|
| 333 |
+
if not shortest_key_response:
|
| 334 |
+
shortest_key_response = resp.split(indicator)[-1].strip()
|
| 335 |
+
else:
|
| 336 |
+
if len(resp.split(indicator)[-1].strip()) < len(shortest_key_response):
|
| 337 |
+
shortest_key_response = resp.split(indicator)[-1].strip()
|
| 338 |
+
|
| 339 |
+
if shortest_key_response:
|
| 340 |
+
# and it's not trivial
|
| 341 |
+
if shortest_key_response.strip() not in [":", ",", ".", "!", "?", ";", ":", "'"]:
|
| 342 |
+
key_responses.append(shortest_key_response)
|
| 343 |
+
if len(key_responses) == 0: # did not found any
|
| 344 |
+
return [response]
|
| 345 |
+
return key_responses
|
| 346 |
+
|
| 347 |
+
key_responses = get_key_subresponses(response)
|
| 348 |
+
|
| 349 |
+
pred_list = key_responses.copy() # keep the original string response
|
| 350 |
+
for resp in key_responses:
|
| 351 |
+
pred_list.extend(extract_numbers(resp))
|
| 352 |
+
|
| 353 |
+
tmp_pred_list = []
|
| 354 |
+
for i in range(len(pred_list)):
|
| 355 |
+
tmp_pred_list.extend(normalize_str(pred_list[i], answer))
|
| 356 |
+
pred_list = tmp_pred_list
|
| 357 |
+
|
| 358 |
+
# remove duplicates
|
| 359 |
+
pred_list = list(set(pred_list))
|
| 360 |
+
|
| 361 |
+
return pred_list
|
| 362 |
+
|
| 363 |
+
|
| 364 |
+
def get_TF_prediction(response):
|
| 365 |
+
"""get the prediction from the generated response,
|
| 366 |
+
return a list of predicted strings or numbers"""
|
| 367 |
+
|
| 368 |
+
def get_key_subresponses(response):
|
| 369 |
+
key_responses = []
|
| 370 |
+
response = response.strip("。").strip()
|
| 371 |
+
sub_responses = re.split(r"。|\n", response)
|
| 372 |
+
indicators_of_keys = ["是", "为", "所以", "判断", "陈述", "说法", "表达", "答案", "结果"]
|
| 373 |
+
key_responses = []
|
| 374 |
+
for index, resp in enumerate(sub_responses):
|
| 375 |
+
shortest_key_response = None # the shortest response that may contain the answer (tail part of the response)
|
| 376 |
+
for indicator in indicators_of_keys:
|
| 377 |
+
if indicator in resp:
|
| 378 |
+
if not shortest_key_response:
|
| 379 |
+
shortest_key_response = resp.split(indicator)[-1].strip()
|
| 380 |
+
else:
|
| 381 |
+
if len(resp.split(indicator)[-1].strip()) < len(shortest_key_response):
|
| 382 |
+
shortest_key_response = resp.split(indicator)[-1].strip()
|
| 383 |
+
|
| 384 |
+
if shortest_key_response:
|
| 385 |
+
# and it's not trivial
|
| 386 |
+
if shortest_key_response.strip() not in [":", ",", ".", "!", "?", ";", ":", "'"]:
|
| 387 |
+
key_responses.append(shortest_key_response)
|
| 388 |
+
if len(key_responses) == 0: # did not found any
|
| 389 |
+
return [response]
|
| 390 |
+
return key_responses
|
| 391 |
+
|
| 392 |
+
key_responses = get_key_subresponses(response)
|
| 393 |
+
|
| 394 |
+
pred_list = key_responses.copy() # keep the original string response
|
| 395 |
+
# remove duplicates
|
| 396 |
+
pred_list = list(set(pred_list))
|
| 397 |
+
|
| 398 |
+
return pred_list
|
| 399 |
+
|
| 400 |
+
|
| 401 |
+
def get_multi_choice_info(options):
|
| 402 |
+
start_chr = "A"
|
| 403 |
+
all_choices = []
|
| 404 |
+
index2ans = {}
|
| 405 |
+
for i, option in enumerate(options):
|
| 406 |
+
index2ans[chr(ord(start_chr) + i)] = option
|
| 407 |
+
all_choices.append(chr(ord(start_chr) + i))
|
| 408 |
+
|
| 409 |
+
return index2ans, all_choices
|
| 410 |
+
|
| 411 |
+
|
| 412 |
+
def calculate_ins_level_acc(results):
|
| 413 |
+
correct_sum = 0
|
| 414 |
+
entries_sum = 0
|
| 415 |
+
for cat_results in results.values():
|
| 416 |
+
correct_sum += cat_results["correct_num"]
|
| 417 |
+
entries_sum += cat_results["entries_num"]
|
| 418 |
+
if entries_sum == 0:
|
| 419 |
+
return 0
|
| 420 |
+
return correct_sum / entries_sum
|
LaViDa/eval/lmms_eval/tasks/hrbench/hrbench.yaml
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
group: hrbench
|
| 2 |
+
task:
|
| 3 |
+
- hrbench4k
|
| 4 |
+
- hrbench8k
|
| 5 |
+
metadata:
|
| 6 |
+
version: 0.0
|
| 7 |
+
gpt_eval_model_name: "gpt-3.5-turbo"
|
| 8 |
+
max_workers: 1
|
LaViDa/eval/lmms_eval/tasks/hrbench/hrbench4k.yaml
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
dataset_path: DreamMr/HR-Bench
|
| 2 |
+
dataset_name: hrbench_version_split
|
| 3 |
+
dataset_kwargs:
|
| 4 |
+
token: True
|
| 5 |
+
task: "hrbench4k"
|
| 6 |
+
test_split: hrbench_4k
|
| 7 |
+
output_type: generate_until
|
| 8 |
+
doc_to_visual: !function utils.hrbench_doc_to_visual
|
| 9 |
+
doc_to_text: !function utils.hrbench_doc_to_text
|
| 10 |
+
doc_to_target: "answer"
|
| 11 |
+
# The return value of process_results will be used by metrics
|
| 12 |
+
process_results: !function utils.hrbench_process_results
|
| 13 |
+
# Note that the metric name can be either a registed metric function (such as the case for GQA) or a key name returned by process_results
|
| 14 |
+
metric_list:
|
| 15 |
+
- metric: single
|
| 16 |
+
aggregation: !function utils.hrbench_aggregate_results
|
| 17 |
+
higher_is_better: true
|
| 18 |
+
- metric: cross
|
| 19 |
+
aggregation: !function utils.hrbench_aggregate_results
|
| 20 |
+
higher_is_better: true
|
| 21 |
+
- metric: average
|
| 22 |
+
aggregation: !function utils.hrbench_aggregate_results
|
| 23 |
+
higher_is_better: true
|
LaViDa/eval/lmms_eval/tasks/hrbench/hrbench8k.yaml
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
dataset_path: DreamMr/HR-Bench
|
| 2 |
+
dataset_name: hrbench_version_split
|
| 3 |
+
dataset_kwargs:
|
| 4 |
+
token: True
|
| 5 |
+
task: "hrbench8k"
|
| 6 |
+
test_split: hrbench_8k
|
| 7 |
+
output_type: generate_until
|
| 8 |
+
doc_to_visual: !function utils.hrbench_doc_to_visual
|
| 9 |
+
doc_to_text: !function utils.hrbench_doc_to_text
|
| 10 |
+
doc_to_target: "answer"
|
| 11 |
+
# The return value of process_results will be used by metrics
|
| 12 |
+
process_results: !function utils.hrbench_process_results
|
| 13 |
+
# Note that the metric name can be either a registed metric function (such as the case for GQA) or a key name returned by process_results
|
| 14 |
+
metric_list:
|
| 15 |
+
- metric: single
|
| 16 |
+
aggregation: !function utils.hrbench_aggregate_results
|
| 17 |
+
higher_is_better: true
|
| 18 |
+
- metric: cross
|
| 19 |
+
aggregation: !function utils.hrbench_aggregate_results
|
| 20 |
+
higher_is_better: true
|
| 21 |
+
- metric: average
|
| 22 |
+
aggregation: !function utils.hrbench_aggregate_results
|
| 23 |
+
higher_is_better: true
|
LaViDa/eval/lmms_eval/tasks/hrbench/hrbench_evals.py
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import copy as cp
|
| 2 |
+
import os
|
| 3 |
+
import string
|
| 4 |
+
import time
|
| 5 |
+
from concurrent.futures import ThreadPoolExecutor
|
| 6 |
+
|
| 7 |
+
import pandas as pd
|
| 8 |
+
import requests
|
| 9 |
+
from loguru import logger as eval_logger
|
| 10 |
+
from tqdm import tqdm
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
class HRBenchEval:
|
| 14 |
+
API_TYPE = os.getenv("API_TYPE", "openai")
|
| 15 |
+
|
| 16 |
+
if API_TYPE == "openai":
|
| 17 |
+
API_URL = os.getenv("OPENAI_API_URL", "https://api.openai.com/v1/chat/completions")
|
| 18 |
+
API_KEY = os.getenv("OPENAI_API_KEY", "YOUR_API_KEY")
|
| 19 |
+
headers = {
|
| 20 |
+
"Authorization": f"Bearer {API_KEY}",
|
| 21 |
+
"Content-Type": "application/json",
|
| 22 |
+
}
|
| 23 |
+
elif API_TYPE == "azure":
|
| 24 |
+
API_URL = os.getenv("AZURE_ENDPOINT", "https://api.cognitive.microsoft.com/sts/v1.0/issueToken")
|
| 25 |
+
API_KEY = os.getenv("AZURE_API_KEY", "YOUR_API_KEY")
|
| 26 |
+
headers = {
|
| 27 |
+
"api-key": API_KEY,
|
| 28 |
+
"Content-Type": "application/json",
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
def __init__(self, api_key, gpt_model="gpt-3.5-turbo", max_workers=12):
|
| 32 |
+
self.api_key = api_key
|
| 33 |
+
self.gpt_model = gpt_model
|
| 34 |
+
self.max_workers = max_workers
|
| 35 |
+
|
| 36 |
+
def _post_request(self, payload):
|
| 37 |
+
headers = {
|
| 38 |
+
"Authorization": f"Bearer {self.api_key}",
|
| 39 |
+
"Content-Type": "application/json",
|
| 40 |
+
}
|
| 41 |
+
response = requests.post(self.API_URL, headers=headers, json=payload, timeout=30)
|
| 42 |
+
response.raise_for_status()
|
| 43 |
+
return response.json()
|
| 44 |
+
|
| 45 |
+
def can_infer_option(self, answer, choices):
|
| 46 |
+
verbose = os.environ.get("VERBOSE", 0)
|
| 47 |
+
# Choices is a dictionary
|
| 48 |
+
if "Failed to obtain answer via API" in answer:
|
| 49 |
+
return False
|
| 50 |
+
|
| 51 |
+
reject_to_answer = ["Sorry, I can't help with images of people yet.", "I can't process this file.", "I'm sorry, but without the image provided", "Cannot determine the answer"]
|
| 52 |
+
for err in reject_to_answer:
|
| 53 |
+
if err in answer:
|
| 54 |
+
return "Z"
|
| 55 |
+
|
| 56 |
+
def count_choice(splits, choices, prefix="", suffix=""):
|
| 57 |
+
cnt = 0
|
| 58 |
+
for c in choices:
|
| 59 |
+
if prefix + c + suffix in splits:
|
| 60 |
+
cnt += 1
|
| 61 |
+
return cnt
|
| 62 |
+
|
| 63 |
+
answer_mod = cp.copy(answer)
|
| 64 |
+
chars = ".()[],:;!*#{}"
|
| 65 |
+
for c in chars:
|
| 66 |
+
answer_mod = answer_mod.replace(c, " ")
|
| 67 |
+
|
| 68 |
+
splits = [x.strip() for x in answer_mod.split()]
|
| 69 |
+
count = count_choice(splits, choices)
|
| 70 |
+
|
| 71 |
+
if count == 1:
|
| 72 |
+
for ch in choices:
|
| 73 |
+
if "A" in splits and len(splits) > 3 and verbose:
|
| 74 |
+
return False
|
| 75 |
+
if ch in splits:
|
| 76 |
+
return ch
|
| 77 |
+
elif count == 0 and count_choice(splits, {"Z", ""}) == 1:
|
| 78 |
+
return "Z"
|
| 79 |
+
return False
|
| 80 |
+
|
| 81 |
+
def can_infer_text(self, answer, choices):
|
| 82 |
+
answer = answer.lower()
|
| 83 |
+
assert isinstance(choices, dict)
|
| 84 |
+
for k in choices:
|
| 85 |
+
assert k in string.ascii_uppercase
|
| 86 |
+
choices[k] = str(choices[k]).lower()
|
| 87 |
+
cands = []
|
| 88 |
+
for k in choices:
|
| 89 |
+
if choices[k] in answer:
|
| 90 |
+
cands.append(k)
|
| 91 |
+
if len(cands) == 1:
|
| 92 |
+
return cands[0]
|
| 93 |
+
return False
|
| 94 |
+
|
| 95 |
+
def can_infer(self, answer, choices):
|
| 96 |
+
answer = str(answer)
|
| 97 |
+
copt = self.can_infer_option(answer, choices)
|
| 98 |
+
return copt if copt else self.can_infer_text(answer, choices)
|
| 99 |
+
|
| 100 |
+
def get_chat_response(self, data, temperature=0, max_tokens=256, patience=10, sleep_time=0):
|
| 101 |
+
question = data["question"]
|
| 102 |
+
options = data["options"]
|
| 103 |
+
prediction = data["prediction"]
|
| 104 |
+
ret = self.can_infer(prediction, options)
|
| 105 |
+
if ret:
|
| 106 |
+
data["gpt_prediction"] = ret
|
| 107 |
+
return data
|
| 108 |
+
|
| 109 |
+
prompt = self.build_prompt(question, options, prediction)
|
| 110 |
+
messages = [
|
| 111 |
+
{"role": "user", "content": prompt},
|
| 112 |
+
]
|
| 113 |
+
payload = {"model": self.gpt_model, "messages": messages, "temperature": temperature, "max_tokens": max_tokens, "n": 1}
|
| 114 |
+
|
| 115 |
+
while patience > 0:
|
| 116 |
+
patience -= 1
|
| 117 |
+
try:
|
| 118 |
+
response = self._post_request(payload)
|
| 119 |
+
prediction = response["choices"][0]["message"]["content"].strip()
|
| 120 |
+
if prediction and prediction != "" and "Failed to obtain answer via API" not in prediction:
|
| 121 |
+
ret = self.can_infer(prediction, options)
|
| 122 |
+
data["gpt_prediction"] = ret
|
| 123 |
+
return data
|
| 124 |
+
|
| 125 |
+
except Exception as e:
|
| 126 |
+
# some model may output repetitive answer, which ChatGPT will throw an error.
|
| 127 |
+
eval_logger.error(e)
|
| 128 |
+
|
| 129 |
+
if sleep_time > 0:
|
| 130 |
+
time.sleep(sleep_time)
|
| 131 |
+
return data
|
| 132 |
+
|
| 133 |
+
def build_prompt(self, question, options, prediction):
|
| 134 |
+
options_prompt = ""
|
| 135 |
+
for key, item in options.items():
|
| 136 |
+
options_prompt += f"{key}. {item}\n"
|
| 137 |
+
tmpl = (
|
| 138 |
+
"You are an AI assistant who will help me to match "
|
| 139 |
+
"an answer with several options of a single-choice question. "
|
| 140 |
+
"You are provided with a question, several options, and an answer, "
|
| 141 |
+
"and you need to find which option is most similar to the answer. "
|
| 142 |
+
"If the meaning of all options are significantly different from the answer, output Z. "
|
| 143 |
+
"Your should output a single uppercase character in A, B, C, D (if they are valid options), and Z. \n"
|
| 144 |
+
"Example 1: \n"
|
| 145 |
+
"Question: What is the main object in image?\nOptions: A. teddy bear B. rabbit C. cat D. dog\n"
|
| 146 |
+
"Answer: a cute teddy bear\nYour output: A\n"
|
| 147 |
+
"Example 2: \n"
|
| 148 |
+
"Question: What is the main object in image?\nOptions: A. teddy bear B. rabbit C. cat D. dog\n"
|
| 149 |
+
"Answer: Spider\nYour output: Z\n"
|
| 150 |
+
"Example 3: \n"
|
| 151 |
+
"Question: {}\nOptions: {}\nAnswer: {}\nYour output: "
|
| 152 |
+
)
|
| 153 |
+
return tmpl.format(question, options_prompt, prediction)
|
LaViDa/eval/lmms_eval/tasks/hrbench/utils.py
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import base64
|
| 2 |
+
import datetime
|
| 3 |
+
import io
|
| 4 |
+
import json
|
| 5 |
+
import os
|
| 6 |
+
import string
|
| 7 |
+
from collections import defaultdict
|
| 8 |
+
from pathlib import Path
|
| 9 |
+
|
| 10 |
+
import numpy as np
|
| 11 |
+
import pandas as pd
|
| 12 |
+
import yaml
|
| 13 |
+
from loguru import logger as eval_logger
|
| 14 |
+
from PIL import Image
|
| 15 |
+
|
| 16 |
+
from lmms_eval.tasks.hrbench.hrbench_evals import HRBenchEval
|
| 17 |
+
|
| 18 |
+
with open(Path(__file__).parent / "hrbench.yaml", "r") as f:
|
| 19 |
+
raw_data = f.readlines()
|
| 20 |
+
safe_data = []
|
| 21 |
+
for i, line in enumerate(raw_data):
|
| 22 |
+
# remove function definition since yaml load cannot handle it
|
| 23 |
+
if "!function" not in line:
|
| 24 |
+
safe_data.append(line)
|
| 25 |
+
|
| 26 |
+
config = yaml.safe_load("".join(safe_data))
|
| 27 |
+
|
| 28 |
+
hrbench_evaluator = HRBenchEval(api_key=os.getenv("OPENAI_API_KEY", "YOUR_API_KEY"), gpt_model=config["metadata"]["gpt_eval_model_name"], max_workers=config["metadata"]["max_workers"])
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
def decode_base64_to_image(base64_string, target_size=-1):
|
| 32 |
+
image_data = base64.b64decode(base64_string)
|
| 33 |
+
image = Image.open(io.BytesIO(image_data)).convert("RGB")
|
| 34 |
+
if target_size > 0:
|
| 35 |
+
image.thumbnail((target_size, target_size))
|
| 36 |
+
return image
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
def hrbench_doc_to_visual(doc):
|
| 40 |
+
image = decode_base64_to_image(doc["image"])
|
| 41 |
+
return [image]
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
def hrbench_doc_to_options(doc):
|
| 45 |
+
options = {cand: doc[cand] for cand in string.ascii_uppercase if cand in doc and not pd.isna(doc[cand])}
|
| 46 |
+
return options
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
def hrbench_doc_to_text(doc, lmms_eval_specific_kwargs=None):
|
| 50 |
+
question = doc["question"].strip()
|
| 51 |
+
options = hrbench_doc_to_options(doc)
|
| 52 |
+
options_prompt = ""
|
| 53 |
+
for key, item in options.items():
|
| 54 |
+
options_prompt += f"{key}. {item}\n"
|
| 55 |
+
prompt = ""
|
| 56 |
+
prompt += f"{question}\n{options_prompt}Answer the option letter directly."
|
| 57 |
+
return prompt
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
def hrbench_process_results(doc, results):
|
| 61 |
+
"""
|
| 62 |
+
Args:
|
| 63 |
+
doc: a instance of the eval dataset
|
| 64 |
+
results: [pred]
|
| 65 |
+
Returns:
|
| 66 |
+
a dictionary with key: metric name, value: metric value
|
| 67 |
+
"""
|
| 68 |
+
pred = results[0].strip()
|
| 69 |
+
gt = doc["answer"]
|
| 70 |
+
options = hrbench_doc_to_options(doc)
|
| 71 |
+
question = doc["question"]
|
| 72 |
+
resp_dic = hrbench_evaluator.get_chat_response({"question": question, "options": options, "prediction": pred})
|
| 73 |
+
gpt_prediction = resp_dic["gpt_prediction"]
|
| 74 |
+
category = doc["category"]
|
| 75 |
+
cycle_category = doc["cycle_category"]
|
| 76 |
+
|
| 77 |
+
gpt_score = 0
|
| 78 |
+
if gt.lower() == gpt_prediction.lower():
|
| 79 |
+
gpt_score = 1
|
| 80 |
+
|
| 81 |
+
return {category: {"index": doc["index"], "cycle_category": cycle_category, "gpt_score": gpt_score}, "average": {"index": doc["index"], "cycle_category": cycle_category, "gpt_score": gpt_score}}
|
| 82 |
+
|
| 83 |
+
|
| 84 |
+
def hrbench_aggregate_results(results, args):
|
| 85 |
+
"""
|
| 86 |
+
Args:
|
| 87 |
+
results: a list of values returned by process_results
|
| 88 |
+
Returns:
|
| 89 |
+
A score
|
| 90 |
+
"""
|
| 91 |
+
cycle_category_scores = defaultdict(list)
|
| 92 |
+
for result in results:
|
| 93 |
+
score = result["gpt_score"]
|
| 94 |
+
cycle_category = result["cycle_category"]
|
| 95 |
+
cycle_category_scores[cycle_category].append(score)
|
| 96 |
+
|
| 97 |
+
cycle_category_avg_score = {}
|
| 98 |
+
for cycle_category, scores in cycle_category_scores.items():
|
| 99 |
+
avg_score = sum(scores) / len(scores)
|
| 100 |
+
cycle_category_avg_score[cycle_category] = avg_score
|
| 101 |
+
|
| 102 |
+
avg_score = sum(cycle_category_avg_score.values()) / len(cycle_category_avg_score)
|
| 103 |
+
return avg_score
|
LaViDa/eval/lmms_eval/tasks/livexiv_vqa/livexiv_vqa.yaml
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
group: livexiv_vqa
|
| 2 |
+
task:
|
| 3 |
+
- livexiv_vqa_v1
|
| 4 |
+
- livexiv_vqa_v2
|
| 5 |
+
- livexiv_vqa_v3
|
| 6 |
+
- livexiv_vqa_v4
|
| 7 |
+
- livexiv_vqa_v5
|
| 8 |
+
- livexiv_vqa_v6
|
| 9 |
+
|
LaViDa/eval/lmms_eval/tasks/livexiv_vqa/livexiv_vqa_template_yaml
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
dataset_path: LiveXiv/LiveXiv
|
| 2 |
+
dataset_kwargs:
|
| 3 |
+
token: True
|
| 4 |
+
test_split: test
|
| 5 |
+
dataset_name: VQA-2024-09-21
|
| 6 |
+
output_type: generate_until
|
| 7 |
+
doc_to_visual: !function utils.livexiv_doc_to_visual
|
| 8 |
+
doc_to_text: !function utils.livexiv_doc_to_text
|
| 9 |
+
doc_to_target: "answer"
|
| 10 |
+
generation_kwargs:
|
| 11 |
+
until:
|
| 12 |
+
- "ASSISTANT:"
|
| 13 |
+
image_aspect_ratio: original
|
| 14 |
+
process_results: !function utils.livexiv_process_result
|
| 15 |
+
process_results_use_image: true
|
| 16 |
+
metric_list:
|
| 17 |
+
- metric: livexiv_vqa
|
| 18 |
+
aggregation: !function utils.livexiv_aggregation_result
|
| 19 |
+
higher_is_better: true
|
| 20 |
+
metadata:
|
| 21 |
+
- version: 0.0
|
| 22 |
+
|
| 23 |
+
lmms_eval_specific_kwargs:
|
| 24 |
+
default:
|
| 25 |
+
pre_prompt: ""
|
| 26 |
+
post_prompt: ""
|
LaViDa/eval/lmms_eval/tasks/livexiv_vqa/livexiv_vqa_v1.yaml
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
task: "livexiv_vqa_v1"
|
| 2 |
+
dataset_name: "VQA-2024-09-21"
|
| 3 |
+
include: livexiv_vqa_template_yaml
|
LaViDa/eval/lmms_eval/tasks/livexiv_vqa/livexiv_vqa_v2.yaml
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
task: "livexiv_vqa_v2"
|
| 2 |
+
dataset_name: "VQA-2024-10-26"
|
| 3 |
+
include: livexiv_vqa_template_yaml
|
LaViDa/eval/lmms_eval/tasks/livexiv_vqa/livexiv_vqa_v3.yaml
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
task: "livexiv_vqa_v3"
|
| 2 |
+
dataset_name: "v3-VQA"
|
| 3 |
+
include: livexiv_vqa_template_yaml
|
LaViDa/eval/lmms_eval/tasks/livexiv_vqa/livexiv_vqa_v4.yaml
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
task: "livexiv_vqa_v4"
|
| 2 |
+
dataset_name: "v4-VQA"
|
| 3 |
+
include: livexiv_vqa_template_yaml
|
LaViDa/eval/lmms_eval/tasks/livexiv_vqa/livexiv_vqa_v5.yaml
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
task: "livexiv_vqa_v5"
|
| 2 |
+
dataset_name: "v5-VQA"
|
| 3 |
+
include: livexiv_vqa_template_yaml
|
LaViDa/eval/lmms_eval/tasks/livexiv_vqa/livexiv_vqa_v6.yaml
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
task: "livexiv_vqa_v6"
|
| 2 |
+
dataset_name: "v6-VQA"
|
| 3 |
+
include: livexiv_vqa_template_yaml
|
LaViDa/eval/lmms_eval/tasks/livexiv_vqa/utils.py
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import json
|
| 2 |
+
import re
|
| 3 |
+
|
| 4 |
+
|
| 5 |
+
def extract_answer(text):
|
| 6 |
+
match = re.findall(r"(?<!^)[A-Z]", text)
|
| 7 |
+
if match:
|
| 8 |
+
return match[0]
|
| 9 |
+
return None
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
def livexiv_doc_to_visual(doc):
|
| 13 |
+
return [doc["image"].convert("RGB")]
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
def livexiv_doc_to_text(doc, model_specific_kwargs=None):
|
| 17 |
+
question = doc["question"]
|
| 18 |
+
question += "\n" + f"A. {doc['option_a']}\n"
|
| 19 |
+
question += f"B. {doc['option_b']}\n"
|
| 20 |
+
question += f"C. {doc['option_c']}\n"
|
| 21 |
+
question += f"D. {doc['option_d']}"
|
| 22 |
+
return f"{question}\nAnswer with the option's letter from the given choices directly."
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
def livexiv_process_result(doc, result):
|
| 26 |
+
pred = result[0].strip()
|
| 27 |
+
if len(pred) > 1:
|
| 28 |
+
if "answer" in pred.lower():
|
| 29 |
+
pred = extract_answer(pred)
|
| 30 |
+
else:
|
| 31 |
+
pred = pred[0]
|
| 32 |
+
answer = doc["gt"]
|
| 33 |
+
|
| 34 |
+
return {f"livexiv_vqa": {"pred": pred, "answer": answer}}
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
def livexiv_aggregation_result(results):
|
| 38 |
+
total_count = 0
|
| 39 |
+
total_correct = 0
|
| 40 |
+
for result in results:
|
| 41 |
+
try:
|
| 42 |
+
if result["pred"].lower().strip() == result["answer"].lower().strip():
|
| 43 |
+
total_correct += 1
|
| 44 |
+
except Exception as e:
|
| 45 |
+
print(e)
|
| 46 |
+
|
| 47 |
+
total_count += 1
|
| 48 |
+
return total_correct / total_count
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
def livexiv_aggregation_result_all(results):
|
| 52 |
+
score = livexiv_aggregation_result(results)
|
| 53 |
+
stored_results = []
|
| 54 |
+
for result in results:
|
| 55 |
+
stored_results.append({"question_id": result["question_id"], "prediction": result["pred"]})
|
| 56 |
+
with open("./livexiv_vqa_submission.json", "w") as f:
|
| 57 |
+
json.dump(stored_results, f, indent=4)
|
| 58 |
+
print("Storing files for LiveXiv-VQA submission ...")
|
| 59 |
+
|
| 60 |
+
return score
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
def livexiv_doc_to_text_mc(doc):
|
| 64 |
+
question = doc["question"]
|
| 65 |
+
return f"{question} Answer :"
|
| 66 |
+
|
| 67 |
+
|
| 68 |
+
def livexiv_doc_to_choice(doc):
|
| 69 |
+
return [doc["option_a"], doc["option_b"], doc["option_c"], doc["option_d"]]
|
| 70 |
+
|
| 71 |
+
|
| 72 |
+
def livexiv_doc_to_mc_target(doc):
|
| 73 |
+
answer2choice = {"A": "option_a", "B": "option_b", "C": "option_c", "D": "option_d"}
|
| 74 |
+
return doc[answer2choice[doc["answer"]]]
|
LaViDa/eval/lmms_eval/tasks/mlvu/mlvu_dev.yaml
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
dataset_path: sy1998/MLVU_dev
|
| 2 |
+
dataset_kwargs:
|
| 3 |
+
token: True
|
| 4 |
+
cache_dir: mlvu
|
| 5 |
+
video: True
|
| 6 |
+
generation_kwargs:
|
| 7 |
+
max_new_tokens: 16
|
| 8 |
+
temperature: 0
|
| 9 |
+
top_p: 1.0
|
| 10 |
+
num_beams: 1
|
| 11 |
+
do_sample: false
|
| 12 |
+
task: mlvu_dev
|
| 13 |
+
test_split: test
|
| 14 |
+
output_type: generate_until
|
| 15 |
+
doc_to_visual: !function utils.mlvu_doc_to_visual_dev
|
| 16 |
+
doc_to_text: !function utils.mlvu_doc_to_text
|
| 17 |
+
doc_to_target: "answer"
|
| 18 |
+
# The return value of process_results will be used by metrics
|
| 19 |
+
process_results: !function utils.mlvu_process_results
|
| 20 |
+
# Note that the metric name can be either a registed metric function (such as the case for GQA) or a key name returned by process_results
|
| 21 |
+
metric_list:
|
| 22 |
+
- metric: mlvu_percetion_score
|
| 23 |
+
aggregation: !function utils.mlvu_aggregate_results_dev
|
| 24 |
+
higher_is_better: true
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
|
LaViDa/eval/lmms_eval/tasks/mlvu/mlvu_test.yaml
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
dataset_path: sy1998/MLVU_Test
|
| 2 |
+
dataset_kwargs:
|
| 3 |
+
token: True
|
| 4 |
+
cache_dir: mlvu_test
|
| 5 |
+
video: True
|
| 6 |
+
generation_kwargs:
|
| 7 |
+
max_new_tokens: 16
|
| 8 |
+
temperature: 0
|
| 9 |
+
top_p: 1.0
|
| 10 |
+
num_beams: 1
|
| 11 |
+
do_sample: false
|
| 12 |
+
task: mlvu_test
|
| 13 |
+
test_split: test
|
| 14 |
+
output_type: generate_until
|
| 15 |
+
doc_to_visual: !function utils.mlvu_doc_to_visual_test
|
| 16 |
+
doc_to_text: !function utils.mlvu_doc_to_text
|
| 17 |
+
doc_to_target: "answer"
|
| 18 |
+
# The return value of process_results will be used by metrics
|
| 19 |
+
process_results: !function utils.mlvu_process_results
|
| 20 |
+
# Note that the metric name can be either a registed metric function (such as the case for GQA) or a key name returned by process_results
|
| 21 |
+
metric_list:
|
| 22 |
+
- metric: mlvu_percetion_score
|
| 23 |
+
aggregation: !function utils.mlvu_aggregate_results_test
|
| 24 |
+
higher_is_better: true
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
|
LaViDa/eval/lmms_eval/tasks/mlvu/utils.py
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import datetime
|
| 2 |
+
import json
|
| 3 |
+
import os
|
| 4 |
+
import re
|
| 5 |
+
import sys
|
| 6 |
+
from collections import defaultdict
|
| 7 |
+
from pathlib import Path
|
| 8 |
+
from typing import Dict, List, Optional, Union
|
| 9 |
+
|
| 10 |
+
import cv2
|
| 11 |
+
import numpy as np
|
| 12 |
+
import yaml
|
| 13 |
+
from loguru import logger as eval_logger
|
| 14 |
+
|
| 15 |
+
from lmms_eval.tasks._task_utils.file_utils import generate_submission_file
|
| 16 |
+
|
| 17 |
+
hf_home = os.getenv("HF_HOME", "./~/.cache/huggingface")
|
| 18 |
+
# hf_home="/share/junjie/shuyan/lmms-eval/~/.cache/huggingface"
|
| 19 |
+
base_cache_dir = os.path.expanduser(hf_home)
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
with open(Path(__file__).parent / "mlvu_dev.yaml", "r") as f:
|
| 23 |
+
raw_data_dev = f.readlines()
|
| 24 |
+
safe_data_dev = []
|
| 25 |
+
for i, line in enumerate(raw_data_dev):
|
| 26 |
+
# remove function definition since yaml load cannot handle it
|
| 27 |
+
if "!function" not in line:
|
| 28 |
+
safe_data_dev.append(line)
|
| 29 |
+
cache_name_dev = yaml.safe_load("".join(safe_data_dev))["dataset_kwargs"]["cache_dir"]
|
| 30 |
+
cache_dir_dev = os.path.join(base_cache_dir, cache_name_dev)
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
with open(Path(__file__).parent / "mlvu_test.yaml", "r") as f:
|
| 34 |
+
raw_data_test = f.readlines()
|
| 35 |
+
safe_data_test = []
|
| 36 |
+
for i, line in enumerate(raw_data_test):
|
| 37 |
+
# remove function definition since yaml load cannot handle it
|
| 38 |
+
if "!function" not in line:
|
| 39 |
+
safe_data_test.append(line)
|
| 40 |
+
cache_name_test = yaml.safe_load("".join(safe_data_test))["dataset_kwargs"]["cache_dir"]
|
| 41 |
+
cache_dir_test = os.path.join(base_cache_dir, cache_name_test)
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
def mlvu_doc_to_visual_dev(doc):
|
| 45 |
+
video_path = doc["video_name"]
|
| 46 |
+
video_path = os.path.join(cache_dir_dev, video_path)
|
| 47 |
+
if os.path.exists(video_path):
|
| 48 |
+
video_path = video_path
|
| 49 |
+
else:
|
| 50 |
+
sys.exit(f"video path:{video_path} does not exist, please check")
|
| 51 |
+
return [video_path]
|
| 52 |
+
|
| 53 |
+
|
| 54 |
+
def mlvu_doc_to_visual_test(doc):
|
| 55 |
+
video_path = doc["video_name"]
|
| 56 |
+
video_path = os.path.join(cache_dir_test, video_path)
|
| 57 |
+
if os.path.exists(video_path):
|
| 58 |
+
video_path = video_path
|
| 59 |
+
else:
|
| 60 |
+
sys.exit(f"video path:{video_path} does not exist, please check")
|
| 61 |
+
return [video_path]
|
| 62 |
+
|
| 63 |
+
|
| 64 |
+
def mlvu_doc_to_text(doc, lmms_eval_specific_kwargs=None):
|
| 65 |
+
# option_prompt="Carefully watch this video and pay attention to every detail. Based on your observations, select the best option that accurately addresses the question."
|
| 66 |
+
option_prompt = ""
|
| 67 |
+
question = doc["question"] + "\nOnly give the best option.\n"
|
| 68 |
+
full_prompt = option_prompt + "\n" + question + "\n" + "Best option: ("
|
| 69 |
+
return full_prompt
|
| 70 |
+
|
| 71 |
+
|
| 72 |
+
def extract_characters_regex(s):
|
| 73 |
+
s = s.strip()
|
| 74 |
+
if ")" in s:
|
| 75 |
+
index = s.index(")")
|
| 76 |
+
pred = s[index - 1 : index]
|
| 77 |
+
return pred
|
| 78 |
+
else:
|
| 79 |
+
return s
|
| 80 |
+
|
| 81 |
+
|
| 82 |
+
def mlvu_process_results(doc, results):
|
| 83 |
+
"""
|
| 84 |
+
Args:
|
| 85 |
+
doc: a instance of the eval dataset
|
| 86 |
+
results: [pred]
|
| 87 |
+
Returns:
|
| 88 |
+
a dictionary with key: metric name (in this case videomme score), value: metric value
|
| 89 |
+
"""
|
| 90 |
+
pred = results[0]
|
| 91 |
+
|
| 92 |
+
pred_ans = extract_characters_regex(pred)
|
| 93 |
+
|
| 94 |
+
task_type = doc["task_type"]
|
| 95 |
+
data_dict = {"question_id": doc["question"], "task_type": task_type, "pred_answer": pred_ans, "answer": doc["answer"]}
|
| 96 |
+
|
| 97 |
+
return {f"mlvu_percetion_score": data_dict}
|
| 98 |
+
|
| 99 |
+
|
| 100 |
+
def mlvu_aggregate_results_dev(results):
|
| 101 |
+
"""
|
| 102 |
+
Args:
|
| 103 |
+
results: a list of values returned by process_results
|
| 104 |
+
Returns:
|
| 105 |
+
A score
|
| 106 |
+
"""
|
| 107 |
+
TASK_TYPES = {"anomaly_reco", "count", "ego", "needle", "order", "plotQA", "topic_reasoning"}
|
| 108 |
+
category2score = {}
|
| 109 |
+
for task_type in TASK_TYPES:
|
| 110 |
+
category2score[task_type] = {"correct": 0, "answered": 0}
|
| 111 |
+
|
| 112 |
+
for result in results:
|
| 113 |
+
task_type = result["task_type"]
|
| 114 |
+
category2score[task_type]["answered"] += 1
|
| 115 |
+
category2score[task_type]["correct"] += result["pred_answer"] == result["answer"]
|
| 116 |
+
|
| 117 |
+
task_category_scores = {}
|
| 118 |
+
|
| 119 |
+
# Calculate and log accuracy for each task category
|
| 120 |
+
for task_cate in TASK_TYPES:
|
| 121 |
+
total_correct = 0
|
| 122 |
+
total_answered = 0
|
| 123 |
+
for k, v in category2score.items():
|
| 124 |
+
if task_cate in k:
|
| 125 |
+
total_correct += v["correct"]
|
| 126 |
+
total_answered += v["answered"]
|
| 127 |
+
accuracy = 100 * total_correct / total_answered if total_answered > 0 else 0
|
| 128 |
+
task_category_scores[task_cate] = accuracy
|
| 129 |
+
eval_logger.info(f"Evaluation on Task Categories: {task_cate}: {accuracy:.1f}%")
|
| 130 |
+
|
| 131 |
+
# Calculate and log average accuracy across all task categories
|
| 132 |
+
if TASK_TYPES:
|
| 133 |
+
average_accuracy = sum(task_category_scores.values()) / len(TASK_TYPES)
|
| 134 |
+
else:
|
| 135 |
+
average_accuracy = 0
|
| 136 |
+
|
| 137 |
+
eval_logger.info(f"Average Performance Across All Task Categories: {average_accuracy:.1f}%")
|
| 138 |
+
|
| 139 |
+
return average_accuracy
|
| 140 |
+
|
| 141 |
+
|
| 142 |
+
def mlvu_aggregate_results_test(results):
|
| 143 |
+
"""
|
| 144 |
+
Args:
|
| 145 |
+
results: a list of values returned by process_results
|
| 146 |
+
Returns:
|
| 147 |
+
A score
|
| 148 |
+
"""
|
| 149 |
+
TASK_TYPES = {"anomaly_reco", "count", "ego", "needleQA", "order", "plotQA", "sportsQA", "topic_reasoning", "tutorialQA"}
|
| 150 |
+
category2score = {}
|
| 151 |
+
for task_type in TASK_TYPES:
|
| 152 |
+
category2score[task_type] = {"correct": 0, "answered": 0}
|
| 153 |
+
|
| 154 |
+
for result in results:
|
| 155 |
+
task_type = result["task_type"]
|
| 156 |
+
category2score[task_type]["answered"] += 1
|
| 157 |
+
category2score[task_type]["correct"] += result["pred_answer"] == result["answer"]
|
| 158 |
+
|
| 159 |
+
task_category_scores = {}
|
| 160 |
+
|
| 161 |
+
# Calculate and log accuracy for each task category
|
| 162 |
+
for task_cate in TASK_TYPES:
|
| 163 |
+
total_correct = 0
|
| 164 |
+
total_answered = 0
|
| 165 |
+
for k, v in category2score.items():
|
| 166 |
+
if task_cate in k:
|
| 167 |
+
total_correct += v["correct"]
|
| 168 |
+
total_answered += v["answered"]
|
| 169 |
+
accuracy = 100 * total_correct / total_answered if total_answered > 0 else 0
|
| 170 |
+
task_category_scores[task_cate] = accuracy
|
| 171 |
+
eval_logger.info(f"Evaluation on Task Categories: {task_cate}: {accuracy:.1f}%")
|
| 172 |
+
|
| 173 |
+
# Calculate and log average accuracy across all task categories
|
| 174 |
+
if TASK_TYPES:
|
| 175 |
+
average_accuracy = sum(task_category_scores.values()) / len(TASK_TYPES)
|
| 176 |
+
else:
|
| 177 |
+
average_accuracy = 0
|
| 178 |
+
|
| 179 |
+
eval_logger.info(f"Average Performance Across All Task Categories: {average_accuracy:.1f}%")
|
| 180 |
+
|
| 181 |
+
return average_accuracy
|
LaViDa/eval/lmms_eval/tasks/mmlu/default/_default_template_yaml
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
dataset_path: hails/mmlu_no_train # a copy of `cais/mmlu` with no auxiliary_train split
|
| 2 |
+
test_split: test
|
| 3 |
+
fewshot_split: dev
|
| 4 |
+
fewshot_config:
|
| 5 |
+
sampler: first_n
|
| 6 |
+
output_type: multiple_choice
|
| 7 |
+
doc_to_text: "{{question.strip()}}\nA. {{choices[0]}}\nB. {{choices[1]}}\nC. {{choices[2]}}\nD. {{choices[3]}}\nAnswer:"
|
| 8 |
+
doc_to_choice: ["A", "B", "C", "D"]
|
| 9 |
+
doc_to_target: answer
|
| 10 |
+
metric_list:
|
| 11 |
+
- metric: acc
|
| 12 |
+
aggregation: mean
|
| 13 |
+
higher_is_better: true
|
| 14 |
+
metadata:
|
| 15 |
+
version: 1.0
|
| 16 |
+
dataset_kwargs:
|
| 17 |
+
trust_remote_code: true
|
LaViDa/eval/lmms_eval/tasks/mmlu/default/_mmlu.yaml
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
group: mmlu
|
| 2 |
+
task:
|
| 3 |
+
- mmlu_stem
|
| 4 |
+
- mmlu_other
|
| 5 |
+
- mmlu_social_sciences
|
| 6 |
+
- mmlu_humanities
|
| 7 |
+
aggregate_metric_list:
|
| 8 |
+
- metric: acc
|
| 9 |
+
weight_by_size: True
|
| 10 |
+
metadata:
|
| 11 |
+
version: 2
|
LaViDa/eval/lmms_eval/tasks/mmlu/default/_mmlu_humanities.yaml
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
group: mmlu_humanities
|
| 2 |
+
group_alias: humanities
|
| 3 |
+
task:
|
| 4 |
+
- mmlu_humanities_tasks
|
| 5 |
+
aggregate_metric_list:
|
| 6 |
+
- metric: acc
|
| 7 |
+
weight_by_size: True
|
| 8 |
+
metadata:
|
| 9 |
+
version: 2
|
LaViDa/eval/lmms_eval/tasks/mmlu/default/_mmlu_other.yaml
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
group: mmlu_other
|
| 2 |
+
group_alias: other
|
| 3 |
+
task:
|
| 4 |
+
- mmlu_other_tasks
|
| 5 |
+
aggregate_metric_list:
|
| 6 |
+
- metric: acc
|
| 7 |
+
weight_by_size: True
|
| 8 |
+
metadata:
|
| 9 |
+
version: 2
|
LaViDa/eval/lmms_eval/tasks/mmlu/default/_mmlu_social_sciences.yaml
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
group: mmlu_social_sciences
|
| 2 |
+
group_alias: social sciences
|
| 3 |
+
task:
|
| 4 |
+
- mmlu_social_sciences_tasks
|
| 5 |
+
aggregate_metric_list:
|
| 6 |
+
- metric: acc
|
| 7 |
+
weight_by_size: True
|
| 8 |
+
metadata:
|
| 9 |
+
version: 2
|
LaViDa/eval/lmms_eval/tasks/mmlu/default/_mmlu_stem.yaml
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
group: mmlu_stem
|
| 2 |
+
group_alias: stem
|
| 3 |
+
task:
|
| 4 |
+
- mmlu_stem_tasks
|
| 5 |
+
aggregate_metric_list:
|
| 6 |
+
- metric: acc
|
| 7 |
+
weight_by_size: True
|
| 8 |
+
metadata:
|
| 9 |
+
version: 2
|
LaViDa/eval/lmms_eval/tasks/mmlu/default/mmlu_abstract_algebra.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"dataset_name": "abstract_algebra"
|
| 2 |
+
"description": "The following are multiple choice questions (with answers) about abstract\
|
| 3 |
+
\ algebra.\n\n"
|
| 4 |
+
"tag": "mmlu_stem_tasks"
|
| 5 |
+
"include": "_default_template_yaml"
|
| 6 |
+
"task": "mmlu_abstract_algebra"
|
| 7 |
+
"task_alias": "abstract_algebra"
|
LaViDa/eval/lmms_eval/tasks/mmlu/default/mmlu_anatomy.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"dataset_name": "anatomy"
|
| 2 |
+
"description": "The following are multiple choice questions (with answers) about anatomy.\n\
|
| 3 |
+
\n"
|
| 4 |
+
"tag": "mmlu_stem_tasks"
|
| 5 |
+
"include": "_default_template_yaml"
|
| 6 |
+
"task": "mmlu_anatomy"
|
| 7 |
+
"task_alias": "anatomy"
|
LaViDa/eval/lmms_eval/tasks/mmlu/default/mmlu_astronomy.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"dataset_name": "astronomy"
|
| 2 |
+
"description": "The following are multiple choice questions (with answers) about astronomy.\n\
|
| 3 |
+
\n"
|
| 4 |
+
"tag": "mmlu_stem_tasks"
|
| 5 |
+
"include": "_default_template_yaml"
|
| 6 |
+
"task": "mmlu_astronomy"
|
| 7 |
+
"task_alias": "astronomy"
|
LaViDa/eval/lmms_eval/tasks/mmlu/default/mmlu_business_ethics.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"dataset_name": "business_ethics"
|
| 2 |
+
"description": "The following are multiple choice questions (with answers) about business\
|
| 3 |
+
\ ethics.\n\n"
|
| 4 |
+
"tag": "mmlu_other_tasks"
|
| 5 |
+
"include": "_default_template_yaml"
|
| 6 |
+
"task": "mmlu_business_ethics"
|
| 7 |
+
"task_alias": "business_ethics"
|
LaViDa/eval/lmms_eval/tasks/mmlu/default/mmlu_clinical_knowledge.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"dataset_name": "clinical_knowledge"
|
| 2 |
+
"description": "The following are multiple choice questions (with answers) about clinical\
|
| 3 |
+
\ knowledge.\n\n"
|
| 4 |
+
"tag": "mmlu_other_tasks"
|
| 5 |
+
"include": "_default_template_yaml"
|
| 6 |
+
"task": "mmlu_clinical_knowledge"
|
| 7 |
+
"task_alias": "clinical_knowledge"
|
LaViDa/eval/lmms_eval/tasks/mmlu/default/mmlu_college_biology.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"dataset_name": "college_biology"
|
| 2 |
+
"description": "The following are multiple choice questions (with answers) about college\
|
| 3 |
+
\ biology.\n\n"
|
| 4 |
+
"tag": "mmlu_stem_tasks"
|
| 5 |
+
"include": "_default_template_yaml"
|
| 6 |
+
"task": "mmlu_college_biology"
|
| 7 |
+
"task_alias": "college_biology"
|
LaViDa/eval/lmms_eval/tasks/mmlu/default/mmlu_college_chemistry.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"dataset_name": "college_chemistry"
|
| 2 |
+
"description": "The following are multiple choice questions (with answers) about college\
|
| 3 |
+
\ chemistry.\n\n"
|
| 4 |
+
"tag": "mmlu_stem_tasks"
|
| 5 |
+
"include": "_default_template_yaml"
|
| 6 |
+
"task": "mmlu_college_chemistry"
|
| 7 |
+
"task_alias": "college_chemistry"
|
LaViDa/eval/lmms_eval/tasks/mmlu/default/mmlu_college_computer_science.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"dataset_name": "college_computer_science"
|
| 2 |
+
"description": "The following are multiple choice questions (with answers) about college\
|
| 3 |
+
\ computer science.\n\n"
|
| 4 |
+
"tag": "mmlu_stem_tasks"
|
| 5 |
+
"include": "_default_template_yaml"
|
| 6 |
+
"task": "mmlu_college_computer_science"
|
| 7 |
+
"task_alias": "college_computer_science"
|
LaViDa/eval/lmms_eval/tasks/mmlu/default/mmlu_college_mathematics.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"dataset_name": "college_mathematics"
|
| 2 |
+
"description": "The following are multiple choice questions (with answers) about college\
|
| 3 |
+
\ mathematics.\n\n"
|
| 4 |
+
"tag": "mmlu_stem_tasks"
|
| 5 |
+
"include": "_default_template_yaml"
|
| 6 |
+
"task": "mmlu_college_mathematics"
|
| 7 |
+
"task_alias": "college_mathematics"
|
LaViDa/eval/lmms_eval/tasks/mmlu/default/mmlu_college_medicine.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"dataset_name": "college_medicine"
|
| 2 |
+
"description": "The following are multiple choice questions (with answers) about college\
|
| 3 |
+
\ medicine.\n\n"
|
| 4 |
+
"tag": "mmlu_other_tasks"
|
| 5 |
+
"include": "_default_template_yaml"
|
| 6 |
+
"task": "mmlu_college_medicine"
|
| 7 |
+
"task_alias": "college_medicine"
|
LaViDa/eval/lmms_eval/tasks/mmlu/default/mmlu_college_physics.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"dataset_name": "college_physics"
|
| 2 |
+
"description": "The following are multiple choice questions (with answers) about college\
|
| 3 |
+
\ physics.\n\n"
|
| 4 |
+
"tag": "mmlu_stem_tasks"
|
| 5 |
+
"include": "_default_template_yaml"
|
| 6 |
+
"task": "mmlu_college_physics"
|
| 7 |
+
"task_alias": "college_physics"
|
LaViDa/eval/lmms_eval/tasks/mmlu/default/mmlu_computer_security.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"dataset_name": "computer_security"
|
| 2 |
+
"description": "The following are multiple choice questions (with answers) about computer\
|
| 3 |
+
\ security.\n\n"
|
| 4 |
+
"tag": "mmlu_stem_tasks"
|
| 5 |
+
"include": "_default_template_yaml"
|
| 6 |
+
"task": "mmlu_computer_security"
|
| 7 |
+
"task_alias": "computer_security"
|
LaViDa/eval/lmms_eval/tasks/mmlu/default/mmlu_conceptual_physics.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"dataset_name": "conceptual_physics"
|
| 2 |
+
"description": "The following are multiple choice questions (with answers) about conceptual\
|
| 3 |
+
\ physics.\n\n"
|
| 4 |
+
"tag": "mmlu_stem_tasks"
|
| 5 |
+
"include": "_default_template_yaml"
|
| 6 |
+
"task": "mmlu_conceptual_physics"
|
| 7 |
+
"task_alias": "conceptual_physics"
|
LaViDa/eval/lmms_eval/tasks/mmlu/default/mmlu_econometrics.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"dataset_name": "econometrics"
|
| 2 |
+
"description": "The following are multiple choice questions (with answers) about econometrics.\n\
|
| 3 |
+
\n"
|
| 4 |
+
"tag": "mmlu_social_sciences_tasks"
|
| 5 |
+
"include": "_default_template_yaml"
|
| 6 |
+
"task": "mmlu_econometrics"
|
| 7 |
+
"task_alias": "econometrics"
|
LaViDa/eval/lmms_eval/tasks/mmlu/default/mmlu_electrical_engineering.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"dataset_name": "electrical_engineering"
|
| 2 |
+
"description": "The following are multiple choice questions (with answers) about electrical\
|
| 3 |
+
\ engineering.\n\n"
|
| 4 |
+
"tag": "mmlu_stem_tasks"
|
| 5 |
+
"include": "_default_template_yaml"
|
| 6 |
+
"task": "mmlu_electrical_engineering"
|
| 7 |
+
"task_alias": "electrical_engineering"
|
LaViDa/eval/lmms_eval/tasks/mmlu/default/mmlu_elementary_mathematics.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"dataset_name": "elementary_mathematics"
|
| 2 |
+
"description": "The following are multiple choice questions (with answers) about elementary\
|
| 3 |
+
\ mathematics.\n\n"
|
| 4 |
+
"tag": "mmlu_stem_tasks"
|
| 5 |
+
"include": "_default_template_yaml"
|
| 6 |
+
"task": "mmlu_elementary_mathematics"
|
| 7 |
+
"task_alias": "elementary_mathematics"
|
LaViDa/eval/lmms_eval/tasks/mmlu/default/mmlu_formal_logic.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"dataset_name": "formal_logic"
|
| 2 |
+
"description": "The following are multiple choice questions (with answers) about formal\
|
| 3 |
+
\ logic.\n\n"
|
| 4 |
+
"tag": "mmlu_humanities_tasks"
|
| 5 |
+
"include": "_default_template_yaml"
|
| 6 |
+
"task": "mmlu_formal_logic"
|
| 7 |
+
"task_alias": "formal_logic"
|
LaViDa/eval/lmms_eval/tasks/mmlu/default/mmlu_global_facts.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"dataset_name": "global_facts"
|
| 2 |
+
"description": "The following are multiple choice questions (with answers) about global\
|
| 3 |
+
\ facts.\n\n"
|
| 4 |
+
"tag": "mmlu_other_tasks"
|
| 5 |
+
"include": "_default_template_yaml"
|
| 6 |
+
"task": "mmlu_global_facts"
|
| 7 |
+
"task_alias": "global_facts"
|
LaViDa/eval/lmms_eval/tasks/mmlu/default/mmlu_high_school_biology.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"dataset_name": "high_school_biology"
|
| 2 |
+
"description": "The following are multiple choice questions (with answers) about high\
|
| 3 |
+
\ school biology.\n\n"
|
| 4 |
+
"tag": "mmlu_stem_tasks"
|
| 5 |
+
"include": "_default_template_yaml"
|
| 6 |
+
"task": "mmlu_high_school_biology"
|
| 7 |
+
"task_alias": "high_school_biology"
|