Spaces:
Running
Running
File size: 11,095 Bytes
6ae8aba 10db86a 5b42e90 78efe8b 6ae8aba 5b42e90 bf9faf8 6ae8aba 5b42e90 bf9faf8 6ae8aba 01ad525 baae497 74aafd0 10db86a 74aafd0 01ad525 baae497 74aafd0 10db86a 74aafd0 bf9faf8 01ad525 74aafd0 10db86a 74aafd0 bf9faf8 64dcfc0 5b42e90 64dcfc0 78ffed6 64dcfc0 bf9faf8 10db86a 78ffed6 bf9faf8 6ae8aba bf9faf8 78efe8b bf9faf8 6ae8aba 74aafd0 6ae8aba bf9faf8 74aafd0 bf9faf8 74aafd0 0d46775 74aafd0 10db86a 592b931 74aafd0 5fe97ad 74aafd0 6ae8aba 74aafd0 6ae8aba 74aafd0 64dcfc0 bf9faf8 5b42e90 74aafd0 64dcfc0 74aafd0 64dcfc0 74aafd0 6ae8aba 5b42e90 64dcfc0 5b42e90 10db86a 6ae8aba 10db86a bf9faf8 10db86a bf9faf8 baae497 64dcfc0 bf9faf8 64dcfc0 bf9faf8 6ae8aba 5b42e90 10db86a 6ae8aba bf9faf8 6ae8aba 5b42e90 6ae8aba d7a1226 10db86a d7a1226 10db86a d7a1226 10db86a d7a1226 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 | import json
import os
import pandas as pd
from datetime import datetime
from utils import create_hyperlinked_names, process_model_size, MODEL_SIZE_COL_NAME
from datasets import *
BASE_COLS = ['Rank', 'Models', MODEL_SIZE_COL_NAME, 'Date']
BASE_DATA_TITLE_TYPE = ['str', 'markdown', 'str', 'str']
OVERALL_COLS_V2 = ["Overall-V2", 'Image-Overall', 'Video-Overall', 'Visdoc-Overall']
COLUMN_NAMES_V2 = BASE_COLS + OVERALL_COLS_V2
DATA_TITLE_TYPE_V2 = BASE_DATA_TITLE_TYPE + \
['number'] * len(OVERALL_COLS_V2)
OVERALL_COLS_V3 = ["Overall", "Overall-V3๐", "Text-Overall", "Audio-Overall", "Agent-Overall"]
COLUMN_NAMES_V3 = BASE_COLS + OVERALL_COLS_V3
DATA_TITLE_TYPE_V3 = BASE_DATA_TITLE_TYPE + \
['number'] * len(OVERALL_COLS_V3)
SUB_TASKS_T = ["FollowIR", "R2MED", "InfoSearch", "BRIGHT", "LongEmbed", "MultiConIR", "NanoBEIR"]
TASKS_T = ['Text-Overall'] + SUB_TASKS_T + ALL_DATASETS_SPLITS['text']
COLUMN_NAMES_T = BASE_COLS + TASKS_T
DATA_TITLE_TYPE_T = BASE_DATA_TITLE_TYPE + \
['number'] * len(TASKS_T)
SUB_TASKS_I = ["I-CLS", "I-QA", "I-RET", "I-VG"]
TASKS_I = ['Image-Overall'] + SUB_TASKS_I + ALL_DATASETS_SPLITS['image']
COLUMN_NAMES_I = BASE_COLS + TASKS_I
DATA_TITLE_TYPE_I = BASE_DATA_TITLE_TYPE + \
['number'] * len(TASKS_I)
SUB_TASKS_V = ["V-CLS", "V-QA", "V-RET", "V-MRET"]
TASKS_V = ['Video-Overall'] + SUB_TASKS_V + ALL_DATASETS_SPLITS['video']
COLUMN_NAMES_V = BASE_COLS + TASKS_V
DATA_TITLE_TYPE_V = BASE_DATA_TITLE_TYPE + \
['number'] * len(TASKS_V)
SUB_TASKS_A = ["A-CLS", "A-RET"]
TASKS_A = ['Audio-Overall'] + SUB_TASKS_A + ALL_DATASETS_SPLITS['audio']
COLUMN_NAMES_A = BASE_COLS + TASKS_A
DATA_TITLE_TYPE_A = BASE_DATA_TITLE_TYPE + \
['number'] * len(TASKS_A)
SUB_TASKS_D = ['ViDoRe-V1', 'ViDoRe-V2', 'VisRAG', 'VisDoc-OOD']
TASKS_D = ['Visdoc-Overall'] + SUB_TASKS_D + ALL_DATASETS_SPLITS['visdoc']
COLUMN_NAMES_D = BASE_COLS + TASKS_D
DATA_TITLE_TYPE_D = BASE_DATA_TITLE_TYPE + \
['number'] * len(TASKS_D)
SUB_TASKS_AG = ['Tool', 'GUI', 'Memory']
TASKS_AG = ['Agent-Overall'] + SUB_TASKS_AG + ALL_DATASETS_SPLITS['agent']
COLUMN_NAMES_AG = BASE_COLS + TASKS_AG
DATA_TITLE_TYPE_AG = BASE_DATA_TITLE_TYPE + \
['number'] * len(TASKS_AG)
TABLE_INTRODUCTION = """**MMEB**: Massive MultiModal Embedding Benchmark \n
Models are ranked based on **Overall**(V3-ALL). **Overall-V3๐**: Newly added datasets in V3."""
TABLE_INTRODUCTION_I = """**I-CLS**: Image Classification, **I-QA**: (Image) Visual Question Answering, **I-RET**: Image Retrieval, **I-VG**: (Image) Visual Grounding \n
Models are ranked based on **Image-Overall**\n
**Models from the old V1 leaderboard are missing detailed scores of each dataset.
We hope the authors of the models on V1 leaderboard could rerun your models using our updated V2 pipeline,
and provide us the scores sheet with the new format, so that we can make them consistent with the other models' formats.**"""
TABLE_INTRODUCTION_V = """**V-CLS**: Video Classification, **V-QA**: (Video) Visual Question Answering, **V-RET**: Video Retrieval, **V-MRET**: Video Moment Retrieval \n
Models are ranked based on **Video-Overall**"""
TABLE_INTRODUCTION_A = """**A-CLS**: Audio Classification, **A-RET**: Audio Retrieval \n
Models are ranked based on **Audio-Overall**"""
TABLE_INTRODUCTION_D = """โ ๏ธ Please re-evaluate your models if you see a 0 on ViDoSeek-page-fixed or MMLongBench-page-fixed datasets. \n
**VisDoc**: Visual Document Understanding \n
Models are ranked based on **Visdoc-Overall**"""
TABLE_INTRODUCTION_AG = """**Tool**: Tool Retrieval, **GUI**: GUI Control, **Memory**: Agent Memory Retrieval \n
Models are ranked based on **Agent-Overall**"""
LEADERBOARD_INFO = """
## Dataset Summary
"""
CITATION_BUTTON_TEXT_V2 = r"""@misc{meng2025vlm2vecv2advancingmultimodalembedding,
title={VLM2Vec-V2: Advancing Multimodal Embedding for Videos, Images, and Visual Documents},
author={Rui Meng and Ziyan Jiang and Ye Liu and Mingyi Su and Xinyi Yang and Yuepeng Fu and Can Qin and Zeyuan Chen and Ran Xu and Caiming Xiong and Yingbo Zhou and Wenhu Chen and Semih Yavuz},
year={2025},
eprint={2507.04590},
archivePrefix={arXiv},
primaryClass={cs.CV},
url={https://arxiv.org/abs/2507.04590},
}"""
CITATION_BUTTON_TEXT_V3 = r"""@misc{huang2026mmebv3measuringperformancegaps,
title={MMEB-V3: Measuring the Performance Gaps of Omni-Modality Embedding Models},
author={Haohang Huang and Xuan Lu and Mingyi Su and Xuan Zhang and Ziyan Jiang and Ping Nie and Kai Zou and Tomas Pfister and Wenhu Chen and Wei Zhang and Xiaoyu Shen and Rui Meng},
year={2026},
eprint={2604.23321},
archivePrefix={arXiv},
primaryClass={cs.IR},
url={https://arxiv.org/abs/2604.23321},
}"""
def load_single_json(file_path):
with open(file_path, 'r') as file:
data = json.load(file)
return data
def load_data(base_dir=SCORE_BASE_DIR):
all_data = []
for file_name in os.listdir(base_dir):
if file_name.endswith('.json'):
file_path = os.path.join(base_dir, file_name)
data = load_single_json(file_path)
all_data.append(data)
return all_data
def load_scores(raw_scores={}):
"""This function loads the raw scores from the user provided scores summary and flattens them into a single dictionary."""
# temp fix, will figure out later ===========
if any(_ in raw_scores for _ in ['tool', 'gui', 'memory']):
raw_scores['agent'] = raw_scores.pop('tool', {}) | raw_scores.pop('gui', {}) | raw_scores.pop('memory', {})
# ===========================================
all_scores = {}
for modality, datasets_list in DATASETS.items(): # Ex.: ('image', {'I-CLS': [...], 'I-QA': [...]})
for sub_task, datasets in datasets_list.items(): # Ex.: ('I-CLS', ['VOC2007', 'N24News', ...])
for dataset in datasets: # Ex.: 'VOC2007'
score = raw_scores.get(modality, {}).get(dataset, 0.0)
score = 0.0 if isinstance(score, str) and "N/A" in score else score
metric = SPECIAL_METRICS.get(dataset, 'hit@1')
if isinstance(score, dict):
if 'visdoc' in modality:
metric = "ndcg_linear@5" if "ndcg_linear@5" in score else "ndcg@5"
score = score.get(metric, 0.0)
all_scores[dataset] = round(score * 100.0, 2)
return all_scores
def calculate_score(raw_scores=None):
"""This function calculates the overall average scores for all datasets as well as avg scores for each modality and sub-task based on the raw scores.
"""
def get_avg(sum_score, leng):
avg = sum_score / leng if leng > 0 else 0.0
avg = round(avg, 2) # Round to 2 decimal places
return avg
all_scores = load_scores(raw_scores)
avg_scores = {}
# Calculate overall score for all datasets
avg_scores['Overall'] = get_avg(sum(all_scores.values()), len(ALL_DATASETS))
v2_scores = {k:v for k,v in all_scores.items() if k in ALL_DATASETS_SPLITS['image'] or k in ALL_DATASETS_SPLITS['video'] or k in ALL_DATASETS_SPLITS['visdoc']}
avg_scores['Overall-V2'] = get_avg(sum(v2_scores.values()), len(v2_scores))
v3_newonly_scores = {k:v for k,v in all_scores.items() if k in ALL_DATASETS_SPLITS['text'] or k in ALL_DATASETS_SPLITS['audio'] or k in ALL_DATASETS_SPLITS['agent']}
avg_scores['Overall-V3๐'] = get_avg(sum(v3_newonly_scores.values()), len(v3_newonly_scores))
# Calculate scores for each modality
for modality in MODALITIES:
datasets_for_each_modality = ALL_DATASETS_SPLITS[modality]
avg_scores[f"{modality.capitalize()}-Overall"] = get_avg(
sum(all_scores.get(dataset, 0.0) for dataset in datasets_for_each_modality),
len(datasets_for_each_modality)
)
# Calculate scores for each sub-task
for modality, datasets_list in DATASETS.items():
for sub_task, datasets in datasets_list.items():
sub_task_score = sum(all_scores.get(dataset, 0.0) for dataset in datasets)
avg_scores[sub_task] = get_avg(sub_task_score, len(datasets))
all_scores.update(avg_scores)
return all_scores
def generate_model_row(data):
metadata = data['metadata']
row = {
'Models': metadata.get('model_name', None),
MODEL_SIZE_COL_NAME: metadata.get('model_size', None),
'URL': metadata.get('url', None),
'Submitted by': metadata.get('data_source', 'Self-Reported'),
'Date': metadata.get('report_generated_date', None)
}
scores = calculate_score(data['metrics'])
row.update(scores)
return row
def print_time(time: str|None):
try:
dt = datetime.strptime(time, "%Y-%m-%dT%H:%M:%S.%f")
return dt.strftime("%y-%m-%d")
except (ValueError, TypeError):
return 'unknown'
medal_map = {
"1": "๐",
"2": "๐ฅ",
"3": "๐ฅ"
}
def rank_models(df, column='Overall', rank_name='Rank'):
"""Ranks the models based on the specific score."""
df = df.sort_values(by=column, ascending=False).reset_index(drop=True)
df[rank_name] = df[column].rank(method='min', ascending=False).astype(int).astype(str).map(lambda x: medal_map.get(x, x))
return df
def get_df(rank_column='Overall'):
"""Generates a DataFrame from the loaded data."""
all_data = load_data()
rows = [generate_model_row(data) for data in all_data]
df = pd.DataFrame(rows)
df[MODEL_SIZE_COL_NAME] = df[MODEL_SIZE_COL_NAME].apply(process_model_size)
df['Date'] = df['Date'].apply(print_time)
df = create_hyperlinked_names(df)
df = rank_models(df, column=rank_column)
return df
def refresh_data():
df = get_df()
return df[COLUMN_NAMES]
def search_and_filter_models(df, query, min_size, max_size):
filtered_df = df.copy()
if query:
filtered_df = filtered_df[filtered_df['Models'].str.contains(query, case=False, na=False)]
size_mask = filtered_df[MODEL_SIZE_COL_NAME].apply(lambda x:
(min_size <= 1000.0 <= max_size) if x == 'unknown'
else (min_size <= x <= max_size))
filtered_df = filtered_df[size_mask]
return filtered_df[COLUMN_NAMES]
def save_ranking_summary(df, name, save_now=True, dir='rankings'):
csv_path, json_path = os.path.join(dir, f'{name}.csv'), os.path.join(dir, f'{name}.jsonl')
if save_now:
df.to_csv(csv_path, index=False)
df.to_json(json_path, orient='records', lines=True)
return csv_path, json_path
def download_ranking(df, name, format='csv', dir='rankings'):
csv_path, json_path = save_ranking_summary(df, name, save_now=False, dir=dir)
return csv_path if format == 'csv' else json_path
|