spl16's picture
Upload fork.js with huggingface_hub
6fd0097 verified
Raw History Blame Contribute Delete
28.5 kB
/* Quant-picking frontend. Catalog + fit data come live from the
* LocalLLaMA explorer API; the best-quant choice per model comes from
* rankQuants.js + quant_scores.json (measured KL benchmarks). */
"use strict";
const API = "https://codelion-local-model-explorer.hf.space";
const $ = (s, r = document) => r.querySelector(s);
const $$ = (s, r = document) => [...r.querySelectorAll(s)];
let META = null, SCORES = null, runId = 0, offset = 0, total = 0, nofitDropped = 0, autoPages = 0, seenModels = [];
function el(tag, cls, text) {
const n = document.createElement(tag);
if (cls) n.className = cls;
if (text !== undefined) n.textContent = text;
return n;
}
function opt(value, label, selected) {
const o = document.createElement("option");
o.value = value; o.textContent = label;
if (selected) o.selected = true;
return o;
}
const gb = (v, d = 1) => v === null || v === undefined ? "?" : `${Number(v).toFixed(d)} GB`;
const bytesGB = (b) => gb(b / 1e9);
const params = (p) => p >= 1e9 ? `${+(p / 1e9).toFixed(p >= 1e10 ? 0 : 1)}B` : `${Math.round(p / 1e6)}M`;
const compact = (n) => n >= 1e6 ? `${(n / 1e6).toFixed(1)}M` : n >= 1e3 ? `${Math.round(n / 1e3)}k` : String(n || 0);
const ctxLabel = (c) => c >= 1024 ? `${Math.round(c / 1024)}k` : String(c);
function rig() {
const kind = $('input[name="kind"]:checked').value;
const out = { kind, gpus: [], ram_gb: 32,
vram_spare: +($("#vram-spare") || {}).value || 0,
ram_spare: +($("#ram-spare") || {}).value || 0 };
if (kind === "gpu") {
const one = (sel, vsel, csel, fb) => {
const name = $(sel).value;
const each = name === "custom" ? Math.max(1, Math.min(256, +$(vsel).value || fb)) : META.hardware.gpus[name];
return Array.from({ length: +$(csel).value || 1 }, () => each);
};
out.gpus = one("#gpu", "#custom-vram", "#gpu-count", 24);
if (!$("#gpu2-wrap").hidden) out.gpus = out.gpus.concat(one("#gpu2", "#custom-vram2", "#gpu2-count", 8)).slice(0, 16);
out.ram_gb = +$("#ram").value;
} else if (kind === "unified") {
out.unified_system = $("#usys").value;
out.ram_gb = +$("#umem").value;
} else {
out.ram_gb = +$("#ram").value;
}
return out;
}
function query(append) {
const r = rig();
const pair = $("#kv").value;
// upstream kv_type only accepts f16/q8_0/q4_0 with K=V. ask q8_0 and
// rescale client-side (rescaleKvFits): q8_0-based scores and fits are
// close to every smaller pair, so the page stays nearly consistent
// (an f16 base would leave every score stale). f16/bf16 ask f16.
const q8base = pair !== "f16/f16" && pair !== "bf16/bf16";
const rescaled = q8base ? kvScale(pair) * 16 / 8.5 < 1 : false;
return {
hardware: { kind: r.kind, gpus: r.gpus, ram_gb: r.ram_gb,
...(r.unified_system ? { unified_system: r.unified_system } : {}) },
context: +$("#ctx").value, kv_type: q8base ? "q8_0" : "f16", kv_pair: pair,
min_bits: +$("#min-bits").value,
sort: $("#sort").value, family: $("#family").value || null, size: $("#size").value || null,
search: $("#search").value.trim() || null,
moe_only: $("#moe-only").checked, vision_only: $("#vision-only").checked,
fits_only: rescaled ? false : ($("#fits-only").checked || $("#sort").value === "best"),
vram_only: rescaled ? false : (r.kind === "gpu" && $("#vram-only").checked),
mmproj: $("#mmproj").value,
offset: append ? offset : 0, limit: 24,
};
}
function rankWithReserve(allOptions, fam, r) {
// rank headroom-kept options; when the reserve hides every fitting
// quant, fall back to ranking everything so the card can name what
// missed and by how much instead of showing nothing-fits.
const fitOk = (o) => ({ ...o,
fit_ok: o.fit && o.fit.tier !== "no" && o.fit.tier !== "no_vram" });
const { kept, hidden } = applyHeadroom(allOptions, headroomCaps(r), r.kind);
let { pick, warnings } = rankOptions(kept.map(fitOk), fam, SCORES);
let overReserve = false;
if (!pick && hidden) {
({ pick, warnings } = rankOptions((allOptions || []).map(fitOk), fam, SCORES));
overReserve = !!pick;
}
return { pick, warnings, hidden, overReserve };
}
function reserveNote(pick, r) {
if (!pick || !pick.fit) return null;
const caps = headroomCaps(r);
const over = [];
if (r.kind !== "cpu" && (pick.fit.gpu_gb || 0) > caps.vram)
over.push(`${gb((pick.fit.gpu_gb || 0) - caps.vram)} VRAM`);
if ((pick.fit.ram_gb || 0) > caps.ram)
over.push(`${gb((pick.fit.ram_gb || 0) - caps.ram)} RAM`);
if (!over.length) return null;
return `Over your headroom reserve by ${over.join(" + ")} — lower "Keep free" to run it.`;
}
const SCORE_PARTS = [["fit", "Fit"], ["capacity", "Size"], ["popularity", "Downloads"], ["recency", "New"], ["community", "Reports"]];
function scoreTitle(m) {
const w = META.score_weights || {};
return SCORE_PARTS.map(([k, l]) => `${l}: ${Math.round((m.components[k] || 0) * w[k] * 100)} of ${Math.round(w[k] * 100)}`).join("\n");
}
function rail(fit, r) {
if (!fit) return null;
const box = el("div", "rail");
const pct = (v, cap) => `${Math.max(0, Math.min(100, (v / cap) * 100))}%`;
const vram = r.kind === "gpu" ? r.gpus.reduce((a, v) => a + v, 0) : 0;
const ram = r.ram_gb;
if (r.kind === "unified") {
const share = (META.hardware.unified_shares || {})[r.unified_system];
const cap = r.ram_gb * (share || (r.ram_gb <= 36 ? 0.67 : 0.75));
const pool = el("div", "pool");
pool.style.flex = "1";
const i = el("i", "gpu"); i.style.width = pct(fit.gpu_gb, cap); pool.append(i);
if (fit.gpu_gb > cap) { const o = el("i", "over"); o.style.width = "30%"; pool.append(o); }
box.append(pool);
return box;
}
if (vram) {
const pool = el("div", "pool"); pool.style.flex = `${vram / (vram + ram)}`;
const i = el("i", "gpu"); i.style.width = pct(fit.gpu_gb, vram); pool.append(i);
box.append(pool);
}
const ramPool = el("div", "pool"); ramPool.style.flex = `${ram / ((vram || 1) + ram)}`;
const j = el("i", fit.tier === "gpu_moe" ? "exp" : "ram"); j.style.width = pct(fit.ram_gb, ram);
ramPool.append(j);
if (fit.tier === "no" || fit.tier === "no_vram") { const o = el("i", "over"); o.style.width = "30%"; ramPool.append(o); }
box.append(ramPool);
return box;
}
function fitText(fit) {
if (!fit) return "";
const parts = [fit.label];
if (fit.tier !== "no" && fit.tier !== "no_vram") parts.push(`${gb(fit.gpu_gb)} GPU, ${gb(fit.ram_gb)} RAM`);
return parts.join(" · ");
}
function card(m) {
const c = el("div", "card");
const h = el("h3");
const btn = el("button", null, m.name);
h.append(btn);
c.append(h);
const tags = [
m.params ? params(m.params) + (m.active_params ? ` (${params(m.active_params)} active)` : "") : null,
m.moe ? "MoE" : null, m.vision ? "vision" : null, m.family,
`${m.repo_count} GGUF repos`, `${compact(m.downloads)} downloads`,
].filter(Boolean).join(" · ");
c.append(el("div", "meta", tags));
const side = el("div", "r-side");
const sc = el("span", "score", String(Math.round(m.score)));
sc.title = scoreTitle(m) + "\nHardware ranking, not model quality.";
side.append(sc, el("span", "muted", "score"));
c.append(side);
const status = el("p", "muted", "Ranking quants…");
c.append(status);
btn.addEventListener("click", () => openDetail(m, query()));
return { c, status };
}
// the backend bakes the QUERIED kv type into run commands; rewrite the
// flags to the picked K/V pair (asymmetric included). f16 needs no flags.
function kvCmd(cmd, pair) {
let [k, v] = String(pair || "f16/f16").split("/");
if (KV_BITS[k] === undefined) k = "f16";
if (KV_BITS[v] === undefined) v = "f16";
cmd = cmd.replace(/\s*(--cache-type-k|-ctk)([=\s]+)\S+/g, k === "f16" ? "" : ` -ctk ${k}`)
.replace(/\s*(--cache-type-v|-ctv)([=\s]+)\S+/g, v === "f16" ? "" : ` -ctv ${v}`);
if (k !== "f16" && !/(--cache-type-k|-ctk)([=\s]|$)/.test(cmd)) cmd += ` -ctk ${k}`;
if (v !== "f16" && !/(--cache-type-v|-ctv)([=\s]|$)/.test(cmd)) cmd += ` -ctv ${v}`;
return cmd;
}
function renderDetail(m, body, kvPair) {
const d = m._detail, pick = m._pick;
const g = d.geometry;
const facts = [
d.params ? `${params(d.params)} parameters${d.active_params ? `, ${params(d.active_params)} active` : ""}` : null,
g ? `${g.n_layers} layers` : null,
g && g.moe ? `${g.expert_count} experts, ${g.expert_used} per token` : null,
d.context_length ? `${ctxLabel(d.context_length)} native context` : null,
g && g.notes && g.notes.length ? g.notes.join(", ") : null,
].filter(Boolean).join(" • ");
if (facts) body.append(el("p", "muted", facts));
const opts = d.options || [];
const sel = opts.find((o) => pick && o.repo === pick.repo && o.quant === pick.quant) || opts[0];
if (sel && sel.commands) {
const row = el("div", "row");
const copy = el("button", "btn ghost", "Copy command");
// upstream still emits the old `llama-server` binary name; current llama.cpp renamed it.
const pre = el("pre", "cmd", kvCmd((sel.commands["llama.cpp"] || "").replace(/llama-server/g, "llama serve"), kvPair));
copy.addEventListener("click", async () => {
try { await navigator.clipboard.writeText(pre.textContent); copy.textContent = "Copied"; }
catch { copy.textContent = "Select and copy"; }
setTimeout(() => (copy.textContent = "Copy command"), 1500);
});
row.append(el("span", "muted", `Run it (${sel.quant} from ${sel.repo.split("/")[0]}):`), copy);
body.append(row, pre);
if (sel.fit) body.append(el("div", "muted", fitText(sel.fit)));
if (m._reserveNote) body.append(el("div", "warn", m._reserveNote));
}
body.append(el("h3", null, `Every quant (${opts.length})`));
const hr = headroomNote(m);
if (hr) body.append(el("p", "muted", hr));
if (d.hidden_below_min_bits) {
body.append(el("p", "muted",
`${d.hidden_below_min_bits} quant(s) hidden by the bit floor. Lower "Lowest quant to consider" to see them.`));
}
const t = el("table", "quants");
const head = el("tr");
for (const [h, num] of [["Uploader", 0], ["Quant", 0], ["Size", 1], ["On your hardware", 0]]) {
head.append(el("th", num ? "num" : null, h));
}
const tb = el("tbody");
for (const o of [...opts].sort((a, b) => a.size - b.size)) {
const tr = el("tr");
if (pick && o.quant === pick.quant && o.repo === pick.repo) tr.className = "is-pick";
const qtd = el("td");
qtd.append(el("b", null, o.quant));
if (pick && o.quant === pick.quant && o.repo === pick.repo) qtd.append(" ◀ pick");
const link = el("a", null, o.repo.split("/")[0]);
link.href = o.url; link.target = "_blank"; link.rel = "noopener";
const utd = el("td"); utd.append(link);
tr.append(utd, qtd, el("td", "num", bytesGB(o.size)), el("td", null, o.fit ? o.fit.label : "?"));
tb.append(tr);
}
t.append(head, tb);
body.append(t);
if (d.kv_cache_gb) {
body.append(el("h3", null, "KV cache"));
const strip = el("div", "kv-strip");
for (const [ctx, v] of Object.entries(d.kv_cache_gb)) {
const s = el("span", null, `${ctxLabel(+ctx)} `);
s.append(el("b", null, gb(v, v < 10 ? 2 : 1)));
strip.append(s);
}
body.append(strip);
}
const fm = d.other_formats || {};
const names = { mlx: "MLX", onnx: "ONNX", awq: "AWQ", gptq: "GPTQ", fp8: "FP8", exl3: "EXL3", exl2: "EXL2" };
const any = Object.keys(names).filter((k) => fm[k] && fm[k].length);
if (any.length) {
body.append(el("h3", null, "Other formats"));
for (const k of any) {
const p = el("p", "muted", `${names[k]} (${fm[k].length}): `);
for (const id of fm[k].slice(0, 4)) {
const a = el("a", null, id.split("/")[1] || id);
a.href = `https://huggingface.co/${id}`; a.target = "_blank"; a.rel = "noopener";
p.append(a, " ");
}
body.append(p);
}
}
const cm = d.community;
if (cm && cm.bench_rows && cm.bench_rows.length) {
body.append(el("h3", null, "Community benchmarks"));
const bt = el("table", "quants");
const bh = el("tr");
for (const [h, num] of [["Quant", 0], ["Hardware", 0], ["Backend", 0], ["Prompt t/s", 1], ["Gen t/s", 1]]) {
bh.append(el("th", num ? "num" : null, h));
}
const bb = el("tbody");
for (const b of cm.bench_rows) {
const tr = el("tr");
tr.append(el("td", null, b.quant || "?"),
el("td", null, b.gpu_name || b.gpu_model || (b.vram_class ? `${b.vram_class} GB GPU` : "CPU")),
el("td", null, b.backend || "?"),
el("td", "num", b.prompt_tps ? String(Math.round(b.prompt_tps)) : "—"),
el("td", "num", b.generation_tps ? b.generation_tps.toFixed(1) : "—"));
bb.append(tr);
}
bt.append(bh, bb);
body.append(bt);
}
}
function headroomCaps(r) {
// usable GB after keeping the spare free. the upstream estimator has
// no headroom params, so this is a client-side filter on fit_gb.
if (r.kind === "unified") {
const share = (META.hardware.unified_shares || {})[r.unified_system];
const cap = r.ram_gb * (share || (r.ram_gb <= 36 ? 0.67 : 0.75));
return { vram: cap - r.ram_spare, ram: cap - r.ram_spare };
}
const vram = r.kind === "gpu" ? r.gpus.reduce((a, v) => a + v, 0) : 0;
return { vram: vram - r.vram_spare, ram: r.ram_gb - r.ram_spare };
}
function applyHeadroom(options, caps, kind) {
// drop options that fit the estimator but leave less than the spare
// free, e.g. a 31.7GB-RAM fit on a 32GB box with a 2GB reserve.
// already-failing tiers pass through: the ranker reports those.
let hidden = 0;
const kept = [];
for (const o of options || []) {
const fit = o.fit || {};
const okTier = fit.tier && fit.tier !== "no" && fit.tier !== "no_vram";
const over = (kind !== "cpu" && (fit.gpu_gb || 0) > caps.vram)
|| (fit.ram_gb || 0) > caps.ram;
if (okTier && over) { hidden++; continue; }
kept.push(o);
}
return { kept, hidden };
}
// Nominal bits per cached element (quants carry block-scale overhead).
// Merged bench: quant-bench/kv_scores.json (3 models, KL vs f16 @4k).
const KV_BITS = { f16: 16, bf16: 16, q8_0: 8.5, q5_0: 5.5, q5_1: 6,
q4_0: 4.5, q4_1: 5, iq4_nl: 4.4 };
const KV_FULL_TIERS = new Set(["gpu", "gpu_moe", "cpu", "unified", "ram"]);
function kvScale(pair) {
const [k, v] = String(pair || "f16/f16").split("/");
return ((KV_BITS[k] ?? 16) + (KV_BITS[v] ?? 16)) / 2 / 16;
}
// f16-base rescale: the upstream API only accepts f16/q8_0/q4_0 and one
// type for both K and V, so always query f16 and scale the KV part.
// KV bytes are exact math (2*layers*kv_heads*head_dim*ctx*bpe), verified
// against the estimator's own kv_cache_gb; weights + per-model overhead
// pass through untouched. Only full tiers and failing tiers are adjusted;
// partial offloads keep the estimator's f16 numbers (conservative).
function rescaleKvFits(d, pair, ctx, hw) {
// ratio is against the queried base: q8_0 for everything below it,
// f16 for f16/bf16 (ratio 1, no-op). see query().
const base = pair === "f16/f16" || pair === "bf16/bf16" ? 16 : 8.5;
const ratio = kvScale(pair) * 16 / base;
if (!(ratio < 1)) return;
const kvf = d.kv_cache_gb && d.kv_cache_gb[String(ctx)];
if (!(kvf > 0)) return;
const scaled = {};
for (const [c, g] of Object.entries(d.kv_cache_gb)) scaled[c] = g * ratio;
d.kv_cache_gb = scaled;
const delta = kvf * (1 - ratio);
const vram = hw.kind === "gpu" ? hw.gpus.reduce((a, x) => a + x, 0) : 0;
// per-model overhead + RAM constant: median over the estimator's own
// full-gpu options (single-option calibration flips picks on 0.2GB
// noise; the backend's implied overhead spans ~1.7-2.8 per model).
let oh = 1.75, ramConst = 1.2;
const gpuRefs = (d.options || []).filter((o) => o.fit && o.fit.tier === "gpu");
if (gpuRefs.length) {
const med = (xs) => { const s = xs.filter((x) => x > 0).sort((a, b) => a - b);
return s.length ? s[Math.floor(s.length / 2)] : null; };
oh = med(gpuRefs.map((o) => (o.fit.gpu_gb || 0) - o.size / 1e9 - kvf)) ?? oh;
ramConst = med(gpuRefs.map((o) => o.fit.ram_gb || 0)) ?? ramConst;
} else {
const ref = (d.options || []).find((o) => o.fit &&
(o.fit.tier === "cpu" || o.fit.tier === "ram"));
if (ref) oh = Math.max(0, (ref.fit.gpu_gb || ref.fit.ram_gb || 0) - ref.size / 1e9 - kvf);
}
const full = (o, tier, gpuGb, ramGb, label) => {
o.fit.tier = tier; o.fit.gpu_gb = gpuGb; o.fit.ram_gb = ramGb;
o.fit.label = label; o.fit.ngl = o.fit.layers;
};
const promote = (o) => {
// failing AND partial tiers: the estimator graded these under f16,
// where nothing big fits whole. rebuild as full when the scaled
// footprint fits; otherwise leave the estimator's numbers alone.
const sizeGb = o.size / 1e9;
const candGpu = sizeGb + kvf * ratio + oh;
if (hw.kind === "cpu") {
if (candGpu <= hw.ram_gb) full(o, "cpu", 0, candGpu, "Fits in RAM (CPU)");
} else if (hw.kind === "unified") {
const share = (META.hardware.unified_shares || {})[hw.unified_system];
const cap = hw.ram_gb * (share || (hw.ram_gb <= 36 ? 0.67 : 0.75));
if (candGpu <= cap) full(o, "unified", candGpu, 0, "Fits in shared memory");
} else if (candGpu <= vram) {
full(o, "gpu", candGpu, ramConst, "Fits on GPU");
}
// deliberately no ram-tier promotion on gpu rigs: a CPU-resident pick
// would outrank GPU picks on quality and recommend slower inference.
// the estimator's partial/no tiers stand instead, as before.
};
for (const o of d.options || []) {
const fit = o.fit;
if (!fit) continue;
if (!KV_FULL_TIERS.has(fit.tier)) { promote(o); continue; }
if (fit.tier === "gpu" || fit.tier === "gpu_moe") fit.gpu_gb -= delta;
else if (fit.tier === "cpu" || fit.tier === "ram") fit.ram_gb -= delta;
else if (fit.tier === "unified") fit.gpu_gb -= delta;
}
}
function headroomNote(m) {
if (!m._hiddenHeadroom) return null;
const s = m._spares || {};
const bits = [];
if (s.v) bits.push(`${s.v} GB VRAM`);
if (s.r) bits.push(`${s.r} GB RAM`);
return `${m._hiddenHeadroom} quant(s) hidden by the headroom reserve (${bits.join(" + ")} kept free). Lower it to see them.`;
}
function ensureDialog() {
let dlg = $("#detail");
if (!dlg) {
dlg = document.createElement("dialog");
dlg.id = "detail";
const x = el("button", "btn ghost small dlg-x", "Close");
x.addEventListener("click", () => dlg.close());
dlg.append(x, el("h3", "dlg-title"), el("div", "dlg-body"));
dlg.addEventListener("click", (e) => { if (e.target === dlg) dlg.close(); });
document.body.append(dlg);
}
return dlg;
}
async function openDetail(m, q) {
const dlg = ensureDialog();
const body = $(".dlg-body", dlg);
$(".dlg-title", dlg).textContent = m.name;
if (!m._detail || m._kvPair !== q.kv_pair || m._ctx !== q.context) {
body.replaceChildren(el("p", "muted", "Loading quants…"));
if (!dlg.open) dlg.showModal();
try {
const d = await detailFor(m.key, q);
const r = rig();
rescaleKvFits(d, q.kv_pair, q.context, q.hardware);
const { pick, hidden, overReserve } = rankWithReserve(d.options, famGuess(m.key), r);
m._detail = d; m._pick = pick; m._kvPair = q.kv_pair; m._ctx = q.context;
m._hiddenHeadroom = hidden;
m._overReserve = overReserve;
m._reserveNote = overReserve ? reserveNote(pick, r) : null;
m._spares = { v: r.vram_spare, r: r.ram_spare };
} catch (err) {
body.replaceChildren(el("p", "muted",
`Couldn't load quants (${String(err).slice(0, 100)}).`));
return;
}
} else if (!dlg.open) {
dlg.showModal();
}
body.replaceChildren();
renderDetail(m, body, q.kv_pair);
}
async function detailFor(key, q, signal) {
const r = await fetch(`${API}/api/model`, { method: "POST",
headers: { "content-type": "application/json" }, signal,
body: JSON.stringify({ key, hardware: q.hardware, context: q.context,
kv_type: q.kv_type, priority: "balanced", min_bits: q.min_bits,
vram_only: q.vram_only, mmproj: q.mmproj }) });
// priority is the upstream estimator's required field; our client-side
// pick is single-mode and ignores it.
if (!r.ok) throw new Error(`model ${r.status}`);
return r.json();
}
function famGuess(key) {
if (/qwen/i.test(key)) return "Qwen";
if (/gemma/i.test(key)) return "Gemma";
return null;
}
async function search(append) {
const id = ++runId;
const q = query(append);
if (!append) offset = 0;
const box = $("#results");
if (!append) box.replaceChildren();
$("#count").textContent = append ? $("#count").textContent : "Finding models…";
const ctrl = new AbortController();
const alive = () => id === runId;
let res;
try {
const rr = await fetch(`${API}/api/recommend`, { method: "POST",
headers: { "content-type": "application/json" }, signal: ctrl.signal,
body: JSON.stringify(q) });
if (!rr.ok) throw new Error(`recommend ${rr.status}`);
res = await rr.json();
} catch {
if (alive()) $("#count").textContent = "Couldn't reach the catalog API. Try again.";
return;
}
if (!alive()) return;
total = res.total;
offset += res.results.length;
$("#count").textContent = `${total.toLocaleString()} models`;
$("#more").hidden = offset >= total;
const r = rig();
// best-sort promises fitting models, so non-fits are filtered server-side
// (fits_only above) and dropped client-side (headroom residuals) below.
const bestSort = q.sort === "best";
if (!append) { nofitDropped = 0; autoPages = 0; seenModels = []; }
seenModels.push(...res.results);
for (const m of res.results) {
const ui = card(m);
m._ui = ui;
box.append(ui.c);
}
const queue = [...res.results];
async function worker() {
while (alive() && queue.length) {
const m = queue.shift();
try {
const d = await detailFor(m.key, q, ctrl.signal);
if (!alive()) return;
rescaleKvFits(d, q.kv_pair, q.context, q.hardware);
const { pick, warnings, hidden, overReserve } = rankWithReserve(d.options, famGuess(m.key), r);
m._detail = d; m._pick = pick;
m._hiddenHeadroom = hidden;
m._overReserve = overReserve;
m._reserveNote = overReserve ? reserveNote(pick, r) : null;
m._spares = { v: r.vram_spare, r: r.ram_spare };
const ui = m._ui;
if (!ui) continue;
ui.status.replaceChildren();
if (pick && !(bestSort && overReserve)) {
const line = el("div", "choice");
line.append(el("b", null, pick.quant),
` from ${pick.repo.split("/")[0]} — ${bytesGB(pick.size)}${pick.full === false ? " (partial offload)" : ""}`);
ui.status.append(line);
ui.status.append(el("div", "muted", fitText(pick.fit)));
for (const w of warnings) ui.status.append(el("div", "warn", w));
if (m._reserveNote) ui.status.append(el("div", "warn", m._reserveNote));
const hr = headroomNote(m);
if (hr && !overReserve) ui.status.append(el("div", "muted", hr));
const railEl = rail(pick.fit, r);
if (railEl) ui.status.append(railEl);
} else if (bestSort) {
ui.c.remove();
nofitDropped++;
} else {
ui.status.textContent = warnings[0] || "Doesn't fit this hardware.";
}
} catch (err) {
if (alive() && m._ui) m._ui.status.textContent =
`Quant ranking failed (${String(err).slice(0, 100)}).`;
}
}
}
await Promise.all(Array.from({ length: 4 }, worker));
if (!alive()) return;
// a best-sort batch can hide entirely (e.g. nothing but 35Bs on top at
// tight headroom): page forward while the screen is still empty, bounded
// so it can never run away. any new search or click stops the chain.
if (bestSort && box.childElementCount === 0 && autoPages < 4 && offset < total) {
autoPages++;
search(true);
return;
}
// the server can no longer pre-filter fits (it only speaks q8_0/f16),
// so best-sort keeps server score order and the client drops whatever
// has no pick. count what is shown — the server total is unfiltered.
// the vram-only and fits-only checkboxes are enforced here too, since
// their server-side equivalents are forced off while rescaling.
if (bestSort || $("#fits-only").checked) {
for (const m of seenModels) {
if (!m._ui || !m._ui.c.isConnected) continue;
if (!m._pick) { m._ui.c.remove(); nofitDropped++; }
}
}
if ($("#vram-only").checked && r.kind === "gpu") {
for (const m of seenModels) {
if (!m._ui || !m._ui.c.isConnected) continue;
if (!m._pick || !m._pick.fit || m._pick.fit.tier !== "gpu") {
m._ui.c.remove(); nofitDropped++;
}
}
}
if (bestSort) {
$("#count").textContent =
`${box.childElementCount.toLocaleString()} models that fit your hardware`;
}
}
let deb;
function schedule(append) {
clearTimeout(deb);
deb = setTimeout(() => search(append || false), 250);
}
function syncKind() {
const kind = $('input[name="kind"]:checked').value;
$$("[data-show]").forEach((n) => {
if (n.id === "gpu2-wrap") return; // toggle-owned, not kind-owned
n.hidden = !n.dataset.show.split(" ").includes(kind);
});
$("#custom-vram-field").hidden = kind !== "gpu" || $("#gpu").value !== "custom";
$("#custom-vram2-field").hidden = $("#gpu2").value !== "custom";
$("#gpu2-toggle").textContent = $("#gpu2-wrap").hidden ? "Add a different card" : "Remove the other card";
}
async function boot() {
try {
META = await fetch(`${API}/api/meta`).then((r) => r.json());
SCORES = await fetch("quant_scores.json").then((r) => r.json());
} catch {
$("#count").textContent = "Couldn't load. Check your connection and refresh.";
return;
}
const H = META.hardware;
const groups = (sel) => {
for (const [label, names] of H.gpu_groups) {
const g = document.createElement("optgroup");
g.label = label;
for (const n of names) g.append(opt(n, `${n.replace(/^(NVIDIA|AMD|Intel) /, "")} (${H.gpus[n]} GB)`));
$(sel).append(g);
}
$(sel).append(opt("custom", "Other: enter VRAM"));
};
groups("#gpu"); groups("#gpu2");
// Steam Hardware Survey defaults (Jul 2026): RTX 3060 most common GPU,
// 16 GB most common RAM, 64k ctx per the bench follow-ups.
$("#gpu").value = "NVIDIA RTX 3060 12GB";
$("#gpu2").value = "NVIDIA RTX 4060";
const vramSet = [...new Set(Object.values(H.gpus))].sort((a, b) => a - b);
for (const sel of ["#custom-vram", "#custom-vram2"]) {
for (const v of vramSet) $(sel).append(opt(v, `${v} GB`, v === 12));
}
for (const sel of ["#gpu-count", "#gpu2-count"]) {
for (const n of [1, 2, 3, 4, 6, 8]) $(sel).append(opt(n, n, n === 1));
}
for (const v of H.ram) $("#ram").append(opt(v, `${v} GB`, v === 16));
for (const s of Object.keys(H.unified)) $("#usys").append(opt(s, s));
const syncMem = () => {
const mems = H.unified[$("#usys").value] || [];
$("#umem").replaceChildren(...mems.map((m) => opt(m, `${m} GB`)));
};
$("#usys").addEventListener("change", () => { syncMem(); schedule(); });
syncMem();
for (const c of H.contexts) $("#ctx").append(opt(c, `${ctxLabel(c)} tokens`, c === 65536));
for (const f of META.families) $("#family").append(opt(f.family, `${f.family} (${f.count})`));
for (const s of META.sizes) $("#size").append(opt(s, s));
$("#kind").addEventListener("change", () => { syncKind(); schedule(); });
$("#gpu").addEventListener("change", syncKind);
$("#gpu2").addEventListener("change", syncKind);
$("#gpu2-toggle").addEventListener("click", () => {
$("#gpu2-wrap").hidden = !$("#gpu2-wrap").hidden;
syncKind(); schedule();
});
$("#more").addEventListener("click", () => search(true));
$("#search").addEventListener("input", () => schedule());
for (const sel of ["#gpu", "#custom-vram", "#gpu-count", "#gpu2", "#custom-vram2", "#gpu2-count",
"#ram", "#usys", "#umem", "#ctx", "#kv", "#mmproj", "#min-bits",
"#vram-spare", "#ram-spare", "#family", "#size", "#sort"]) {
$(sel).addEventListener("change", () => schedule());
}
for (const sel of ["#vram-only", "#fits-only", "#moe-only", "#vision-only"]) {
$(sel).addEventListener("change", () => schedule());
}
$$('input[name="kind"]').forEach((i) => i.addEventListener("change", () => schedule()));
syncKind();
search(false);
}
boot();