Slep's picture
Cosmetic Changes
81bfe1c
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()