Spaces:
Running
Overview table gets a row per variant, and its cost columns follow the row
Browse filesThe cross-subset overview picked each column's value independently, taking the
extremum per model. For the two cost columns that meant the minimum, which is
always the default variant, while the model cell was labelled with whichever
variant led on the selected metric. A row reading "RealMLP (tuned + ensembled)"
quoted the default's fit time: 10.06 against 2950.72, roughly 200x low, because
tuning fits 200 configurations where the default fits one. 20 of 39 model rows
were affected, by 6.8x to 902x.
Rows are now keyed by (model, variant), so default, tuned and tuned + ensembled
each get their own line and a row's cost is the cost of the run it scores. That
removes the mismatch by construction, and puts the price of tuning on the page.
"One per model" collapses each method to its best variant, decided by the
leading column. It sits in the overview's own row and feeds only that table,
and is named after the win-rate matrix's button so the two read as one control.
The upstream artifacts were correct throughout: the full leaderboard table
(72,992 time values) and pareto_front_points.csv (67,232) both agree with
website_leaderboard.csv per (model, variant), and api.py works per record.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
@@ -45,6 +45,11 @@ def _choice_hints() -> dict[str, str]:
|
|
| 45 |
hints[label] = notes[key]
|
| 46 |
|
| 47 |
hints["🤖 Models"] = "Always on: TabArena is a model benchmark first."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 48 |
hints["Include imputed models"] = PROTOCOL_NOTES["imputed"]
|
| 49 |
hints["TabArena-Lite (single split)"] = PROTOCOL_NOTES["lite"]
|
| 50 |
# A category with no entrant yet says so, matching the disabled state the page renders.
|
|
@@ -332,7 +337,8 @@ CSS = """
|
|
| 332 |
the chips themselves. `main.taStampTitles` moves each one into a native `title`, so it shows
|
| 333 |
on hover instead, and the ? badge is what says the text is there at all. */
|
| 334 |
.ta-controls span[data-testid="block-info"] { display: none !important; }
|
| 335 |
-
.ta-controlrow .ta-catchip label::after
|
|
|
|
| 336 |
content: "?";
|
| 337 |
flex: 0 0 auto;
|
| 338 |
width: 14px;
|
|
@@ -346,7 +352,8 @@ CSS = """
|
|
| 346 |
line-height: 12px;
|
| 347 |
text-align: center;
|
| 348 |
}
|
| 349 |
-
.ta-controlrow .ta-catchip label:hover::after
|
|
|
|
| 350 |
/* Chip-bar buttons carry a tooltip too; a dotted underline hints at it without a badge on
|
| 351 |
every chip, which at five per row would be louder than the chips. */
|
| 352 |
.ta-controls .tab-buttons button[title] { text-decoration: underline dotted #ffffff40 1px; text-underline-offset: 3px; }
|
|
@@ -1818,6 +1825,8 @@ function taStampTitles() {
|
|
| 1818 |
};
|
| 1819 |
document.querySelectorAll(".ta-controls .ta-catchip label").forEach(stamp);
|
| 1820 |
document.querySelectorAll(".ta-controls .tab-buttons button").forEach(stamp);
|
|
|
|
|
|
|
| 1821 |
|
| 1822 |
// The row caption is a CSS ::before, which cannot hold a title, so it goes on the element
|
| 1823 |
// the caption is drawn on. A chip inside has its own title, and the nearest one wins, so
|
|
|
|
| 45 |
hints[label] = notes[key]
|
| 46 |
|
| 47 |
hints["🤖 Models"] = "Always on: TabArena is a model benchmark first."
|
| 48 |
+
hints["One per model"] = (
|
| 49 |
+
"Keep only each model's best-performing variant, one row per model — as the win-rate "
|
| 50 |
+
"matrix does. With it off, every variant gets its own row, so you can read what "
|
| 51 |
+
"tuning bought."
|
| 52 |
+
)
|
| 53 |
hints["Include imputed models"] = PROTOCOL_NOTES["imputed"]
|
| 54 |
hints["TabArena-Lite (single split)"] = PROTOCOL_NOTES["lite"]
|
| 55 |
# A category with no entrant yet says so, matching the disabled state the page renders.
|
|
|
|
| 337 |
the chips themselves. `main.taStampTitles` moves each one into a native `title`, so it shows
|
| 338 |
on hover instead, and the ? badge is what says the text is there at all. */
|
| 339 |
.ta-controls span[data-testid="block-info"] { display: none !important; }
|
| 340 |
+
.ta-controlrow .ta-catchip label::after,
|
| 341 |
+
.metric-select .ta-catchip label::after {
|
| 342 |
content: "?";
|
| 343 |
flex: 0 0 auto;
|
| 344 |
width: 14px;
|
|
|
|
| 352 |
line-height: 12px;
|
| 353 |
text-align: center;
|
| 354 |
}
|
| 355 |
+
.ta-controlrow .ta-catchip label:hover::after,
|
| 356 |
+
.metric-select .ta-catchip label:hover::after { opacity: 0.85; }
|
| 357 |
/* Chip-bar buttons carry a tooltip too; a dotted underline hints at it without a badge on
|
| 358 |
every chip, which at five per row would be louder than the chips. */
|
| 359 |
.ta-controls .tab-buttons button[title] { text-decoration: underline dotted #ffffff40 1px; text-underline-offset: 3px; }
|
|
|
|
| 1825 |
};
|
| 1826 |
document.querySelectorAll(".ta-controls .ta-catchip label").forEach(stamp);
|
| 1827 |
document.querySelectorAll(".ta-controls .tab-buttons button").forEach(stamp);
|
| 1828 |
+
// The overview's own toggle sits outside the control card but explains itself the same way.
|
| 1829 |
+
document.querySelectorAll(".metric-select .ta-catchip label").forEach(stamp);
|
| 1830 |
|
| 1831 |
// The row caption is a CSS ::before, which cannot hold a title, so it goes on the element
|
| 1832 |
// the caption is drawn on. A chip inside has its own title, and the nearest one wins, so
|
|
@@ -359,9 +359,10 @@ def render_internal_page(page: LeaderboardPage) -> None:
|
|
| 359 |
gr.HTML(
|
| 360 |
'<div class="ta-section-head" id="ta-overview-section">'
|
| 361 |
"<h2>🔭 Performance across leaderboards</h2>"
|
| 362 |
-
'<p class="ta-section-sub">
|
| 363 |
"The quickest way to spot the ones that are strong everywhere against those that shine on "
|
| 364 |
-
"one subset.</
|
|
|
|
| 365 |
"</div>"
|
| 366 |
)
|
| 367 |
with gr.Row(elem_classes="metric-select"):
|
|
@@ -375,16 +376,43 @@ def render_internal_page(page: LeaderboardPage) -> None:
|
|
| 375 |
min_width=200,
|
| 376 |
)
|
| 377 |
metric_tldr = gr.Markdown(OVERVIEW_METRIC_TLDR["Elo"], elem_classes="metric-tldr")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 378 |
overview_metric.change(
|
| 379 |
lambda m: OVERVIEW_METRIC_TLDR.get(m, ""), overview_metric, metric_tldr, api_visibility="private"
|
| 380 |
)
|
| 381 |
|
| 382 |
# The overview follows the selectors too: the column each one points at leads its group and
|
| 383 |
# is tinted, so the reader's own view is where their eye already is.
|
| 384 |
-
@gr.render(
|
| 385 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 386 |
make_cross_subset_overview(
|
| 387 |
-
page.data_root,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 388 |
)
|
| 389 |
|
| 390 |
# The "I care about" metric drives the overview's own selector, so the two cannot disagree
|
|
|
|
| 359 |
gr.HTML(
|
| 360 |
'<div class="ta-section-head" id="ta-overview-section">'
|
| 361 |
"<h2>🔭 Performance across leaderboards</h2>"
|
| 362 |
+
'<p class="ta-section-sub">Every method variant across every task and dataset-size subset. '
|
| 363 |
"The quickest way to spot the ones that are strong everywhere against those that shine on "
|
| 364 |
+
"one subset, and to see what tuning buys. <i>One per model</i> collapses each method to its "
|
| 365 |
+
"best variant.</p>"
|
| 366 |
"</div>"
|
| 367 |
)
|
| 368 |
with gr.Row(elem_classes="metric-select"):
|
|
|
|
| 376 |
min_width=200,
|
| 377 |
)
|
| 378 |
metric_tldr = gr.Markdown(OVERVIEW_METRIC_TLDR["Elo"], elem_classes="metric-tldr")
|
| 379 |
+
# Lives here rather than in the control card because it only decides which rows this one
|
| 380 |
+
# table has. Same collapse the win-rate matrix offers and named the same, so the two read
|
| 381 |
+
# as one control. Off by default: how much tuning buys a model is one of the things this
|
| 382 |
+
# table is for.
|
| 383 |
+
overview_one_per_model = gr.Checkbox(
|
| 384 |
+
value=False,
|
| 385 |
+
label="One per model",
|
| 386 |
+
container=False,
|
| 387 |
+
scale=0,
|
| 388 |
+
min_width=180,
|
| 389 |
+
elem_classes=["ta-catchip"],
|
| 390 |
+
)
|
| 391 |
overview_metric.change(
|
| 392 |
lambda m: OVERVIEW_METRIC_TLDR.get(m, ""), overview_metric, metric_tldr, api_visibility="private"
|
| 393 |
)
|
| 394 |
|
| 395 |
# The overview follows the selectors too: the column each one points at leads its group and
|
| 396 |
# is tinted, so the reader's own view is where their eye already is.
|
| 397 |
+
@gr.render(
|
| 398 |
+
inputs=[
|
| 399 |
+
overview_metric,
|
| 400 |
+
entrants_state,
|
| 401 |
+
tasks_state,
|
| 402 |
+
datasets_state,
|
| 403 |
+
care_state,
|
| 404 |
+
overview_one_per_model,
|
| 405 |
+
]
|
| 406 |
+
)
|
| 407 |
+
def _render_overview(metric, entrants, tasks, datasets, care, one_per_model):
|
| 408 |
make_cross_subset_overview(
|
| 409 |
+
page.data_root,
|
| 410 |
+
metric,
|
| 411 |
+
entrants=entrants,
|
| 412 |
+
tasks=tasks,
|
| 413 |
+
datasets=datasets,
|
| 414 |
+
care=care,
|
| 415 |
+
one_per_model=one_per_model,
|
| 416 |
)
|
| 417 |
|
| 418 |
# The "I care about" metric drives the overview's own selector, so the two cannot disagree
|
|
@@ -997,8 +997,15 @@ _GROUP_TITLE = {"cost": "What it costs", "task": "By Task", "size": "By Dataset
|
|
| 997 |
# Size definitions are reused from DATASET_SIZE_NOTE so they can't drift from the subset blurbs.
|
| 998 |
_COLUMN_TOOLTIPS: dict[str, str] = {
|
| 999 |
"Overall": "All tasks across every dataset size. This is the headline ranking.",
|
| 1000 |
-
"Fit (s/1K)":
|
| 1001 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1002 |
"Class.": "Classification tasks only (binary + multiclass).",
|
| 1003 |
"Regr.": "Regression tasks only.",
|
| 1004 |
"Binary": "Binary classification tasks only.",
|
|
@@ -1046,26 +1053,30 @@ def _selected_overview_columns(tasks: str, datasets: str, care: str) -> list[str
|
|
| 1046 |
return [c for c in wanted if c]
|
| 1047 |
|
| 1048 |
|
| 1049 |
-
|
| 1050 |
-
|
|
|
|
|
|
|
|
|
|
| 1051 |
|
| 1052 |
Systems stay in. Which entrants compete is decided by the pool the reader selected, and
|
| 1053 |
the overview reports the numbers computed for that pool, so dropping a competitor here
|
| 1054 |
would show a field the numbers were not computed against.
|
| 1055 |
"""
|
| 1056 |
-
df = df.copy()
|
| 1057 |
-
df = df.dropna(subset=[column])
|
| 1058 |
parsed = df["Model"].map(parse_model)
|
| 1059 |
df["base"] = [p[0] for p in parsed]
|
| 1060 |
df["variant"] = [p[1] for p in parsed]
|
| 1061 |
df["url"] = [p[2] for p in parsed]
|
| 1062 |
df["imputed"] = df["Imputed"].astype(bool) if "Imputed" in df.columns else False
|
| 1063 |
df["verified"] = df["Verified"] if "Verified" in df.columns else ""
|
| 1064 |
-
|
| 1065 |
-
|
| 1066 |
-
|
| 1067 |
-
|
| 1068 |
-
|
|
|
|
|
|
|
| 1069 |
|
| 1070 |
|
| 1071 |
def _overview_th(label: str, *, rowspan: int | None = None, selected: bool = False) -> str:
|
|
@@ -1227,8 +1238,14 @@ def make_cross_subset_overview(
|
|
| 1227 |
tasks: str = "all",
|
| 1228 |
datasets: str = "all",
|
| 1229 |
care: str = "quality",
|
|
|
|
| 1230 |
) -> gr.HTML:
|
| 1231 |
-
"""Heatmap of
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1232 |
|
| 1233 |
`entrants` selects the pool. Every column is read from that pool's artifacts, so the whole
|
| 1234 |
grid is one consistent field of competitors.
|
|
@@ -1243,29 +1260,50 @@ def make_cross_subset_overview(
|
|
| 1243 |
metric = "Elo"
|
| 1244 |
column, higher_is_better, fmt = _OVERVIEW_METRIC_SPECS[metric]
|
| 1245 |
|
| 1246 |
-
val_by_col: dict[str, dict[str, float]] = {}
|
| 1247 |
-
imp_by_col: dict[str, dict[str, bool]] = {}
|
| 1248 |
-
meta: dict[str, dict] = {}
|
| 1249 |
present: list[tuple[str, str]] = [] # (label, group)
|
| 1250 |
|
|
|
|
|
|
|
| 1251 |
for label, group, subset, value_column in _OVERVIEW_COLUMNS:
|
| 1252 |
subset = replace(subset, entrants=entrants)
|
| 1253 |
path = Path(data_root) / subset.rel_path / "website_leaderboard.csv"
|
| 1254 |
if not path.exists():
|
| 1255 |
continue
|
| 1256 |
-
|
| 1257 |
-
col
|
| 1258 |
-
if
|
| 1259 |
-
|
| 1260 |
-
|
| 1261 |
-
|
| 1262 |
-
|
| 1263 |
-
|
| 1264 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1265 |
present.append((label, group))
|
| 1266 |
-
for _, row in
|
| 1267 |
meta.setdefault(
|
| 1268 |
-
|
| 1269 |
{
|
| 1270 |
"type_name": row["TypeName"],
|
| 1271 |
"emoji": row["Type"],
|
|
@@ -1293,8 +1331,8 @@ def make_cross_subset_overview(
|
|
| 1293 |
|
| 1294 |
sort_label = present[0][0]
|
| 1295 |
worst_sort = float("-inf") if higher_is_better else float("inf")
|
| 1296 |
-
|
| 1297 |
-
meta, key=lambda
|
| 1298 |
)
|
| 1299 |
|
| 1300 |
rank_by_col, bounds = {}, {}
|
|
@@ -1322,10 +1360,10 @@ def make_cross_subset_overview(
|
|
| 1322 |
|
| 1323 |
# -- Body
|
| 1324 |
body = []
|
| 1325 |
-
for
|
| 1326 |
-
m = meta[
|
| 1327 |
color = model_type_color.get(m["type_name"], "#9e9e9e")
|
| 1328 |
-
name = html.escape(
|
| 1329 |
if m["variant"]:
|
| 1330 |
name += f' <span class="ta-variant">({html.escape(m["variant"])})</span>'
|
| 1331 |
if m.get("verified") == "✔️":
|
|
@@ -1343,7 +1381,7 @@ def make_cross_subset_overview(
|
|
| 1343 |
f'<td class="ta-model-cell">{name_html}</td>',
|
| 1344 |
]
|
| 1345 |
for label, _ in present:
|
| 1346 |
-
val = val_by_col[label].get(
|
| 1347 |
if val is None:
|
| 1348 |
cells.append('<td class="ta-na">–</td>')
|
| 1349 |
continue
|
|
@@ -1357,10 +1395,10 @@ def make_cross_subset_overview(
|
|
| 1357 |
else:
|
| 1358 |
frac_best = (val - lo) / (hi - lo) if col_higher_better else (hi - val) / (hi - lo)
|
| 1359 |
bg = _interp_color(1 - frac_best)
|
| 1360 |
-
medal = _MEDALS.get(rank_by_col[label].get(
|
| 1361 |
imp = (
|
| 1362 |
'<sup class="ta-imp" title="Score is (partly) imputed">*</sup>'
|
| 1363 |
-
if imp_by_col[label].get(
|
| 1364 |
else ""
|
| 1365 |
)
|
| 1366 |
sel = " ta-col-sel" if label in highlighted else ""
|
|
@@ -1372,10 +1410,15 @@ def make_cross_subset_overview(
|
|
| 1372 |
body.append(f"<tr>{''.join(cells)}</tr>")
|
| 1373 |
|
| 1374 |
direction = "Higher is better" if higher_is_better else "Lower is better"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1375 |
caption = (
|
| 1376 |
-
f'<div class="ta-cap">
|
| 1377 |
f"(with imputation, all repeats). {direction}; 🥇🥈🥉 mark the top 3 in each column. "
|
| 1378 |
-
"
|
| 1379 |
'<div class="ta-cap ta-cap-legend">✔️ = verified implementation · '
|
| 1380 |
'<span class="ta-imp">*</span> = (partly) imputed score · '
|
| 1381 |
"💡 Click any <u>underlined</u> model name (↗) to open its paper or code.</div>"
|
|
|
|
| 997 |
# Size definitions are reused from DATASET_SIZE_NOTE so they can't drift from the subset blurbs.
|
| 998 |
_COLUMN_TOOLTIPS: dict[str, str] = {
|
| 999 |
"Overall": "All tasks across every dataset size. This is the headline ranking.",
|
| 1000 |
+
"Fit (s/1K)": (
|
| 1001 |
+
"Median seconds to train per 1000 rows, across all datasets, for the variant shown. "
|
| 1002 |
+
"Tuning fits 200 configurations, so a tuned variant costs far more than its default. "
|
| 1003 |
+
"Lower is better."
|
| 1004 |
+
),
|
| 1005 |
+
"Infer (s/1K)": (
|
| 1006 |
+
"Median seconds to predict per 1000 rows, across all datasets, for the variant shown. "
|
| 1007 |
+
"Lower is better."
|
| 1008 |
+
),
|
| 1009 |
"Class.": "Classification tasks only (binary + multiclass).",
|
| 1010 |
"Regr.": "Regression tasks only.",
|
| 1011 |
"Binary": "Binary classification tasks only.",
|
|
|
|
| 1053 |
return [c for c in wanted if c]
|
| 1054 |
|
| 1055 |
|
| 1056 |
+
_SUBSET_FIELDS = ["base", "TypeName", "Type", "variant", "url", "verified", "imputed"]
|
| 1057 |
+
|
| 1058 |
+
|
| 1059 |
+
def _subset_rows(df: pd.DataFrame, column: str) -> pd.DataFrame:
|
| 1060 |
+
"""A subset's rows, `Model` split into base/variant/url and `column` renamed to `val`.
|
| 1061 |
|
| 1062 |
Systems stay in. Which entrants compete is decided by the pool the reader selected, and
|
| 1063 |
the overview reports the numbers computed for that pool, so dropping a competitor here
|
| 1064 |
would show a field the numbers were not computed against.
|
| 1065 |
"""
|
| 1066 |
+
df = df.dropna(subset=[column]).copy()
|
|
|
|
| 1067 |
parsed = df["Model"].map(parse_model)
|
| 1068 |
df["base"] = [p[0] for p in parsed]
|
| 1069 |
df["variant"] = [p[1] for p in parsed]
|
| 1070 |
df["url"] = [p[2] for p in parsed]
|
| 1071 |
df["imputed"] = df["Imputed"].astype(bool) if "Imputed" in df.columns else False
|
| 1072 |
df["verified"] = df["Verified"] if "Verified" in df.columns else ""
|
| 1073 |
+
return df.rename(columns={column: "val"})[[*_SUBSET_FIELDS, "val"]]
|
| 1074 |
+
|
| 1075 |
+
|
| 1076 |
+
def _subset_best(rows: pd.DataFrame, higher_is_better: bool) -> pd.DataFrame:
|
| 1077 |
+
"""Best-performing variant per model, one row each."""
|
| 1078 |
+
grouped = rows.groupby("base")["val"]
|
| 1079 |
+
return rows.loc[grouped.idxmax() if higher_is_better else grouped.idxmin()]
|
| 1080 |
|
| 1081 |
|
| 1082 |
def _overview_th(label: str, *, rowspan: int | None = None, selected: bool = False) -> str:
|
|
|
|
| 1238 |
tasks: str = "all",
|
| 1239 |
datasets: str = "all",
|
| 1240 |
care: str = "quality",
|
| 1241 |
+
one_per_model: bool = False,
|
| 1242 |
) -> gr.HTML:
|
| 1243 |
+
"""Heatmap of `metric` per entrant (rows) and subset (columns), within one pool.
|
| 1244 |
+
|
| 1245 |
+
A row is one model *variant* — default, tuned, or tuned + ensembled — so its quality and its
|
| 1246 |
+
cost are always the same run's. With `one_per_model` only each model's best-performing
|
| 1247 |
+
variant is kept, decided by the leading column, as the win-rate matrix's button of the same
|
| 1248 |
+
name does.
|
| 1249 |
|
| 1250 |
`entrants` selects the pool. Every column is read from that pool's artifacts, so the whole
|
| 1251 |
grid is one consistent field of competitors.
|
|
|
|
| 1260 |
metric = "Elo"
|
| 1261 |
column, higher_is_better, fmt = _OVERVIEW_METRIC_SPECS[metric]
|
| 1262 |
|
| 1263 |
+
val_by_col: dict[str, dict[tuple[str, str], float]] = {}
|
| 1264 |
+
imp_by_col: dict[str, dict[tuple[str, str], bool]] = {}
|
| 1265 |
+
meta: dict[tuple[str, str], dict] = {}
|
| 1266 |
present: list[tuple[str, str]] = [] # (label, group)
|
| 1267 |
|
| 1268 |
+
# Read every column first. A cost column reports its own metric, the rest the selected one.
|
| 1269 |
+
loaded: list[tuple[str, str, pd.DataFrame]] = []
|
| 1270 |
for label, group, subset, value_column in _OVERVIEW_COLUMNS:
|
| 1271 |
subset = replace(subset, entrants=entrants)
|
| 1272 |
path = Path(data_root) / subset.rel_path / "website_leaderboard.csv"
|
| 1273 |
if not path.exists():
|
| 1274 |
continue
|
| 1275 |
+
df = load_leaderboard_csv(str(path.resolve()))
|
| 1276 |
+
col = _FIXED_COLUMN_SPECS[label][0] if value_column is not None else column
|
| 1277 |
+
if col not in df.columns:
|
| 1278 |
+
continue
|
| 1279 |
+
rows = _subset_rows(df, col)
|
| 1280 |
+
if not rows.empty:
|
| 1281 |
+
loaded.append((label, group, rows))
|
| 1282 |
+
|
| 1283 |
+
if not loaded:
|
| 1284 |
+
return gr.HTML("<p>No overview data available.</p>")
|
| 1285 |
+
|
| 1286 |
+
# The leading column decides which variant stands for each model, so the kept row is the one
|
| 1287 |
+
# the reader is ranking by.
|
| 1288 |
+
keep = None
|
| 1289 |
+
if one_per_model:
|
| 1290 |
+
lead = next((r for lbl, _, r in loaded if lbl not in _FIXED_COLUMN_SPECS), loaded[0][2])
|
| 1291 |
+
best = _subset_best(lead, higher_is_better)
|
| 1292 |
+
keep = set(zip(best["base"], best["variant"]))
|
| 1293 |
+
|
| 1294 |
+
for label, group, rows in loaded:
|
| 1295 |
+
keys = list(zip(rows["base"], rows["variant"]))
|
| 1296 |
+
if keep is not None:
|
| 1297 |
+
rows = rows[[k in keep for k in keys]]
|
| 1298 |
+
keys = [k for k in keys if k in keep]
|
| 1299 |
+
if rows.empty:
|
| 1300 |
+
continue
|
| 1301 |
+
val_by_col[label] = dict(zip(keys, rows["val"]))
|
| 1302 |
+
imp_by_col[label] = dict(zip(keys, rows["imputed"]))
|
| 1303 |
present.append((label, group))
|
| 1304 |
+
for key, (_, row) in zip(keys, rows.iterrows()):
|
| 1305 |
meta.setdefault(
|
| 1306 |
+
key,
|
| 1307 |
{
|
| 1308 |
"type_name": row["TypeName"],
|
| 1309 |
"emoji": row["Type"],
|
|
|
|
| 1331 |
|
| 1332 |
sort_label = present[0][0]
|
| 1333 |
worst_sort = float("-inf") if higher_is_better else float("inf")
|
| 1334 |
+
entries = sorted(
|
| 1335 |
+
meta, key=lambda k: val_by_col[sort_label].get(k, worst_sort), reverse=higher_is_better
|
| 1336 |
)
|
| 1337 |
|
| 1338 |
rank_by_col, bounds = {}, {}
|
|
|
|
| 1360 |
|
| 1361 |
# -- Body
|
| 1362 |
body = []
|
| 1363 |
+
for key in entries:
|
| 1364 |
+
m = meta[key]
|
| 1365 |
color = model_type_color.get(m["type_name"], "#9e9e9e")
|
| 1366 |
+
name = html.escape(key[0])
|
| 1367 |
if m["variant"]:
|
| 1368 |
name += f' <span class="ta-variant">({html.escape(m["variant"])})</span>'
|
| 1369 |
if m.get("verified") == "✔️":
|
|
|
|
| 1381 |
f'<td class="ta-model-cell">{name_html}</td>',
|
| 1382 |
]
|
| 1383 |
for label, _ in present:
|
| 1384 |
+
val = val_by_col[label].get(key)
|
| 1385 |
if val is None:
|
| 1386 |
cells.append('<td class="ta-na">–</td>')
|
| 1387 |
continue
|
|
|
|
| 1395 |
else:
|
| 1396 |
frac_best = (val - lo) / (hi - lo) if col_higher_better else (hi - val) / (hi - lo)
|
| 1397 |
bg = _interp_color(1 - frac_best)
|
| 1398 |
+
medal = _MEDALS.get(rank_by_col[label].get(key), "")
|
| 1399 |
imp = (
|
| 1400 |
'<sup class="ta-imp" title="Score is (partly) imputed">*</sup>'
|
| 1401 |
+
if imp_by_col[label].get(key)
|
| 1402 |
else ""
|
| 1403 |
)
|
| 1404 |
sel = " ta-col-sel" if label in highlighted else ""
|
|
|
|
| 1410 |
body.append(f"<tr>{''.join(cells)}</tr>")
|
| 1411 |
|
| 1412 |
direction = "Higher is better" if higher_is_better else "Lower is better"
|
| 1413 |
+
scope = (
|
| 1414 |
+
"Each model shows its best-performing variant."
|
| 1415 |
+
if one_per_model
|
| 1416 |
+
else "One row per model variant, so a row's cost is the cost of the run it scores."
|
| 1417 |
+
)
|
| 1418 |
caption = (
|
| 1419 |
+
f'<div class="ta-cap"><b>{html.escape(metric)}</b> per entrant across subsets '
|
| 1420 |
f"(with imputation, all repeats). {direction}; 🥇🥈🥉 mark the top 3 in each column. "
|
| 1421 |
+
f"{scope}</div>"
|
| 1422 |
'<div class="ta-cap ta-cap-legend">✔️ = verified implementation · '
|
| 1423 |
'<span class="ta-imp">*</span> = (partly) imputed score · '
|
| 1424 |
"💡 Click any <u>underlined</u> model name (↗) to open its paper or code.</div>"
|
|
@@ -643,10 +643,19 @@ YOUR_BENCHMARK_LINKS = [
|
|
| 643 |
]
|
| 644 |
|
| 645 |
VERSION_HISTORY_BUTTON_TEXT = """
|
| 646 |
-
**Current Version: TabArena-v0.1.8.
|
| 647 |
|
| 648 |
The following details updates to the leaderboard (date format is YYYY/MM/DD):
|
| 649 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 650 |
* 2026/08/10-v0.1.8.1:
|
| 651 |
* Updated verified model: ChimeraBoost, now at version 0.30.0.
|
| 652 |
* 2026/08/06-v0.1.8:
|
|
|
|
| 643 |
]
|
| 644 |
|
| 645 |
VERSION_HISTORY_BUTTON_TEXT = """
|
| 646 |
+
**Current Version: TabArena-v0.1.8.2**
|
| 647 |
|
| 648 |
The following details updates to the leaderboard (date format is YYYY/MM/DD):
|
| 649 |
|
| 650 |
+
* 2026/08/17-v0.1.8.2:
|
| 651 |
+
* The *Performance across leaderboards* table now has a row per model variant, so default,
|
| 652 |
+
tuned and tuned + ensembled each get their own line and the cost of tuning is on the page.
|
| 653 |
+
Its new *One per model* toggle collapses each method to its best variant, as the win-rate
|
| 654 |
+
matrix's button of the same name does.
|
| 655 |
+
* Fixed the *Fit (s/1K)* and *Infer (s/1K)* columns of that table, which reported the cheapest
|
| 656 |
+
variant of each model rather than the variant on the row. A row labelled
|
| 657 |
+
*(tuned + ensembled)* showed its default's fit time, roughly 200x too low, because tuning
|
| 658 |
+
fits 200 configurations where the default fits one.
|
| 659 |
* 2026/08/10-v0.1.8.1:
|
| 660 |
* Updated verified model: ChimeraBoost, now at version 0.30.0.
|
| 661 |
* 2026/08/06-v0.1.8:
|