Spaces:
Running on CPU Upgrade
Running on CPU Upgrade
v3 update part 2
Browse files- app.py +3 -1
- datasets.py +6 -4
- report_score_v3.py +250 -0
- utils.py +14 -9
- utils_v3.py +20 -7
app.py
CHANGED
|
@@ -42,7 +42,7 @@ with gr.Blocks() as block:
|
|
| 42 |
|
| 43 |
df = get_df()
|
| 44 |
df['Date'] = 'unknown'
|
| 45 |
-
df2 = v3.get_df()
|
| 46 |
min_size2, max_size2 = get_size_range(df2)
|
| 47 |
|
| 48 |
with gr.Row():
|
|
@@ -159,6 +159,7 @@ with gr.Blocks() as block:
|
|
| 159 |
|
| 160 |
# table 5, audio scores
|
| 161 |
with gr.TabItem("🎵 Audio (NEW)", elem_id="tab-audio", id=5):
|
|
|
|
| 162 |
data_component_a = gr.components.Dataframe(
|
| 163 |
value=v3.rank_models(df2[v3.COLUMN_NAMES_A], 'Audio-Overall'),
|
| 164 |
headers=v3.COLUMN_NAMES_A,
|
|
@@ -193,6 +194,7 @@ with gr.Blocks() as block:
|
|
| 193 |
|
| 194 |
# table 7, agent scores
|
| 195 |
with gr.TabItem("🤖 Agents (NEW)", elem_id="tab-agents", id=7):
|
|
|
|
| 196 |
data_component_ag = gr.components.Dataframe(
|
| 197 |
value=v3.rank_models(df2[v3.COLUMN_NAMES_AG], 'Agent-Overall'),
|
| 198 |
headers=v3.COLUMN_NAMES_AG,
|
|
|
|
| 42 |
|
| 43 |
df = get_df()
|
| 44 |
df['Date'] = 'unknown'
|
| 45 |
+
df2 = v3.get_df('Overall-V2')
|
| 46 |
min_size2, max_size2 = get_size_range(df2)
|
| 47 |
|
| 48 |
with gr.Row():
|
|
|
|
| 159 |
|
| 160 |
# table 5, audio scores
|
| 161 |
with gr.TabItem("🎵 Audio (NEW)", elem_id="tab-audio", id=5):
|
| 162 |
+
gr.Markdown(v3.TABLE_INTRODUCTION_A)
|
| 163 |
data_component_a = gr.components.Dataframe(
|
| 164 |
value=v3.rank_models(df2[v3.COLUMN_NAMES_A], 'Audio-Overall'),
|
| 165 |
headers=v3.COLUMN_NAMES_A,
|
|
|
|
| 194 |
|
| 195 |
# table 7, agent scores
|
| 196 |
with gr.TabItem("🤖 Agents (NEW)", elem_id="tab-agents", id=7):
|
| 197 |
+
gr.Markdown(v3.TABLE_INTRODUCTION_AG)
|
| 198 |
data_component_ag = gr.components.Dataframe(
|
| 199 |
value=v3.rank_models(df2[v3.COLUMN_NAMES_AG], 'Agent-Overall'),
|
| 200 |
headers=v3.COLUMN_NAMES_AG,
|
datasets.py
CHANGED
|
@@ -36,13 +36,15 @@ DATASETS = {
|
|
| 36 |
"V-MRET": ['QVHighlight', 'Charades-STA', 'MomentSeeker']
|
| 37 |
},
|
| 38 |
"audio": {
|
| 39 |
-
"A-CLS": ["SpeechCommand", "UrbanSound8k", "
|
| 40 |
-
"A-RET": ['Clotho', 'SoundDescs', 'TUTSound', 'TUTSound(hard)', 'AVE', 'SpeechCOCO'
|
| 41 |
},
|
| 42 |
"agent": {
|
| 43 |
-
"
|
|
|
|
|
|
|
| 44 |
"GUI": ['GAE-GUIAct_q2t', 'GAE-GUIAct_q2s', 'GAE-GUIAct_s2s', 'GAE-GUIAct_t2s', 'GAE-Mind2Web_q2t', 'GAE-Mind2Web_q2s', 'GAE-Mind2Web_s2s', 'GAE-Mind2Web_t2s'],
|
| 45 |
-
"
|
| 46 |
}
|
| 47 |
}
|
| 48 |
ALL_DATASETS_SPLITS = {k: sum_lol(list(v.values())) for k, v in DATASETS.items()}
|
|
|
|
| 36 |
"V-MRET": ['QVHighlight', 'Charades-STA', 'MomentSeeker']
|
| 37 |
},
|
| 38 |
"audio": {
|
| 39 |
+
"A-CLS": ["SpeechCommand", "UrbanSound8k", "ESC-50", "NSynth", "CREMA-D"],
|
| 40 |
+
"A-RET": ['Clotho', 'SoundDescs', 'TUTSound', 'TUTSound(hard)', 'AVE', 'SpeechCOCO']
|
| 41 |
},
|
| 42 |
"agent": {
|
| 43 |
+
"Tool": ['apibank', 'apigen', 'mnms', 'reversechain', 'rotbench', 't-eval-dialog', 't-eval-step', 'taskbench-daily', 'toolace', 'toolbench', 'toolemu', 'tooleyes', 'toollens', 'ultratool', 'autotools-food', 'autotools-music', 'autotools-weather', 'restgpt-spotify', 'restgpt-tmdb',
|
| 44 |
+
'craft-math-algebra', 'craft-tabmwp', 'craft-vqa', 'gorilla-huggingface', 'gorilla-pytorch', 'gorilla-tensor', 'toolink',
|
| 45 |
+
'appbench', 'gpt4tools', 'gta', 'taskbench-huggingface', 'taskbench-multimedia', 'metatool', 'tool-be-honest', 'toolalpaca', 'toolbench-sam'],
|
| 46 |
"GUI": ['GAE-GUIAct_q2t', 'GAE-GUIAct_q2s', 'GAE-GUIAct_s2s', 'GAE-GUIAct_t2s', 'GAE-Mind2Web_q2t', 'GAE-Mind2Web_q2s', 'GAE-Mind2Web_s2s', 'GAE-Mind2Web_t2s'],
|
| 47 |
+
"Memory": ["REALTALK", "KnowMeBench", "PeerQA", "DeepPlanning"]
|
| 48 |
}
|
| 49 |
}
|
| 50 |
ALL_DATASETS_SPLITS = {k: sum_lol(list(v.values())) for k, v in DATASETS.items()}
|
report_score_v3.py
ADDED
|
@@ -0,0 +1,250 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
report_score_v3.py: The official script to generate the final scores report (in JSON) for MMEB-V3 leaderboard submission.
|
| 3 |
+
You should only modify the Configuration section below to add your model's metadata. No other changes are needed.
|
| 4 |
+
An example configuration is provided for your reference.
|
| 5 |
+
"""
|
| 6 |
+
|
| 7 |
+
import os
|
| 8 |
+
import json
|
| 9 |
+
from datetime import datetime
|
| 10 |
+
|
| 11 |
+
# ==============================================================================
|
| 12 |
+
# Configuration
|
| 13 |
+
# ==============================================================================
|
| 14 |
+
|
| 15 |
+
# ==> Unified list of experiments to process.
|
| 16 |
+
# Fill in the metadata for each experiment. `None` will become `null` in the JSON.
|
| 17 |
+
|
| 18 |
+
EXAMPLES = [
|
| 19 |
+
{
|
| 20 |
+
"path": "vlm2vec_exps/VLM2Vec-Qwen2VL-V2.0-2B/",
|
| 21 |
+
"metadata": {
|
| 22 |
+
"model_name": "VLM2Vec-Qwen2VL-V2.0-2B",
|
| 23 |
+
"model_size": "2", # in B, digits only here. 2 for 2B, 0.4 for 400M, etc.
|
| 24 |
+
"embedding_dimension": None, # Please fill in
|
| 25 |
+
"max_length_tokens": None, # Please fill in
|
| 26 |
+
"model_release_date": "2025-04-01", # Please adjust this date
|
| 27 |
+
"score_source": "", # e.g., "Self-Reported" or "TIGER-Lab"
|
| 28 |
+
"url": "" # e.g., Paper, GitHub, or Hugging Face link
|
| 29 |
+
}
|
| 30 |
+
},
|
| 31 |
+
{
|
| 32 |
+
"path": "vlm2vec_exps/VLM2Vec-Qwen2VL-V2.1-2B/",
|
| 33 |
+
"metadata": {
|
| 34 |
+
"model_name": "VLM2Vec-Qwen2VL-V2.1-2B",
|
| 35 |
+
"model_size": "2", # in B, digits only here. 2 for 2B, 0.4 for 400M, etc.
|
| 36 |
+
"embedding_dimension": None, # Please fill in
|
| 37 |
+
"max_length_tokens": None, # Please fill in
|
| 38 |
+
"model_release_date": "2025-05-15", # Please adjust this date
|
| 39 |
+
"score_source": "", # e.g., "Self-Reported" or "TIGER-Lab"
|
| 40 |
+
"url": "" # e.g., Paper, GitHub, or Hugging Face link
|
| 41 |
+
}
|
| 42 |
+
},
|
| 43 |
+
]
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
# ==============================================================================
|
| 47 |
+
# TODO: Your models' metadata goes here. Please fill in the required fields.
|
| 48 |
+
# ==============================================================================
|
| 49 |
+
|
| 50 |
+
EXPERIMENTS = [
|
| 51 |
+
{
|
| 52 |
+
"path": ...,
|
| 53 |
+
"metadata": {
|
| 54 |
+
"model_name": ..., # * Mandatory Field
|
| 55 |
+
"model_backbone": ...,
|
| 56 |
+
"model_size": ...,
|
| 57 |
+
"embedding_dimension": ...,
|
| 58 |
+
"max_length_tokens": ...,
|
| 59 |
+
"model_release_date": ...,
|
| 60 |
+
"data_source": "Self-Reported",
|
| 61 |
+
"url": ...,
|
| 62 |
+
"contact": ...,
|
| 63 |
+
}
|
| 64 |
+
},
|
| 65 |
+
...
|
| 66 |
+
]
|
| 67 |
+
|
| 68 |
+
|
| 69 |
+
# ==============================================================================
|
| 70 |
+
# Main Processing Logic (No changes needed below this line)
|
| 71 |
+
# ==============================================================================
|
| 72 |
+
|
| 73 |
+
|
| 74 |
+
# Define the datasets grouped by modality
|
| 75 |
+
modality2dataset = {
|
| 76 |
+
"audio": [
|
| 77 |
+
'SpeechCommand', 'UrbanSound8k', 'ESC-50', 'NSynth', 'CREMA-D', 'Clotho', 'SoundDescs', 'TUTSound', 'TUTSound(hard)', 'AVE', 'SpeechCOCO'
|
| 78 |
+
],
|
| 79 |
+
"image": [
|
| 80 |
+
"ImageNet-1K", "N24News", "HatefulMemes", "VOC2007", "SUN397", "Place365", "ImageNet-A", "ImageNet-R", "ObjectNet", "Country211",
|
| 81 |
+
"OK-VQA", "A-OKVQA", "DocVQA", "InfographicsVQA", "ChartQA", "Visual7W", "ScienceQA", "VizWiz", "GQA", "TextVQA",
|
| 82 |
+
"VisDial", "CIRR", "VisualNews_t2i", "VisualNews_i2t", "MSCOCO_t2i", "MSCOCO_i2t", "NIGHTS", "WebQA", "FashionIQ", "Wiki-SS-NQ", "OVEN", "EDIS",
|
| 83 |
+
"MSCOCO", "RefCOCO", "RefCOCO-Matching", "Visual7W-Pointing"
|
| 84 |
+
],
|
| 85 |
+
"video": [
|
| 86 |
+
"K700", "SmthSmthV2", "HMDB51", "UCF101", "Breakfast",
|
| 87 |
+
"MVBench", "Video-MME", "NExTQA", "EgoSchema", "ActivityNetQA",
|
| 88 |
+
"DiDeMo", "MSR-VTT", "MSVD", "VATEX", "YouCook2",
|
| 89 |
+
"QVHighlight", "Charades-STA", "MomentSeeker",
|
| 90 |
+
],
|
| 91 |
+
"visdoc": [
|
| 92 |
+
"ViDoRe_arxivqa", "ViDoRe_docvqa", "ViDoRe_infovqa", "ViDoRe_tabfquad", "ViDoRe_tatdqa", "ViDoRe_shiftproject",
|
| 93 |
+
"ViDoRe_syntheticDocQA_artificial_intelligence", "ViDoRe_syntheticDocQA_energy", "ViDoRe_syntheticDocQA_government_reports", "ViDoRe_syntheticDocQA_healthcare_industry",
|
| 94 |
+
"ViDoRe_esg_reports_human_labeled_v2", "ViDoRe_biomedical_lectures_v2_multilingual", "ViDoRe_economics_reports_v2_multilingual", "ViDoRe_esg_reports_v2_multilingual",
|
| 95 |
+
"VisRAG_ArxivQA", "VisRAG_ChartQA", "VisRAG_MP-DocVQA", "VisRAG_SlideVQA", "VisRAG_InfoVQA", "VisRAG_PlotQA",
|
| 96 |
+
"ViDoSeek-page", "ViDoSeek-doc", "MMLongBench-page", "MMLongBench-doc"
|
| 97 |
+
],
|
| 98 |
+
"text": [
|
| 99 |
+
'core17-instructions', 'news21-instructions', 'robust04-instructions', 'Bioinformatics', 'Biology', 'IIYi-Clinical', 'MedQA-Diag', 'MedXpertQA-Exam', 'Medical-Sciences', 'PMC-Clinical', 'PMC-Treatment', 'Audience-v1', 'Clarity-v1', 'Format-v1', 'Language-v1', 'Length-v1', 'Source-v1', 'aops', 'biology', 'earth_science', 'economics', 'leetcode', 'pony', 'psychology', 'robotics', 'stackoverflow', 'sustainable_living', 'theoremqa_questions', 'theoremqa_theorems', '2wikimqa', 'narrativeqa', 'needle', 'passkey', 'qmsum', 'summ_screen_fd', 'Books', 'Legal Document', 'Medical Case', 'Movies', 'People', 'NanoArguAna', 'NanoClimateFEVER', 'NanoDBPedia', 'NanoFEVER', 'NanoFiQA2018', 'NanoHotpotQA', 'NanoMSMARCO', 'NanoNFCorpus', 'NanoNQ', 'NanoQuoraRetrieval', 'NanoSCIDOCS', 'NanoSciFact', 'NanoTouche2020'
|
| 100 |
+
],
|
| 101 |
+
"tool": [
|
| 102 |
+
'apibank', 'apigen', 'mnms', 'reversechain', 'rotbench', 't-eval-dialog', 't-eval-step', 'taskbench-daily', 'toolace', 'toolbench', 'toolemu', 'tooleyes', 'toollens', 'ultratool', 'autotools-food', 'autotools-music', 'autotools-weather', 'restgpt-spotify', 'restgpt-tmdb', 'craft-math-algebra', 'craft-tabmwp', 'craft-vqa', 'gorilla-huggingface', 'gorilla-pytorch', 'gorilla-tensor', 'toolink', 'appbench', 'gpt4tools', 'gta', 'taskbench-huggingface', 'taskbench-multimedia', 'metatool', 'tool-be-honest', 'toolalpaca', 'toolbench-sam'
|
| 103 |
+
],
|
| 104 |
+
"gui": [
|
| 105 |
+
'GAE-GUIAct_q2t', 'GAE-GUIAct_q2s', 'GAE-GUIAct_s2s', 'GAE-GUIAct_t2s', 'GAE-Mind2Web_q2t', 'GAE-Mind2Web_q2s', 'GAE-Mind2Web_s2s', 'GAE-Mind2Web_t2s'
|
| 106 |
+
],
|
| 107 |
+
"memory": [
|
| 108 |
+
'REALTALK', 'KnowMeBench', 'PeerQA', 'DeepPlanning'
|
| 109 |
+
]
|
| 110 |
+
}
|
| 111 |
+
modality2metric = {
|
| 112 |
+
"image": "hit@1",
|
| 113 |
+
"video": "hit@1",
|
| 114 |
+
"visdoc": "ndcg_linear@5",
|
| 115 |
+
"audio": "hit@1",
|
| 116 |
+
"text": "hit@1",
|
| 117 |
+
"tool": "hit@1",
|
| 118 |
+
"gui": "hit@1",
|
| 119 |
+
"memory": "hit@1"
|
| 120 |
+
}
|
| 121 |
+
modalities = ["image", "video", "visdoc", "audio", "text", "tool", "gui", "memory"] # Process in this order
|
| 122 |
+
|
| 123 |
+
for experiment in EXPERIMENTS:
|
| 124 |
+
base_path = experiment['path']
|
| 125 |
+
experiment_metadata = experiment['metadata']
|
| 126 |
+
experiment_name_for_log = os.path.basename(base_path.strip('/'))
|
| 127 |
+
|
| 128 |
+
current_experiment_scores = {}
|
| 129 |
+
|
| 130 |
+
print(f"\nProcessing experiment: {experiment_name_for_log}")
|
| 131 |
+
print(f"Path: {base_path}")
|
| 132 |
+
|
| 133 |
+
for modality in modalities:
|
| 134 |
+
current_experiment_scores[modality] = {}
|
| 135 |
+
modality_specific_result_dir = os.path.join(base_path, modality)
|
| 136 |
+
|
| 137 |
+
for dataset_name in modality2dataset.get(modality, []):
|
| 138 |
+
current_experiment_scores[modality][dataset_name] = "FILE_N/A" # Initialize
|
| 139 |
+
|
| 140 |
+
if not os.path.isdir(modality_specific_result_dir):
|
| 141 |
+
print(f" Directory not found: {modality_specific_result_dir}")
|
| 142 |
+
for dataset_name in modality2dataset.get(modality, []):
|
| 143 |
+
current_experiment_scores[modality][dataset_name] = "DIR_N/A"
|
| 144 |
+
continue
|
| 145 |
+
|
| 146 |
+
for filename in os.listdir(modality_specific_result_dir):
|
| 147 |
+
if filename.endswith("_score.json"):
|
| 148 |
+
score_file_path = os.path.join(modality_specific_result_dir, filename)
|
| 149 |
+
dataset_name_from_file = None
|
| 150 |
+
for known_dataset in modality2dataset.get(modality, []):
|
| 151 |
+
if filename == f"{known_dataset}_score.json":
|
| 152 |
+
dataset_name_from_file = known_dataset
|
| 153 |
+
break
|
| 154 |
+
|
| 155 |
+
if dataset_name_from_file:
|
| 156 |
+
try:
|
| 157 |
+
with open(score_file_path, "r") as f:
|
| 158 |
+
score_data = json.load(f)
|
| 159 |
+
current_experiment_scores[modality][dataset_name_from_file] = score_data
|
| 160 |
+
except json.JSONDecodeError:
|
| 161 |
+
print(f" Error decoding JSON from {score_file_path}")
|
| 162 |
+
current_experiment_scores[modality][dataset_name_from_file] = "JSON_ERROR"
|
| 163 |
+
except Exception as e:
|
| 164 |
+
print(f" Error reading file {score_file_path}: {e}")
|
| 165 |
+
current_experiment_scores[modality][dataset_name_from_file] = "READ_ERROR"
|
| 166 |
+
|
| 167 |
+
# --- Construct and Save the Final JSON Report ---
|
| 168 |
+
final_metadata = experiment_metadata.copy()
|
| 169 |
+
final_metadata['report_generated_date'] = datetime.now().isoformat()
|
| 170 |
+
# --- Special handling ---
|
| 171 |
+
# Special handling for VisDoc datasets with "-fixed" suffix
|
| 172 |
+
current_experiment_scores['visdoc'] = {(f'{k}-fixed' if k in ['MMLongBench-page', 'ViDoSeek-page'] else k): v
|
| 173 |
+
for k, v in current_experiment_scores['visdoc'].items()} # temp fix
|
| 174 |
+
# merge "tool", "gui", and "memory" into "agent"
|
| 175 |
+
# current_experiment_scores['agent'] = current_experiment_scores.pop('tool', {}) | current_experiment_scores.pop('gui', {}) | current_experiment_scores.pop('memory', {})
|
| 176 |
+
# -------------------------
|
| 177 |
+
|
| 178 |
+
final_output = {
|
| 179 |
+
"metadata": final_metadata,
|
| 180 |
+
"metrics": current_experiment_scores
|
| 181 |
+
}
|
| 182 |
+
|
| 183 |
+
output_json_path = os.path.join(base_path, f"{final_metadata['model_name']}.json")
|
| 184 |
+
try:
|
| 185 |
+
with open(output_json_path, "w") as f:
|
| 186 |
+
json.dump(final_output, f, indent=4)
|
| 187 |
+
print(f" Report for '{experiment_name_for_log}' saved to: {output_json_path}")
|
| 188 |
+
except Exception as e:
|
| 189 |
+
print(f" Error saving JSON report for '{experiment_name_for_log}' to {output_json_path}: {e}")
|
| 190 |
+
|
| 191 |
+
|
| 192 |
+
# --- Print detailed main scores per dataset for easy copy to spreadsheet ---
|
| 193 |
+
print(f"\n --- Detailed Main Scores for Spreadsheet (Experiment: {experiment_name_for_log}) ---")
|
| 194 |
+
for modality in modalities:
|
| 195 |
+
main_metric_key = modality2metric[modality]
|
| 196 |
+
for dataset_name in modality2dataset.get(modality, []):
|
| 197 |
+
score_to_print_val = "NOT_FOUND_IN_RESULTS"
|
| 198 |
+
modality_data = current_experiment_scores.get(modality, {})
|
| 199 |
+
score_info = modality_data.get(dataset_name)
|
| 200 |
+
|
| 201 |
+
if isinstance(score_info, dict):
|
| 202 |
+
metric_value = score_info.get(main_metric_key)
|
| 203 |
+
if isinstance(metric_value, (int, float)):
|
| 204 |
+
score_to_print_val = f"{metric_value:.4f}"
|
| 205 |
+
else:
|
| 206 |
+
score_to_print_val = f"METRIC_KEY_MISSING ({main_metric_key})"
|
| 207 |
+
elif isinstance(score_info, str):
|
| 208 |
+
score_to_print_val = score_info
|
| 209 |
+
|
| 210 |
+
print(f"{dataset_name}\t{score_to_print_val}")
|
| 211 |
+
print("")
|
| 212 |
+
|
| 213 |
+
# --- Print average scores and missing datasets per modality ---
|
| 214 |
+
print(f"\n --- Summary for Experiment: {experiment_name_for_log} ---")
|
| 215 |
+
for modality in modalities:
|
| 216 |
+
if modality not in current_experiment_scores:
|
| 217 |
+
print(f" Modality '{modality.upper()}' not processed.")
|
| 218 |
+
continue
|
| 219 |
+
main_metric_key = modality2metric[modality]
|
| 220 |
+
modality_data = current_experiment_scores[modality]
|
| 221 |
+
collected_metric_values = []
|
| 222 |
+
datasets_missing_score_file = []
|
| 223 |
+
datasets_file_found_metric_missing = []
|
| 224 |
+
|
| 225 |
+
for dataset_name in modality2dataset.get(modality, []):
|
| 226 |
+
score_info = modality_data.get(dataset_name)
|
| 227 |
+
if isinstance(score_info, dict):
|
| 228 |
+
metric_value = score_info.get(main_metric_key)
|
| 229 |
+
if isinstance(metric_value, (int, float)):
|
| 230 |
+
collected_metric_values.append(metric_value)
|
| 231 |
+
else:
|
| 232 |
+
datasets_file_found_metric_missing.append(f"{dataset_name} (metric '{main_metric_key}' missing/invalid)")
|
| 233 |
+
else:
|
| 234 |
+
datasets_missing_score_file.append(f"{dataset_name} (status: {score_info if score_info else 'Not Processed'})")
|
| 235 |
+
|
| 236 |
+
if collected_metric_values:
|
| 237 |
+
average_score = sum(collected_metric_values) / len(collected_metric_values)
|
| 238 |
+
print(f" Average of {modality.upper()}\t- {main_metric_key}:\t{average_score:.4f} (from {len(collected_metric_values)} datasets)")
|
| 239 |
+
else:
|
| 240 |
+
print(f" Average of {modality.upper()}\t- {main_metric_key}:\tN/A (no valid scores found)")
|
| 241 |
+
|
| 242 |
+
if datasets_missing_score_file:
|
| 243 |
+
print(f" Datasets with missing/errored score files:")
|
| 244 |
+
for ds_status in datasets_missing_score_file: print(f" - {ds_status}")
|
| 245 |
+
if datasets_file_found_metric_missing:
|
| 246 |
+
print(f" Score files found but main metric ('{main_metric_key}') missing/invalid:")
|
| 247 |
+
for ds_status in datasets_file_found_metric_missing: print(f" - {ds_status}")
|
| 248 |
+
|
| 249 |
+
|
| 250 |
+
print("\nProcessing complete.")
|
utils.py
CHANGED
|
@@ -26,13 +26,14 @@ LEADERBOARD_INTRODUCTION = """
|
|
| 26 |
- four video-based tasks: Video Retrieval, Moment Retrieval, Video Classification, and Video Question Answering
|
| 27 |
- one task focused on visual documents: Visual Document Retrieval.
|
| 28 |
|
| 29 |
-
**MMEB-V3** extends
|
| 30 |
- Audio Tasks: audio classification, cross-modal audio retrieval, and audio temporal grounding.
|
| 31 |
- Text Retrieval: instruction-following retrieval, reasoning retrieval, long-context retrieval, multi-condition retrieval, and general text retrieval.
|
| 32 |
- Agent Tasks: tool retrieval, GUI control, and agent memory retrieval.
|
| 33 |
|
| 34 |
**🔥 What's NEW:**
|
| 35 |
<ul>
|
|
|
|
| 36 |
<li>[2026-07] MMEB-V3 is accepted to COLM 2026!</li>
|
| 37 |
<li>[2026-04] MMEB-V3 released!</li>
|
| 38 |
<li>[2025-06] MMEB-V2 released!</li>
|
|
@@ -91,8 +92,14 @@ SUBMIT_INTRODUCTION = """# Submit on MMEB Leaderboard Introduction \n
|
|
| 91 |
- You can directly use the Hugging Face Space's web UI to upload your files:
|
| 92 |
- Go to the [scores folder](https://huggingface.co/spaces/TIGER-Lab/MMEB-Leaderboard/upload/main/scores)
|
| 93 |
- Select "Upload file" and upload your JSON files.
|
| 94 |
-
- Submit a pull request. We will then review and update the leaderboard accordingly.
|
| 95 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 96 |
```json
|
| 97 |
{
|
| 98 |
"metadata": {
|
|
@@ -100,7 +107,7 @@ SUBMIT_INTRODUCTION = """# Submit on MMEB Leaderboard Introduction \n
|
|
| 100 |
"url": "<Model URL>" or null,
|
| 101 |
"model_size": <Model Size> or null,
|
| 102 |
"data_source": "Self-Reported",
|
| 103 |
-
"contact": xxx@
|
| 104 |
... ...
|
| 105 |
},
|
| 106 |
"metrics": {
|
|
@@ -123,11 +130,9 @@ SUBMIT_INTRODUCTION = """# Submit on MMEB Leaderboard Introduction \n
|
|
| 123 |
}
|
| 124 |
```
|
| 125 |
## ⚠️ Special Instructions for submitting to MMEB Image (Previously MMEB-V1) Leaderboard
|
| 126 |
-
We understand that some researchers want to exclusively submit to the Image leaderboard, but unfortunately our current leaderboard
|
| 127 |
-
To do so,
|
| 128 |
-
The leaderboard will automatically assign a 0 to the missing datasets.
|
| 129 |
-
We might be able to hide your model from the other leaderboards in the next leaderboard updates, but for now your model will be shown on all leaderboards and might have a lower rank. \n
|
| 130 |
-
We highly recommend joining our [discord server](https://discord.gg/njyKubdtry), which provides a convenient way to stay informed with latest updates, or share any feedback you have for improving the leaderboard experience. We appreciate your contributions to the MMEB community!
|
| 131 |
"""
|
| 132 |
|
| 133 |
def create_hyperlinked_names(df):
|
|
|
|
| 26 |
- four video-based tasks: Video Retrieval, Moment Retrieval, Video Classification, and Video Question Answering
|
| 27 |
- one task focused on visual documents: Visual Document Retrieval.
|
| 28 |
|
| 29 |
+
**MMEB-V3** further extends to a fuller modality setting by adding three major new evaluation categories:
|
| 30 |
- Audio Tasks: audio classification, cross-modal audio retrieval, and audio temporal grounding.
|
| 31 |
- Text Retrieval: instruction-following retrieval, reasoning retrieval, long-context retrieval, multi-condition retrieval, and general text retrieval.
|
| 32 |
- Agent Tasks: tool retrieval, GUI control, and agent memory retrieval.
|
| 33 |
|
| 34 |
**🔥 What's NEW:**
|
| 35 |
<ul>
|
| 36 |
+
<li>[2026-07] MMEB-V3 Leaderboard is now live! </li>
|
| 37 |
<li>[2026-07] MMEB-V3 is accepted to COLM 2026!</li>
|
| 38 |
<li>[2026-04] MMEB-V3 released!</li>
|
| 39 |
<li>[2025-06] MMEB-V2 released!</li>
|
|
|
|
| 92 |
- You can directly use the Hugging Face Space's web UI to upload your files:
|
| 93 |
- Go to the [scores folder](https://huggingface.co/spaces/TIGER-Lab/MMEB-Leaderboard/upload/main/scores)
|
| 94 |
- Select "Upload file" and upload your JSON files.
|
| 95 |
+
- Submit a pull request and leave any comments you have. We will then review and update the leaderboard accordingly.\n
|
| 96 |
+
- To delete or modify your submission, submit a new pull request with the updated file.\n\n
|
| 97 |
+
|
| 98 |
+
## 🐞 Bug reporting and feedback
|
| 99 |
+
If you encounter any issues or have suggestions for improvement, please report them in Discussion or open an issue on our [GitHub repository](https://github.com/TIGER-AI-Lab/VLM2Vec/issues).
|
| 100 |
+
If you cannot reach us via above methods, please email us at **m7su@uwaterloo.ca**.
|
| 101 |
+
|
| 102 |
+
## Appendix 1: Please double check your score sheet have the following JSON format ⬇️: \n
|
| 103 |
```json
|
| 104 |
{
|
| 105 |
"metadata": {
|
|
|
|
| 107 |
"url": "<Model URL>" or null,
|
| 108 |
"model_size": <Model Size> or null,
|
| 109 |
"data_source": "Self-Reported",
|
| 110 |
+
"contact": xxx@xxxxx.com
|
| 111 |
... ...
|
| 112 |
},
|
| 113 |
"metrics": {
|
|
|
|
| 130 |
}
|
| 131 |
```
|
| 132 |
## ⚠️ Special Instructions for submitting to MMEB Image (Previously MMEB-V1) Leaderboard
|
| 133 |
+
We understand that some researchers want to exclusively submit to the Image leaderboard, but unfortunately our current leaderboard cannot exclude your model from other modalities' leaderboards.
|
| 134 |
+
To do so, run the 36 image datasets only and simply ignore other datasets.
|
| 135 |
+
The leaderboard will automatically assign a 0 to the missing datasets and your model will be shown on all leaderboards, and might have a lower rank. \n
|
|
|
|
|
|
|
| 136 |
"""
|
| 137 |
|
| 138 |
def create_hyperlinked_names(df):
|
utils_v3.py
CHANGED
|
@@ -6,7 +6,7 @@ from utils import create_hyperlinked_names, process_model_size
|
|
| 6 |
from datasets import *
|
| 7 |
|
| 8 |
BASE_COLS = ['Rank', 'Models', 'Model Size(B)', 'Date']
|
| 9 |
-
BASE_DATA_TITLE_TYPE = ['
|
| 10 |
|
| 11 |
OVERALL_COLS = ["Overall", "Overall-V2", "Text-Overall", 'Image-Overall', 'Video-Overall', 'Audio-Overall', 'Visdoc-Overall', "Agent-Overall"]
|
| 12 |
COLUMN_NAMES = BASE_COLS + OVERALL_COLS
|
|
@@ -43,14 +43,14 @@ COLUMN_NAMES_D = BASE_COLS + TASKS_D
|
|
| 43 |
DATA_TITLE_TYPE_D = BASE_DATA_TITLE_TYPE + \
|
| 44 |
['number'] * len(TASKS_D)
|
| 45 |
|
| 46 |
-
SUB_TASKS_AG = ['
|
| 47 |
TASKS_AG = ['Agent-Overall'] + SUB_TASKS_AG + ALL_DATASETS_SPLITS['agent']
|
| 48 |
COLUMN_NAMES_AG = BASE_COLS + TASKS_AG
|
| 49 |
DATA_TITLE_TYPE_AG = BASE_DATA_TITLE_TYPE + \
|
| 50 |
['number'] * len(TASKS_AG)
|
| 51 |
|
| 52 |
TABLE_INTRODUCTION = """**MMEB**: Massive MultiModal Embedding Benchmark \n
|
| 53 |
-
Models are ranked based on **Overall**"""
|
| 54 |
TABLE_INTRODUCTION_I = """**I-CLS**: Image Classification, **I-QA**: (Image) Visual Question Answering, **I-RET**: Image Retrieval, **I-VG**: (Image) Visual Grounding \n
|
| 55 |
Models are ranked based on **Image-Overall**\n
|
| 56 |
**Models from the old V1 leaderboard are missing detailed scores of each dataset.
|
|
@@ -58,9 +58,13 @@ TABLE_INTRODUCTION_I = """**I-CLS**: Image Classification, **I-QA**: (Image) Vis
|
|
| 58 |
and provide us the scores sheet with the new format, so that we can make them consistent with the other models' formats.**"""
|
| 59 |
TABLE_INTRODUCTION_V = """**V-CLS**: Video Classification, **V-QA**: (Video) Visual Question Answering, **V-RET**: Video Retrieval, **V-MRET**: Video Moment Retrieval \n
|
| 60 |
Models are ranked based on **Video-Overall**"""
|
|
|
|
|
|
|
| 61 |
TABLE_INTRODUCTION_D = """⚠️ Please re-evaluate your models if you see a 0 on ViDoSeek-page-fixed or MMLongBench-page-fixed datasets. \n
|
| 62 |
**VisDoc**: Visual Document Understanding \n
|
| 63 |
Models are ranked based on **Visdoc-Overall**"""
|
|
|
|
|
|
|
| 64 |
|
| 65 |
LEADERBOARD_INFO = """
|
| 66 |
## Dataset Summary
|
|
@@ -99,8 +103,12 @@ def load_data(base_dir=SCORE_BASE_DIR):
|
|
| 99 |
all_data.append(data)
|
| 100 |
return all_data
|
| 101 |
|
| 102 |
-
def load_scores(raw_scores=
|
| 103 |
"""This function loads the raw scores from the user provided scores summary and flattens them into a single dictionary."""
|
|
|
|
|
|
|
|
|
|
|
|
|
| 104 |
all_scores = {}
|
| 105 |
for modality, datasets_list in DATASETS.items(): # Ex.: ('image', {'I-CLS': [...], 'I-QA': [...]})
|
| 106 |
for sub_task, datasets in datasets_list.items(): # Ex.: ('I-CLS', ['VOC2007', 'N24News', ...])
|
|
@@ -168,13 +176,18 @@ def print_time(time: str|None):
|
|
| 168 |
except (ValueError, TypeError):
|
| 169 |
return 'unknown'
|
| 170 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 171 |
def rank_models(df, column='Overall', rank_name='Rank'):
|
| 172 |
"""Ranks the models based on the specific score."""
|
| 173 |
df = df.sort_values(by=column, ascending=False).reset_index(drop=True)
|
| 174 |
-
df[rank_name] =
|
| 175 |
return df
|
| 176 |
|
| 177 |
-
def get_df():
|
| 178 |
"""Generates a DataFrame from the loaded data."""
|
| 179 |
all_data = load_data()
|
| 180 |
rows = [generate_model_row(data) for data in all_data]
|
|
@@ -182,7 +195,7 @@ def get_df():
|
|
| 182 |
df['Model Size(B)'] = df['Model Size(B)'].apply(process_model_size)
|
| 183 |
df['Date'] = df['Date'].apply(print_time)
|
| 184 |
df = create_hyperlinked_names(df)
|
| 185 |
-
df = rank_models(df, column=
|
| 186 |
return df
|
| 187 |
|
| 188 |
def refresh_data():
|
|
|
|
| 6 |
from datasets import *
|
| 7 |
|
| 8 |
BASE_COLS = ['Rank', 'Models', 'Model Size(B)', 'Date']
|
| 9 |
+
BASE_DATA_TITLE_TYPE = ['str', 'markdown', 'str', 'str']
|
| 10 |
|
| 11 |
OVERALL_COLS = ["Overall", "Overall-V2", "Text-Overall", 'Image-Overall', 'Video-Overall', 'Audio-Overall', 'Visdoc-Overall', "Agent-Overall"]
|
| 12 |
COLUMN_NAMES = BASE_COLS + OVERALL_COLS
|
|
|
|
| 43 |
DATA_TITLE_TYPE_D = BASE_DATA_TITLE_TYPE + \
|
| 44 |
['number'] * len(TASKS_D)
|
| 45 |
|
| 46 |
+
SUB_TASKS_AG = ['Tool', 'GUI', 'Memory']
|
| 47 |
TASKS_AG = ['Agent-Overall'] + SUB_TASKS_AG + ALL_DATASETS_SPLITS['agent']
|
| 48 |
COLUMN_NAMES_AG = BASE_COLS + TASKS_AG
|
| 49 |
DATA_TITLE_TYPE_AG = BASE_DATA_TITLE_TYPE + \
|
| 50 |
['number'] * len(TASKS_AG)
|
| 51 |
|
| 52 |
TABLE_INTRODUCTION = """**MMEB**: Massive MultiModal Embedding Benchmark \n
|
| 53 |
+
Models are ranked based on **Overall-V2**."""
|
| 54 |
TABLE_INTRODUCTION_I = """**I-CLS**: Image Classification, **I-QA**: (Image) Visual Question Answering, **I-RET**: Image Retrieval, **I-VG**: (Image) Visual Grounding \n
|
| 55 |
Models are ranked based on **Image-Overall**\n
|
| 56 |
**Models from the old V1 leaderboard are missing detailed scores of each dataset.
|
|
|
|
| 58 |
and provide us the scores sheet with the new format, so that we can make them consistent with the other models' formats.**"""
|
| 59 |
TABLE_INTRODUCTION_V = """**V-CLS**: Video Classification, **V-QA**: (Video) Visual Question Answering, **V-RET**: Video Retrieval, **V-MRET**: Video Moment Retrieval \n
|
| 60 |
Models are ranked based on **Video-Overall**"""
|
| 61 |
+
TABLE_INTRODUCTION_A = """**A-CLS**: Audio Classification, **A-RET**: Audio Retrieval \n
|
| 62 |
+
Models are ranked based on **Audio-Overall**"""
|
| 63 |
TABLE_INTRODUCTION_D = """⚠️ Please re-evaluate your models if you see a 0 on ViDoSeek-page-fixed or MMLongBench-page-fixed datasets. \n
|
| 64 |
**VisDoc**: Visual Document Understanding \n
|
| 65 |
Models are ranked based on **Visdoc-Overall**"""
|
| 66 |
+
TABLE_INTRODUCTION_AG = """**Tool**: Tool Retrieval, **GUI**: GUI Control, **Memory**: Agent Memory Retrieval \n
|
| 67 |
+
Models are ranked based on **Agent-Overall**"""
|
| 68 |
|
| 69 |
LEADERBOARD_INFO = """
|
| 70 |
## Dataset Summary
|
|
|
|
| 103 |
all_data.append(data)
|
| 104 |
return all_data
|
| 105 |
|
| 106 |
+
def load_scores(raw_scores={}):
|
| 107 |
"""This function loads the raw scores from the user provided scores summary and flattens them into a single dictionary."""
|
| 108 |
+
# temp fix, will figure out later ===========
|
| 109 |
+
if any(_ in raw_scores for _ in ['tool', 'gui', 'memory']):
|
| 110 |
+
raw_scores['agent'] = raw_scores.pop('tool', {}) | raw_scores.pop('gui', {}) | raw_scores.pop('memory', {})
|
| 111 |
+
# ===========================================
|
| 112 |
all_scores = {}
|
| 113 |
for modality, datasets_list in DATASETS.items(): # Ex.: ('image', {'I-CLS': [...], 'I-QA': [...]})
|
| 114 |
for sub_task, datasets in datasets_list.items(): # Ex.: ('I-CLS', ['VOC2007', 'N24News', ...])
|
|
|
|
| 176 |
except (ValueError, TypeError):
|
| 177 |
return 'unknown'
|
| 178 |
|
| 179 |
+
medal_map = {
|
| 180 |
+
"1": "🏆",
|
| 181 |
+
"2": "🥈",
|
| 182 |
+
"3": "🥉"
|
| 183 |
+
}
|
| 184 |
def rank_models(df, column='Overall', rank_name='Rank'):
|
| 185 |
"""Ranks the models based on the specific score."""
|
| 186 |
df = df.sort_values(by=column, ascending=False).reset_index(drop=True)
|
| 187 |
+
df[rank_name] = df[column].rank(method='min', ascending=False).astype(int).astype(str).map(lambda x: medal_map.get(x, x))
|
| 188 |
return df
|
| 189 |
|
| 190 |
+
def get_df(rank_column='Overall'):
|
| 191 |
"""Generates a DataFrame from the loaded data."""
|
| 192 |
all_data = load_data()
|
| 193 |
rows = [generate_model_row(data) for data in all_data]
|
|
|
|
| 195 |
df['Model Size(B)'] = df['Model Size(B)'].apply(process_model_size)
|
| 196 |
df['Date'] = df['Date'].apply(print_time)
|
| 197 |
df = create_hyperlinked_names(df)
|
| 198 |
+
df = rank_models(df, column=rank_column)
|
| 199 |
return df
|
| 200 |
|
| 201 |
def refresh_data():
|