llm-bench.io-leaderboard / template.html
Hermes
Fix scenario-column sorting (values nested under row.scenarios)
9530654
Raw History Blame Contribute Delete
9.57 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>llm-bench.io — Local LLM Leaderboard</title>
<meta name="description" content="Live leaderboard of local LLMs benchmarked on real hardware — quality, speed, and VRAM requirements. Powered by llm-bench.io.">
<style>
:root{
--bg:#0b0e14; --panel:#11151f; --panel2:#161b28; --border:#232a3b;
--text:#e8ecf4; --muted:#8b94a7; --accent:#5b8cff; --accent2:#7c5bff;
--good:#4ade80; --mid:#facc15; --bad:#f87171;
}
*{box-sizing:border-box;margin:0;padding:0}
body{background:var(--bg);color:var(--text);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;line-height:1.5;padding:24px 16px 60px}
.wrap{max-width:1180px;margin:0 auto}
header{display:flex;align-items:baseline;gap:12px;flex-wrap:wrap;margin-bottom:6px}
h1{font-size:24px;font-weight:700}
h1 .dot{color:var(--accent)}
.sub{color:var(--muted);font-size:13px;margin-bottom:18px}
.sub a{color:var(--accent);text-decoration:none}
.sub a:hover{text-decoration:underline}
.toolbar{display:flex;gap:10px;flex-wrap:wrap;align-items:center;margin-bottom:14px}
.chips{display:flex;gap:6px;flex-wrap:wrap}
.chip{background:var(--panel);border:1px solid var(--border);color:var(--muted);border-radius:999px;padding:5px 12px;font-size:12.5px;cursor:pointer;user-select:none;transition:all .15s}
.chip:hover{color:var(--text);border-color:#3a445c}
.chip.active{background:var(--accent);border-color:var(--accent);color:#fff}
.search{margin-left:auto;background:var(--panel);border:1px solid var(--border);border-radius:8px;color:var(--text);padding:7px 12px;font-size:13px;min-width:200px}
.search::placeholder{color:var(--muted)}
.meta{color:var(--muted);font-size:12px;margin-bottom:10px;display:flex;gap:16px;flex-wrap:wrap}
.meta b{color:var(--text);font-weight:600}
.card{background:var(--panel);border:1px solid var(--border);border-radius:12px;overflow:auto}
table{width:100%;border-collapse:collapse;font-size:13px;min-width:900px}
th,td{padding:9px 12px;text-align:left;border-bottom:1px solid var(--border);white-space:nowrap}
th{position:sticky;top:0;background:var(--panel2);color:var(--muted);font-size:11.5px;text-transform:uppercase;letter-spacing:.04em;cursor:pointer;user-select:none;z-index:1}
th:hover{color:var(--text)}
th .arrow{font-size:10px;margin-left:3px;opacity:.7}
td.num,th.num{text-align:right;font-variant-numeric:tabular-nums}
tr:hover td{background:rgba(91,140,255,.05)}
.model-cell{display:flex;flex-direction:column;gap:1px;max-width:340px}
.model-name{font-weight:600;color:var(--text);overflow:hidden;text-overflow:ellipsis}
.model-hw{color:var(--muted);font-size:11.5px;overflow:hidden;text-overflow:ellipsis}
.vram{color:var(--accent2);font-weight:600}
.qbar{display:inline-block;width:52px;height:5px;border-radius:3px;background:var(--border);vertical-align:middle;margin-right:7px;overflow:hidden}
.qbar i{display:block;height:100%;border-radius:3px}
.sc{color:var(--text)}
.sc.dim{color:var(--muted)}
.updated{color:var(--muted);font-size:11.5px}
footer{margin-top:22px;color:var(--muted);font-size:12px;display:flex;gap:8px;flex-wrap:wrap;align-items:center}
footer a{color:var(--accent);text-decoration:none}
footer a:hover{text-decoration:underline}
.empty{padding:40px;text-align:center;color:var(--muted)}
@media(max-width:700px){ .search{margin-left:0;width:100%} }
</style>
</head>
<body>
<div class="wrap">
<header>
<h1>llm-bench<span class="dot">.io</span> — Local LLM Leaderboard</h1>
</header>
<div class="sub">
Real-world benchmarks from actual users — LLM-judged <b>quality</b> and <b>speed</b> across coding, agent, role-play &amp; research tasks, grouped by VRAM.
<a href="https://llm-bench.io" target="_blank" rel="noopener">Run your own test →</a>
</div>
<div class="toolbar">
<div class="chips" id="vramChips"></div>
<input class="search" id="search" type="search" placeholder="Filter model name…" aria-label="Filter models">
</div>
<div class="meta" id="meta">
__META__
</div>
<div class="card">
<table>
<thead>
<tr>
<th data-sort="model">Model</th>
<th data-sort="vram" class="num">VRAM</th>
<th data-sort="runs" class="num">Runs</th>
<th data-sort="quality" class="num">Quality</th>
<th data-sort="speed" class="num">Speed (tok/s)</th>
<th data-sort="coding_agent" class="num">Coding</th>
<th data-sort="openclaw" class="num">Agent</th>
<th data-sort="roleplay" class="num">Role-Play</th>
<th data-sort="research" class="num">Research</th>
<th data-sort="updated" class="num">Updated</th>
</tr>
</thead>
<tbody id="rows">
__ROWS__
</tbody>
</table>
</div>
<footer>
<span>Data: last <b id="win">__WIN__</b> days, ≥ <b id="minr">__MINR__</b> runs per model · generated <span id="gen">__GEN__</span></span>
<span>·</span>
<span>Methodology: <a href="https://llm-bench.io/benchmark-methodology" target="_blank" rel="noopener">how we measure</a></span>
<span>·</span>
<span>Dataset on Hugging Face: <a href="https://huggingface.co/datasets/llmbenchio/benchmarks-by-vram" target="_blank" rel="noopener">llmbenchio/benchmarks-by-vram</a></span>
</footer>
</div>
<script>
let DATA=null, sortKey="quality", sortDir=-1, vramFilter=null, query="";
async function init(){
// Table rows + meta are pre-rendered at build time (static view for the
// no-JS org card / crawlers). data.json enables interactive
// filtering + sorting on the live Space page.
try{
DATA = await (await fetch("data.json")).json();
}catch(e){ DATA=null; }
if(!DATA) return;
renderChips(); bindHeader(); bindSearch(); render();
}
function renderChips(){
const vals=[...new Set(DATA.rows.map(r=>r.vram))].sort((a,b)=>a-b);
const box=document.getElementById("vramChips");
const all=document.createElement("div");
all.className="chip active"; all.textContent="All VRAM";
all.onclick=()=>{vramFilter=null;[...box.children].forEach(c=>c.classList.remove("active"));all.classList.add("active");render();};
box.appendChild(all);
for(const v of vals){
const c=document.createElement("div");
c.className="chip"; c.textContent=v+" GB";
c.onclick=()=>{vramFilter=v;[...box.children].forEach(x=>x.classList.remove("active"));c.classList.add("active");render();};
box.appendChild(c);
}
}
function bindHeader(){
document.querySelectorAll("th[data-sort]").forEach(th=>{
th.addEventListener("click",()=>{
const k=th.dataset.sort;
if(sortKey===k) sortDir*=-1; else {sortKey=k;sortDir=(k==="model"?1:-1);}
render();
});
});
}
function bindSearch(){
document.getElementById("search").addEventListener("input",e=>{query=e.target.value.toLowerCase();render();});
}
function qColor(v){ if(v==null)return "var(--bad)"; if(v>=85)return "var(--good)"; if(v>=75)return "var(--mid)"; return "var(--bad)"; }
function esc(s){ return String(s).replace(/[&<>"']/g,c=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"}[c])); }
function render(){
let rows=DATA.rows.slice();
if(vramFilter!=null) rows=rows.filter(r=>r.vram===vramFilter);
if(query) rows=rows.filter(r=>r.model.toLowerCase().includes(query));
rows.sort((a,b)=>{
// scenario values are nested under r.scenarios; other keys are top-level
const val=r=>{ const v=(sortKey in r)?r[sortKey]:r.scenarios?.[sortKey]; return v==null?-1:v; };
let x=val(a), y=val(b);
if(typeof x==="string"||typeof y==="string") return sortDir*String(x).localeCompare(String(y));
return sortDir*(x-y);
});
const head=document.querySelector("thead tr");
[...head.children].forEach(th=>{
const t=th.querySelector(".arrow"); if(t)t.remove();
if(th.dataset.sort===sortKey){const a=document.createElement("span");a.className="arrow";a.textContent=sortDir<0?"▼":"▲";th.appendChild(a);}
});
const tb=document.getElementById("rows");
if(!rows.length){ tb.innerHTML='<tr><td colspan="10" class="empty">No models match this filter.</td></tr>'; return; }
tb.innerHTML=rows.map(r=>{
const link=`https://llm-bench.io/benchmarks?model=${encodeURIComponent(r.model)}`;
const sc=k=>r.scenarios[k]!=null
? `<td class="num sc">${r.scenarios[k].toFixed(1)}</td>`
: `<td class="num sc dim">–</td>`;
const q=r.quality;
const qCell=q!=null
? `<td class="num"><span class="qbar"><i style="width:${Math.max(0,Math.min(100,q))}%;background:${qColor(q)}"></i></span><b>${q.toFixed(1)}</b></td>`
: `<td class="num sc dim">–</td>`;
return `<tr style="cursor:pointer" title="Open on llm-bench.io">
<td><div class="model-cell"><a class="model-name" href="${link}" target="_blank" rel="noopener" onclick="event.stopPropagation()">${esc(r.model)}</a><span class="model-hw">${esc(r.hardware)}</span></div></td>
<td class="num vram">${r.vram} GB</td>
<td class="num">${r.runs}</td>
${qCell}
<td class="num">${r.speed!=null?r.speed.toFixed(1):"–"}</td>
${sc("coding_agent")}${sc("openclaw")}${sc("roleplay")}${sc("research")}
<td class="num updated">${r.updated}</td>
</tr>`;
}).join("");
document.getElementById("meta").innerHTML=
`<span><b>${rows.length}</b> models</span>`+
`<span><b>${DATA.inWindow}</b> submissions in window</span>`+
`<span>of <b>${DATA.totalSubmissions}</b> total on llm-bench.io</span>`;
}
init();
</script>
</body>
</html>