Spaces:
Running
Running
| import gradio as gr | |
| import pandas as pd | |
| import os | |
| # Load data from CSV files | |
| DATA_DIR = "data" | |
| def load_csv_data(filename): | |
| """Load data from CSV file""" | |
| filepath = os.path.join(DATA_DIR, filename) | |
| if os.path.exists(filepath): | |
| return pd.read_csv(filepath) | |
| else: | |
| return pd.DataFrame() | |
| # Load datasets | |
| CLASSIFICATION_DF = load_csv_data("classification.csv") | |
| DETECTION_DF = load_csv_data("detection.csv") | |
| SEGMENTATION_DF = load_csv_data("segmentation.csv") | |
| def filter_and_search(df, search, datasets, models, organizations, columns): | |
| filtered = df.copy() | |
| if search: | |
| mask = filtered.apply(lambda row: row.astype(str).str.contains(search, case=False).any(), axis=1) | |
| filtered = filtered[mask] | |
| if datasets: | |
| filtered = filtered[filtered["Dataset"].isin(datasets)] | |
| if models: | |
| filtered = filtered[filtered["Model"].isin(models)] | |
| if organizations: | |
| filtered = filtered[filtered["Organization"].isin(organizations)] | |
| if columns: | |
| display_cols = [col for col in columns if col in filtered.columns] | |
| filtered = filtered[display_cols] | |
| return filtered | |
| def build_tab(df, name): | |
| """Build a leaderboard tab from a DataFrame""" | |
| if df.empty: | |
| return gr.TabItem(name) | |
| # Pivot the dataframe to have columns like "Dataset1 (Metric1)", "Dataset1 (Metric2)", etc. | |
| datasets = sorted(df["Dataset"].unique().tolist()) | |
| models = sorted(df["Model"].unique().tolist()) | |
| organizations = sorted(df["Organization"].unique().tolist()) | |
| metric_cols = [col for col in df.columns if col not in ["Model", "Organization", "Dataset", "Author", "Author Link"]] | |
| # Create pivoted dataframe | |
| pivoted_data = [] | |
| for model in models: | |
| for org in organizations: | |
| model_org_data = df[(df["Model"] == model) & (df["Organization"] == org)] | |
| if not model_org_data.empty: | |
| # Get Author and Author Link from the first entry (they should be the same for model+org) | |
| author = model_org_data["Author"].values[0] | |
| author_link = model_org_data["Author Link"].values[0] | |
| # Format as markdown link if author_link exists | |
| if pd.notna(author_link) and author_link.strip(): | |
| author_display = f"[{author}]({author_link})" | |
| else: | |
| author_display = author | |
| row = {"Model": model, "Organization": org, "Author": author_display} | |
| for dataset in datasets: | |
| dataset_data = model_org_data[model_org_data["Dataset"] == dataset] | |
| if not dataset_data.empty: | |
| for metric in metric_cols: | |
| col_name = f"{dataset} ({metric})" | |
| row[col_name] = dataset_data[metric].values[0] | |
| else: | |
| for metric in metric_cols: | |
| col_name = f"{dataset} ({metric})" | |
| row[col_name] = "-" | |
| pivoted_data.append(row) | |
| pivoted_df = pd.DataFrame(pivoted_data) | |
| # Build column list for selector | |
| metric_combo_cols = [] | |
| for dataset in datasets: | |
| for metric in metric_cols: | |
| metric_combo_cols.append(f"{dataset} ({metric})") | |
| all_cols = ["Model", "Organization", "Author"] + metric_combo_cols | |
| with gr.TabItem(name, elem_id="llm-benchmark-tab-table"): | |
| with gr.Row(): | |
| with gr.Column(scale=4): | |
| search_bar = gr.Textbox( | |
| label="Search", | |
| placeholder="Separate multiple queries with ';'", | |
| elem_id="search-bar" | |
| ) | |
| # Column selector for base columns only (not dataset+metric combos) | |
| base_cols = ["Model", "Organization", "Author"] | |
| col_selector = gr.CheckboxGroup( | |
| choices=base_cols, | |
| value=base_cols, | |
| label="Select Columns to Display:", | |
| elem_classes="column-select" | |
| ) | |
| # Set datatype to 'markdown' for Author column to enable clickable links | |
| datatypes = [] | |
| for col in pivoted_df.columns: | |
| if col == "Author": | |
| datatypes.append("markdown") | |
| else: | |
| datatypes.append("str") | |
| table = gr.Dataframe( | |
| value=pivoted_df, | |
| elem_id="leaderboard-table", | |
| interactive=False, | |
| wrap=True, | |
| datatype=datatypes | |
| ) | |
| with gr.Column(scale=1): | |
| gr.Markdown("**Model types**") | |
| model_filter = gr.CheckboxGroup( | |
| choices=models, | |
| value=models, | |
| label="", | |
| elem_classes="filter-group" | |
| ) | |
| gr.Markdown("**Organizations**") | |
| org_filter = gr.CheckboxGroup( | |
| choices=organizations, | |
| value=organizations, | |
| label="", | |
| elem_classes="filter-group" | |
| ) | |
| gr.Markdown("**Datasets**") | |
| dataset_filter = gr.CheckboxGroup( | |
| choices=datasets, | |
| value=datasets, | |
| label="", | |
| elem_classes="filter-group" | |
| ) | |
| gr.Markdown("**Metrics**") | |
| metric_filter = gr.CheckboxGroup( | |
| choices=metric_cols, | |
| value=metric_cols, | |
| label="", | |
| elem_classes="filter-group" | |
| ) | |
| def update(search, md, org, dset, metrics, cols): | |
| filtered = pivoted_df.copy() | |
| if search: | |
| mask = filtered.apply(lambda row: row.astype(str).str.contains(search, case=False).any(), axis=1) | |
| filtered = filtered[mask] | |
| if md: | |
| filtered = filtered[filtered["Model"].isin(md)] | |
| if org: | |
| filtered = filtered[filtered["Organization"].isin(org)] | |
| # Build display columns based on selected base columns and dataset/metric filters | |
| display_cols = [] | |
| # Add selected base columns | |
| for col in cols: | |
| if col in base_cols: | |
| display_cols.append(col) | |
| # Add metric columns that match selected datasets and metrics | |
| for col in metric_combo_cols: | |
| # Check if this column matches selected datasets and metrics | |
| col_dataset = col.split(" (")[0] | |
| col_metric = col.split(" (")[1].rstrip(")") | |
| if col_dataset in dset and col_metric in metrics: | |
| display_cols.append(col) | |
| filtered = filtered[display_cols] | |
| return filtered | |
| search_bar.change(update, [search_bar, model_filter, org_filter, dataset_filter, metric_filter, col_selector], table) | |
| model_filter.change(update, [search_bar, model_filter, org_filter, dataset_filter, metric_filter, col_selector], table) | |
| org_filter.change(update, [search_bar, model_filter, org_filter, dataset_filter, metric_filter, col_selector], table) | |
| dataset_filter.change(update, [search_bar, model_filter, org_filter, dataset_filter, metric_filter, col_selector], table) | |
| metric_filter.change(update, [search_bar, model_filter, org_filter, dataset_filter, metric_filter, col_selector], table) | |
| col_selector.change(update, [search_bar, model_filter, org_filter, dataset_filter, metric_filter, col_selector], table) | |
| custom_css = """ | |
| .markdown-text { | |
| font-size: 16px !important; | |
| } | |
| #leaderboard-table { | |
| margin-top: 15px; | |
| } | |
| #leaderboard-table table { | |
| width: 100%; | |
| table-layout: auto; | |
| } | |
| #leaderboard-table thead th { | |
| font-weight: bold; | |
| text-align: center; | |
| padding: 12px 8px; | |
| white-space: normal; | |
| word-wrap: break-word; | |
| } | |
| #leaderboard-table tbody td { | |
| text-align: center; | |
| padding: 10px 8px; | |
| white-space: nowrap; | |
| } | |
| #leaderboard-table tbody td:first-child { | |
| text-align: left; | |
| font-weight: 500; | |
| min-width: 120px; | |
| max-width: 200px; | |
| white-space: nowrap; | |
| } | |
| #leaderboard-table thead th:first-child { | |
| text-align: left; | |
| font-weight: bold; | |
| min-width: 120px; | |
| max-width: 200px; | |
| white-space: nowrap; | |
| } | |
| #leaderboard-table tbody td:nth-child(2), | |
| #leaderboard-table thead th:nth-child(2) { | |
| text-align: left; | |
| min-width: 100px; | |
| } | |
| #leaderboard-table tbody td:nth-child(3), | |
| #leaderboard-table thead th:nth-child(3) { | |
| text-align: left; | |
| min-width: 120px; | |
| } | |
| /* Style links in Author column */ | |
| #leaderboard-table a { | |
| color: #0066cc; | |
| text-decoration: none; | |
| } | |
| #leaderboard-table a:hover { | |
| text-decoration: underline; | |
| } | |
| #search-bar { | |
| margin-bottom: 0px; | |
| } | |
| #search-bar textarea { | |
| border: 1px solid #e0e0e0 !important; | |
| border-radius: 8px !important; | |
| } | |
| .tab-buttons button { | |
| font-size: 20px; | |
| } | |
| .filter-group { | |
| margin-bottom: 1em; | |
| } | |
| .filter-group label { | |
| font-size: 14px; | |
| } | |
| .column-select { | |
| margin-bottom: 1.5em; | |
| } | |
| .column-select label { | |
| display: flex; | |
| flex-wrap: wrap; | |
| gap: 0.5em; | |
| } | |
| .column-select label > span { | |
| display: inline-flex; | |
| align-items: center; | |
| } | |
| """ | |
| TITLE = """<h1 align="center" id="space-title">Mars-Bench Leaderboard</h1>""" | |
| INTRO = """ | |
| A comprehensive benchmark for evaluating computer vision models on Mars-specific datasets. | |
| This leaderboard tracks model performance across three key tasks: classification, segmentation, and object detection. | |
| """ | |
| demo = gr.Blocks(css=custom_css, title="Mars-Bench Leaderboard") | |
| with demo: | |
| gr.HTML(TITLE) | |
| gr.Markdown(INTRO, elem_classes="markdown-text") | |
| with gr.Tabs(elem_classes="tab-buttons"): | |
| build_tab(CLASSIFICATION_DF, "🏅 Classification") | |
| build_tab(SEGMENTATION_DF, "🏅 Segmentation") | |
| build_tab(DETECTION_DF, "🏅 Object Detection") | |
| with gr.TabItem("📝 Submit", elem_id="submit-tab"): | |
| gr.Markdown(""" | |
| # Submit Your Model Results | |
| To submit your model's results to Mars-Bench, please provide the following information. | |
| All submissions will be reviewed before being added to the leaderboard. | |
| """) | |
| gr.Markdown(""" | |
| ### How to submit: | |
| 1. Fill out the form below | |
| 2. Click "Generate Submission Text" | |
| 3. Copy the generated text | |
| 4. Go to the [Community tab](https://huggingface.co/spaces/gremlin97/MarsBoard/discussions) | |
| 5. Click "New discussion" | |
| 6. Paste the text and submit | |
| --- | |
| """) | |
| with gr.Row(): | |
| with gr.Column(): | |
| submit_task = gr.Dropdown( | |
| choices=["Classification", "Segmentation", "Object Detection"], | |
| label="Task Type", | |
| info="Select the task category" | |
| ) | |
| submit_model = gr.Textbox( | |
| label="Model Name", | |
| placeholder="e.g., ResNet-50", | |
| info="Name of your model" | |
| ) | |
| submit_org = gr.Textbox( | |
| label="Organization", | |
| placeholder="e.g., Microsoft, Google", | |
| info="Your organization or affiliation" | |
| ) | |
| submit_dataset = gr.Textbox( | |
| label="Dataset", | |
| placeholder="e.g., DoMars16, Mars Crater", | |
| info="Dataset used for evaluation" | |
| ) | |
| with gr.Column(): | |
| submit_author = gr.Textbox( | |
| label="Author", | |
| placeholder="e.g., K. He", | |
| info="Name of the author" | |
| ) | |
| submit_author_link = gr.Textbox( | |
| label="Author Page Link (Optional)", | |
| placeholder="https://scholar.google.com/... or https://github.com/...", | |
| info="Link to author's Google Scholar, GitHub, or personal page" | |
| ) | |
| submit_metrics = gr.Textbox( | |
| label="Metrics (JSON format)", | |
| placeholder='{"Accuracy": 95.8, "F1-Score": 94.9}', | |
| info="Provide metrics in JSON format", | |
| lines=3 | |
| ) | |
| submit_paper = gr.Textbox( | |
| label="Paper Link (Optional)", | |
| placeholder="https://arxiv.org/abs/...", | |
| info="Link to your research paper" | |
| ) | |
| submit_code = gr.Textbox( | |
| label="Code Repository (Optional)", | |
| placeholder="https://github.com/...", | |
| info="Link to your code repository" | |
| ) | |
| submit_email = gr.Textbox( | |
| label="Contact Email", | |
| placeholder="your.email@example.com", | |
| info="We'll contact you about your submission" | |
| ) | |
| submit_notes = gr.Textbox( | |
| label="Additional Notes (Optional)", | |
| placeholder="Training details, hyperparameters, reproduction instructions...", | |
| lines=4, | |
| info="Any additional information" | |
| ) | |
| generate_btn = gr.Button("Generate Submission Text", variant="primary", size="lg") | |
| submission_output = gr.Textbox( | |
| label="Copy this text and create a new discussion in the Community tab", | |
| lines=15, | |
| interactive=True | |
| ) | |
| gr.Markdown(""" | |
| We'll review your submission and add it to the leaderboard if approved. | |
| """) | |
| def generate_submission_text(task, model, org, dataset, author, author_link, metrics, paper, code, email, notes): | |
| if not all([task, model, org, dataset, author, metrics, email]): | |
| return "❌ Error: Please fill in all required fields (Task Type, Model Name, Organization, Dataset, Author, Metrics, Contact Email)" | |
| submission_text = f"""## New Model Submission | |
| **Task Type:** {task} | |
| **Model Name:** {model} | |
| **Organization:** {org} | |
| **Dataset:** {dataset} | |
| **Author:** {author} | |
| **Author Page Link:** {author_link if author_link else "N/A"} | |
| ### Metrics | |
| ```json | |
| {metrics} | |
| ``` | |
| ### Links | |
| - **Paper:** {paper if paper else "N/A"} | |
| - **Code:** {code if code else "N/A"} | |
| ### Contact | |
| **Email:** {email} | |
| ### Additional Notes | |
| {notes if notes else "N/A"} | |
| --- | |
| *Please review this submission for inclusion in Mars-Bench.* | |
| """ | |
| return submission_text | |
| generate_btn.click( | |
| generate_submission_text, | |
| inputs=[submit_task, submit_model, submit_org, submit_dataset, submit_author, | |
| submit_author_link, submit_metrics, submit_paper, submit_code, submit_email, submit_notes], | |
| outputs=submission_output | |
| ) | |
| if __name__ == "__main__": | |
| demo.launch() | |