File size: 6,088 Bytes
03696ac | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | from __future__ import annotations
import html
import logging
import re
from datetime import datetime, timezone
from pathlib import Path
from threading import RLock
from typing import Any
import gradio as gr
import pandas as pd
from apscheduler.schedulers.background import BackgroundScheduler
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from huggingface_hub import snapshot_download
from src.about import (
CITATION_BUTTON_LABEL,
CITATION_BUTTON_TEXT,
EVALUATION_QUEUE_TEXT,
LLM_BENCHMARKS_TEXT,
TITLE,
Tasks,
)
from src.display.utils import (
BENCHMARK_COLS,
COLS,
EVAL_COLS,
ModelType,
Precision,
WeightType,
)
from src.envs import EVAL_REQUESTS_PATH, EVAL_RESULTS_PATH, QUEUE_REPO, RESULTS_REPO, TOKEN
from src.populate import get_evaluation_queue_df, get_leaderboard_df
from src.submission.submit import add_new_eval
logging.basicConfig(level=logging.INFO)
LOGGER = logging.getLogger("leaderboard")
ROOT = Path(__file__).parent
STATIC_DIR = ROOT / "static"
MODEL_LINK_RE = re.compile(r'href=["\']https://huggingface\.co/([^"\']+)["\']')
DATA_LOCK = RLock()
DATA: dict[str, Any] = {}
def _download_dataset(repo_id: str, local_dir: str) -> None:
Path(local_dir).mkdir(parents=True, exist_ok=True)
snapshot_download(
repo_id=repo_id,
local_dir=local_dir,
repo_type="dataset",
tqdm_class=None,
etag_timeout=30,
token=TOKEN,
)
def _json_value(value: Any) -> Any:
if pd.isna(value):
return None
if hasattr(value, "item"):
value = value.item()
return value
def _model_id(value: Any) -> str:
text = str(value or "")
if match := MODEL_LINK_RE.search(text):
return html.unescape(match.group(1))
return html.unescape(re.sub("<[^>]+>", "", text))
def _records(frame: pd.DataFrame) -> list[dict[str, Any]]:
records = []
for row in frame.to_dict(orient="records"):
clean_row = {str(key): _json_value(value) for key, value in row.items()}
if "Model" in clean_row:
clean_row["Model"] = _model_id(clean_row["Model"])
if "model" in clean_row:
clean_row["model"] = _model_id(clean_row["model"])
records.append(clean_row)
return records
def _empty_payload(message: str | None = None) -> dict[str, Any]:
return {
"rows": [],
"queues": {"finished": [], "running": [], "pending": []},
"benchmarks": [task.value.col_name for task in Tasks],
"model_types": [item.to_str(" · ") for item in ModelType if item is not ModelType.Unknown],
"precisions": [item.value.name for item in Precision if item is not Precision.Unknown],
"weight_types": [item.value.name for item in WeightType],
"copy": {
"title": TITLE,
"about": LLM_BENCHMARKS_TEXT.strip(),
"submission": EVALUATION_QUEUE_TEXT.strip(),
"citation_label": CITATION_BUTTON_LABEL,
"citation": CITATION_BUTTON_TEXT.strip(),
},
"updated_at": datetime.now(timezone.utc).isoformat(),
"error": message,
}
def refresh_data(*, download: bool = True) -> dict[str, Any]:
"""Refresh leaderboard and queue data without taking the Space offline."""
errors = []
if download:
for repo_id, local_dir in (
(QUEUE_REPO, EVAL_REQUESTS_PATH),
(RESULTS_REPO, EVAL_RESULTS_PATH),
):
try:
_download_dataset(repo_id, local_dir)
except Exception as exc: # Keep serving the last successful snapshot.
LOGGER.exception("Could not refresh %s", repo_id)
errors.append(f"Could not refresh {repo_id}: {exc}")
payload = _empty_payload("; ".join(errors) or None)
try:
leaderboard = get_leaderboard_df(EVAL_RESULTS_PATH, EVAL_REQUESTS_PATH, COLS, BENCHMARK_COLS)
payload["rows"] = _records(leaderboard)
except Exception as exc:
LOGGER.exception("Could not build leaderboard data")
payload["error"] = f"Could not build leaderboard data: {exc}"
try:
finished, running, pending = get_evaluation_queue_df(EVAL_REQUESTS_PATH, EVAL_COLS)
payload["queues"] = {
"finished": _records(finished),
"running": _records(running),
"pending": _records(pending),
}
except Exception as exc:
LOGGER.exception("Could not build evaluation queues")
payload["error"] = f"Could not build evaluation queues: {exc}"
with DATA_LOCK:
DATA.clear()
DATA.update(payload)
return dict(DATA)
server = gr.Server(
title="Open LLM Benchmark",
description="A clean, customizable Gradio 6 leaderboard template.",
version="2.0.0",
)
server.mount("/static", StaticFiles(directory=STATIC_DIR), name="static")
@server.get("/", response_class=HTMLResponse, include_in_schema=False)
async def homepage() -> HTMLResponse:
return HTMLResponse((STATIC_DIR / "index.html").read_text())
@server.api(name="leaderboard_data", queue=False, concurrency_limit=None)
def leaderboard_data() -> dict[str, Any]:
"""Return the current leaderboard, evaluation queues, filters, and template copy."""
with DATA_LOCK:
return dict(DATA) if DATA else _empty_payload("Data is still loading.")
@server.api(name="submit_model", concurrency_limit=4)
def submit_model(
model: str,
base_model: str,
revision: str,
precision: str,
weight_type: str,
model_type: str,
) -> dict[str, str]:
"""Validate a public Hugging Face model and add it to the evaluation queue."""
result = add_new_eval(model, base_model, revision, precision, weight_type, model_type)
if result["status"] == "success":
refresh_data(download=False)
return result
if __name__ == "__main__":
refresh_data()
scheduler = BackgroundScheduler(daemon=True)
scheduler.add_job(refresh_data, "interval", minutes=10, max_instances=1, coalesce=True)
scheduler.start()
server.launch()
|