Commit ·
9472758
1
Parent(s): e08b34a
Revert "Add Bradley-Terry rankings tab (#26)"
Browse filesThis reverts commit e08b34a37838e80b978b0620ee54c7e0d7f86463.
- app.py +132 -111
- requirements.txt +0 -2
- src/rankings.py +0 -152
app.py
CHANGED
|
@@ -42,7 +42,6 @@ def patch_gradio_leaderboard():
|
|
| 42 |
|
| 43 |
patch_gradio_leaderboard()
|
| 44 |
|
| 45 |
-
import pandas as pd
|
| 46 |
import gradio as gr
|
| 47 |
from apscheduler.schedulers.background import BackgroundScheduler
|
| 48 |
from gradio_leaderboard import ColumnFilter, Leaderboard, SelectColumns
|
|
@@ -51,25 +50,58 @@ from huggingface_hub import HfApi
|
|
| 51 |
from src.charts import (
|
| 52 |
clean_markdown_link,
|
| 53 |
create_leaderboard_benchmark_plot,
|
| 54 |
-
|
| 55 |
)
|
| 56 |
from src.display.text_blocks import (
|
| 57 |
HOW_TO_USE_TEXT,
|
| 58 |
INTRODUCTION_TEXT,
|
| 59 |
LLM_BENCHMARKS_TEXT,
|
| 60 |
)
|
| 61 |
-
from src.leaderboard import
|
| 62 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 63 |
|
| 64 |
REPO_ID = "taagarwa/coding-agent-leaderboard"
|
| 65 |
TOKEN = os.environ.get("HF_TOKEN")
|
| 66 |
API = HfApi(token=TOKEN)
|
| 67 |
COLOR_BY_CHOICES = ["Model", "Harness"]
|
| 68 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 69 |
DEFAULT_COLOR_PALETTE = "Citrus"
|
| 70 |
PLOT_BACKGROUND_CHOICES = ["Dark", "White"]
|
| 71 |
DEFAULT_PLOT_BACKGROUND = "Dark"
|
| 72 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 73 |
<script>
|
| 74 |
(() => {
|
| 75 |
const url = new URL(window.location.href);
|
|
@@ -80,6 +112,8 @@ FORCE_DARK_MODE_HEAD = """
|
|
| 80 |
})();
|
| 81 |
</script>
|
| 82 |
"""
|
|
|
|
|
|
|
| 83 |
|
| 84 |
|
| 85 |
def restart_space():
|
|
@@ -89,7 +123,7 @@ def restart_space():
|
|
| 89 |
BENCHMARK_NAMES = get_benchmark_names()
|
| 90 |
DEFAULT_BENCHMARK = BENCHMARK_NAMES[0] if BENCHMARK_NAMES else None
|
| 91 |
BENCHMARK_RUN_DF = get_benchmark_run_df()
|
| 92 |
-
|
| 93 |
|
| 94 |
|
| 95 |
def render_leaderboard_benchmark_plot(
|
|
@@ -107,19 +141,39 @@ def render_leaderboard_benchmark_plot(
|
|
| 107 |
)
|
| 108 |
|
| 109 |
|
| 110 |
-
|
|
|
|
| 111 |
benchmark_name,
|
|
|
|
| 112 |
color_by,
|
|
|
|
|
|
|
|
|
|
| 113 |
color_palette=DEFAULT_COLOR_PALETTE,
|
| 114 |
plot_background=DEFAULT_PLOT_BACKGROUND,
|
| 115 |
):
|
| 116 |
-
|
| 117 |
-
SCORE_VS_COST_DF,
|
| 118 |
benchmark_name=benchmark_name,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 119 |
color_by=color_by,
|
|
|
|
|
|
|
|
|
|
| 120 |
palette_name=color_palette,
|
| 121 |
background_name=plot_background,
|
| 122 |
)
|
|
|
|
| 123 |
|
| 124 |
|
| 125 |
def build_header_html(df):
|
|
@@ -244,128 +298,95 @@ with demo:
|
|
| 244 |
outputs=plot,
|
| 245 |
)
|
| 246 |
|
| 247 |
-
with gr.Tab("
|
| 248 |
-
|
| 249 |
-
|
| 250 |
-
|
| 251 |
-
|
|
|
|
|
|
|
|
|
|
| 252 |
)
|
| 253 |
with gr.Row():
|
| 254 |
-
|
| 255 |
-
choices=
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 256 |
value="Model",
|
| 257 |
label="Color by",
|
| 258 |
-
elem_classes="color-control",
|
| 259 |
)
|
| 260 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 261 |
choices=COLOR_PALETTE_CHOICES,
|
| 262 |
value=DEFAULT_COLOR_PALETTE,
|
| 263 |
label="Color palette",
|
| 264 |
-
elem_classes="color-control",
|
| 265 |
)
|
| 266 |
-
|
| 267 |
choices=PLOT_BACKGROUND_CHOICES,
|
| 268 |
value=DEFAULT_PLOT_BACKGROUND,
|
| 269 |
label="Image background",
|
| 270 |
-
elem_classes="color-control",
|
| 271 |
)
|
| 272 |
-
|
| 273 |
-
|
| 274 |
-
|
| 275 |
-
|
| 276 |
-
|
| 277 |
-
|
| 278 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 279 |
show_label=False,
|
| 280 |
elem_classes="responsive-plot",
|
| 281 |
)
|
| 282 |
-
|
| 283 |
-
|
| 284 |
-
|
| 285 |
-
|
| 286 |
-
|
| 287 |
-
cost_color_by.change(
|
| 288 |
-
fn=render_score_vs_cost_plot,
|
| 289 |
-
inputs=[cost_benchmark, cost_color_by, cost_palette, cost_background],
|
| 290 |
-
outputs=score_vs_cost_plot,
|
| 291 |
-
)
|
| 292 |
-
cost_palette.change(
|
| 293 |
-
fn=render_score_vs_cost_plot,
|
| 294 |
-
inputs=[cost_benchmark, cost_color_by, cost_palette, cost_background],
|
| 295 |
-
outputs=score_vs_cost_plot,
|
| 296 |
-
)
|
| 297 |
-
cost_background.change(
|
| 298 |
-
fn=render_score_vs_cost_plot,
|
| 299 |
-
inputs=[cost_benchmark, cost_color_by, cost_palette, cost_background],
|
| 300 |
-
outputs=score_vs_cost_plot,
|
| 301 |
)
|
| 302 |
|
| 303 |
-
|
| 304 |
-
|
| 305 |
-
|
| 306 |
-
|
| 307 |
-
|
| 308 |
-
|
| 309 |
-
|
| 310 |
-
|
| 311 |
-
|
| 312 |
-
|
| 313 |
-
|
| 314 |
-
rank_by = gr.Dropdown(
|
| 315 |
-
choices=list(RANK_BY_OPTIONS.keys()),
|
| 316 |
-
value="Benchmark Score",
|
| 317 |
-
label="Rank by",
|
| 318 |
-
)
|
| 319 |
-
rank_oss_models = gr.Checkbox(value=False, label="Open models only")
|
| 320 |
-
rank_oss_harnesses = gr.Checkbox(value=False, label="Open harnesses only")
|
| 321 |
-
with gr.Row():
|
| 322 |
-
rank_benchmark_filter = gr.CheckboxGroup(
|
| 323 |
-
choices=rank_benchmark_choices,
|
| 324 |
-
value=rank_benchmark_choices,
|
| 325 |
-
label="Benchmarks",
|
| 326 |
-
)
|
| 327 |
-
with gr.Row():
|
| 328 |
-
rank_model_filter = gr.CheckboxGroup(
|
| 329 |
-
choices=rank_model_choices,
|
| 330 |
-
value=rank_model_choices,
|
| 331 |
-
label="Models",
|
| 332 |
-
)
|
| 333 |
-
with gr.Row():
|
| 334 |
-
rank_harness_filter = gr.CheckboxGroup(
|
| 335 |
-
choices=rank_harness_choices,
|
| 336 |
-
value=rank_harness_choices,
|
| 337 |
-
label="Harnesses",
|
| 338 |
-
)
|
| 339 |
-
|
| 340 |
-
harness_df_init, model_df_init, pair_df_init = load_and_rank("results.csv")
|
| 341 |
-
|
| 342 |
-
gr.Markdown("#### Harness Rankings")
|
| 343 |
-
harness_table = gr.Dataframe(value=harness_df_init, interactive=False)
|
| 344 |
-
gr.Markdown("#### Model Rankings")
|
| 345 |
-
model_table = gr.Dataframe(value=model_df_init, interactive=False)
|
| 346 |
-
gr.Markdown("#### (Model, Harness) Rankings")
|
| 347 |
-
pair_table = gr.Dataframe(value=pair_df_init, interactive=False)
|
| 348 |
-
|
| 349 |
-
def update_rankings(rank_by_val, oss_models, oss_harnesses, benchmarks, models, harnesses):
|
| 350 |
-
h, m, p = load_and_rank(
|
| 351 |
-
"results.csv",
|
| 352 |
-
open_models_only=oss_models,
|
| 353 |
-
open_harnesses_only=oss_harnesses,
|
| 354 |
-
benchmarks=benchmarks,
|
| 355 |
-
models=models,
|
| 356 |
-
harnesses=harnesses,
|
| 357 |
-
rank_by=rank_by_val,
|
| 358 |
-
)
|
| 359 |
-
return h, m, p
|
| 360 |
-
|
| 361 |
-
ranking_inputs = [rank_by, rank_oss_models, rank_oss_harnesses, rank_benchmark_filter, rank_model_filter, rank_harness_filter]
|
| 362 |
-
for control in ranking_inputs:
|
| 363 |
control.change(
|
| 364 |
-
fn=
|
| 365 |
-
inputs=
|
| 366 |
-
outputs=[
|
| 367 |
)
|
| 368 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 369 |
with gr.Tab("🏃 Benchmark Runs"):
|
| 370 |
benchmark_runs = init_benchmark_runs(BENCHMARK_RUN_DF)
|
| 371 |
|
|
|
|
| 42 |
|
| 43 |
patch_gradio_leaderboard()
|
| 44 |
|
|
|
|
| 45 |
import gradio as gr
|
| 46 |
from apscheduler.schedulers.background import BackgroundScheduler
|
| 47 |
from gradio_leaderboard import ColumnFilter, Leaderboard, SelectColumns
|
|
|
|
| 50 |
from src.charts import (
|
| 51 |
clean_markdown_link,
|
| 52 |
create_leaderboard_benchmark_plot,
|
| 53 |
+
create_performance_vs_resource_plot,
|
| 54 |
)
|
| 55 |
from src.display.text_blocks import (
|
| 56 |
HOW_TO_USE_TEXT,
|
| 57 |
INTRODUCTION_TEXT,
|
| 58 |
LLM_BENCHMARKS_TEXT,
|
| 59 |
)
|
| 60 |
+
from src.leaderboard import (
|
| 61 |
+
EFFICIENCY_RESOURCE_METRICS,
|
| 62 |
+
get_analysis_df,
|
| 63 |
+
get_benchmark_names,
|
| 64 |
+
get_benchmark_run_df,
|
| 65 |
+
get_efficiency_df,
|
| 66 |
+
get_token_efficiency_table_df,
|
| 67 |
+
)
|
| 68 |
|
| 69 |
REPO_ID = "taagarwa/coding-agent-leaderboard"
|
| 70 |
TOKEN = os.environ.get("HF_TOKEN")
|
| 71 |
API = HfApi(token=TOKEN)
|
| 72 |
COLOR_BY_CHOICES = ["Model", "Harness"]
|
| 73 |
+
EFFICIENCY_COLOR_BY_CHOICES = ["Model", "Harness"]
|
| 74 |
+
COLOR_PALETTE_CHOICES = [
|
| 75 |
+
"Citrus",
|
| 76 |
+
"Okabe-Ito",
|
| 77 |
+
"High contrast",
|
| 78 |
+
"Rainbow",
|
| 79 |
+
"Grayscale",
|
| 80 |
+
"Viridis",
|
| 81 |
+
"Plasma",
|
| 82 |
+
"Cividis",
|
| 83 |
+
]
|
| 84 |
DEFAULT_COLOR_PALETTE = "Citrus"
|
| 85 |
PLOT_BACKGROUND_CHOICES = ["Dark", "White"]
|
| 86 |
DEFAULT_PLOT_BACKGROUND = "Dark"
|
| 87 |
+
RESPONSIVE_PLOT_MIN_HEIGHT_PX = 420
|
| 88 |
+
RESPONSIVE_PLOT_CSS = f"""
|
| 89 |
+
<style>
|
| 90 |
+
.responsive-plot {{
|
| 91 |
+
overflow-x: auto;
|
| 92 |
+
width: 100%;
|
| 93 |
+
min-height: {RESPONSIVE_PLOT_MIN_HEIGHT_PX}px;
|
| 94 |
+
}}
|
| 95 |
+
.responsive-plot .plot-container,
|
| 96 |
+
.responsive-plot .js-plotly-plot,
|
| 97 |
+
.responsive-plot .plotly-graph-div {{
|
| 98 |
+
width: 100% !important;
|
| 99 |
+
min-height: {RESPONSIVE_PLOT_MIN_HEIGHT_PX}px;
|
| 100 |
+
}}
|
| 101 |
+
</style>
|
| 102 |
+
"""
|
| 103 |
+
FORCE_DARK_MODE_HEAD = (
|
| 104 |
+
"""
|
| 105 |
<script>
|
| 106 |
(() => {
|
| 107 |
const url = new URL(window.location.href);
|
|
|
|
| 112 |
})();
|
| 113 |
</script>
|
| 114 |
"""
|
| 115 |
+
+ RESPONSIVE_PLOT_CSS
|
| 116 |
+
)
|
| 117 |
|
| 118 |
|
| 119 |
def restart_space():
|
|
|
|
| 123 |
BENCHMARK_NAMES = get_benchmark_names()
|
| 124 |
DEFAULT_BENCHMARK = BENCHMARK_NAMES[0] if BENCHMARK_NAMES else None
|
| 125 |
BENCHMARK_RUN_DF = get_benchmark_run_df()
|
| 126 |
+
ANALYSIS_DF = get_analysis_df()
|
| 127 |
|
| 128 |
|
| 129 |
def render_leaderboard_benchmark_plot(
|
|
|
|
| 141 |
)
|
| 142 |
|
| 143 |
|
| 144 |
+
|
| 145 |
+
def render_efficiency(
|
| 146 |
benchmark_name,
|
| 147 |
+
token_metric,
|
| 148 |
color_by,
|
| 149 |
+
x_scale,
|
| 150 |
+
show_pareto_frontier,
|
| 151 |
+
show_labels,
|
| 152 |
color_palette=DEFAULT_COLOR_PALETTE,
|
| 153 |
plot_background=DEFAULT_PLOT_BACKGROUND,
|
| 154 |
):
|
| 155 |
+
plot_df = get_efficiency_df(
|
|
|
|
| 156 |
benchmark_name=benchmark_name,
|
| 157 |
+
resource_metric=token_metric,
|
| 158 |
+
analysis_df=ANALYSIS_DF,
|
| 159 |
+
)
|
| 160 |
+
table_df = get_token_efficiency_table_df(
|
| 161 |
+
benchmark_name=benchmark_name,
|
| 162 |
+
analysis_df=ANALYSIS_DF,
|
| 163 |
+
)
|
| 164 |
+
exclusion_count = plot_df.attrs.get("exclusion_count", 0)
|
| 165 |
+
note = f"{exclusion_count} runs excluded for this benchmark because {token_metric.lower()} was missing or non-positive."
|
| 166 |
+
figure = create_performance_vs_resource_plot(
|
| 167 |
+
plot_df,
|
| 168 |
+
resource_metric=token_metric,
|
| 169 |
color_by=color_by,
|
| 170 |
+
x_scale=x_scale,
|
| 171 |
+
show_pareto_frontier=show_pareto_frontier,
|
| 172 |
+
show_labels=show_labels,
|
| 173 |
palette_name=color_palette,
|
| 174 |
background_name=plot_background,
|
| 175 |
)
|
| 176 |
+
return figure, table_df, note
|
| 177 |
|
| 178 |
|
| 179 |
def build_header_html(df):
|
|
|
|
| 298 |
outputs=plot,
|
| 299 |
)
|
| 300 |
|
| 301 |
+
with gr.Tab("⚡ Efficiency") as efficiency_tab:
|
| 302 |
+
gr.Markdown(
|
| 303 |
+
"### Efficiency\n"
|
| 304 |
+
"Compare score with resource use within one benchmark. The x-axis can show total tokens, "
|
| 305 |
+
"cost per task, or agent execution time per task. The dashed Pareto frontier connects runs "
|
| 306 |
+
"for which no other displayed run uses an equal or lower amount of the selected resource "
|
| 307 |
+
"while achieving an equal or higher score. Tokens Per Solved Task remains in the ranking "
|
| 308 |
+
"table as a reference metric."
|
| 309 |
)
|
| 310 |
with gr.Row():
|
| 311 |
+
efficiency_benchmark = gr.Dropdown(
|
| 312 |
+
choices=BENCHMARK_NAMES,
|
| 313 |
+
value=BENCHMARK_NAMES[0] if BENCHMARK_NAMES else None,
|
| 314 |
+
label="Benchmark",
|
| 315 |
+
)
|
| 316 |
+
efficiency_metric = gr.Dropdown(
|
| 317 |
+
choices=list(EFFICIENCY_RESOURCE_METRICS),
|
| 318 |
+
value="Total tokens",
|
| 319 |
+
label="Resource metric",
|
| 320 |
+
)
|
| 321 |
+
efficiency_color_by = gr.Radio(
|
| 322 |
+
choices=EFFICIENCY_COLOR_BY_CHOICES,
|
| 323 |
value="Model",
|
| 324 |
label="Color by",
|
|
|
|
| 325 |
)
|
| 326 |
+
efficiency_scale = gr.Radio(choices=["Log", "Linear"], value="Log", label="X-axis scale")
|
| 327 |
+
with gr.Row():
|
| 328 |
+
efficiency_pareto = gr.Checkbox(value=True, label="Show Pareto frontier")
|
| 329 |
+
efficiency_labels = gr.Checkbox(value=False, label="Show point labels")
|
| 330 |
+
efficiency_palette = gr.Dropdown(
|
| 331 |
choices=COLOR_PALETTE_CHOICES,
|
| 332 |
value=DEFAULT_COLOR_PALETTE,
|
| 333 |
label="Color palette",
|
|
|
|
| 334 |
)
|
| 335 |
+
efficiency_background = gr.Dropdown(
|
| 336 |
choices=PLOT_BACKGROUND_CHOICES,
|
| 337 |
value=DEFAULT_PLOT_BACKGROUND,
|
| 338 |
label="Image background",
|
|
|
|
| 339 |
)
|
| 340 |
+
|
| 341 |
+
initial_efficiency = render_efficiency(
|
| 342 |
+
BENCHMARK_NAMES[0] if BENCHMARK_NAMES else None,
|
| 343 |
+
"Total tokens",
|
| 344 |
+
"Model",
|
| 345 |
+
"Log",
|
| 346 |
+
True,
|
| 347 |
+
False,
|
| 348 |
+
DEFAULT_COLOR_PALETTE,
|
| 349 |
+
DEFAULT_PLOT_BACKGROUND,
|
| 350 |
+
)
|
| 351 |
+
efficiency_note = gr.Markdown(initial_efficiency[2])
|
| 352 |
+
efficiency_plot = gr.Plot(
|
| 353 |
+
value=initial_efficiency[0],
|
| 354 |
show_label=False,
|
| 355 |
elem_classes="responsive-plot",
|
| 356 |
)
|
| 357 |
+
gr.Markdown("#### Efficiency ranking")
|
| 358 |
+
efficiency_table = gr.Dataframe(
|
| 359 |
+
value=initial_efficiency[1],
|
| 360 |
+
interactive=False,
|
| 361 |
+
show_label=False,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 362 |
)
|
| 363 |
|
| 364 |
+
efficiency_controls = [
|
| 365 |
+
efficiency_benchmark,
|
| 366 |
+
efficiency_metric,
|
| 367 |
+
efficiency_color_by,
|
| 368 |
+
efficiency_scale,
|
| 369 |
+
efficiency_pareto,
|
| 370 |
+
efficiency_labels,
|
| 371 |
+
efficiency_palette,
|
| 372 |
+
efficiency_background,
|
| 373 |
+
]
|
| 374 |
+
for control in efficiency_controls:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 375 |
control.change(
|
| 376 |
+
fn=render_efficiency,
|
| 377 |
+
inputs=efficiency_controls,
|
| 378 |
+
outputs=[efficiency_plot, efficiency_table, efficiency_note],
|
| 379 |
)
|
| 380 |
|
| 381 |
+
# Gradio initially lays out hidden tabs without reliable dimensions. Re-render
|
| 382 |
+
# once Efficiency becomes visible so Plotly can autosize against the real
|
| 383 |
+
# container instead of keeping the hidden-tab geometry.
|
| 384 |
+
efficiency_tab.select(
|
| 385 |
+
fn=render_efficiency,
|
| 386 |
+
inputs=efficiency_controls,
|
| 387 |
+
outputs=[efficiency_plot, efficiency_table, efficiency_note],
|
| 388 |
+
)
|
| 389 |
+
|
| 390 |
with gr.Tab("🏃 Benchmark Runs"):
|
| 391 |
benchmark_runs = init_benchmark_runs(BENCHMARK_RUN_DF)
|
| 392 |
|
requirements.txt
CHANGED
|
@@ -15,5 +15,3 @@ tqdm
|
|
| 15 |
transformers
|
| 16 |
tokenizers>=0.15.0
|
| 17 |
sentencepiece
|
| 18 |
-
choix
|
| 19 |
-
scipy
|
|
|
|
| 15 |
transformers
|
| 16 |
tokenizers>=0.15.0
|
| 17 |
sentencepiece
|
|
|
|
|
|
src/rankings.py
DELETED
|
@@ -1,152 +0,0 @@
|
|
| 1 |
-
from typing import Any
|
| 2 |
-
from pathlib import Path
|
| 3 |
-
|
| 4 |
-
import numpy as np
|
| 5 |
-
import pandas as pd
|
| 6 |
-
import choix
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
def prepare_ranking_data(
|
| 10 |
-
df: pd.DataFrame,
|
| 11 |
-
catcol: str | list[str],
|
| 12 |
-
metcol: str,
|
| 13 |
-
descending: bool = False,
|
| 14 |
-
eqvcol: str | list[str] = [],
|
| 15 |
-
) -> tuple[list[tuple[int, int]], list[Any], dict]:
|
| 16 |
-
ndata = df.shape[0]
|
| 17 |
-
if ndata < 2:
|
| 18 |
-
raise ValueError("Not enough data to prepare ranking comparisons")
|
| 19 |
-
catcol = catcol if isinstance(catcol, list) else [catcol]
|
| 20 |
-
eqvcol = eqvcol if isinstance(eqvcol, list) else [eqvcol]
|
| 21 |
-
ncat = len(catcol)
|
| 22 |
-
neqv = len(eqvcol)
|
| 23 |
-
tcols = catcol + eqvcol + [metcol]
|
| 24 |
-
t = list(df[tcols].itertuples(index=False, name=None))
|
| 25 |
-
metvals = [x[-1] for x in t]
|
| 26 |
-
if ncat > 1:
|
| 27 |
-
catvals = [x[:ncat] for x in t]
|
| 28 |
-
else:
|
| 29 |
-
catvals = [x[0] for x in t]
|
| 30 |
-
if neqv > 1:
|
| 31 |
-
eqvvals = [x[ncat : ncat + neqv] for x in t]
|
| 32 |
-
elif neqv == 1:
|
| 33 |
-
eqvvals = [x[ncat] for x in t]
|
| 34 |
-
else:
|
| 35 |
-
eqvvals = ["[ALL]"] * ndata
|
| 36 |
-
umap = dict([(y, x) for x, y in enumerate(sorted(set(catvals)))])
|
| 37 |
-
cats = sorted(umap.keys())
|
| 38 |
-
eqvcats = sorted(set(eqvvals))
|
| 39 |
-
eqvdata = {}
|
| 40 |
-
for eqv in eqvcats:
|
| 41 |
-
eqvdata[eqv] = [[] for _ in range(len(cats))]
|
| 42 |
-
compvals = [(umap[c], m, e) for c, m, e in zip(catvals, metvals, eqvvals)]
|
| 43 |
-
for category, metric, equivalence in compvals:
|
| 44 |
-
eqvdata[equivalence][category].append(metric)
|
| 45 |
-
comps = []
|
| 46 |
-
for i in range(ndata):
|
| 47 |
-
ic, im, ie = compvals[i]
|
| 48 |
-
for j in range(i):
|
| 49 |
-
jc, jm, je = compvals[j]
|
| 50 |
-
if ie != je:
|
| 51 |
-
continue
|
| 52 |
-
if im == jm:
|
| 53 |
-
continue
|
| 54 |
-
iwin = im < jm if descending else im > jm
|
| 55 |
-
if iwin:
|
| 56 |
-
comps.append((ic, jc))
|
| 57 |
-
else:
|
| 58 |
-
comps.append((jc, ic))
|
| 59 |
-
return comps, cats, eqvdata
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
def ranking_dataframe(cats, params, eqvdata) -> pd.DataFrame:
|
| 63 |
-
ranking = np.argsort(params)[::-1]
|
| 64 |
-
rows = []
|
| 65 |
-
for rank, idx in enumerate(ranking, start=1):
|
| 66 |
-
row = {
|
| 67 |
-
"Rank": rank,
|
| 68 |
-
"Category": cats[idx] if not isinstance(cats[idx], tuple) else " + ".join(cats[idx]),
|
| 69 |
-
}
|
| 70 |
-
for k in sorted(eqvdata.keys()):
|
| 71 |
-
mets = eqvdata[k][idx]
|
| 72 |
-
row[k] = round(float(np.mean(mets)), 3) if len(mets) > 0 else None
|
| 73 |
-
rows.append(row)
|
| 74 |
-
return pd.DataFrame(rows)
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
RANK_BY_OPTIONS = {
|
| 78 |
-
"Benchmark Score": ("metrics.score", False),
|
| 79 |
-
"Mean Cost Per Task (USD)": ("metrics.mean_cost_usd_per_task", True),
|
| 80 |
-
"Mean Tokens Per Task": ("metrics.mean_tokens_per_task", True),
|
| 81 |
-
}
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
def compute_ranking(df, catcol, metcol="metrics.score", descending=False, eqvcol="benchmark.name"):
|
| 85 |
-
comps, cats, eqvdata = prepare_ranking_data(
|
| 86 |
-
df, catcol, metcol, descending=descending, eqvcol=eqvcol
|
| 87 |
-
)
|
| 88 |
-
params = choix.ilsr_pairwise(len(cats), comps, alpha=1e-3)
|
| 89 |
-
return ranking_dataframe(cats, params, eqvdata)
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
def rank_harnesses(df: pd.DataFrame, metcol="metrics.score", descending=False) -> pd.DataFrame:
|
| 93 |
-
return compute_ranking(df, "harness.name", metcol, descending)
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
def rank_models(df: pd.DataFrame, metcol="metrics.score", descending=False) -> pd.DataFrame:
|
| 97 |
-
return compute_ranking(df, "model.name", metcol, descending)
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
def rank_pairs(df: pd.DataFrame, metcol="metrics.score", descending=False) -> pd.DataFrame:
|
| 101 |
-
return compute_ranking(df, ["model.name", "harness.name"], metcol, descending)
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
def _load_csv(csv_path: str | Path = "results.csv") -> pd.DataFrame:
|
| 105 |
-
df = pd.read_csv(csv_path)
|
| 106 |
-
df = df.dropna(subset=["metrics.score"])
|
| 107 |
-
df = df.loc[df["metrics.score"] > 0]
|
| 108 |
-
return df.reset_index(drop=True)
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
def _empty_table():
|
| 112 |
-
return pd.DataFrame({"Rank": [], "Category": []})
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
def load_and_rank(
|
| 116 |
-
csv_path: str | Path = "results.csv",
|
| 117 |
-
open_models_only: bool = False,
|
| 118 |
-
open_harnesses_only: bool = False,
|
| 119 |
-
benchmarks: list[str] | None = None,
|
| 120 |
-
models: list[str] | None = None,
|
| 121 |
-
harnesses: list[str] | None = None,
|
| 122 |
-
rank_by: str = "Benchmark Score",
|
| 123 |
-
) -> tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]:
|
| 124 |
-
df = _load_csv(csv_path)
|
| 125 |
-
if open_models_only:
|
| 126 |
-
df = df.loc[df["model.is_oss"] == True]
|
| 127 |
-
if open_harnesses_only:
|
| 128 |
-
df = df.loc[df["harness.is_oss"] == True]
|
| 129 |
-
if benchmarks is not None:
|
| 130 |
-
df = df.loc[df["benchmark.name"].isin(benchmarks)]
|
| 131 |
-
if models is not None:
|
| 132 |
-
df = df.loc[df["model.name"].isin(models)]
|
| 133 |
-
if harnesses is not None:
|
| 134 |
-
df = df.loc[df["harness.name"].isin(harnesses)]
|
| 135 |
-
|
| 136 |
-
metcol, descending = RANK_BY_OPTIONS.get(rank_by, ("metrics.score", False))
|
| 137 |
-
df = df.dropna(subset=[metcol])
|
| 138 |
-
if descending:
|
| 139 |
-
df = df.loc[df[metcol] > 0]
|
| 140 |
-
df = df.reset_index(drop=True)
|
| 141 |
-
|
| 142 |
-
if len(df) < 2:
|
| 143 |
-
empty = _empty_table()
|
| 144 |
-
return empty, empty, empty
|
| 145 |
-
|
| 146 |
-
results = []
|
| 147 |
-
for rank_fn in (rank_harnesses, rank_models, rank_pairs):
|
| 148 |
-
try:
|
| 149 |
-
results.append(rank_fn(df, metcol, descending))
|
| 150 |
-
except ValueError:
|
| 151 |
-
results.append(_empty_table())
|
| 152 |
-
return results[0], results[1], results[2]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|