SLM_Regression_Line / index.html
Harley-ml's picture
Upload index.html
f517626 verified
Raw
History Blame Contribute Delete
96.6 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Silver Regression Explorer</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4"></script>
<style>
:root{
--bg0:#f6f7f9;
--bg1:#e4e7ec;
--bg2:#c8ced8;
--surface:#ffffff;
--surface2:#f9fafc;
--surface3:#eef2f7;
--ink:#111318;
--ink2:#2f3540;
--muted:#5e6675;
--muted2:#788190;
--accent:#2f6fed;
--accent2:#1f9d7a;
--line:#d8dde6;
--line2:#b7bfcc;
--shadow:0 18px 45px rgba(29,38,52,.12);
--shadow2:0 10px 24px rgba(29,38,52,.10);
--radius:8px;
--radius2:8px;
--radius3:8px;
}
body[data-theme="dark"]{
--bg0:#101216;
--bg1:#161a21;
--bg2:#202631;
--surface:#181d25;
--surface2:#202631;
--surface3:#252d39;
--ink:#f2f5f9;
--ink2:#d7dde7;
--muted:#a5adba;
--muted2:#87909f;
--accent:#7fb0ff;
--accent2:#72d4ba;
--line:#303847;
--line2:#465163;
--shadow:0 18px 50px rgba(0,0,0,.38);
--shadow2:0 10px 24px rgba(0,0,0,.30);
}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{
margin:0;
min-height:100vh;
padding:24px;
color:var(--ink);
font-family:Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
background:
linear-gradient(180deg, rgba(255,255,255,.72), rgba(255,255,255,0) 260px),
linear-gradient(135deg, var(--bg0), var(--bg1) 48%, var(--bg2));
transition: background .25s ease, color .25s ease;
}
body[data-theme="dark"]{
background:
linear-gradient(180deg, rgba(255,255,255,.05), rgba(255,255,255,0) 280px),
linear-gradient(135deg, var(--bg0), var(--bg1) 50%, var(--bg2));
}
.app{max-width:1540px;margin:0 auto;display:grid;gap:18px}
.hero, .panel, .chart-card, .info-card, .disclaimer{
border:1px solid var(--line);
background:linear-gradient(180deg, rgba(255,255,255,.96), rgba(247,249,252,.92));
box-shadow:var(--shadow);
backdrop-filter:blur(12px);
transition: background .25s ease, border-color .25s ease, color .25s ease, box-shadow .25s ease;
}
body[data-theme="dark"] .hero,
body[data-theme="dark"] .panel,
body[data-theme="dark"] .chart-card,
body[data-theme="dark"] .info-card,
body[data-theme="dark"] .disclaimer{
border-color:var(--line);
background:linear-gradient(180deg, rgba(255,255,255,.06), rgba(255,255,255,.025));
}
.hero{
border-radius:var(--radius);
padding:26px;
position:relative;
overflow:hidden;
}
.hero::before{
content:"";
position:absolute;
inset:0 0 auto;
height:4px;
pointer-events:none;
background:linear-gradient(90deg, var(--accent), var(--accent2), rgba(255,255,255,.6));
}
body[data-theme="dark"] .hero::before{
background:linear-gradient(90deg, var(--accent), var(--accent2), rgba(255,255,255,.16));
}
.hero::after{
content:"";
position:absolute;
inset:0;
pointer-events:none;
background:linear-gradient(90deg, rgba(47,111,237,.08), transparent 42%, rgba(31,157,122,.07));
}
body[data-theme="dark"] .hero::after{
background:linear-gradient(90deg, rgba(127,176,255,.08), transparent 42%, rgba(114,212,186,.06));
}
.hero-top{
position:relative;
z-index:1;
display:flex;
align-items:flex-start;
justify-content:space-between;
gap:16px;
flex-wrap:wrap;
}
.eyebrow{
position:relative;z-index:1;
text-transform:uppercase;
letter-spacing:.18em;
font-size:11px;
color:var(--muted);
margin-bottom:12px;
font-weight:700;
}
body[data-theme="dark"] .eyebrow{color:var(--muted)}
h1{
position:relative;z-index:1;
margin:0;
font-size:clamp(34px, 4.6vw, 64px);
line-height:1;
letter-spacing:0;
font-weight:880;
}
.title-silver{
background:linear-gradient(180deg, #ffffff 0%, #dce3ee 38%, #6d7687 100%);
-webkit-background-clip:text;
background-clip:text;
color:transparent;
text-shadow:0 1px 0 rgba(255,255,255,.36);
}
body[data-theme="dark"] .title-silver{
background:linear-gradient(180deg, #ffffff 0%, #ccd7e6 36%, #8793a5 100%);
-webkit-background-clip:text;
background-clip:text;
color:transparent;
text-shadow:none;
}
.sub{
position:relative;z-index:1;
margin:14px 0 0;
max-width:1060px;
color:var(--muted);
line-height:1.65;
font-size:14px;
}
.theme-toggle-group{
position:relative;
z-index:1;
display:flex;
gap:8px;
flex-wrap:wrap;
align-items:center;
justify-content:flex-end;
}
.theme-pill{
padding:10px 14px;
border-radius:var(--radius3);
font-size:13px;
border:1px solid var(--line);
background:var(--surface);
color:var(--ink2);
box-shadow:0 1px 0 rgba(255,255,255,.75) inset;
}
body[data-theme="dark"] .theme-pill{
border-color:var(--line);
background:var(--surface2);
color:var(--ink);
}
.layout{display:grid;grid-template-columns:360px minmax(0,1fr);gap:18px;align-items:start}
.panel{
position:sticky;top:18px;
border-radius:var(--radius);
padding:18px;
background:linear-gradient(180deg, rgba(255,255,255,.96), rgba(247,249,252,.92));
}
body[data-theme="dark"] .panel{background:linear-gradient(180deg, rgba(255,255,255,.06), rgba(255,255,255,.025))}
.panel h2, .chart-card h2, .info-card h2{
margin:0 0 14px;
font-size:12px;
color:#6d7380;
text-transform:uppercase;
letter-spacing:.16em;
font-weight:850;
}
body[data-theme="dark"] .panel h2,
body[data-theme="dark"] .chart-card h2,
body[data-theme="dark"] .info-card h2{color:#a8afbd}
.section{margin-bottom:18px}
.section-label{
display:block;
margin-bottom:10px;
color:#4d525e;
font-size:11px;
text-transform:uppercase;
letter-spacing:.15em;
font-weight:800;
}
body[data-theme="dark"] .section-label{color:#c0c6d1}
.btn-grid{display:flex;flex-wrap:wrap;gap:8px}
button, .chip, .tiny-btn, .org-chip, .pill{
border:1px solid var(--line);
background:linear-gradient(180deg, var(--surface), var(--surface3));
color:var(--ink2);
padding:10px 13px;
border-radius:var(--radius3);
cursor:pointer;
font:inherit;
font-size:13px;
user-select:none;
transition:transform .16s ease, border-color .16s ease, background .16s ease, color .16s ease, box-shadow .16s ease;
outline:none;
box-shadow:0 1px 0 rgba(255,255,255,.72) inset;
}
body[data-theme="dark"] button,
body[data-theme="dark"] .chip,
body[data-theme="dark"] .tiny-btn,
body[data-theme="dark"] .org-chip,
body[data-theme="dark"] .pill{
border-color:var(--line);
background:linear-gradient(180deg, var(--surface2), var(--surface));
color:var(--ink);
box-shadow:none;
}
button:hover, .chip:hover, .tiny-btn:hover, .org-chip:hover, .pill:hover{
transform:translateY(-1px);
border-color:var(--line2);
color:var(--ink);
box-shadow:0 10px 22px rgba(29,38,52,.10);
}
body[data-theme="dark"] button:hover,
body[data-theme="dark"] .chip:hover,
body[data-theme="dark"] .tiny-btn:hover,
body[data-theme="dark"] .org-chip:hover,
body[data-theme="dark"] .pill:hover{
border-color:var(--line2);
color:#fff;
box-shadow:0 10px 24px rgba(0,0,0,.18);
}
button:focus-visible, .chip:focus-visible, .search:focus-visible, .select:focus-visible{
box-shadow:0 0 0 3px rgba(47,111,237,.18);
}
body[data-theme="dark"] button:focus-visible,
body[data-theme="dark"] .chip:focus-visible,
body[data-theme="dark"] .search:focus-visible,
body[data-theme="dark"] .select:focus-visible{
box-shadow:0 0 0 3px rgba(127,176,255,.22);
}
button.active, .chip.active, .tiny-btn.active, .org-chip.active, .pill.active{
color:#0f1724;
border-color:rgba(47,111,237,.45);
background:linear-gradient(180deg, #ffffff, #e9f0ff);
box-shadow:0 0 0 1px rgba(47,111,237,.12) inset, 0 8px 18px rgba(47,111,237,.10);
}
body[data-theme="dark"] button.active,
body[data-theme="dark"] .chip.active,
body[data-theme="dark"] .tiny-btn.active,
body[data-theme="dark"] .org-chip.active,
body[data-theme="dark"] .pill.active{
color:#ffffff;
border-color:rgba(127,176,255,.44);
background:linear-gradient(180deg, rgba(127,176,255,.24), rgba(127,176,255,.10));
}
.search, .select{
width:100%;
border:1px solid var(--line);
background:var(--surface);
color:var(--ink);
border-radius:var(--radius3);
padding:12px 14px;
outline:none;
font:inherit;
box-shadow:0 1px 0 rgba(255,255,255,.8) inset;
}
body[data-theme="dark"] .search,
body[data-theme="dark"] .select{
border-color:var(--line);
background:var(--surface2);
color:var(--ink);
box-shadow:none;
}
.search::placeholder{color:#8a909c}
body[data-theme="dark"] .search::placeholder{color:#8f96a4}
.search:focus, .select:focus{border-color:rgba(47,111,237,.45);background:white}
body[data-theme="dark"] .search:focus, body[data-theme="dark"] .select:focus{border-color:rgba(127,176,255,.45);background:rgba(255,255,255,.08)}
.toggle-row{display:flex;gap:10px;flex-wrap:wrap}
.small-note{color:#6f7684;font-size:12px;line-height:1.6;margin-top:10px}
body[data-theme="dark"] .small-note{color:#aab1bf}
.prediction-list{
margin-top:12px;
display:grid;
gap:8px;
}
.prediction-item{
display:flex;
justify-content:space-between;
gap:10px;
align-items:center;
padding:10px 12px;
border-radius:var(--radius3);
border:1px solid var(--line);
background:linear-gradient(180deg, var(--surface), var(--surface2));
font-size:13px;
line-height:1.35;
}
body[data-theme="dark"] .prediction-item{
border-color:var(--line);
background:linear-gradient(180deg, var(--surface2), var(--surface));
}
.prediction-item .label{font-weight:800;color:#111318}
body[data-theme="dark"] .prediction-item .label{color:#f4f5f7}
.prediction-item .value{font-variant-numeric:tabular-nums;color:#3c424c;font-weight:800}
body[data-theme="dark"] .prediction-item .value{color:#dfe4ec}
body[data-mode="mobile"] .desktop-only{
display:none !important;
}
body[data-mode="mobile"]{
padding:14px;
}
body[data-mode="mobile"] .hero{
padding:20px;
}
body[data-mode="mobile"] .hero .sub{
display:none;
}
body[data-mode="mobile"] h1{
font-size:clamp(30px, 8vw, 46px);
line-height:1;
}
body[data-mode="mobile"] .layout{
grid-template-columns:1fr;
gap:14px;
}
body[data-mode="mobile"] .panel{
position:static;
padding:14px;
}
body[data-mode="mobile"] .chart-card{
min-height:auto;
padding:14px 14px 10px;
}
body[data-mode="mobile"] .canvas-wrap{
height:420px;
}
body[data-mode="mobile"] .chart-title{
font-size:17px;
}
body[data-mode="mobile"] .chart-sub{
font-size:12px;
}
body[data-mode="mobile"] .org-shell{
padding:10px;
}
body[data-mode="mobile"] .stat-grid{
grid-template-columns:1fr;
}
body[data-mode="mobile"] .prediction-item{
padding:9px 10px;
font-size:12px;
}
body[data-mode="mobile"] .theme-toggle-group{
gap:6px;
}
.stat-grid{display:grid;grid-template-columns:repeat(2, minmax(0,1fr));gap:10px;margin-top:8px}
.stat{
background:linear-gradient(180deg, rgba(255,255,255,.94), rgba(230,234,240,.84));
border:1px solid rgba(16,17,20,.08);
border-radius:var(--radius3);
padding:13px;
min-height:74px;
}
body[data-theme="dark"] .stat{background:linear-gradient(180deg, rgba(255,255,255,.07), rgba(255,255,255,.03));border-color:var(--line)}
.stat .k{color:#6f7684;font-size:10px;text-transform:uppercase;letter-spacing:.14em;font-weight:800}
body[data-theme="dark"] .stat .k{color:#aab1bf}
.stat .v{margin-top:7px;color:#111318;font-size:18px;font-weight:900;font-variant-numeric:tabular-nums;line-height:1.1}
body[data-theme="dark"] .stat .v{color:#f4f5f7}
.chart-card{
border-radius:var(--radius);
padding:18px 18px 12px;
min-height:820px;
overflow:hidden;
background:linear-gradient(180deg, rgba(255,255,255,.98), rgba(247,249,252,.92));
}
body[data-theme="dark"] .chart-card{background:linear-gradient(180deg, rgba(255,255,255,.06), rgba(255,255,255,.03))}
.chart-top{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;flex-wrap:wrap;margin-bottom:12px}
.chart-title{margin:0;font-size:19px;font-weight:860;letter-spacing:0}
.chart-sub{margin:5px 0 0;color:#66707d;font-size:13px;line-height:1.5;max-width:980px}
body[data-theme="dark"] .chart-sub{color:#aab1bf}
.badge{
padding:9px 12px;border-radius:var(--radius3);
background:linear-gradient(180deg, var(--surface), var(--surface3));
border:1px solid var(--line);
color:#13161c;
font-size:13px;
font-variant-numeric:tabular-nums;
white-space:nowrap;
box-shadow:var(--shadow2)
}
body[data-theme="dark"] .badge{
background:linear-gradient(180deg, var(--surface2), var(--surface));
border-color:var(--line);
color:#f4f5f7;
}
.callout{
margin-top:11px;display:inline-flex;align-items:center;gap:10px;
padding:9px 12px;border-radius:var(--radius3);border:1px solid var(--line);
background:linear-gradient(180deg, var(--surface), var(--surface2));
color:#14171c;font-size:12px;
}
body[data-theme="dark"] .callout{
border-color:var(--line);
background:linear-gradient(180deg, var(--surface2), var(--surface));
color:#f4f5f7;
}
.callout .dot{
width:9px;height:9px;border-radius:999px;
background:linear-gradient(180deg, var(--accent), var(--accent2));
box-shadow:0 0 12px rgba(47,111,237,.20);
flex:0 0 auto;
border:1px solid rgba(16,17,20,.08);
}
.canvas-wrap{position:relative;height:680px}
canvas{width:100% !important;height:100% !important}
.info-grid{display:grid;grid-template-columns:repeat(4, minmax(0, 1fr));gap:14px}
.info-card{
border-radius:var(--radius);padding:16px;
background:linear-gradient(180deg, var(--surface), var(--surface2));
}
body[data-theme="dark"] .info-card{background:linear-gradient(180deg, rgba(255,255,255,.07), rgba(255,255,255,.03))}
.info-card .label{color:#6f7684;font-size:11px;text-transform:uppercase;letter-spacing:.13em;font-weight:800}
body[data-theme="dark"] .info-card .label{color:#aab1bf}
.info-card .big{margin-top:7px;color:#111318;font-size:22px;font-weight:900;font-variant-numeric:tabular-nums;line-height:1.1}
body[data-theme="dark"] .info-card .big{color:#f4f5f7}
.disclaimer{
border-radius:var(--radius);
background:linear-gradient(180deg, rgba(255,255,255,.92), rgba(240,243,248,.82));
padding:16px;
color:#646b79;
line-height:1.68;
font-size:13px;
}
body[data-theme="dark"] .disclaimer{color:#aab1bf}
.disclaimer strong{color:#111318;font-weight:900}
body[data-theme="dark"] .disclaimer strong{color:#f4f5f7}
.cta-grid{display:grid;grid-template-columns:repeat(2, minmax(0,1fr));gap:12px;margin-top:12px}
.cta-link{
display:block;text-decoration:none;
border:1px solid rgba(16,17,20,.10);
border-radius:var(--radius);
background:linear-gradient(180deg, var(--surface), var(--surface2));
padding:14px 16px;color:#111318;
transition:transform .15s ease, border-color .15s ease, background .15s ease;
}
body[data-theme="dark"] .cta-link{
border-color:rgba(255,255,255,.10);
background:linear-gradient(180deg, rgba(255,255,255,.08), rgba(255,255,255,.04));
color:#f4f5f7;
}
.cta-link:hover{transform:translateY(-1px);border-color:var(--line2);background:linear-gradient(180deg, #ffffff, rgba(232,236,242,.98))}
body[data-theme="dark"] .cta-link:hover{border-color:rgba(255,255,255,.20);background:linear-gradient(180deg, rgba(255,255,255,.12), rgba(255,255,255,.06))}
.cta-kicker{color:#6f7684;font-size:11px;text-transform:uppercase;letter-spacing:.13em;margin-bottom:6px;font-weight:800}
body[data-theme="dark"] .cta-kicker{color:#aab1bf}
.cta-title{color:#111318;font-weight:900;line-height:1.35;font-size:14px}
body[data-theme="dark"] .cta-title{color:#f4f5f7}
.cta-sub{margin-top:5px;color:#616776;font-size:13px;line-height:1.5}
body[data-theme="dark"] .cta-sub{color:#b0b7c4}
.org-shell{
border:1px solid var(--line);
border-radius:var(--radius);
background:linear-gradient(180deg, var(--surface), var(--surface2));
padding:12px;
box-shadow:var(--shadow2);
}
body[data-theme="dark"] .org-shell{border-color:var(--line);background:linear-gradient(180deg, rgba(255,255,255,.06), rgba(255,255,255,.03))}
.org-header{
display:flex;
align-items:center;
justify-content:space-between;
gap:10px;
margin-bottom:10px;
}
.org-header strong{
font-size:12px;
letter-spacing:.14em;
text-transform:uppercase;
color:#4f5561;
}
body[data-theme="dark"] .org-header strong{color:#c0c6d1}
.org-summary{font-size:12px;color:#68707d}
body[data-theme="dark"] .org-summary{color:#aab1bf}
.org-controls{display:grid;gap:10px}
.org-search-row{display:grid;grid-template-columns:1fr auto;gap:10px;align-items:center}
.org-chip-row{
display:flex;
flex-wrap:wrap;
gap:8px;
max-height:240px;
overflow:auto;
padding-right:2px;
}
.org-chip{
font-size:12px;
padding:9px 12px;
border-radius:var(--radius3);
white-space:nowrap;
}
.org-chip.all{font-weight:800}
.scrollbar-slim::-webkit-scrollbar{width:10px;height:10px}
.scrollbar-slim::-webkit-scrollbar-thumb{background:rgba(16,17,20,.14);border-radius:999px;border:3px solid rgba(255,255,255,.82)}
body[data-theme="dark"] .scrollbar-slim::-webkit-scrollbar-thumb{background:rgba(255,255,255,.16);border:3px solid rgba(0,0,0,.18)}
.scrollbar-slim::-webkit-scrollbar-track{background:transparent}
.mini-line{
width:100%;height:1px;
background:linear-gradient(90deg, transparent, rgba(16,17,20,.14), transparent);
margin:10px 0 14px;
}
body[data-theme="dark"] .mini-line{background:linear-gradient(90deg, transparent, rgba(255,255,255,.18), transparent)}
@media (max-width:1120px){
.layout{grid-template-columns:1fr}
.panel{position:static}
.canvas-wrap{height:700px}
.info-grid{grid-template-columns:repeat(2, minmax(0,1fr))}
}
@media (max-width:760px){
body{padding:16px}
.hero, .panel, .chart-card, .info-card{border-radius:var(--radius)}
.canvas-wrap{height:520px}
.stat-grid{grid-template-columns:1fr}
.info-grid{grid-template-columns:1fr}
.cta-grid{grid-template-columns:1fr}
.org-search-row{grid-template-columns:1fr}
.hero-top{flex-direction:column;align-items:flex-start}
.theme-toggle-group{justify-content:flex-start}
}
</style>
</head>
<body data-theme="light">
<div class="app">
<section class="hero">
<div class="hero-top">
<div>
<div class="eyebrow">Regression explorer</div>
<h1><span class="title-silver">SLM Regression Line </span></h1>
<p class="sub">
Choose a benchmark, filter by org or size, and compare models to the size trend. Furthermore, you can submit specific parameter counts and see the predicted benchmark scores. Enjoy!
</p>
</div>
<div class="theme-toggle-group">
<button id="themeLight" class="theme-pill active" type="button">Light Silver</button>
<button id="themeDark" class="theme-pill" type="button">Dark Silver</button>
<button id="modeDesktop" class="theme-pill active" type="button">Computer mode</button>
<button id="modeMobile" class="theme-pill" type="button">Mobile mode</button>
</div>
</div>
</section>
<div class="layout">
<aside class="panel">
<h2>Controls</h2>
<div class="section">
<span class="section-label">Benchmark</span>
<div class="btn-grid" id="benchmarkButtons"></div>
</div>
<div class="section">
<span class="section-label">Search models</span>
<input id="searchBox" class="search" type="text" placeholder="Type a model or org name..." />
<div class="small-note">Filters the visible points only.</div>
</div>
<div class="section">
<span class="section-label">Predict scores</span>
<div class="org-shell">
<div class="org-controls">
<div class="org-search-row">
<input id="paramInput" class="search" type="text" placeholder="Enter 12M, 250K, or 1.5B" />
<button id="predictBtn" class="tiny-btn" type="button">Predict</button>
</div>
<div class="small-note">Uses the current benchmark fits to estimate scores for the entered parameter count.</div>
<div id="predictionSummary" class="small-note" style="margin-top:0"></div>
<div id="predictionList" class="prediction-list"></div>
</div>
</div>
</div>
<div class="section">
<span class="section-label">Parameter buckets</span>
<div class="btn-grid" id="bucketButtons"></div>
<div class="small-note">Buckets only change which points are visible. The regression line still uses the full eligible set.</div>
</div>
<div class="section desktop-only">
<span class="section-label">Filter by org</span>
<div class="org-shell">
<div class="org-header">
<strong>Orgs</strong>
<div class="org-summary" id="orgSummary">All orgs</div>
</div>
<div class="org-controls">
<div class="org-search-row">
<input id="orgSearch" class="search" type="text" placeholder="Search orgs..." />
<button id="clearOrg" class="tiny-btn">Clear</button>
</div>
<div class="org-chip-row scrollbar-slim" id="orgChips"></div>
</div>
</div>
<div class="small-note">This filter is only for visibility. The regression line is still computed from the full eligible set.</div>
</div>
<div class="section desktop-only">
<span class="section-label">Point emphasis</span>
<div class="toggle-row">
<button id="toggleOutliers" class="chip" aria-pressed="false">Show residual labels</button>
<button id="toggleLineOnly" class="chip" aria-pressed="false">Line emphasis</button>
</div>
<div class="small-note">These toggles will change which model points are visible. </div>
</div>
<div class="section desktop-only">
<span class="section-label">Regression stats</span>
<div class="stat-grid">
<div class="stat"><div class="k">Curvature</div><div class="v" id="statSlope"></div></div>
<div class="stat"><div class="k">Mid-slope</div><div class="v" id="statIntercept"></div></div>
<div class="stat"><div class="k">Center score</div><div class="v" id="statMSE"></div></div>
<div class="stat"><div class="k">RMSE</div><div class="v" id="statRMSE"></div></div>
<div class="stat"><div class="k"></div><div class="v" id="statR2"></div></div>
</div>
<div class="small-note" id="fitNote">The line is locked to the full eligible dataset for the selected benchmark.</div>
</div>
</aside>
<main style="display:grid; gap:18px;">
<section class="chart-card">
<div class="chart-top">
<div>
<h2 class="chart-title" id="chartTitle">Average score vs log parameters</h2>
<div class="callout">
<span class="dot"></span>
<span>Hover for details. Click a point to open the model page.</span>
</div>
</div>
<div class="badge" id="countBadge">0 visible / 0 bins</div>
</div>
<div class="canvas-wrap">
<canvas id="scatterChart"></canvas>
</div>
</section>
<section class="info-grid desktop-only">
<div class="info-card"><div class="label">Selected benchmark</div><div class="big" id="infoBenchmark">Avg</div></div>
<div class="info-card"><div class="label">Visible models</div><div class="big" id="infoCount">0</div></div>
<div class="info-card"><div class="label">Fit bins</div><div class="big" id="infoFitCount">0</div></div>
<div class="info-card"><div class="label">Mean absolute residual</div><div class="big" id="infoMAE"></div></div>
<div class="info-card"><div class="label">Residual spread</div><div class="big" id="infoResidualSpread"></div></div>
<div class="info-card"><div class="label">Visible match rate</div><div class="big" id="infoMatchRate"></div></div>
<div class="info-card"><div class="label">Visible orgs</div><div class="big" id="infoOrgs"></div></div>
<div class="info-card"><div class="label">Plot mode</div><div class="big" id="infoMode">Silver</div></div>
</section>
<div class="cta-grid">
<a class="cta-link" href="https://huggingface.co/spaces/fromziro/SLM_Regression_Line/discussions" target="_blank" rel="noopener noreferrer">
<div class="cta-kicker">Contribute</div>
<div class="cta-title">Want to add your model? Open a discussion or PR.</div>
<div class="cta-sub">Send a model link, and it can be reviewed for inclusion.</div>
</a>
<a class="cta-link" href="https://huggingface.co/spaces/AxiomicLabs/Open_SLM_Leaderboard" target="_blank" rel="noopener noreferrer">
<div class="cta-kicker">Deep dive</div>
<div class="cta-title">Need a more detailed breakdown of your model?</div>
<div class="cta-sub">Go here for a fuller analysis and broader comparisons.</div>
</a>
</div>
</section>
</main>
</div>
</div>
<script>
const MODELS = [
{ name: 'SmolLM2-135M', org: 'HuggingFace', params: 135000000, arc_easy: 0.5858585858585859, arc_challenge: 0.2960750853242321, piqa: 0.6849836779107725, hellaswag: 0.43108942441744674, avg_4: 0.5177858993388165, url: 'https://huggingface.co/HuggingFaceTB/SmolLM2-135M' },
{ name: 'GPT-X2-125M', org: 'AxiomicLabs', params: 125081664, arc_easy: 0.5151515151515151, arc_challenge: 0.2764505119453925, piqa: 0.6751904243743199, hellaswag: 0.40529774945230035, avg_4: 0.4898234185711896, url: 'https://huggingface.co/AxiomicLabs/GPT-X2-125M' },
{ name: 'GPT-X-125M', org: 'AxiomicLabs', params: 124561728, arc_easy: 0.5075757575757576, arc_challenge: 0.2687713310580205, piqa: 0.6517954298150164, hellaswag: 0.36496713802031466, avg_4: 0.464060299783275, url: 'https://huggingface.co/AxiomicLabs/GPT-X-125M' },
{ name: 'MobileLLM-R1-140M-base', org: 'Facebook', params: 140000000, arc_easy: 0.4992424242424242, arc_challenge: 0.24744027303754265, piqa: 0.6322089227421109, hellaswag: 0.3384379853648824, avg_4: 0.44383, url: 'https://huggingface.co/facebook/MobileLLM-R1-140M-base' },
{ name: 'Supra-50M-Base', org: 'SupraLabs', params: 51786240, arc_easy: 0.460016835016835, arc_challenge: 0.25, piqa: 0.6207834602829162, hellaswag: 0.31776538538139815, avg_4: 0.4252144857313513, url: 'https://huggingface.co/SupraLabs/Supra-50M-Base' },
{ name: 'Supra-50M-Instruct', org: 'SupraLabs', params: 51786240, arc_easy: 0.444, arc_challenge: 0.273, piqa: 0.5947, hellaswag: 0.2909, avg_4: 0.403, url: 'https://huggingface.co/SupraLabs/Supra-50M-Instruct' },
{ name: 'Supra-50M-Reasoning', org: 'SupraLabs', params: 51786240, arc_easy: 0.4444, arc_challenge: 0.2739, piqa: 0.593, hellaswag: 0.291, avg_4: 0.4006, url: 'https://huggingface.co/SupraLabs/Supra-50M-Reasoning' },
{ name: 'SmolLM-135M', org: 'HuggingFace', params: 135000000, arc_easy: 0.5631, arc_challenge: 0.2901, piqa: 0.6828, hellaswag: 0.427, avg_4: 0.4908, url: 'https://huggingface.co/HuggingFaceTB/SmolLM-135M' },
{ name: 'OPT-125M', org: 'Facebook', params: 125000000, arc_easy: 0.4028, arc_challenge: 0.227, piqa: 0.6224, hellaswag: 0.3131, avg_4: 0.3913, url: 'https://huggingface.co/facebook/opt-125m' },
{ name: 'GPT-2', org: 'OpenAI', params: 124000000, arc_easy: 0.3935, arc_challenge: 0.2235, piqa: 0.6208, hellaswag: 0.3126, avg_4: 0.3892, url: 'https://huggingface.co/openai-community/gpt2' },
{ name: 'Spark-5M-Base-v4', org: 'LH-Tech-AI', params: 5000000, arc_easy: 0.3316, arc_challenge: 0.215, piqa: 0.5332, hellaswag: 0.2703, avg_4: 0.325, url: 'https://huggingface.co/LH-Tech-AI/Spark-5M-Base-v4' },
{ name: 'Supra-Mini-v5-8M', org: 'SupraLabs', params: 7870000, arc_easy: 0.3321, arc_challenge: 0.2116, piqa: 0.5403, hellaswag: 0.2637, avg_4: 0.3219, url: 'https://huggingface.co/SupraLabs/Supra-Mini-v5-8M' },
{ name: 'Pythia-70M', org: 'EleutherAI', params: 70000000, arc_easy: 0.3165, arc_challenge: 0.2363, piqa: 0.5348, hellaswag: 0.2749, avg_4: 0.3657, url: 'https://huggingface.co/EleutherAI/pythia-70m' },
{ name: 'Supra-Mini-v4-2M', org: 'SupraLabs', params: 2620000, arc_easy: 0.3098, arc_challenge: 0.215, piqa: 0.519, hellaswag: 0.2552, avg_4: 0.3188, url: 'https://huggingface.co/SupraLabs/Supra-Mini-v4-2M' },
{ name: 'Pythia-31M', org: 'EleutherAI', params: 31000000, arc_easy: 0.3388, arc_challenge: 0.2167, piqa: 0.5626, hellaswag: 0.2714, avg_4: 0.3474, url: 'https://huggingface.co/EleutherAI/pythia-31m' },
{ name: 'Stentor3-50M', org: 'StentorLabs', params: 50000000, arc_easy: 0.2967, arc_challenge: 0.2167, piqa: 0.5375, hellaswag: 0.271, avg_4: 0.3335, url: 'https://huggingface.co/StentorLabs/Stentor3-50M' },
{ name: 'Stentor3-20M', org: 'StentorLabs', params: 20000000, arc_easy: 0.295, arc_challenge: 0.2312, piqa: 0.5506, hellaswag: 0.2706, avg_4: 0.3394, url: 'https://huggingface.co/StentorLabs/Stentor3-20M' },
{ name: 'Portimbria-150M', org: 'StentorLabs', params: 151026432, arc_easy: 0.3582, arc_challenge: 0.1877, piqa: 0.5827, hellaswag: 0.2709, avg_4: 0.3499, url: 'https://huggingface.co/StentorLabs/Portimbria-150M' },
{ name: 'nanowhale-100m-base', org: 'HuggingFace', params: 100000000, arc_easy: 0.2879, arc_challenge: 0.2483, piqa: 0.518, hellaswag: 0.2631, avg_4: 0.3293, url: 'https://huggingface.co/HuggingFaceTB/nanowhale-100m-base' },
{ name: 'Pythia-14M', org: 'EleutherAI', params: 14000000, arc_easy: 0.3228, arc_challenge: 0.21, piqa: 0.5588, hellaswag: 0.262, avg_4: 0.3384, url: 'https://huggingface.co/EleutherAI/pythia-14m' },
{ name: 'Tenete-8M', org: 'Harley-ml', params: 8000000, arc_easy: 0.3169, arc_challenge: 0.2184, piqa: 0.5566, hellaswag: 0.2675, avg_4: 0.3409, url: 'https://huggingface.co/Harley-ml/Tenete-8M' },
{ name: 'Dillion-1.2M', org: 'Harley-ml', params: 1281384, arc_easy: 0.3119, arc_challenge: 0.2278, piqa: 0.5305, hellaswag: 0.2665, avg_4: 0.3338, url: 'https://huggingface.co/Harley-ml/Dillion-1.2M' },
{ name: 'CinnabarLM-1.4M-Base', org: 'MihaiPopa-1', params: 1510000, arc_easy: 0.2854, arc_challenge: 0.2338, piqa: 0.525, hellaswag: 0.2708, avg_4: 0.3416, url: 'https://huggingface.co/MihaiPopa-1/CinnabarLM-1.4M-Base' },
{ name: 'CinnabarLM-4M-Base', org: 'MihaiPopa-1', params: 4230000, arc_easy: 0.2828, arc_challenge: 0.227, piqa: 0.5229, hellaswag: 0.2771, avg_4: 0.3302, url: 'https://huggingface.co/MihaiPopa-1/CinnabarLM-4M-Base' },
{ name: 'CinnabarLM-1.5M-Base', org: 'MihaiPopa-1', params: 1710000, arc_easy: 0.2811, arc_challenge: 0.2193, piqa: 0.5294, hellaswag: 0.2708, avg_4: 0.3338, url: 'https://huggingface.co/MihaiPopa-1/CinnabarLM-1.5M-Base' },
{ name: 'Dillionv2-1.3M', org: 'Harley-ml', params: 1285200, arc_easy: 0.2963, arc_challenge: 0.2224, piqa: 0.5305, hellaswag: 0.2738, avg_4: 0.3292, url: 'https://huggingface.co/Harley-ml/Dillionv2-1.3M' },
{ name: 'KeyLM-75M', org: 'Eclipse-Senpai', params: 75251200, arc_easy: 0.3573, arc_challenge: 0.2398, piqa: 0.605, hellaswag: 0.2966, avg_4: 0.3947, url: 'https://huggingface.co/Eclipse-Senpai/KeyLM-75M' },
{ name: 'Supra-Mini-v6-1M', org: 'SupraLabs', params: 1410688, arc_easy: 0.3068, arc_challenge: 0.2048, piqa: 0.537, hellaswag: 0.2722, avg_4: 0.3322, url: 'https://huggingface.co/SupraLabs/Supra-Mini-v6-1M' },
{ name: 'GPT-S-1.4M', org: 'AxiomicLabs', params: 1426000, arc_easy: 0.3186, arc_challenge: 0.221, piqa: 0.5511, hellaswag: 0.2686, avg_4: 0.3341, url: 'https://huggingface.co/AxiomicLabs/GPT-S-1.4M' },
{ name: 'Archaea-74M', org: 'GODELEV', params: 74016256, arc_easy: 0.3906, arc_challenge: 0.227, piqa: 0.5827, hellaswag: 0.2727, avg_4: 0.3812, url: 'https://huggingface.co/GODELEV/Archaea-74M' },
{ name: 'Cali-0.1B', org: 'Sandroeth', params: 123782400, arc_easy: 0.2753, arc_challenge: 0.2449, piqa: 0.5212, hellaswag: 0.2684, avg_4: 0.3274, url: 'https://huggingface.co/Sandroeth/cali-0.1B' },
{ name: 'Quark-50M', org: 'ThingAI', params: 56666496, arc_easy: 0.3678, arc_challenge: 0.2526, piqa: 0.5783, hellaswag: 0.2848, avg_4: 0.3717, url: 'https://huggingface.co/ThingAI/Quark-50m' },
{ name: 'Quark-135M', org: 'ThingAI', params: 134561088, arc_easy: 0.4789, arc_challenge: 0.2824, piqa: 0.5865, hellaswag: 0.3137, avg_4: 0.4143, url: 'https://huggingface.co/ThingAI/Quark-135m' },
{ name: 'Veyra-30M-Base', org: 'veyra-ai', params: 34611712, arc_easy: 0.3594, arc_challenge: 0.2389, piqa: 0.5903, hellaswag: 0.2787, avg_4: 0.3692, url: 'https://huggingface.co/veyra-ai/veyra-30m-base-5b-tokens' },
{ name: 'Syn-2.6M', org: 'FromZero', params: 2604210, arc_easy: 0.3211, arc_challenge: 0.2039, piqa: 0.5365, hellaswag: 0.2702, avg_4: 0.3331, url: 'https://huggingface.co/fromziro/Syn-2.6M' },
{ name: 'Ant-5M', org: 'GODELEV', params: 4713344, arc_easy: 0.2639, arc_challenge: 0.2577, piqa: 0.4864, hellaswag: 0.2599, avg_4: 0.3195, url: 'https://huggingface.co/GODELEV/Ant-5m' },
{ name: 'Er-Medium-12.5M', org: 'FromZero', params: 12497520, arc_easy: 0.3476, arc_challenge: 0.2082, piqa: 0.5783, hellaswag: 0.2841, avg_4: 0.3668, url: 'https://huggingface.co/fromziro/Er-Medium-12.5M' },
{ name: 'michel-tiny', org: 'finnianx', params: 55719040, arc_easy: 0.3737, arc_challenge: 0.2176, piqa: 0.5734, hellaswag: 0.2815, avg_4: 0.3502, url: 'https://huggingface.co/finnianx/michel-tiny' },
{ name: 'OdinNext-138M-Base', org: 'joelhenwang', params: 138449696, arc_easy: 0.4508, arc_challenge: 0.2381, piqa: 0.5952, hellaswag: 0.2809, avg_4: 0.392, url: 'https://huggingface.co/joelhenwang/OdinNext-138M-Base' },
{ name: 'OdinNext-138M-Instruct', org: 'joelhenwang', params: 138451232, arc_easy: 0.444, arc_challenge: 0.2312, piqa: 0.5865, hellaswag: 0.2886, avg_4: 0.3888, url: 'https://huggingface.co/joelhenwang/OdinNext-138M-Instruct' },
{ name: 'michel-micro', org: 'finnianx', params: 28355072, arc_easy: 0.3859, arc_challenge: 0.2312, piqa: 0.5762, hellaswag: 0.2823, avg_4: 0.3803, url: 'https://huggingface.co/finnianx/michel-micro' },
{ name: 'kirk-tung', org: 'RTC', params: 53111296, arc_easy: 0.3043, arc_challenge: 0.2201, piqa: 0.5261, hellaswag: 0.2632, avg_4: 0.3184, url: 'https://huggingface.co/rtc2022/kirk-tung' },
{ name: 'ettin-decoder-32m', org: 'JHU CLSP', params: 32081344, arc_easy: 0.3173, arc_challenge: 0.2201, piqa: 0.5229, hellaswag: 0.2779, avg_4: 0.3348, url: 'https://huggingface.co/jhu-clsp/ettin-decoder-32m' },
{ name: 'ettin-decoder-17m', org: 'JHU CLSP', params: 16913600, arc_easy: 0.3165, arc_challenge: 0.2227, piqa: 0.5337, hellaswag: 0.2739, avg_4: 0.3438, url: 'https://huggingface.co/jhu-clsp/ettin-decoder-17m' },
{ name: 'Er-Tiny-1.3M', org: 'FromZero', params: 1332744, arc_easy: 0.3009, arc_challenge: 0.2235, piqa: 0.5272, hellaswag: 0.2767, avg_4: 0.3292, url: 'https://huggingface.co/fromziro/Er-Tiny-1.3M' },
{ name: 'michel-nano', org: 'finnianx', params: 5963008, arc_easy: 0.3329, arc_challenge: 0.227, piqa: 0.5479, hellaswag: 0.2712, avg_4: 0.3464, url: 'https://huggingface.co/finnianx/michel-nano' },
{ name: 'Supra-1.5-50M-base-exp', org: 'SupraLabs', params: 51786240, arc_easy: 0.484, arc_challenge: 0.2551, piqa: 0.6001, hellaswag: 0.2978, avg_4: 0.4288, url: 'https://huggingface.co/SupraLabs/Supra-1.5-50M-base-exp' },
{ name: 'ettin-decoder-68m', org: 'JHU CLSP', params: 68457664, arc_easy: 0.3274, arc_challenge: 0.2304, piqa: 0.5218, hellaswag: 0.2781, avg_4: 0.3394, url: 'https://huggingface.co/jhu-clsp/ettin-decoder-68m' },
{ name: 'ettin-decoder-150m', org: 'JHU CLSP', params: 149655232, arc_easy: 0.2997, arc_challenge: 0.2423, piqa: 0.5125, hellaswag: 0.2595, avg_4: 0.3189, url: 'https://huggingface.co/jhu-clsp/ettin-decoder-150m' },
{ name: 'Ant-10M', org: 'GODELEV', params: 9902336, arc_easy: 0.2753, arc_challenge: 0.2824, piqa: 0.5065, hellaswag: 0.2696, avg_4: 0.3302, url: 'https://huggingface.co/GODELEV/Ant-19m' },
{ name: 'Supra-1.5-50M-Instruct-exp', org: 'SupraLabs', params: 51786240, arc_easy: 0.4394, arc_challenge: 0.2611, piqa: 0.5941, hellaswag: 0.2926, avg_4: 0.4077, url: 'https://huggingface.co/SupraLabs/Supra-1.5-50M-Instruct-exp' },
{ name: 'SLM-10M', org: 'Liodon AI', params: 9968640, arc_easy: 0.3552, arc_challenge: 0.2346, piqa: 0.5707, hellaswag: 0.274, avg_4: 0.3401, url: 'https://huggingface.co/liodon-ai/slm-10m' },
{ name: 'Doge-20M', org: 'SmallDoge', params: 13118728, arc_easy: 0.3338, arc_challenge: 0.2073, piqa: 0.543, hellaswag: 0.2661, avg_4: 0.3236, url: 'https://huggingface.co/SmallDoge/Doge-20M' },
{ name: 'LH-Tech-AI/Quark-v2-0.5M', org: 'LH-Tech-AI', params: 465504, arc_easy: 0.2836700336700337, arc_challenge: 0.22696245733788395, piqa: 0.5103373231773667, hellaswag: 0.2552280422226648, avg_4: 0.30708401794759005, url: 'https://huggingface.co/LH-Tech-AI/Quark-v2-0.5M' },
{ name: 'LH-Tech-AI/Quark-0.5M', org: 'LH-Tech-AI', params: 465504, arc_easy: 0.29292929292929293, arc_challenge: 0.23208191126279865, piqa: 0.514145810663765, hellaswag: 0.2515435172276439, avg_4: 0.30910481700352405, url: 'https://huggingface.co/LH-Tech-AI/Quark-0.5M' },
{ name: 'SupraLabs/MicroSupra-1k', org: 'SupraLabs', params: 1037, arc_easy: 0.26725589225589225, arc_challenge: 0.24488054607508533, piqa: 0.48313384113166485, hellaswag: 0.24945230033857796, avg_4: 0.29785984136262333, url: 'https://huggingface.co/SupraLabs/MicroSupra-1k' },
{ name: 'SupraLabs/Supra-Mini-v2-0.1M', org: 'SupraLabs', params: 167760, arc_easy: 0.2840909090909091, arc_challenge: 0.2440273037542662, piqa: 0.4929270946681175, hellaswag: 0.2544313881696873, avg_4: 0.30551021467393485, url: 'https://huggingface.co/SupraLabs/Supra-Mini-v2-0.1M' },
{ name: 'SupraLabs/Supra-Mini-v3-0.5M', org: 'SupraLabs', params: 467648, arc_easy: 0.2815656565656566, arc_challenge: 0.23122866894197952, piqa: 0.5032644178454843, hellaswag: 0.2546305516829317, avg_4: 0.30500259958503706, url: 'https://huggingface.co/SupraLabs/Supra-Mini-v3-0.5M' },
{ name: 'AxiomicLabs/GPT-S-5M', org: 'AxiomicLabs', params: 5158464, arc_easy: 0.3324915824915825, arc_challenge: 0.21160409556313994, piqa: 0.5685527747551686, hellaswag: 0.273451503684525, avg_4: 0.3503980378849074, url: 'https://huggingface.co/AxiomicLabs/GPT-S-5M' },
{ name: 'GODELEV/Ant-5M', org: 'GODELEV', params: 4713344, arc_easy: 0.2638888888888889, arc_challenge: 0.257679180887372, piqa: 0.48639825897714906, hellaswag: 0.2599083847839076, avg_4: 0.30509948534467235, url: 'https://huggingface.co/GODELEV/Ant-5M' },
{ name: 'veyra-ai/Veyra-30M-Base', org: 'veyra-ai', params: 34611712, arc_easy: 0.35942760942760943, arc_challenge: 0.23890784982935154, piqa: 0.5903155603917302, hellaswag: 0.2787293367855009, avg_4: 0.3692233471040932, url: 'https://huggingface.co/veyra-ai/Veyra-30M-Base' },
{ name: 'Abiray/Kshana-170M-Base', org: 'Abiray', params: 169906752, arc_easy: 0.5046296296296297, arc_challenge: 0.2883959044368601, piqa: 0.6605005440696409, hellaswag: 0.3975303724357698, avg_4: 0.47554968859483593, url: 'https://huggingface.co/Abiray/Kshana-170M-Base' },
{ name: 'cmpatino/nanowhale-100m', org: 'cmpatino', params: 110369621, arc_easy: 0.3409090909090909, arc_challenge: 0.2235494880546075, piqa: 0.5674646354733406, hellaswag: 0.26867157936666003, avg_4: 0.35491651949252023, url: 'https://huggingface.co/cmpatino/nanowhale-100m' },
{ name: 'nickypro/tinyllama-15M', org: 'nickypro', params: 15191712, arc_easy: 0.27946127946127947, arc_challenge: 0.22184300341296928, piqa: 0.5321001088139282, hellaswag: 0.2689703246365266, avg_4: 0.3357823510426074, url: 'https://huggingface.co/nickypro/tinyllama-15M' },
{ name: 'MultivexAI/Plyx-15M', org: 'MultivexAI', params: 16060672, arc_easy: 0.3085016835016835, arc_challenge: 0.21331058020477817, piqa: 0.529379760609358, hellaswag: 0.25761800438159727, avg_4: 0.3228536782377339, url: 'https://huggingface.co/MultivexAI/Plyx-15M' },
{ name: 'MultivexAI/Aurelius-Llama-4.0M-v1.0', org: 'MultivexAI', params: 4033728, arc_easy: 0.2668350168350168, arc_challenge: 0.24488054607508533, piqa: 0.5059847660500544, hellaswag: 0.25761800438159727, avg_4: 0.3179348053267532, url: 'https://huggingface.co/MultivexAI/Aurelius-Llama-4.0M-v1.0' },
{ name: 'Tralalabs/PicoLM-15M', org: 'Tralalabs', params: 19032576, arc_easy: 0.27735690235690236, arc_challenge: 0.23293515358361774, piqa: 0.5250272034820457, hellaswag: 0.25562636924915355, avg_4: 0.3148621238349137, url: 'https://huggingface.co/Tralalabs/PicoLM-15M' },
{ name: 'CromIA/MicroLM2-1M', org: 'CromIA', params: 1705600, arc_easy: 0.27441077441077444, arc_challenge: 0.24573378839590443, piqa: 0.499455930359086, hellaswag: 0.2548297151961761, avg_4: 0.3039513220882634, url: 'https://huggingface.co/CromIA/MicroLM2-1M' },
{ name: 'Harley-ml/MiniMD-28M', org: 'Harley-ml', params: 28061568, arc_easy: 0.27146464646464646, arc_challenge: 0.2354948805460751, piqa: 0.5348204570184983, hellaswag: 0.2815176259709221, avg_4: 0.3294000998266804, url: 'https://huggingface.co/Harley-ml/MiniMD-28M' },
{ name: 'Harley-ml/PicoWord-5k', org: 'Harley-ml', params: 5092, arc_easy: 0.24537037037037038, arc_challenge: 0.24658703071672355, piqa: 0.5206746463547334, hellaswag: 0.2748456482772356, avg_4: 0.30727060662356864, url: 'https://huggingface.co/Harley-ml/PicoWord-5k' },
{ name: 'EleutherAI/pythia-160m', org: 'EleutherAI', params: 162322944, arc_easy: 0.39646464646464646, arc_challenge: 0.2363481228668942, piqa: 0.6191512513601741, hellaswag: 0.30262895837482573, avg_4: 0.41544723722088583, url: 'https://huggingface.co/EleutherAI/pythia-160m' },
{ name: 'peft-internal-testing/opt-125m', org: 'peft-internal-testing', params: 125239296, arc_easy: 0.40025252525252525, arc_challenge: 0.22440273037542663, piqa: 0.6202393906420022, hellaswag: 0.3157737502489544, avg_4: 0.4213909021369317, url: 'https://huggingface.co/peft-internal-testing/opt-125m' },
{ name: 'JackFram/llama-160m', org: 'JackFram', params: 162417408, arc_easy: 0.35648148148148145, arc_challenge: 0.2380546075085324, piqa: 0.6403699673558215, hellaswag: 0.34704242182832107, avg_4: 0.422477869182767, url: 'https://huggingface.co/JackFram/llama-160m' },
{ name: 'erwanf/gpt2-mini', org: 'erwanf', params: 38604288, arc_easy: 0.34974747474747475, arc_challenge: 0.22696245733788395, piqa: 0.5837867247007617, hellaswag: 0.26757618004381595, avg_4: 0.3718686911288584, url: 'https://huggingface.co/erwanf/gpt2-mini' },
{ name: 'SimpleStories/SimpleStories-1.25M', org: 'SimpleStories', params: 1245824, arc_easy: 0.25084175084175087, arc_challenge: 0.25170648464163825, piqa: 0.5065288356909684, hellaswag: 0.24815773750248954, avg_4: 0.3066404037027792, url: 'https://huggingface.co/SimpleStories/SimpleStories-1.25M' },
{ name: 'nisten/Biggie-SmoLlm-0.15B-Base', org: 'nisten', params: 152215488, arc_easy: 0.5185185185185185, arc_challenge: 0.2883959044368601, piqa: 0.6594124047878128, hellaswag: 0.39982075283808005, avg_4: 0.4753188893042979, url: 'https://huggingface.co/nisten/Biggie-SmoLlm-0.15B-Base' },
{ name: 'distilbert/distilgpt2', org: 'distilbert', params: 81912576, arc_easy: 0.36574074074074076, arc_challenge: 0.2295221843003413, piqa: 0.5984766050054406, hellaswag: 0.27504481179047996, avg_4: 0.3870288867618822, url: 'https://huggingface.co/distilbert/distilgpt2' },
{ name: 'FrontiersMind/Nandi-Mini-150M', org: 'FrontiersMind', params: 153412928, arc_easy: 0.5214646464646465, arc_challenge: 0.26621160409556316, piqa: 0.64689880304679, hellaswag: 0.37134037044413465, avg_4: 0.47265964184311693, url: 'https://huggingface.co/FrontiersMind/Nandi-Mini-150M' },
{ name: 'amd/AMD-Llama-135m', org: 'amd', params: 134105856, arc_easy: 0.3181818181818182, arc_challenge: 0.26023890784982934, piqa: 0.6071817192600653, hellaswag: 0.2713602867954591, avg_4: 0.3461261263434566, url: 'https://huggingface.co/amd/AMD-Llama-135m' },
{ name: 'state-spaces/mamba-130m-hf', org: 'state-spaces', params: 129135360, arc_easy: 0.41919191919191917, arc_challenge: 0.24232081911262798, piqa: 0.6322089227421109, hellaswag: 0.3525194184425413, avg_4: 0.4466829854669691, url: 'https://huggingface.co/state-spaces/mamba-130m-hf' },
{ name: 'PleIAs/Monad', org: 'PleIAs', params: 56656128, arc_easy: 0.4036195286195286, arc_challenge: 0.24914675767918087, piqa: 0.5478781284004353, hellaswag: 0.3069109739095798, avg_4: 0.3853659212686808, url: 'https://huggingface.co/PleIAs/Monad' },
{ name: 'arnir0/Tiny-LLM', org: 'arnir0', params: 12988992, arc_easy: 0.30387205387205385, arc_challenge: 0.22440273037542663, piqa: 0.5614798694232862, hellaswag: 0.2620991834295957, avg_4: 0.33384172613245877, url: 'https://huggingface.co/arnir0/Tiny-LLM' },
{ name: 'Maykeye/TinyLLama-v0', org: 'Maykeye', params: 4621376, arc_easy: 0.2563131313131313, arc_challenge: 0.22525597269624573, piqa: 0.5136017410228509, hellaswag: 0.25871340370444135, avg_4: 0.3062502077399361, url: 'https://huggingface.co/Maykeye/TinyLLama-v0' },
{ name: 'EleutherAI/pythia-14m-deduped', org: 'EleutherAI', params: 14067712, arc_easy: 0.29924242424242425, arc_challenge: 0.20819112627986347, piqa: 0.55930359085963, hellaswag: 0.2620991834295957, avg_4: 0.33316704502828287, url: 'https://huggingface.co/EleutherAI/pythia-14m-deduped' },
{ name: 'abideen/Bitnet-Llama-70M', org: 'abideen', params: 77473536, arc_easy: 0.2542087542087542, arc_challenge: 0.29436860068259385, piqa: 0.49510337323177367, hellaswag: 0.26558454491137223, avg_4: 0.3131276722216144, url: 'https://huggingface.co/abideen/Bitnet-Llama-70M' },
{ name: 'codelion/gpt-2-70m', org: 'codelion', params: 64085504, arc_easy: 0.3543771043771044, arc_challenge: 0.2167235494880546, piqa: 0.5690968443960827, hellaswag: 0.26837283409679347, avg_4: 0.3575113272933605, url: 'https://huggingface.co/codelion/gpt-2-70m' },
{ name: 'crumb/gpt2023', org: 'crumb', params: 124439808, arc_easy: 0.3998316498316498, arc_challenge: 0.23037542662116042, piqa: 0.6289445048966268, hellaswag: 0.3111929894443338, avg_4: 0.4212667548065598, url: 'https://huggingface.co/crumb/gpt2023' },
{ name: 'Felladrin/Minueza-32M-Base', org: 'Felladrin', params: 32792760, arc_easy: 0.3312289562289562, arc_challenge: 0.23122866894197952, piqa: 0.5560391730141458, hellaswag: 0.2635929097789285, avg_4: 0.3489861711239427, url: 'https://huggingface.co/Felladrin/Minueza-32M-Base' },
{ name: 'raincandy-u/TinyChat-1776K', org: 'raincandy-u', params: 1776960, arc_easy: 0.265993265993266, arc_challenge: 0.21843003412969283, piqa: 0.5125136017410229, hellaswag: 0.24596693885680143, avg_4: 0.29828585661761464, url: 'https://huggingface.co/raincandy-u/TinyChat-1776K' },
{ name: 'OuteAI/Lite-Oute-1-65M', org: 'OuteAI', params: 65020416, arc_easy: 0.36952861952861954, arc_challenge: 0.21928327645051193, piqa: 0.6017410228509249, hellaswag: 0.2837084246166102, avg_4: 0.38637481192636225, url: 'https://huggingface.co/OuteAI/Lite-Oute-1-65M' },
{ name: 'PicoKittens/PicoMistral-23M', org: 'PicoKittens', params: 23599488, arc_easy: 0.2975589225589226, arc_challenge: 0.22696245733788395, piqa: 0.5565832426550599, hellaswag: 0.2614021111332404, avg_4: 0.3325121434979931, url: 'https://huggingface.co/PicoKittens/PicoMistral-23M' },
{ name: 'EleutherAI/pythia-70m-deduped-v0', org: 'EleutherAI', params: 70426624, arc_easy: 0.36363636363636365, arc_challenge: 0.2175767918088737, piqa: 0.5930359085963003, hellaswag: 0.2840071698864768, avg_4: 0.3831138080172334, url: 'https://huggingface.co/EleutherAI/pythia-70m-deduped-v0' },
{ name: 'rhysjones/gpt2-124M-edu-fineweb-10B', org: 'rhysjones', params: 124439808, arc_easy: 0.48358585858585856, arc_challenge: 0.2551194539249147, piqa: 0.6273122959738846, hellaswag: 0.3322047400916152, avg_4: 0.4393445596882627, url: 'https://huggingface.co/rhysjones/gpt2-124M-edu-fineweb-10B' },
{ name: 'weiser/30M-0.4', org: 'weiser', params: 30339456, arc_easy: 0.351010101010101, arc_challenge: 0.2150170648464164, piqa: 0.5957562568008705, hellaswag: 0.27325234017128064, avg_4: 0.3662733726996935, url: 'https://huggingface.co/weiser/30M-0.4' },
{ name: 'Felladrin/Minueza-2-96M', org: 'Felladrin', params: 96005280, arc_easy: 0.36069023569023567, arc_challenge: 0.23720136518771331, piqa: 0.5854189336235038, hellaswag: 0.26906990639314876, avg_4: 0.37524065880773166, url: 'https://huggingface.co/Felladrin/Minueza-2-96M' },
{ name: 'crumb/distilpythia', org: 'crumb', params: 70426624, arc_easy: 0.3367003367003367, arc_challenge: 0.22781569965870307, piqa: 0.5832426550598476, hellaswag: 0.2717586138219478, avg_4: 0.3667386105033305, url: 'https://huggingface.co/crumb/distilpythia' },
{ name: 'AICrossSim/clm-60m', org: 'AICrossSim', params: 82101120, arc_easy: 0.30765993265993263, arc_challenge: 0.21843003412969283, piqa: 0.5184983677910773, hellaswag: 0.25054769966142204, avg_4: 0.31430062482303256, url: 'https://huggingface.co/AICrossSim/clm-60m' },
{ name: 'PicoKittens/PicoStories-853K', org: 'PicoKittens', params: 853120, arc_easy: 0.255050505050505, arc_challenge: 0.22013651877133106, piqa: 0.5119695321001088, hellaswag: 0.26488747261501694, avg_4: 0.3128200823244073, url: 'https://huggingface.co/PicoKittens/PicoStories-853K' },
{ name: 'allenai/OLMo-1B-hf', org: 'allenai', params: 1200000000, arc_easy: 0.574, arc_challenge: 0.311, piqa: 0.751, hellaswag: 0.629, avg_4: 0.56625, url: 'https://huggingface.co/allenai/OLMo-1B-hf' },
{ name: 'apple/OpenELM-1_1B', org: 'apple', params: 1100000000, arc_easy: 0.554, arc_challenge: 0.323, piqa: 0.756, hellaswag: 0.648, avg_4: 0.57025, url: 'https://huggingface.co/apple/OpenELM-1_1B' },
{ name: 'state-spaces/mamba2-1.3b', org: 'state-spaces', params: 1300000000, arc_easy: 0.642, arc_challenge: 0.333, piqa: 0.737, hellaswag: 0.600, avg_4: 0.57800, url: 'https://huggingface.co/state-spaces/mamba2-1.3b' },
{ name: 'microsoft/phi-1_5', org: 'microsoft', params: 1400000000, arc_easy: 0.732, arc_challenge: 0.480, piqa: 0.755, hellaswag: 0.626, avg_4: 0.64825, url: 'https://huggingface.co/microsoft/phi-1_5' },
{ name: 'Qwen/Qwen2-1.5B', org: 'Qwen', params: 1500000000, arc_easy: 0.604, arc_challenge: 0.350, piqa: 0.755, hellaswag: 0.654, avg_4: 0.59075, url: 'https://huggingface.co/Qwen/Qwen2-1.5B' },
{ name: 'RWKV/rwkv-6-world-1b6', org: 'RWKV', params: 1600000000, arc_easy: 0.567, arc_challenge: 0.341, piqa: 0.735, hellaswag: 0.583, avg_4: 0.55650, url: 'https://huggingface.co/RWKV/rwkv-6-world-1b6' },
{ name: 'stabilityai/stablelm-2-1_6b', org: 'stabilityai', params: 1600000000, arc_easy: 0.681, arc_challenge: 0.389, piqa: 0.767, hellaswag: 0.690, avg_4: 0.63175, url: 'https://huggingface.co/stabilityai/stablelm-2-1_6b' },
{ name: 'HuggingFaceTB/SmolLM-1.7B', org: 'HuggingFaceTB', params: 1700000000, arc_easy: 0.735, arc_challenge: 0.464, piqa: 0.761, hellaswag: 0.658, avg_4: 0.65450, url: 'https://huggingface.co/HuggingFaceTB/SmolLM-1.7B' },
{ name: 'h2oai/h2o-danube2-1.8b-base', org: 'h2oai', params: 1800000000, arc_easy: 0.690, arc_challenge: 0.399, piqa: 0.773, hellaswag: 0.724, avg_4: 0.64650, url: 'https://huggingface.co/h2oai/h2o-danube2-1.8b-base' },
{ name: 'google/recurrentgemma-2b', org: 'google', params: 2700000000, arc_easy: 0.618, arc_challenge: 0.299, piqa: 0.688, hellaswag: 0.618, avg_4: 0.55575, url: 'https://huggingface.co/google/recurrentgemma-2b' },
{ name: 'Qwen/Qwen2.5-0.5B', org: 'Qwen', params: 494032768, arc_easy: 0.587, arc_challenge: 0.324, piqa: 0.700, hellaswag: 0.521, avg_4: 0.55345, url: 'https://huggingface.co/Qwen/Qwen2.5-0.5B' },
{ name: 'LiquidAI/LFM2.5-350M-Base', org: 'LiquidAI', params: 354483968, arc_easy: 0.688, arc_challenge: 0.410, piqa: 0.672, hellaswag: 0.452, avg_4: 0.55711, url: 'https://huggingface.co/LiquidAI/LFM2.5-350M-Base' },
{ name: 'Qwen/Qwen1.5-0.5B', org: 'Qwen', params: 463987712, arc_easy: 0.524, arc_challenge: 0.296, piqa: 0.693, hellaswag: 0.492, avg_4: 0.52592, url: 'https://huggingface.co/Qwen/Qwen1.5-0.5B' },
{ name: 'bigscience/bloomz-560m', org: 'bigscience', params: 559214592, arc_easy: 0.502, arc_challenge: 0.258, piqa: 0.655, hellaswag: 0.370, avg_4: 0.46342, url: 'https://huggingface.co/bigscience/bloomz-560m' },
{ name: 'tiiuae/Falcon-H1-Tiny-90M-Base', org: 'tiiuae', params: 91131072, arc_easy: 0.489, arc_challenge: 0.282, piqa: 0.652, hellaswag: 0.375, avg_4: 0.46167, url: 'https://huggingface.co/tiiuae/Falcon-H1-Tiny-90M-Base' },
{ name: 'EleutherAI/pythia-410m', org: 'EleutherAI', params: 405334016, arc_easy: 0.457, arc_challenge: 0.243, piqa: 0.672, hellaswag: 0.406, avg_4: 0.48145, url: 'https://huggingface.co/EleutherAI/pythia-410m' },
{ name: 'openai-community/gpt2-medium', org: 'openai-community', params: 354823168, arc_easy: 0.436, arc_challenge: 0.250, piqa: 0.664, hellaswag: 0.394, avg_4: 0.47212, url: 'https://huggingface.co/openai-community/gpt2-medium' },
{ name: 'EleutherAI/pythia-1b', org: 'EleutherAI', params: 1011781632, arc_easy: 0.490, arc_challenge: 0.270, piqa: 0.692, hellaswag: 0.472, avg_4: 0.51795, url: 'https://huggingface.co/EleutherAI/pythia-1b' },
];
const BENCHMARKS = [
{ key: 'avg', label: 'Avg' },
{ key: 'arc_easy', label: 'ARC-Easy' },
{ key: 'arc_challenge', label: 'ARC-Challenge' },
{ key: 'hellaswag', label: 'HellaSwag' },
{ key: 'piqa', label: 'PIQA' }
];
const BENCHMARK_NAMES = {
avg: 'Average',
arc_easy: 'ARC-Easy',
arc_challenge: 'ARC-Challenge',
hellaswag: 'HellaSwag',
piqa: 'PIQA'
};
const MIN_PLOT_PARAMS = 500000;
let activeBenchmark = 'avg';
let activeSearch = '';
let activeOrg = 'all';
let activeOrgSearch = '';
let activeParamBucket = 'all';
let chart = null;
let showResidualLabels = false;
let lineEmphasis = false;
let activeTheme = 'light';
let activeMode = localStorage.getItem('silverRegressionMode') || 'desktop';
const META_KEYS = new Set(['name', 'org', 'params', 'url']);
const fmtParams = (n) => {
if (n >= 1e9) return `${(n / 1e9).toFixed(2)}B`;
if (n >= 1e6) return `${(n / 1e6).toFixed(2)}M`;
if (n >= 1e3) return `${(n / 1e3).toFixed(2)}K`;
return String(n);
};
const toPct = (v) => v * 100;
const clampScore = (v) => Number.isFinite(v) ? Math.min(100, Math.max(0, v)) : null;
const escapeHtml = (value) => String(value).replace(/[&<>"']/g, ch => ({
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#39;'
}[ch]));
const BUCKETS = [
{ key: 'all', label: 'All' },
{ key: 'lt1m', label: '<1M' },
{ key: '1_10m', label: '1-10M' },
{ key: '11_50m', label: '11-50M' },
{ key: '51_100m', label: '51-100M' },
{ key: '100_200m', label: '100-200M' },
{ key: '201_500m', label: '201-500M' },
{ key: 'gt500m', label: '>500M' }
];
function parseParamCount(input) {
const raw = String(input ?? '').trim().replace(/[,\s]/g, '').toUpperCase();
if (!raw) return null;
const match = raw.match(/^([0-9]*\.?[0-9]+)([KMB])?$/);
if (!match) return null;
const value = Number(match[1]);
if (!Number.isFinite(value) || value <= 0) return null;
const suffix = match[2] || '';
const mult = suffix === 'K' ? 1e3 : suffix === 'M' ? 1e6 : suffix === 'B' ? 1e9 : 1;
return value * mult;
}
function formatScore(v) {
return Number.isFinite(v) ? `${clampScore(v).toFixed(2)}%` : '—';
}
function bucketForParams(params) {
if (!Number.isFinite(params)) return 'all';
if (params < 1e6) return 'lt1m';
if (params <= 10e6) return '1_10m';
if (params <= 50e6) return '11_50m';
if (params <= 100e6) return '51_100m';
if (params <= 200e6) return '100_200m';
if (params <= 500e6) return '201_500m';
return 'gt500m';
}
function trimmedMean(values, trimFraction = 0.1) {
const arr = values.filter(Number.isFinite).sort((a, b) => a - b);
if (!arr.length) return 0;
const trim = Math.floor(arr.length * trimFraction);
const sliced = arr.slice(trim, Math.max(trim + 1, arr.length - trim));
const used = sliced.length ? sliced : arr;
return used.reduce((a, b) => a + b, 0) / used.length;
}
function buildBinnedFitSamples(points) {
if (!Array.isArray(points) || points.length < 2) return [];
const xs = points.map(p => p.x).filter(Number.isFinite);
if (!xs.length) return [];
const minX = Math.min(...xs);
const maxX = Math.max(...xs);
const range = Math.max(1e-6, maxX - minX);
const targetBins = Math.max(5, Math.min(14, Math.round(Math.sqrt(points.length))));
const binWidth = Math.max(0.08, range / targetBins);
const firstEdge = Math.floor(minX / binWidth) * binWidth;
const bins = new Map();
for (const p of points) {
const idx = Math.floor((p.x - firstEdge) / binWidth);
if (!bins.has(idx)) bins.set(idx, []);
bins.get(idx).push(p);
}
const samples = [];
for (const [idx, group] of [...bins.entries()].sort((a, b) => a[0] - b[0])) {
const xsInBin = group.map(p => p.x).filter(Number.isFinite);
const ysInBin = group.map(p => p.y).filter(Number.isFinite);
if (!xsInBin.length || !ysInBin.length) continue;
const binX = xsInBin.reduce((a, b) => a + b, 0) / xsInBin.length;
const binY = ysInBin.length >= 4
? trimmedMean(ysInBin, 0.15)
: (ysInBin.reduce((a, b) => a + b, 0) / ysInBin.length);
samples.push({
x: binX,
y: binY,
count: 1,
modelCount: group.length,
binIndex: idx,
params: group[0]?.params,
name: `${group.length} models in size bin`,
org: 'bin',
url: group[0]?.url
});
}
samples.sort((a, b) => a.x - b.x);
return samples;
}
function benchmarkFit(key) {
const fitModels = MODELS.filter(m => {
const score = getMetricValue(m, key);
return Number.isFinite(m.params) &&
m.params >= MIN_PLOT_PARAMS &&
score !== null &&
score !== undefined &&
Number.isFinite(score);
});
if (fitModels.length < 2) return null;
const fitData = fitModels.map(m => {
const score = getMetricValue(m, key);
return {
name: m.name,
org: m.org,
params: m.params,
score: toPct(score),
url: m.url,
x: Math.log10(m.params),
y: toPct(score)
};
});
const fitSamples = buildBinnedFitSamples(fitData);
const fit = bestLinearFit(fitSamples);
const rawFit = enrichLinearFit(weightedLinearRegression(fitData), fitData, 'raw-linear');
return { fitData, fit, rawFit, fitSamples };
}
function buildPredictionRows(paramCount) {
return BENCHMARKS.map(({ key, label }) => {
const bundle = benchmarkFit(key);
if (!bundle || bundle.fit.n < 2) return { key, label, predicted: null };
const x = Math.log10(paramCount);
return { key, label, predicted: clampScore(evaluateFit(bundle.fit, x)) };
});
}
function getMetricValue(model, key) {
if (key === 'avg') {
const values = Object.entries(model)
.filter(([k, v]) => typeof v === 'number' && Number.isFinite(v) && !META_KEYS.has(k) && !k.startsWith('avg'))
.map(([, v]) => v);
if (!values.length) return null;
return values.reduce((a, b) => a + b, 0) / values.length;
}
return model[key];
}
function median(values) {
if (!values.length) return 0;
const sorted = [...values].sort((a, b) => a - b);
const mid = Math.floor(sorted.length / 2);
return sorted.length % 2 ? sorted[mid] : (sorted[mid - 1] + sorted[mid]) / 2;
}
function weightedMedian(values, weights) {
const pairs = values
.map((v, i) => [v, Math.max(0, Number.isFinite(weights?.[i]) ? weights[i] : 1)])
.filter(([v, w]) => Number.isFinite(v) && Number.isFinite(w) && w > 0)
.sort((a, b) => a[0] - b[0]);
if (!pairs.length) return 0;
const total = pairs.reduce((acc, [, w]) => acc + w, 0);
let acc = 0;
for (const [value, weight] of pairs) {
acc += weight;
if (acc >= total / 2) return value;
}
return pairs[pairs.length - 1][0];
}
function evaluatePolynomial(coefficients, x) {
if (!coefficients?.length) return 0;
let y = 0;
for (let i = 0; i < coefficients.length; i += 1) {
y = (y * x) + coefficients[i];
}
return y;
}
function polynomialDerivative(coefficients, x) {
if (!coefficients?.length || coefficients.length < 2) return 0;
const degree = coefficients.length - 1;
let y = 0;
for (let i = 0; i < degree; i += 1) {
const power = degree - i;
y = (y * x) + (coefficients[i] * power);
}
return y;
}
function solveLinearSystem(matrix, vector) {
const n = vector.length;
const a = matrix.map((row, i) => [...row, vector[i]]);
for (let col = 0; col < n; col += 1) {
let pivotRow = col;
let pivotAbs = Math.abs(a[col][col]);
for (let row = col + 1; row < n; row += 1) {
const cand = Math.abs(a[row][col]);
if (cand > pivotAbs) {
pivotAbs = cand;
pivotRow = row;
}
}
if (pivotAbs < 1e-12) {
return null;
}
if (pivotRow !== col) {
const tmp = a[col];
a[col] = a[pivotRow];
a[pivotRow] = tmp;
}
const pivot = a[col][col];
for (let j = col; j <= n; j += 1) {
a[col][j] /= pivot;
}
for (let row = 0; row < n; row += 1) {
if (row === col) continue;
const factor = a[row][col];
if (Math.abs(factor) < 1e-12) continue;
for (let j = col; j <= n; j += 1) {
a[row][j] -= factor * a[col][j];
}
}
}
return a.map(row => row[n]);
}
function weightedPolynomialRegression(points, degree = 1, weights = null) {
const n = points.length;
if (!n) return { degree, coefficients: [0], mse: 0, rmse: 0, r2: 0, n: 0, weightSum: 0 };
const actualDegree = Math.max(0, Math.min(degree, n - 1));
const size = actualDegree + 1;
const matrix = Array.from({ length: size }, () => Array(size).fill(0));
const vector = Array(size).fill(0);
for (let i = 0; i < n; i += 1) {
const p = points[i];
const w = Math.max(0, Number.isFinite(weights?.[i]) ? weights[i] : 1);
if (!w) continue;
const basis = [];
for (let d = actualDegree; d >= 0; d -= 1) {
basis.push(p.x ** d);
}
for (let r = 0; r < size; r += 1) {
vector[r] += w * basis[r] * p.y;
for (let c = 0; c < size; c += 1) {
matrix[r][c] += w * basis[r] * basis[c];
}
}
}
let coefficients = solveLinearSystem(matrix, vector);
if (!coefficients) {
if (actualDegree === 0) {
const avg = points.reduce((acc, p, i) => {
const w = Math.max(0, Number.isFinite(weights?.[i]) ? weights[i] : 1);
return acc + w * p.y;
}, 0);
const sw = points.reduce((acc, p, i) => acc + Math.max(0, Number.isFinite(weights?.[i]) ? weights[i] : 1), 0);
coefficients = [sw ? avg / sw : 0];
} else {
return weightedPolynomialRegression(points, actualDegree - 1, weights);
}
}
const predictions = points.map(p => evaluatePolynomial(coefficients, p.x));
const sw = points.reduce((acc, p, i) => acc + Math.max(0, Number.isFinite(weights?.[i]) ? weights[i] : 1), 0);
const yMean = sw ? points.reduce((acc, p, i) => acc + Math.max(0, Number.isFinite(weights?.[i]) ? weights[i] : 1) * p.y, 0) / sw : 0;
const sse = points.reduce((acc, p, i) => {
const w = Math.max(0, Number.isFinite(weights?.[i]) ? weights[i] : 1);
const resid = p.y - predictions[i];
return acc + w * resid * resid;
}, 0);
const sst = points.reduce((acc, p, i) => {
const w = Math.max(0, Number.isFinite(weights?.[i]) ? weights[i] : 1);
return acc + w * (p.y - yMean) ** 2;
}, 0);
const mse = sw ? sse / sw : 0;
const rmse = Math.sqrt(mse);
const r2 = sst > 0 ? 1 - (sse / sst) : 0;
return { degree: actualDegree, coefficients, mse, rmse, r2, n, weightSum: sw };
}
function weightedLinearRegression(points, weights = null) {
return weightedPolynomialRegression(points, 1, weights);
}
function linearRegression(points) {
return weightedPolynomialRegression(points, 1);
}
function enrichLinearFit(fit, points, method = fit?.method || 'linear') {
const clean = (points || []).filter(p => Number.isFinite(p.x) && Number.isFinite(p.y));
const n = clean.length;
const slope = fit?.coefficients?.[0] ?? 0;
const intercept = fit?.coefficients?.[1] ?? 0;
const xMean = n ? clean.reduce((acc, p) => acc + p.x, 0) / n : 0;
const yMean = n ? clean.reduce((acc, p) => acc + p.y, 0) / n : 0;
const sse = clean.reduce((acc, p) => acc + (p.y - evaluatePolynomial([slope, intercept], p.x)) ** 2, 0);
const sst = clean.reduce((acc, p) => acc + (p.y - yMean) ** 2, 0);
const mse = n ? sse / n : 0;
return {
...fit,
degree: 1,
coefficients: [slope, intercept],
slope,
intercept,
xMean,
centerValue: evaluatePolynomial([slope, intercept], xMean),
centerSlope: slope,
curvature: 0,
mse,
rmse: Math.sqrt(mse),
r2: sst > 0 ? 1 - (sse / sst) : 0,
n,
method
};
}
function fitError(fit, points) {
const residuals = (points || [])
.map(p => p.y - evaluateFit(fit, p.x))
.filter(Number.isFinite)
.sort((a, b) => Math.abs(a) - Math.abs(b));
if (!residuals.length) return Infinity;
const trim = Math.floor(residuals.length * 0.1);
const used = residuals.slice(0, Math.max(1, residuals.length - trim));
return Math.sqrt(used.reduce((acc, r) => acc + r * r, 0) / used.length);
}
function bestLinearFit(fitSamples) {
const candidates = [
enrichLinearFit(robustLinearRegression(fitSamples), fitSamples, 'robust-linear'),
enrichLinearFit(weightedLinearRegression(fitSamples), fitSamples, 'binned-linear')
];
candidates.sort((a, b) => fitError(a, fitSamples) - fitError(b, fitSamples));
return candidates[0];
}
function robustPolynomialRegression(points, degree = 2) {
const n = points.length;
if (n < 2) return weightedPolynomialRegression(points, degree);
const baseWeights = points.map(p => Math.max(1, Number.isFinite(p.count) ? p.count : 1));
let weights = [...baseWeights];
let fit = weightedPolynomialRegression(points, degree, weights);
for (let iter = 0; iter < 10; iter += 1) {
const residuals = points.map((p, i) => p.y - evaluateFit(fit, p.x));
const residMedian = median(residuals);
const absDeviations = residuals.map(r => Math.abs(r - residMedian));
const scale = Math.max(1e-6, 1.4826 * median(absDeviations));
const huberK = 1.345 * scale;
const xMedian = median(points.map(p => p.x));
const xScale = Math.max(1e-6, 1.4826 * median(points.map(p => Math.abs(p.x - xMedian))));
const nextWeights = points.map((p, i) => {
const resid = Math.abs(residuals[i] - residMedian);
let w = baseWeights[i];
if (resid > huberK) w *= huberK / resid;
const leverage = Math.abs(p.x - xMedian) / xScale;
w *= 1 / (1 + 0.18 * leverage + 0.02 * leverage * leverage);
return Math.max(w, 1e-6);
});
const next = weightedPolynomialRegression(points, degree, nextWeights);
const delta = next.coefficients.reduce((acc, coef, i) => acc + Math.abs((fit.coefficients[i] ?? 0) - coef), 0);
fit = next;
weights = nextWeights;
if (delta < 1e-10) break;
}
const xMean = points.reduce((acc, p, i) => {
const w = Math.max(0, Number.isFinite(weights?.[i]) ? weights[i] : 1);
return acc + w * p.x;
}, 0) / Math.max(1e-12, weights.reduce((a, b) => a + b, 0));
fit.xMean = xMean;
fit.centerValue = evaluateFit(fit, xMean);
fit.centerSlope = polynomialDerivative(fit.coefficients, xMean);
fit.curvature = fit.coefficients.length >= 3 ? fit.coefficients[0] : 0;
fit.method = `robust-degree-${fit.degree}`;
fit.effectiveN = weights.reduce((a, b) => a + b, 0);
return fit;
}
function robustLinearRegression(points) {
const n = points.length;
if (n < 2) return weightedPolynomialRegression(points, 1);
const baseWeights = points.map(p => Math.max(1, Number.isFinite(p.count) ? p.count : 1));
const slopes = [];
const slopeWeights = [];
for (let i = 0; i < n; i += 1) {
for (let j = i + 1; j < n; j += 1) {
const dx = points[j].x - points[i].x;
if (Math.abs(dx) < 1e-12) continue;
slopes.push((points[j].y - points[i].y) / dx);
slopeWeights.push(baseWeights[i] * baseWeights[j]);
}
}
let slope = slopes.length ? weightedMedian(slopes, slopeWeights) : 0;
if (!Number.isFinite(slope)) {
slope = weightedLinearRegression(points, baseWeights).coefficients[0] ?? 0;
}
let intercept = weightedMedian(
points.map(p => p.y - slope * p.x),
baseWeights
);
if (!Number.isFinite(intercept)) intercept = 0;
let fit = {
degree: 1,
coefficients: [slope, intercept],
mse: 0,
rmse: 0,
r2: 0,
n,
weightSum: baseWeights.reduce((a, b) => a + b, 0),
method: 'theil-sen-seeded-linear'
};
let weights = [...baseWeights];
for (let iter = 0; iter < 6; iter += 1) {
const residuals = points.map(p => p.y - evaluateFit(fit, p.x));
const residMedian = median(residuals);
const absDeviations = residuals.map(r => Math.abs(r - residMedian));
const scale = Math.max(1e-6, 1.4826 * median(absDeviations));
const huberK = 1.345 * scale;
const xMedian = median(points.map(p => p.x));
const xScale = Math.max(1e-6, 1.4826 * median(points.map(p => Math.abs(p.x - xMedian))));
const nextWeights = points.map((p, i) => {
const resid = Math.abs(residuals[i] - residMedian);
let w = baseWeights[i];
if (resid > huberK) w *= huberK / resid;
const leverage = Math.abs(p.x - xMedian) / xScale;
w *= 1 / (1 + 0.14 * leverage + 0.015 * leverage * leverage);
return Math.max(w, 1e-6);
});
const nextFit = weightedPolynomialRegression(points, 1, nextWeights);
fit = nextFit;
weights = nextWeights;
if (iter > 0) {
const delta = Math.abs((fit.coefficients[0] ?? 0) - slope) + Math.abs((fit.coefficients[1] ?? 0) - intercept);
if (delta < 1e-10) break;
}
slope = fit.coefficients[0] ?? slope;
intercept = fit.coefficients[1] ?? intercept;
}
const xMean = points.reduce((acc, p, i) => {
const w = Math.max(0, Number.isFinite(weights?.[i]) ? weights[i] : 1);
return acc + w * p.x;
}, 0) / Math.max(1e-12, weights.reduce((a, b) => a + b, 0));
fit.xMean = xMean;
fit.centerValue = evaluateFit(fit, xMean);
fit.centerSlope = fit.coefficients[0] ?? 0;
fit.slope = fit.coefficients[0] ?? 0;
fit.intercept = fit.coefficients[1] ?? 0;
fit.curvature = 0;
fit.effectiveN = weights.reduce((a, b) => a + b, 0);
fit.method = 'robust-linear';
return fit;
}
function evaluateFit(fit, x) {
return evaluatePolynomial(fit?.coefficients || [0], x);
}
function fitSlopeAt(fit, x) {
return polynomialDerivative(fit?.coefficients || [0], x);
}
function fitCenter(fit) {
return fit?.xMean ?? 0;
}
function fitSummaryValue(fit) {
return fit?.centerValue ?? 0;
}
function formatFitEquation(fit) {
if (!fit?.coefficients?.length) return '—';
const coeffs = fit.coefficients;
if (fit.degree === 1 && coeffs.length >= 2) {
return `${coeffs[0].toFixed(4)}x + ${coeffs[1].toFixed(2)}`;
}
if (fit.degree >= 2 && coeffs.length >= 3) {
return `${coeffs[0].toFixed(4)}x² + ${coeffs[1].toFixed(4)}x + ${coeffs[2].toFixed(2)}`;
}
return coeffs.map(v => v.toFixed(4)).join(', ');
}
function getEligibleModels() {
return MODELS.filter(m => {
const score = getMetricValue(m, activeBenchmark);
return Number.isFinite(m.params) &&
m.params >= MIN_PLOT_PARAMS &&
score !== null &&
score !== undefined &&
Number.isFinite(score);
});
}
function getVisibleModels() {
const q = activeSearch.trim().toLowerCase();
return getEligibleModels().filter(m => {
if (activeOrg !== 'all' && m.org !== activeOrg) return false;
if (activeParamBucket !== 'all' && bucketForParams(m.params) !== activeParamBucket) return false;
if (!q) return true;
return m.name.toLowerCase().includes(q) || m.org.toLowerCase().includes(q);
});
}
function getOrgList() {
return [...new Set(MODELS.map(m => m.org))].sort((a, b) => a.localeCompare(b));
}
function setChipState(btn, active) {
btn.classList.toggle('active', active);
btn.setAttribute('aria-pressed', active ? 'true' : 'false');
}
function applyTheme(theme) {
activeTheme = theme;
document.body.dataset.theme = theme;
setChipState(document.getElementById('themeLight'), theme === 'light');
setChipState(document.getElementById('themeDark'), theme === 'dark');
localStorage.setItem('silverRegressionTheme', theme);
render();
}
function renderBenchmarkButtons() {
const box = document.getElementById('benchmarkButtons');
box.innerHTML = BENCHMARKS.map(b => `
<button type="button" class="${b.key === activeBenchmark ? 'active' : ''}" data-key="${escapeHtml(b.key)}">${escapeHtml(b.label)}</button>
`).join('');
box.querySelectorAll('button').forEach(btn => {
btn.addEventListener('click', () => {
activeBenchmark = btn.dataset.key;
renderOrgUI();
render();
});
});
}
function renderOrgUI() {
const allOrgs = getOrgList();
const orgSearch = activeOrgSearch.trim().toLowerCase();
const orgs = orgSearch
? allOrgs.filter(o => o.toLowerCase().includes(orgSearch))
: allOrgs;
const chips = document.getElementById('orgChips');
const summary = document.getElementById('orgSummary');
summary.textContent = activeOrg === 'all' ? 'All orgs' : `Org: ${activeOrg}`;
chips.innerHTML = [
`<button type="button" class="org-chip all ${activeOrg === 'all' ? 'active' : ''}" data-org="all">All</button>`,
...orgs.map(org => `<button type="button" class="org-chip ${activeOrg === org ? 'active' : ''}" data-org="${escapeHtml(org)}">${escapeHtml(org)}</button>`)
].join('');
chips.querySelectorAll('button').forEach(btn => {
btn.addEventListener('click', () => {
activeOrg = btn.dataset.org;
document.getElementById('orgSummary').textContent = activeOrg === 'all' ? 'All orgs' : `Org: ${activeOrg}`;
renderOrgUI();
render();
});
});
}
function renderBucketUI() {
const box = document.getElementById('bucketButtons');
box.innerHTML = BUCKETS.map(b => `
<button type="button" class="chip ${b.key === activeParamBucket ? 'active' : ''}" data-bucket="${escapeHtml(b.key)}">${escapeHtml(b.label)}</button>
`).join('');
box.querySelectorAll('button').forEach(btn => {
btn.addEventListener('click', () => {
activeParamBucket = btn.dataset.bucket;
renderBucketUI();
render();
});
});
}
function applyMode(mode) {
activeMode = mode;
document.body.dataset.mode = mode;
setChipState(document.getElementById('modeDesktop'), mode === 'desktop');
setChipState(document.getElementById('modeMobile'), mode === 'mobile');
localStorage.setItem('silverRegressionMode', mode);
render();
}
function updatePredictionPanel() {
const input = document.getElementById('paramInput');
const summary = document.getElementById('predictionSummary');
const list = document.getElementById('predictionList');
const value = parseParamCount(input.value);
if (value === null) {
summary.textContent = 'Enter a parameter count like 12M, 250K, or 1.5B.';
list.innerHTML = '';
return;
}
summary.textContent = `Parameter count: ${fmtParams(value)} (${value.toLocaleString()})`;
const rows = buildPredictionRows(value);
list.innerHTML = rows.map(row => {
const label = row.label === 'Avg' ? 'Average' : row.label;
return `
<div class="prediction-item">
<div class="label">${escapeHtml(label)}</div>
<div class="value">${formatScore(row.predicted)}</div>
</div>
`;
}).join('');
}
function updateStats(fit, visibleCount, residuals, rawCount, binCount, rawFit) {
document.getElementById('statSlope').textContent = fit.n >= 2 ? (fit.curvature ?? 0).toFixed(6) : '—';
document.getElementById('statIntercept').textContent = fit.n >= 2 ? (fit.centerSlope ?? fit.slope ?? 0).toFixed(4) : '—';
document.getElementById('statMSE').textContent = fit.n >= 2 ? `${clampScore(fit.centerValue ?? fitSummaryValue(fit)).toFixed(2)}%` : '—';
document.getElementById('statRMSE').textContent = fit.n >= 2 ? fit.rmse.toFixed(2) : '—';
document.getElementById('statR2').textContent = fit.n >= 2 ? fit.r2.toFixed(3) : '—';
document.getElementById('countBadge').textContent = `${visibleCount} visible / ${binCount} bins`;
document.getElementById('infoBenchmark').textContent = BENCHMARK_NAMES[activeBenchmark] || activeBenchmark;
document.getElementById('infoCount').textContent = String(visibleCount);
document.getElementById('infoFitCount').textContent = String(binCount);
const absMean = residuals.length ? residuals.reduce((a, b) => a + Math.abs(b), 0) / residuals.length : 0;
const mean = residuals.length ? residuals.reduce((a, b) => a + b, 0) / residuals.length : 0;
const spread = residuals.length ? Math.sqrt(residuals.reduce((a, b) => a + (b - mean) ** 2, 0) / residuals.length) : 0;
document.getElementById('infoMAE').textContent = residuals.length ? `${absMean.toFixed(2)} pts` : '—';
document.getElementById('infoResidualSpread').textContent = residuals.length ? `${spread.toFixed(2)} pts` : '—';
const orgCount = new Set(getVisibleModels().map(m => m.org)).size;
document.getElementById('infoOrgs').textContent = `${orgCount} orgs`;
document.getElementById('infoMatchRate').textContent = `${visibleCount}/${rawCount}`;
document.getElementById('infoMode').textContent = activeMode === 'mobile' ? 'Mobile' : 'Computer';
document.getElementById('fitNote').textContent =
`Fit uses ${rawCount} eligible models collapsed into ${binCount} size bins for ${BENCHMARK_NAMES[activeBenchmark] || activeBenchmark}. Raw-point RMSE is ${rawFit.n >= 2 ? rawFit.rmse.toFixed(2) : '—'}; binned fit RMSE is ${fit.n >= 2 ? fit.rmse.toFixed(2) : '—'}. Search and org filters only affect visibility.`;
}
function setText(id, value) {
const target = document.getElementById(id);
if (target) target.textContent = value;
}
const residualLabelPlugin = {
id: 'residualLabelPlugin',
afterDatasetsDraw(chartInstance) {
if (!showResidualLabels) return;
const datasetIndex = 1;
const meta = chartInstance.getDatasetMeta(datasetIndex);
const dataset = chartInstance.data.datasets[datasetIndex];
if (!meta || meta.hidden || !dataset?.data?.length) return;
const { ctx, chartArea } = chartInstance;
ctx.save();
ctx.font = '700 11px Inter, system-ui, sans-serif';
ctx.textBaseline = 'middle';
ctx.lineWidth = 1;
meta.data.forEach((point, index) => {
const raw = dataset.data[index];
if (!raw || !Number.isFinite(raw.residual) || Math.abs(raw.residual) < 3) return;
const label = `${raw.residual >= 0 ? '+' : ''}${raw.residual.toFixed(1)}`;
const metrics = ctx.measureText(label);
const width = metrics.width + 10;
const height = 18;
let x = point.x + 8;
let y = point.y - 12;
x = Math.min(chartArea.right - width - 2, Math.max(chartArea.left + 2, x));
y = Math.min(chartArea.bottom - height / 2 - 2, Math.max(chartArea.top + height / 2 + 2, y));
ctx.fillStyle = activeTheme === 'light' ? 'rgba(255,255,255,.92)' : 'rgba(15,18,24,.92)';
ctx.strokeStyle = raw.residual >= 0 ? 'rgba(47,111,237,.42)' : 'rgba(31,157,122,.42)';
ctx.beginPath();
ctx.roundRect(x, y - height / 2, width, height, 5);
ctx.fill();
ctx.stroke();
ctx.fillStyle = activeTheme === 'light' ? '#111318' : '#f2f5f9';
ctx.fillText(label, x + 5, y);
});
ctx.restore();
}
};
function render() {
const fitModels = getEligibleModels();
const visibleModels = getVisibleModels();
const fitData = fitModels.map(m => {
const score = getMetricValue(m, activeBenchmark);
return {
name: m.name,
org: m.org,
params: m.params,
score: toPct(score),
url: m.url,
x: Math.log10(m.params),
y: toPct(score)
};
});
const data = visibleModels.map(m => {
const score = getMetricValue(m, activeBenchmark);
return {
name: m.name,
org: m.org,
params: m.params,
score: toPct(score),
url: m.url,
x: Math.log10(m.params),
y: toPct(score)
};
});
const chartTitleMap = {
avg: 'Average score vs log parameters',
arc_easy: 'ARC-Easy vs log parameters',
arc_challenge: 'ARC-Challenge vs log parameters',
hellaswag: 'HellaSwag vs log parameters',
piqa: 'PIQA vs log parameters'
};
setText('chartTitle', chartTitleMap[activeBenchmark] || 'Regression vs log parameters');
setText('chartSub',
'Binned linear regression on log10(parameters) for the selected benchmark. Each size bin contributes one equally weighted sample, so the line tracks the average score by parameter region instead of point density.');
if (fitData.length < 2) {
setText('chartSub', 'Need at least 2 eligible models to fit a line.');
document.getElementById('countBadge').textContent = `${visibleModels.length} visible / ${fitData.length} bins`;
document.getElementById('infoBenchmark').textContent = BENCHMARK_NAMES[activeBenchmark] || activeBenchmark;
document.getElementById('infoCount').textContent = String(visibleModels.length);
document.getElementById('infoFitCount').textContent = String(fitData.length);
document.getElementById('infoMAE').textContent = '—';
document.getElementById('infoResidualSpread').textContent = '—';
document.getElementById('statSlope').textContent = '—';
document.getElementById('statIntercept').textContent = '—';
document.getElementById('statRMSE').textContent = '—';
document.getElementById('statR2').textContent = '—';
if (chart) chart.destroy();
return;
}
const fitSamples = buildBinnedFitSamples(fitData);
const fit = bestLinearFit(fitSamples);
const rawFit = enrichLinearFit(weightedLinearRegression(fitData), fitData, 'raw-linear');
const visibleResiduals = data.map(d => d.y - clampScore(evaluateFit(fit, d.x)));
data.forEach((d, i) => {
d.residual = visibleResiduals[i];
d.prediction = clampScore(evaluateFit(fit, d.x));
});
updateStats(fit, data.length, visibleResiduals, fitData.length, fitSamples.length, rawFit);
updatePredictionPanel();
const xMin = Math.min(...fitData.map(d => d.x));
const xMax = Math.max(...fitData.map(d => d.x));
const xPad = Math.max(0.18, (xMax - xMin) * 0.09);
const lineSteps = 50;
const regressionLine = [];
for (let i = 0; i <= lineSteps; i += 1) {
const t = i / lineSteps;
const rawX = (xMin - xPad) + ((xMax + xPad) - (xMin - xPad)) * t;
regressionLine.push({ x: rawX, y: clampScore(evaluateFit(fit, rawX)) });
}
const yMin = Math.min(...fitData.map(d => d.y), ...regressionLine.map(p => p.y)) - 2.2;
const yMax = Math.max(...fitData.map(d => d.y), ...regressionLine.map(p => p.y)) + 2.2;
if (chart) chart.destroy();
const ctx = document.getElementById('scatterChart').getContext('2d');
chart = new Chart(ctx, {
type: 'scatter',
data: {
datasets: [
{
type: 'line',
label: 'Regression',
data: regressionLine,
borderColor: activeTheme === 'light' ? 'rgba(47,111,237,0.92)' : 'rgba(127,176,255,0.95)',
borderWidth: lineEmphasis ? 4 : 3,
borderDash: lineEmphasis ? [] : [2, 8],
borderCapStyle: 'round',
pointRadius: 0,
tension: 0,
order: 0
},
{
label: 'Models',
data,
parsing: false,
pointRadius: activeMode === 'mobile' ? (lineEmphasis ? 5 : 5) : (lineEmphasis ? 6 : 7),
pointHoverRadius: activeMode === 'mobile' ? 10 : 12,
pointHitRadius: activeMode === 'mobile' ? 18 : 24,
borderWidth: 1.5,
backgroundColor: (ctx) => {
const raw = ctx.raw;
if (!raw) return activeTheme === 'light' ? 'rgba(20,22,27,0.95)' : 'rgba(245,246,248,0.95)';
const abs = Math.abs(raw.residual ?? 0);
if (showResidualLabels && abs > 3.0) {
return raw.residual >= 0 ? (activeTheme === 'light' ? 'rgba(47,111,237,0.95)' : 'rgba(127,176,255,0.98)') : 'rgba(31,157,122,0.92)';
}
if (activeTheme === 'light') {
return raw.residual >= 0 ? 'rgba(31,42,58,0.94)' : 'rgba(118,129,146,0.92)';
}
return raw.residual >= 0 ? 'rgba(232,240,255,0.98)' : 'rgba(127,218,196,0.90)';
},
borderColor: (ctx) => {
const raw = ctx.raw;
if (!raw) return activeTheme === 'light' ? 'rgba(255,255,255,0.88)' : 'rgba(255,255,255,0.82)';
if (activeTheme === 'light') {
return raw.residual >= 0 ? 'rgba(255,255,255,0.98)' : 'rgba(20,22,27,0.50)';
}
return raw.residual >= 0 ? 'rgba(255,255,255,0.98)' : 'rgba(18,19,23,0.42)';
},
hoverBackgroundColor: 'rgba(255,255,255,1)',
hoverBorderColor: 'rgba(16,17,20,1)',
order: 2,
showLine: false
}
]
},
options: {
responsive: true,
maintainAspectRatio: false,
animation: { duration: 0 },
interaction: { mode: 'nearest', intersect: true },
onHover: (event, elements) => {
const target = event?.native?.target;
if (target && target.style) target.style.cursor = elements.length ? 'pointer' : 'default';
},
onClick: (event, elements) => {
if (!elements.length) return;
const hit = elements[0];
if (hit.datasetIndex !== 1) return;
const item = chart.data.datasets[hit.datasetIndex].data[hit.index];
if (item?.url) window.open(item.url, '_blank', 'noopener,noreferrer');
},
plugins: {
legend: { display: false },
tooltip: {
enabled: true,
backgroundColor: 'rgba(10,11,14,0.98)',
borderColor: 'rgba(255,255,255,0.18)',
borderWidth: 1,
titleColor: '#ffffff',
bodyColor: '#dbe0e8',
titleFont: { size: 13, weight: '700' },
bodyFont: { size: 12 },
padding: 12,
displayColors: false,
caretPadding: 10,
cornerRadius: 12,
callbacks: {
title: (items) => items[0]?.raw?.name || '',
label: (item) => {
const d = item.raw;
const predicted = clampScore(evaluateFit(fit, d.x));
const resid = d.y - predicted;
return [
`Org: ${d.org}`,
`Params: ${fmtParams(d.params)} (${d.params.toLocaleString()})`,
`Score: ${d.score.toFixed(2)}%`,
`Residual: ${resid >= 0 ? '+' : ''}${resid.toFixed(2)} pts`,
`Predicted (robust line): ${predicted.toFixed(2)}%`
];
},
afterLabel: (item) => {
const d = item.raw;
return showResidualLabels ? `Residual label: ${d.residual.toFixed(2)} pts` : '';
}
}
}
},
scales: {
x: {
type: 'linear',
min: Math.max(3.3, xMin - 0.20),
max: xMax + 0.15,
grid: { color: activeTheme === 'light' ? 'rgba(16,17,20,0.07)' : 'rgba(255,255,255,0.08)' },
ticks: {
color: activeTheme === 'light' ? '#737a87' : '#aab1bf',
callback: v => `10^${Number(v).toFixed(1)}`
},
title: {
display: true,
text: 'Log₁₀(parameters)',
color: activeTheme === 'light' ? '#616876' : '#b8bfcb',
font: { weight: '700' }
}
},
y: {
min: Math.max(0, yMin),
max: yMax,
grid: { color: activeTheme === 'light' ? 'rgba(16,17,20,0.07)' : 'rgba(255,255,255,0.08)' },
ticks: {
color: activeTheme === 'light' ? '#737a87' : '#aab1bf',
callback: v => `${Number(v).toFixed(0)}%`
},
title: {
display: true,
text: 'Score (%)',
color: activeTheme === 'light' ? '#616876' : '#b8bfcb',
font: { weight: '700' }
}
}
}
},
plugins: [residualLabelPlugin]
});
}
document.getElementById('searchBox').addEventListener('input', (e) => {
activeSearch = e.target.value || '';
render();
});
document.getElementById('predictBtn').addEventListener('click', updatePredictionPanel);
document.getElementById('paramInput').addEventListener('input', updatePredictionPanel);
document.getElementById('modeDesktop').addEventListener('click', () => applyMode('desktop'));
document.getElementById('modeMobile').addEventListener('click', () => applyMode('mobile'));
document.getElementById('orgSearch').addEventListener('input', (e) => {
activeOrgSearch = e.target.value || '';
renderOrgUI();
});
document.getElementById('clearOrg').addEventListener('click', () => {
activeOrg = 'all';
activeOrgSearch = '';
document.getElementById('orgSearch').value = '';
renderOrgUI();
render();
});
const residualBtn = document.getElementById('toggleOutliers');
residualBtn.addEventListener('click', () => {
showResidualLabels = !showResidualLabels;
setChipState(residualBtn, showResidualLabels);
render();
});
const lineBtn = document.getElementById('toggleLineOnly');
lineBtn.addEventListener('click', () => {
lineEmphasis = !lineEmphasis;
setChipState(lineBtn, lineEmphasis);
render();
});
document.getElementById('themeLight').addEventListener('click', () => applyTheme('light'));
document.getElementById('themeDark').addEventListener('click', () => applyTheme('dark'));
const savedTheme = localStorage.getItem('silverRegressionTheme');
if (savedTheme === 'dark' || savedTheme === 'light') {
activeTheme = savedTheme;
}
document.body.dataset.theme = activeTheme;
setChipState(document.getElementById('themeLight'), activeTheme === 'light');
setChipState(document.getElementById('themeDark'), activeTheme === 'dark');
const savedMode = localStorage.getItem('silverRegressionMode');
if (savedMode === 'mobile' || savedMode === 'desktop') {
activeMode = savedMode;
}
document.body.dataset.mode = activeMode;
setChipState(document.getElementById('modeDesktop'), activeMode === 'desktop');
setChipState(document.getElementById('modeMobile'), activeMode === 'mobile');
renderBenchmarkButtons();
renderBucketUI();
renderOrgUI();
updatePredictionPanel();
render();
</script>
</body>
</html>