Spaces:
Runtime error
Runtime error
import pandas as pd | |
import gradio as gr | |
from collections import OrderedDict | |
import logging | |
import tempfile | |
import os | |
from huggingface_hub import ( | |
HfApi, | |
hf_hub_download, | |
get_safetensors_metadata, | |
metadata_load, | |
) | |
from utils.misc import human_format, make_clickable_model | |
logging.basicConfig(level=logging.INFO) | |
logger = logging.getLogger(__name__) | |
EXCLUDED_MODELS = [] # For models that misbehave :) | |
K_EVALUATIONS = [1, 5, 10, 20, 50] | |
DIST_EVALUATIONS = [1_000_000, 500_000, 100_000, 10_000] | |
EXPECTED_KEY_TO_COLNAME = OrderedDict( | |
[ | |
("rank", "Rank"), # Just for columns order | |
("model", "Model"), # Just for columns order | |
("model_size", "Model Size (Million)"), # Just for columns order | |
("conditioning", "Conditioning"), | |
("embedding_dim", "Embedding Dimension"), | |
] | |
+ [ | |
(f"recall_at_{K}|{D}", f"R@{K} +{human_format(D)} Dist.") | |
for D in DIST_EVALUATIONS | |
for K in K_EVALUATIONS | |
] | |
+ [ | |
("n_dists", "Available Dists"), | |
], | |
) | |
def get_safetensors_nparams(modelId): | |
try: | |
safetensors = get_safetensors_metadata(modelId) | |
num_parameters = sum(safetensors.parameter_count.values()) | |
return round(num_parameters / 1e6) | |
except Exception: | |
pass | |
def parse_model(m): | |
readme_path = hf_hub_download(m.modelId, filename="README.md") | |
meta = metadata_load(readme_path) | |
if "model-index" not in meta: | |
raise ValueError("Missing `model-index` in metadata") | |
for result in meta["model-index"][0]["results"]: | |
if result["dataset"]["type"] == "Slep/LAION-RVS-Fashion": | |
break # Found the right dataset | |
# Get data from model-index / safetensors metadata | |
d = { | |
EXPECTED_KEY_TO_COLNAME["model"]: make_clickable_model(m.modelId), | |
EXPECTED_KEY_TO_COLNAME["model_size"]: get_safetensors_nparams(m.modelId), | |
} | |
# Get data from exported results | |
for metric in result["metrics"]: | |
t = metric["type"] | |
if t in EXPECTED_KEY_TO_COLNAME: | |
d[EXPECTED_KEY_TO_COLNAME[t]] = metric["value"] | |
return d | |
def get_data_from_hub(): | |
api = HfApi() | |
models = api.list_models(filter="lrvsf-benchmark") | |
df_list = [] | |
for m in models: | |
if m.modelId in EXCLUDED_MODELS: | |
continue | |
try: | |
parsed = parse_model(m) | |
if parsed: | |
df_list.append(parsed) | |
except Exception as e: | |
logging.warning(f"Failed to parse model {m.modelId} : {e}") | |
return pd.DataFrame(df_list, columns=EXPECTED_KEY_TO_COLNAME.values()) | |
def filter_dataframe(df, k_filter, d_filter, c_filter): | |
# ===== FILTER COLUMNS | |
# Fixed column positions | |
selected_columns = [ | |
EXPECTED_KEY_TO_COLNAME["rank"], | |
EXPECTED_KEY_TO_COLNAME["model"], | |
EXPECTED_KEY_TO_COLNAME["conditioning"], | |
EXPECTED_KEY_TO_COLNAME["model_size"], | |
EXPECTED_KEY_TO_COLNAME["embedding_dim"], | |
] | |
datatypes = ["number", "markdown", "number", "number"] | |
for key, name in EXPECTED_KEY_TO_COLNAME.items(): | |
if name in selected_columns: | |
# Already added, probably part of the initial columns | |
continue | |
if key.startswith("recall_at_"): | |
# Process : recall_at_K|D -> recall_at_K , D -> K , D | |
# Could be a regex... but simple enough | |
recall_at_K, D = key.split("|") | |
K = recall_at_K.split("_")[-1] | |
if int(K) in k_filter and int(D) in d_filter: | |
selected_columns.append(name) | |
datatypes.append("str") # Because of the ± std | |
selected_columns.append(EXPECTED_KEY_TO_COLNAME["n_dists"]) | |
datatypes.append("number") | |
df = df[selected_columns] | |
# ===== FILTER ROWS | |
if c_filter != "all": | |
df = df[df[EXPECTED_KEY_TO_COLNAME["conditioning"]] == c_filter] | |
return df[selected_columns], datatypes | |
def add_rank(df): | |
main_metrics = df["R@1 +1M Dist."].str.split("±").str[0].astype(float) | |
# Argsort is from smallest to largest so we reverse it | |
df["Rank"] = df.shape[0] - main_metrics.argsort() | |
return df | |
def save_current_leaderboard(df): | |
filename = tempfile.NamedTemporaryFile( | |
prefix="lrvsf_export_", suffix=".csv", delete=False | |
).name | |
df.to_csv(filename, index=False) | |
return filename | |
def load_lrvsf_models(k_filter, d_filter, c_filter, csv_file): | |
# Remove previous tmpfile | |
if csv_file: | |
os.remove(csv_file) | |
df = get_data_from_hub() | |
df = add_rank(df) | |
df, datatypes = filter_dataframe(df, k_filter, d_filter, c_filter) | |
df = df.sort_values(by="Rank") | |
filename = save_current_leaderboard(df) | |
outputs = [ | |
gr.DataFrame(value=df, datatype=datatypes), | |
gr.File(filename, label="CSV File"), | |
] | |
return outputs | |
if __name__ == "__main__": | |
with gr.Blocks() as demo: | |
gr.Markdown( | |
""" | |
# 👗 LAION - Referred Visual Search - Fashion : Leaderboard | |
- To submit, refer to the [LAION-RVS-Fashion Benchmark repository](https://github.com/Simon-Lepage/LRVSF-Benchmark). | |
- For details on the task and the dataset, refer to the [LRVSF paper](https://arxiv.org/abs/2306.02928). | |
- To download the leaderboard as CSV, click on the file below the table. | |
""" | |
) | |
with gr.Row(): | |
k_filter = gr.CheckboxGroup( | |
choices=K_EVALUATIONS, value=K_EVALUATIONS, label="Recall at K" | |
) | |
d_filter = gr.CheckboxGroup( | |
choices=[(human_format(D), D) for D in DIST_EVALUATIONS], | |
value=DIST_EVALUATIONS, | |
label="Number of Distractors", | |
) | |
c_filter = gr.Radio( | |
choices=["all", "category", "text"], | |
value="all", | |
label="Conditioning", | |
) | |
df_table = gr.Dataframe(type="pandas", interactive=False) | |
csv_file = gr.File(interactive=False) | |
refresh = gr.Button("Refresh") | |
# Actions | |
refresh.click( | |
load_lrvsf_models, | |
inputs=[k_filter, d_filter, c_filter, csv_file], | |
outputs=[df_table, csv_file], | |
) | |
demo.load( | |
load_lrvsf_models, | |
inputs=[k_filter, d_filter, c_filter, csv_file], | |
outputs=[df_table, csv_file], | |
) | |
demo.launch() | |