Skip to main content

update-leaderboard

Regenerate the TabArena website artifacts and refresh a leaderboard Space's `data/` with them. Use this skill whenever a maintainer wants to publish the latest results to the leaderboard — e.g. "update the leaderboard", "regenerate the website artifacts and refresh the LB", "push the new results to the leaderboard Space", "refresh leaderboard-testing with the latest". Runs `scripts/run_generate_website_artifacts.py`, pre-checks that any newly added *models* classify correctly (Foundation Model / Tree-based / … not `❓ Other`; systems are typed from `method_class` and need no pre-check), then swaps the generated artifacts into the Space repo's `data/` folder (deleting the old subtree first) and bumps the version history in `website_texts.py`. Optionally serves the Space locally for preview. Complements `upload-method` (which publishes one method's results so they become downloadable — run that first).

Source facts

Repository
autogluon/tabarena
Last source activity
October 2, 2026 at 10:42
Detected SKILL.md language
English
Stars
339
Forks
79

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
2 files

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
update-leaderboard
description
Regenerate the TabArena website artifacts and refresh a leaderboard Space's `data/` with them. Use this skill whenever a maintainer wants to publish the latest results to the leaderboard — e.g. "update the leaderboard", "regenerate the website artifacts and refresh the LB", "push the new results to the leaderboard Space", "refresh leaderboard-testing with the latest". Runs `scripts/run_generate_website_artifacts.py`, pre-checks that any newly added *models* classify correctly (Foundation Model / Tree-based / … not `❓ Other`; systems are typed from `method_class` and need no pre-check), then swaps the generated artifacts into the Space repo's `data/` folder (deleting the old subtree first) and bumps the version history in `website_texts.py`. Optionally serves the Space locally for preview. Complements `upload-method` (which publishes one method's results so they become downloadable — run that first).
argument-hint
<lb-code-dir> [<generation-venv>]
user-invocable
true
# Regenerate & Publish the TabArena Leaderboard This skill drives the maintainer workflow that turns the **already-uploaded** benchmark results into the tabarena.ai website artifacts and refreshes a leaderboard **Space repo's `data/`** with them. It is the last stage of the lifecycle: `add-model` (integrate) → `benchmark-model` (run) → `upload-method` (publish one method's results to r2, register it in `methods.py`) → **`update-leaderboard`** (regenerate figures/tables + refresh the Space). The authoritative prose lives in the module docstring of `scripts/run_generate_website_artifacts.py` and the Space repo's `README.md`. This skill operationalizes it and bakes in the thing that is easy to get wrong: the **model-type pre-check**. ## What this skill delivers 1. A **model-type pre-check** so newly added models don't ship as `❓ Other`. (Systems are exempt: they are typed from `MethodMetadata.method_class`, not from a name prefix.) 2. A **regeneration run** of `run_generate_website_artifacts.py` (Claude runs it — background + monitor; it's slow but needs no credentials). 3. A **refreshed `data/`** in the leaderboard Space repo, done the safe way (delete-then-copy), with sanity counts. 4. A **version-history bump** in the Space repo's `website_texts.py` (new dated entry + current-version line). 5. Optionally, a **local preview server** started with the Space repo's own `.venv`. 6. A **hand-off**: the maintainer commits + `git push`es the Space (Git LFS + Xet; no token on this box). ## Step 0: Gather inputs Parse `$ARGUMENTS`. Collect (ask only for what's missing or ambiguous): | Input | Example | Notes | |---|---|---| | `lb_code_dir` | `.../leaderboard-testing` | **Required.** The cloned HuggingFace **Space repo** (has `data/`, `main.py`, its own `.venv`). Use `leaderboard-testing` for a **safe private preview**; `leaderboard` is the **live production** Space. Default to `leaderboard-testing` and confirm before touching `leaderboard`. | | `generation_venv` | `~/.venvs/tabarena_<date>` | A venv with **`tabarena[benchmark]`** installed (needed to run the generator — download + ray + figures). This is **not** the Space repo's `.venv` (which only has gradio/pandas). If unset, find the maintainer's under `~/.venvs/tabarena_*`. | | new/changed models | `tabswift` | Which models were just added/uploaded — focus of the Step 1 pre-check. Infer from recent `git status`/`methods.py` diff if unstated. | | arena | `tabarena` (main) | The main leaderboard uses `run_generate_website_artifacts.py` → `data/`. **BeyondArena** is a sibling (see the note at the end) → `run_generate_beyondarena_website_artifacts.py` → `data_beyondarena/`. This skill targets the main leaderboard unless told otherwise. | ## Step 1: Model-type pre-check (do this BEFORE generating) The leaderboard's `Type` / `TypeName` columns are set at generation time by `packages/tabarena/src/tabarena/website/website_format.py`. Any model whose family prefix isn't registered there ships as `❓ Other`. Verify each new/changed model first — it's a 2-minute read that saves a full regeneration. How the classification works (read `website_format.py`): - `add_metadata()` calls `get_model_family(config_type)`. `config_type` is the method's `model_key` (+ optional `name_suffix`); `model_key` **defaults to `ag_key`** (see `_method_metadata.py`). - `get_model_family()` lowercases, **strips a leading `TA-`** (case-insensitive), then prefix-matches against `prefixes_mapping` (`foundational`, `neural_network`, `tree`, `baseline`, `other`). No match → `Constants.other` (`❓ Other`). - **Systems skip all of this.** When `method_class == "system"`, `add_metadata` sets the family to `Constants.system` (📊) directly, and the figure paths recognize them from `system_display_names`. There is no prefix to register, so this pre-check only concerns models. - `get_rename_map()` gives the pretty display name (e.g. `TABSWIFT` → `TabSwift`). Check, for each new model (example: TabSwift, `ag_key="TA-TABSWIFT"`): 1. Its `ag_key`/`model_key` prefix appears under the **intended** family list in `get_model_family`'s `prefixes_mapping` (TabSwift → `Constants.foundational`). The `TA-` strip means listing either `"TABSWIFT"` or `"TA-TABSWIFT"` works. 2. There's a `get_rename_map()` entry for a clean display name. If missing, add the prefix to the right family list (and a rename entry). This is the same edit the `add-model` skill calls out — cross-reference it. Confirm quickly: ```bash <generation_venv>/bin/python -c "from tabarena.website.website_format import get_model_family; print(get_model_family('TA-TABSWIFT'))" # -> Foundation Model (NOT 'Other') ``` ## Step 2: Regenerate the website artifacts (Claude runs; slow, no creds) Run the generator **from `tabarena/scripts/`** (its `base_dir` is the relative `generated_website_artifacts`, so cwd matters) with the **generation venv**. It's long-running — `TabArenaContext.load_results(download_results="auto")` downloads the latest results, then figures + tuning trajectories are built across CPUs with ray (a few minutes on many cores; longer here). **Launch it in the background and poll the log** rather than blocking. ```bash cd <tabarena>/scripts nohup <generation_venv>/bin/python run_generate_website_artifacts.py > <scratch>/gen_website.log 2>&1 & ``` Useful flags (defaults = the fast website-only publish run): `--skip-evaluate` / `--skip-trajectories` reuse the existing raw artifacts for one pipeline when only the other's outputs changed; `--elo-bootstrap-rounds 1` for a toy run (Elo CIs meaningless); `--full-figures` restores the full per-subset paper figure suite (incl. GIF animations); `--zip-raw` re-enables the large raw-artifacts zip (the publish flow only needs the clean zip). Monitor until the process exits, then verify outputs — **don't trust "exited" alone**: - **Harmless noise to ignore:** at the end ray tears down its workers and each logs a `*** SIGTERM received ***` C++ stack trace (dozens of them, one per worker PID). A single Ray `FutureWarning` about accelerator env vars is also fine. Neither is a failure. - **Real success signals** (check these): - `generated_website_artifacts/clean_website_artifacts/website_data/` exists with `imputation_no/` + `imputation_yes/`. - `clean_website_artifacts.zip` was written next to it. - In the generated CSVs, the new model appears with the right `TypeName` — re-confirm Step 1 held: ```bash cd <tabarena>/scripts/generated_website_artifacts/clean_website_artifacts/website_data <generation_venv>/bin/python - <<'PY' import pandas as pd df = pd.read_csv("imputation_no/splits_all/tasks_all/datasets_all/website_leaderboard.csv") print(df.loc[df["Model"].str.contains("TabSwift", case=False), ["Type","TypeName","Model"]].to_string(index=False)) PY ``` - Structural sanity, counted **inside the `entrants_*` roots** (a stale top-level `imputation_*` layout may sit next to them, see Step 3): **8** roots (one per combination of the system categories) and, per root, one `website_leaderboard.csv`, one `n_datasets_*` marker and one `leaderboard_table.html` per subset plus the interactive `*_explorer.html` pages, and **0** `*.png` / `*.png.zip` (TabArena publishes no static figures). The subset count grows with the site (60 subsets per pool in v0.1.8, 116 since the balanced / imbalanced / extreme subsets of v0.1.9: 928 CSVs and 3744 explorers over the 8 pools), so compare the counts and the file list against the Space's current `data/` (`diff <(cd $SRC && find entrants_* -type f | sort) <(cd $DST && find entrants_* -type f | sort)` is empty when no subset was added or removed) rather than against fixed numbers. - Pool sanity: `entrants_models` must contain **no** AutoGluon row, and a model's Elo must differ between `entrants_models` and `entrants_open_llm_api` (a wider field re-rates everyone). If they match, the pool filter did not apply. ## Step 3: Refresh the Space repo's `data/` `data/` in the Space repo mirrors the generated `website_data/`. **Delete the old subtree first, then copy — do not overlay**, so a subset that no longer exists cannot survive as a leftover. TabArena no longer ships PNGs, which retires the old stale-unzipped-`.png` gotcha for `data/`; it still applies to `data_beyondarena/`, whose figures are zipped PNGs served through `data_loading.unzip_png`. ```bash SRC=<tabarena>/scripts/generated_website_artifacts/clean_website_artifacts/website_data DST=<lb_code_dir>/data # 1. Sanity-check nothing but entrants_* lives in data/ (so the rm is safe). A pre-v0.1.8 checkout # still has imputation_* at the top level; those are the old layout and go too. find "$DST" -mindepth 1 -maxdepth 1 ! -name 'entrants_*' ! -name 'imputation_*' # expect: no output # 2. Delete the old subtree, then copy the fresh one in. Copy the entrant pools ONLY: the generator wipes # neither raw_website_artifacts/ nor website_data/, so the pre-pool imputation_no/ + imputation_yes/ # layout (static PNGs) from before v0.1.8 survives at the top level, is re-converted every run and # sits in clean_website_artifacts.zip too, while the Space tracks nothing but entrants_*. rm -rf "$DST"/entrants_* "$DST"/imputation_* cp -r "$SRC"/entrants_* "$DST"/ # 3. Verify the swap: echo "any .png (MUST be 0): $(find "$DST" -name '*.png*' | wc -l)" echo "entrant pools: $(find "$DST" -mindepth 1 -maxdepth 1 -name 'entrants_*' | wc -l)" # 8 echo "csv: $(find "$DST" -name 'website_leaderboard.csv' | wc -l)" # same as before the swap unless a subset changed ``` Then confirm the diff is clean — **all modifications, no adds/deletes/untracked** (a new or removed subset would show up here and means the layout changed): ```bash cd <lb_code_dir> && git status --short | awk '{print $1}' | sort | uniq -c # expect only 'M' ``` (The Space's `README.md` describes an equivalent "unzip `clean_website_artifacts.zip` into `data`" path — the delete-then-copy above is the same result done safely.) ## Step 4: Bump the version history (Claude does now) Every leaderboard refresh gets a new entry in the Space repo's **`website_texts.py`** — the `VERSION_HISTORY_BUTTON_TEXT` block that the UI's "Version History" button renders. **Don't skip this**: it's the user-facing record of what changed, and it's easy to forget because it lives in the Space repo, not in `tabarena`. Read the block first, then `Edit`: 1. **Add a dated entry at the top of the list** (newest first; date format `YYYY/MM/DD`, today's date) with a bumped version number, describing what changed. Match the existing wording: - New model → `Add new verified model: <Name>` or `Add new unverified model: <Name>`. Pick **verified vs unverified from the model's `info.py` `verified` flag** (`verified=False` → "unverified"). List multiple on one line if several shipped together. - Other changes (UI, metric, system, removals) → mirror the phrasing of past entries. 2. **Bump `**Current Version: TabArena-vX.Y.Z**`** at the top of the block to the same new number. Version bumping: increment the **last** component for a normal model-addition / data refresh (`v0.1.5.2` → `v0.1.5.3`); larger jumps (`v0.1.5` → new UI, `v0.1.6`) are for bigger releases — match the granularity of comparable past entries. Example (adding the unverified TabSwift on 2026/07/10, bumping `v0.1.5.2` → `v0.1.5.3`): ``` **Current Version: TabArena-v0.1.5.3** ... * 2026/07/10-v0.1.5.3: * Add new unverified model: TabSwift * 2026/07/08-v0.1.5.2: * Add new verified model: TabFM ``` ## Step 5: Preview locally (optional) Start the app with the **Space repo's own `.venv`** (it has gradio + `gradio_leaderboard`; the generation venv does not). `main.py`'s `launch()` binds `127.0.0.1:7860`. ```bash cd <lb_code_dir> nohup .venv/bin/python main.py > <scratch>/lb_serve.log 2>&1 & ``` Gradio block-buffers stdout to a file, so the log may stay empty — confirm it's up by the port, not the log: ```bash ss -tlnp | grep 7860 ; curl -s -o /dev/null -w "HTTP %{http_code}\n" http://127.0.0.1:7860/ ``` On a remote box the maintainer needs port-forwarding to view it (VS Code forwards `7860` automatically, or `ssh -L 7860:localhost:7860 …`). ## Step 6: Hand off (maintainer commits + pushes) By default the **maintainer** commits/pushes the Space (Git LFS + Git Xet for the `.png.zip` files; `hf auth login --add-to-git-credential` is set up on this box, so Claude *can* push when explicitly asked). From `<lb_code_dir>`: ```bash git add data website_texts.py && git commit -m "Update leaderboard data + version history" && git push ``` `git add data` matters: a refresh both **modifies** the tracked `.png.zip`/CSV files and **adds new untracked files** (the `*_explorer.html` + data-export CSVs) — an IDE commit of "changed files only" silently drops the interactive plots and the site falls back to static PNGs. Surface these caveats: - The `data/` swap only reflects methods whose results were actually **uploaded** (`upload-method`, the real `--no-dry-run`). A method registered in `methods.py` but not uploaded won't have artifacts. - `leaderboard-testing` is the **private preview**; pushing to `leaderboard` publishes **live**. ### Storage-limit rejections (`Repository storage limit reached (Max: 1 GB)`) Space repos cap git-LFS storage at 1 GB and each refresh adds ~85 MB of new figure zips, so this
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub