MINGYISU commited on
Commit
e0f67eb
·
1 Parent(s): 4b9147f

v3 update part 2

Browse files
Files changed (5) hide show
  1. app.py +3 -1
  2. datasets.py +6 -4
  3. report_score_v3.py +250 -0
  4. utils.py +14 -9
  5. 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", "ESC50", "NSynth", "CREMA-D"],
40
- "A-RET": ['Clotho', 'SoundDescs', 'TUTSound', 'TUTSound(hard)', 'AVE', 'SpeechCOCO', '?Event']
41
  },
42
  "agent": {
43
- "ToolRET": ['toolde/web/apibank', 'toolde/web/apigen', 'toolde/web/mnms', 'toolde/web/reversechain', 'toolde/web/rotbench', 'toolde/web/t-eval-dialog', 'toolde/web/t-eval-step', 'toolde/web/taskbench-daily', 'toolde/web/toolace', 'toolde/web/toolbench', 'toolde/web/toolemu', 'toolde/web/tooleyes', 'toolde/web/toollens', 'toolde/web/ultratool', 'toolde/web/autotools-food', 'toolde/web/autotools-music', 'toolde/web/autotools-weather', 'toolde/web/restgpt-spotify', 'toolde/web/restgpt-tmdb', 'toolde/code/craft-math-algebra', 'toolde/code/craft-tabmwp', 'toolde/code/craft-vqa', 'toolde/code/gorilla-huggingface', 'toolde/code/gorilla-pytorch', 'toolde/code/gorilla-tensor', 'toolde/code/toolink', 'toolde/customized/appbench', 'toolde/customized/gpt4tools', 'toolde/customized/gta', 'toolde/customized/taskbench-huggingface', 'toolde/customized/taskbench-multimedia', 'toolde/customized/metatool', 'toolde/customized/tool-be-honest', 'toolde/customized/toolalpaca', 'toolde/customized/toolbench-sam'],
 
 
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
- "MemRET": ["REALTALK", "KnowMeBench", "PeerQA", "DeepPlanning"]
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 MMEB-V2 toward 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 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. \n\n
95
- ## Please double check your score sheet have the following JSON format ⬇️: \n
 
 
 
 
 
 
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@gmail.com
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 system cannot exclude your model from other modalities' leaderboards.
127
- To do so, please run the 36 image datasets only and simply ignore the other datasets.
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 = ['number', '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,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 = ['ToolRET', 'GUI', 'MemRET']
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=None):
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] = range(1, len(df) + 1)
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='Overall')
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():