codelion's picture
AMD BC-250
405c793 verified
Raw History Blame Contribute Delete
37.7 kB
"use strict";
(function () {
const $ = (s, root = document) => root.querySelector(s);
const $$ = (s, root = document) => [...root.querySelectorAll(s)];
function el(tag, attrs, ...kids) {
const n = document.createElement(tag);
for (const [k, v] of Object.entries(attrs || {})) {
if (v === null || v === undefined || v === false) continue;
if (k === "class") n.className = v;
else if (k === "text") n.textContent = v;
else if (k === "style") {
// Property by property: the page's CSP forbids style attributes, not CSSOM writes.
for (const decl of String(v).split(";")) {
const i = decl.indexOf(":");
if (i > 0) n.style.setProperty(decl.slice(0, i).trim(), decl.slice(i + 1).trim());
}
}
else if (k.startsWith("on")) n.addEventListener(k.slice(2), v);
else n.setAttribute(k, v === true ? "" : v);
}
for (const kid of kids.flat()) {
if (kid === null || kid === undefined || kid === false) continue;
n.append(kid instanceof Node ? kid : document.createTextNode(String(kid)));
}
return n;
}
const gb = (v, digits = 1) => (v === null || v === undefined ? "?" : `${Number(v).toFixed(digits)} GB`);
const bytesGB = (b) => (b ? gb(b / 1e9) : "?");
const params = (p) => (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));
const store = {
get(k) { try { return JSON.parse(localStorage.getItem(k)); } catch (e) { return null; } },
set(k, v) { try { localStorage.setItem(k, JSON.stringify(v)); } catch (e) {} },
};
// ------------------------------------------------------------------ telemetry
const Telemetry = (() => {
const gpc = navigator.globalPrivacyControl === true || navigator.doNotTrack === "1";
let optedOut = gpc;
try {
if (localStorage.getItem("lme-optout") === "1") optedOut = true;
else if (gpc && localStorage.getItem("lme-optin") === "1") optedOut = false;
} catch (e) {}
let sid = null;
try { sid = sessionStorage.getItem("lme-sid"); } catch (e) {}
if (!sid || !/^[a-f0-9]{16}$/.test(sid)) {
const b = new Uint8Array(8);
crypto.getRandomValues(b);
sid = [...b].map((x) => x.toString(16).padStart(2, "0")).join("");
try { sessionStorage.setItem("lme-sid", sid); } catch (e) {}
}
let enabled = true;
let build = () => null;
let lastSent = "";
const clean = (o) => Object.fromEntries(Object.entries(o).filter(([, v]) =>
v !== undefined && v !== null && v !== "" && !(Array.isArray(v) && !v.length)));
function post(events, beacon) {
const body = JSON.stringify({ events });
if (beacon && navigator.sendBeacon) navigator.sendBeacon("/api/events", new Blob([body], { type: "application/json" }));
else fetch("/api/events", { method: "POST", headers: { "content-type": "application/json" }, body, keepalive: true }).catch(() => {});
}
function sendSession(beacon) {
if (optedOut || !enabled) return;
const summary = build();
if (!summary) return;
const ev = clean({ event_type: "session", session_id: sid, ...summary });
const key = JSON.stringify(ev);
if (key === lastSent) return;
lastSent = key;
post([ev], beacon);
}
document.addEventListener("visibilitychange", () => { if (document.visibilityState === "hidden") sendSession(true); });
window.addEventListener("pagehide", () => sendSession(true));
return {
gpc,
get optedOut() { return optedOut; },
setOptOut(v) {
optedOut = v;
try {
if (v) { localStorage.setItem("lme-optout", "1"); localStorage.removeItem("lme-optin"); }
else { localStorage.removeItem("lme-optout"); if (gpc) localStorage.setItem("lme-optin", "1"); }
} catch (e) {}
},
setEnabled(v) { enabled = v; },
setBuilder(fn) { build = fn; },
sendSession,
async submit(type, fields) {
if (optedOut) return { ok: false, message: "Sending is turned off in the privacy setting at the bottom of the page." };
const ev = clean({ event_type: type, session_id: sid, ...fields });
try {
const r = await fetch("/api/events", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ events: [ev] }) });
const j = await r.json().catch(() => ({}));
if (r.status === 202) return { ok: true, row: (j.rows || [])[0] || {} };
if (r.status === 429) return { ok: false, message: "Too many submissions from this network. Try again in a minute." };
const d = (j.details || []).map((x) => `${(x.loc || []).slice(-1)[0]}: ${x.msg}`).join("; ");
return { ok: false, message: `Not accepted${d ? ` (${d})` : ""}.` };
} catch (e) {
return { ok: false, message: "Couldn't reach the server. Check your connection and try again." };
}
},
};
})();
// ------------------------------------------------------------------ state
let META = null;
const visit = { families: new Set(), queries: new Set(), viewed: [], clicked: [], copied: new Set(), searched: false, top: null };
const state = { offset: 0, total: 0, loading: 0, detailKey: null };
function rig() {
const kind = $('input[name="kind"]:checked').value;
const out = { kind, ram_gb: 32, gpus: [] };
if (kind === "gpu") {
const cards = (sel, vram, count, fallback) => {
const name = $(sel).value;
const each = name === "custom" ? Math.max(1, Math.min(256, +$(vram).value || fallback)) : META.hardware.gpus[name];
return Array.from({ length: +$(count).value || 1 }, () => each);
};
out.gpus = cards("#gpu", "#custom-vram", "#gpu-count", 24);
if (mixedCards()) out.gpus = out.gpus.concat(cards("#gpu2", "#custom-vram2", "#gpu2-count", 8)).slice(0, 16);
out.ram_gb = +$("#ram").value;
out.gpu_model = $("#gpu").value;
} else if (kind === "unified") {
out.unified_system = $("#unified-system").value;
out.ram_gb = +$("#unified-mem").value;
} else {
out.ram_gb = +$("#ram").value;
}
return out;
}
function mixedCards() { return !$("#gpu2-block").hidden; }
function customCard() { return $("#gpu").value === "custom" || (mixedCards() && $("#gpu2").value === "custom"); }
function hardwarePayload(r) {
const h = { kind: r.kind, gpus: r.gpus, ram_gb: r.ram_gb };
if (r.unified_system) h.unified_system = r.unified_system;
return h;
}
function usableVram(r) {
if (r.kind === "unified") {
const share = (META.hardware.unified_shares || {})[r.unified_system];
return r.ram_gb * (share || (r.ram_gb <= 36 ? 0.67 : 0.75));
}
return r.gpus.reduce((a, v) => a + Math.max(v - 0.5, 0), 0);
}
function renderCapacity() {
const r = rig();
const box = $("#capacity");
if (r.kind === "gpu") {
const total = r.gpus.reduce((a, v) => a + v, 0);
box.replaceChildren(
el("div", { class: "pool gpu" }, el("b", {}, `${total} GB`), `VRAM${r.gpus.length > 1 ? ` on ${r.gpus.length} cards` : ""}`),
el("div", { class: "pool ram" }, el("b", {}, `${r.ram_gb} GB`), "system RAM"));
} else if (r.kind === "unified") {
box.replaceChildren(el("div", { class: "pool gpu" }, el("b", {}, gb(usableVram(r), 0)), `of ${r.ram_gb} GB usable by the GPU by default`));
} else {
box.replaceChildren(el("div", { class: "pool ram" }, el("b", {}, `${r.ram_gb} GB`), "system RAM"));
}
}
function saveRig() {
store.set("lme-rig", {
kind: $('input[name="kind"]:checked').value, gpu: $("#gpu").value, vram: $("#custom-vram").value,
count: $("#gpu-count").value, mixed: mixedCards(), gpu2: $("#gpu2").value, vram2: $("#custom-vram2").value,
count2: $("#gpu2-count").value, ram: $("#ram").value, usys: $("#unified-system").value, umem: $("#unified-mem").value,
context: $("#context").value, kv: $("#kv").value, priority: $('input[name="priority"]:checked').value,
minBits: $("#min-bits").value, fits: $("#fits-only").checked, vramOnly: $("#vram-only").checked, mmproj: $("#mmproj").value,
});
}
function syncKind() {
const kind = $('input[name="kind"]:checked').value;
$$("[data-show]").forEach((n) => { 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 = mixedCards() ? "Remove the other card" : "Add a different card";
const note = (META.hardware.unified_notes || {})[$("#unified-system").value];
$("#unified-note").textContent = note || "";
$("#unified-note").hidden = !note;
const mems = META.hardware.unified[$("#unified-system").value] || [];
const cur = +$("#unified-mem").value;
$("#unified-mem").replaceChildren(...mems.map((m) => el("option", { value: m, selected: m === cur }, `${m} GB`)));
if (!mems.includes(cur) && mems.length) $("#unified-mem").value = mems.includes(64) ? 64 : mems[mems.length - 1];
renderCapacity();
}
function query() {
const r = rig();
return {
hardware: hardwarePayload(r), context: +$("#context").value, kv_type: $("#kv").value,
priority: $('input[name="priority"]:checked').value, 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: $("#fits-only").checked,
vram_only: r.kind === "gpu" && $("#vram-only").checked, mmproj: $("#mmproj").value,
};
}
// ------------------------------------------------------------------ memory rail
const SCORE_PARTS = [["fit", "Fit on your hardware"], ["capacity", "Model size you can run"],
["popularity", "Downloads"], ["recency", "How new"], ["community", "Community reports"]];
function scoreBreakdown(m) {
const w = META.score_weights || {};
return SCORE_PARTS.map(([k, label]) => `${label}: ${Math.round((m.components[k] || 0) * w[k] * 100)} of ${Math.round(w[k] * 100)}`);
}
function rail(best, r) {
const f = best && best.fit;
if (!f) return null;
const box = el("div", { class: "rail", role: "img" });
const pct = (v, cap) => `${Math.max(0, Math.min(100, (v / cap) * 100))}%`;
if (r.kind === "unified") {
const cap = usableVram(r);
const pool = el("div", { class: "pool", style: `flex:1` }, el("i", { class: "gpu", style: `width:${pct(f.gpu_gb, cap)}` }));
if (f.gpu_gb > cap) pool.append(el("i", { class: "over", style: `width:${pct(f.gpu_gb - cap, f.gpu_gb)}` }));
box.append(pool);
box.setAttribute("aria-label", `Needs ${gb(f.gpu_gb)} of ${gb(cap)} the GPU can use`);
return box;
}
const vram = r.kind === "gpu" ? r.gpus.reduce((a, v) => a + v, 0) : 0; // GPU figures include each card's driver context
const ram = r.ram_gb;
const total = vram + ram;
if (vram) {
box.append(el("div", { class: "pool", style: `flex:${vram / total}` },
el("i", { class: "gpu", style: `width:${pct(f.gpu_gb, vram)}` })));
}
const ramPool = el("div", { class: "pool", style: `flex:${ram / total}` },
el("i", { class: f.tier === "gpu_moe" ? "exp" : "ram", style: `width:${pct(f.ram_gb, ram)}` }));
if (f.tier === "no" || f.tier === "no_vram") ramPool.append(el("i", { class: "over", style: "width:30%" }));
box.append(ramPool);
box.setAttribute("aria-label", `GPU ${gb(f.gpu_gb)} of ${gb(vram)}; RAM ${gb(f.ram_gb)} of ${ram} GB`);
return box;
}
function fitBadge(best) {
if (!best || !best.fit) return el("span", { class: "fit t-cpu" }, "Pick hardware");
return el("span", { class: `fit t-${best.fit.tier}${best.estimated ? " t-est" : ""}` },
best.fit.label + (best.estimated ? " (est.)" : ""));
}
// ------------------------------------------------------------------ results
function card(m, r) {
const b = m.best;
const tags = [
m.params ? el("span", { class: "num" }, params(m.params) + (m.active_params ? ` (${params(m.active_params)} active)` : "")) : null,
m.moe ? el("span", { class: "tag" }, "MoE") : null,
m.vision ? el("span", { class: "tag" }, "vision") : null,
el("span", {}, m.family),
el("span", {}, `${m.repo_count} GGUF repo${m.repo_count === 1 ? "" : "s"}`),
el("span", {}, `${compact(m.downloads)} downloads`),
];
const choice = b ? el("div", { class: "r-choice" },
el("span", { class: "num" }, b.quant), " from ", el("span", {}, b.repo.split("/")[0]), " — ",
el("span", { class: "num" }, bytesGB(b.size)),
b.fit && b.fit.tier !== "no" && b.fit.tier !== "no_vram" ? el("span", { class: "muted" }, `, ${gb(b.fit.gpu_gb)} on GPU, ${gb(b.fit.ram_gb)} in RAM`) : null)
: el("div", { class: "r-choice muted" }, "File sizes not loaded yet.");
return el("li", { class: "result" },
el("div", {},
el("div", { class: "r-name" }, el("button", { type: "button", onclick: () => openDetail(m.key) }, m.name)),
el("div", { class: "r-meta" }, tags)),
el("div", { class: "r-side" }, el("div", { class: "score", title: scoreBreakdown(m).join("\n") + "\nA ranking for your hardware, not a measure of model quality." }, Math.round(m.score)), el("div", {}, "score")),
el("div", { class: "r-best" }, choice, fitBadge(b)),
rail(b, r));
}
let inflight = null;
async function search(append) {
const q = query();
if (!append) state.offset = 0;
const payload = { ...q, offset: state.offset, limit: 24 };
const token = Symbol();
inflight = token;
$("#count").textContent = append ? $("#count").textContent : "Finding models…";
let res;
try {
const r = await fetch("/api/recommend", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify(payload) });
if (!r.ok) throw new Error(String(r.status));
res = await r.json();
} catch (e) {
if (inflight === token) $("#count").textContent = "Couldn't load models. Refresh the page to try again.";
return;
}
if (inflight !== token) return;
const hw = rig();
const list = $("#results");
if (!append) list.replaceChildren();
if (!res.results.length && !append) {
list.append(el("li", { class: "empty" }, q.vram_only
? `Nothing here fits entirely in VRAM. Untick “Keep the whole model in VRAM”, lower the context${q.min_bits ? ", allow lower quants" : ""}, or try a smaller size.`
: q.fits_only
? `Nothing here runs on this hardware. Untick “Only models that run”, lower the context${q.min_bits ? ", allow lower quants" : ""}, or try a smaller size.`
: "No models match. Clear the search or pick another family."));
}
res.results.forEach((m) => list.append(card(m, hw)));
state.total = res.total;
state.offset += res.results.length;
$("#count").textContent = `${res.total.toLocaleString()} model${res.total === 1 ? "" : "s"}`;
$("#more").hidden = state.offset >= res.total;
$("#notice").hidden = !res.notices.length;
$("#notice").textContent = res.notices.join(" ");
// Some results were estimated while their files were still being read; the server keeps
// reading, so ask again for the exact numbers, a few times at most, if the user hasn't moved on.
// (The notice is only set for reads still pending, not for files that can't be read.)
const asked = JSON.stringify(q);
if (state.refineFor !== asked) { state.refineFor = asked; state.refines = 0; }
clearTimeout(state.refine);
if (!append && res.notices.some((n) => n.includes("estimated")) && state.refines < 3) {
state.refines += 1;
state.refine = setTimeout(() => { if (JSON.stringify(query()) === asked && state.offset <= 24) search(false); }, 6000 * state.refines);
}
if (!append) {
const first = res.results[0];
visit.top = first ? { key: first.key, quant: first.best && first.best.quant, fit: first.best && first.best.fit && first.best.fit.tier } : null;
if (q.family) visit.families.add(q.family);
if (q.search) visit.searched = true;
visit.queries.add(JSON.stringify([q.family, q.size, q.search, q.context, q.priority, q.hardware]));
visit.lastResults = res.total;
}
}
let debounce;
function schedule() {
clearTimeout(debounce);
debounce = setTimeout(() => search(false), 250);
}
// ------------------------------------------------------------------ detail
async function openDetail(key) {
const dlg = $("#detail");
state.detailKey = key;
$("#d-title").textContent = key.split("/").pop();
$("#d-kicker").textContent = key.includes("/") ? key.split("/")[0] : "Model";
$("#d-facts").textContent = "";
$("#d-body").replaceChildren(el("p", { class: "muted" }, "Reading the model's files… a model nobody has opened yet takes a few seconds."));
if (!dlg.open) dlg.showModal();
if (!visit.viewed.includes(key)) visit.viewed.push(key);
Telemetry.sendSession(false);
const q = query();
let d;
try {
const r = await fetch("/api/model", { method: "POST", headers: { "content-type": "application/json" },
body: JSON.stringify({ key, hardware: q.hardware, context: q.context, kv_type: q.kv_type, priority: q.priority, min_bits: q.min_bits, vram_only: q.vram_only, mmproj: q.mmproj }) });
if (!r.ok) throw new Error(String(r.status));
d = await r.json();
} catch (e) {
if (state.detailKey === key) $("#d-body").replaceChildren(el("p", { class: "status err" }, "Couldn't load this model. Close and try again."));
return;
}
if (state.detailKey !== key) return;
renderDetail(d, q);
}
function renderDetail(d, q) {
const hw = rig();
const g = d.geometry;
$("#d-facts").textContent = [
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.length ? g.notes.join(", ") : null,
].filter(Boolean).join(" • ");
const body = $("#d-body");
body.replaceChildren();
if (d.components) {
body.append(el("details", { class: "score-why" },
el("summary", {}, `Score ${Math.round(d.score)} of 100, and how it's worked out`),
el("ul", {}, scoreBreakdown(d).map((line) => el("li", {}, line))),
el("p", { class: "muted" }, "It ranks what suits your hardware among popular models. It doesn't measure how good a model is: a newer version with fewer downloads can score lower than an older one.")));
}
const opts = d.options || [];
let selected = d.best ? opts.findIndex((o) => o.repo === d.best.repo && o.quant === d.best.quant) : 0;
if (selected < 0) selected = 0;
// command for the selected quant
const cmdBox = el("pre", { class: "cmd" });
const tabs = el("div", { class: "tabs", role: "tablist" });
let runtime = "llama.cpp";
const selLabel = el("p", { class: "muted", style: "margin:4px 0 0;font-size:13px" });
function showCmd() {
const o = opts[selected];
if (!o) { cmdBox.textContent = "No quant files could be read for this model."; return; }
cmdBox.textContent = o.commands[runtime];
$$("button", tabs).forEach((b) => b.setAttribute("aria-selected", String(b.dataset.rt === runtime)));
selLabel.textContent = runtime === "ollama"
? "Ollama picks GPU offload itself and defaults to a short context; set num_ctx to use more."
: `${o.fit ? o.fit.label + ". " : ""}${o.estimated ? "Sizes are estimated from the parameter count. " : ""}` +
(!o.projector_size ? "" : q.mmproj === "off" ? `The ${gb(o.projector_size / 1e9)} vision projector isn't loaded (--no-mmproj): text only.`
: q.mmproj === "ram" ? `Includes the ${gb(o.projector_size / 1e9)} vision projector, kept in system RAM (--no-mmproj-offload); images encode slower.`
: `Includes the ${gb(o.projector_size / 1e9)} vision projector that llama-server loads onto the GPU with -hf. Change "Vision projector" to keep it in RAM or skip it.`);
}
for (const rt of ["llama.cpp", "ollama"]) {
tabs.append(el("button", { type: "button", role: "tab", "data-rt": rt, onclick: () => { runtime = rt; showCmd(); } }, rt));
}
const copyBtn = el("button", { type: "button", class: "btn", onclick: async () => {
try {
await navigator.clipboard.writeText(cmdBox.textContent);
copyBtn.textContent = "Copied";
visit.copied.add(runtime);
setTimeout(() => (copyBtn.textContent = "Copy command"), 1500);
} catch (e) { copyBtn.textContent = "Select and copy"; }
} }, "Copy command");
body.append(el("h3", {}, "Run it"), el("div", { class: "cmd-row" }, tabs, copyBtn), cmdBox, selLabel);
showCmd();
// every quant
const rows = opts.map((o, i) => {
const tr = el("tr", { tabindex: "0", "aria-selected": String(i === selected) },
el("td", {}, el("a", { href: o.url, target: "_blank", rel: "noopener", onclick: (ev) => {
ev.stopPropagation();
if (!visit.clicked.includes(o.repo) && visit.clicked.length < 5) visit.clicked.push(o.repo);
} }, o.repo.split("/")[0])),
el("td", { class: "num" }, o.quant),
el("td", { class: "num" }, bytesGB(o.size)),
el("td", {}, fitBadge(o)),
el("td", {}, rail(o, hw)));
const pick = () => {
selected = i;
$$("tbody tr", body).forEach((row, j) => row.setAttribute("aria-selected", String(j === i)));
showCmd();
};
tr.addEventListener("click", pick);
tr.addEventListener("keydown", (ev) => { if (ev.key === "Enter" || ev.key === " ") { ev.preventDefault(); pick(); } });
return tr;
});
body.append(
el("h3", {}, `Every quant (${opts.length})`),
d.hidden_below_min_bits ? el("p", { class: "muted" }, `${d.hidden_below_min_bits} quant(s) below ${q.min_bits}-bit hidden. Change "Lowest quant to consider" to see them.`) : "",
opts.length ? el("div", { class: "tbl-wrap" }, el("table", {},
el("thead", {}, el("tr", {}, el("th", {}, "Uploader"), el("th", { class: "num" }, "Quant"), el("th", { class: "num" }, "Size"), el("th", {}, "On your hardware"), el("th", {}, "Memory"))),
el("tbody", {}, rows)))
: el("p", { class: "muted" }, "None of this model's GGUF files could be listed. The repos may be gated."));
if (d.kv_cache_gb) {
body.append(el("h3", {}, `KV cache at ${q.kv_type}`), el("div", { class: "kv-strip" },
Object.entries(d.kv_cache_gb).map(([c, v]) => el("span", {}, `${ctxLabel(+c)} `, el("b", {}, gb(v, v < 10 ? 2 : 1))))));
}
// other formats
const fm = d.other_formats || {};
const formats = [];
const lists = (ids) => el("ul", {}, ids.slice(0, 6).map((id) => el("li", {}, el("a", { href: `https://huggingface.co/${id}`, target: "_blank", rel: "noopener" }, id))));
if (fm.mlx) formats.push(el("div", { class: "format" }, el("h4", {}, `MLX (${fm.mlx.length})`),
el("p", { style: "margin:0" }, "For Apple Silicon. ", el("a", { href: META.links.mlx, target: "_blank", rel: "noopener" }, "MLX Model Explorer"), " compares them."), lists(fm.mlx)));
if (fm.onnx) formats.push(el("div", { class: "format" }, el("h4", {}, `ONNX (${fm.onnx.length})`),
el("p", { style: "margin:0" }, el("a", { href: META.links.onnx, target: "_blank", rel: "noopener" }, "ONNX Community model explorer")), lists(fm.onnx)));
for (const [k, label] of [["awq", "AWQ"], ["gptq", "GPTQ"], ["fp8", "FP8"], ["exl3", "EXL3"], ["exl2", "EXL2"]]) {
if (fm[k]) formats.push(el("div", { class: "format" }, el("h4", {}, `${label} (${fm[k].length})`),
el("p", { class: "muted", style: "margin:0" }, k.startsWith("exl") ? "For ExLlama / TabbyAPI." : "For vLLM, SGLang and other GPU servers."), lists(fm[k])));
}
if (formats.length) body.append(el("h3", {}, "Other formats"), el("div", { class: "formats" }, formats));
// community
body.append(el("h3", {}, "Community"));
const c = d.community;
if (c && c.bench_rows && c.bench_rows.length) {
body.append(el("div", { class: "tbl-wrap" }, el("table", {},
el("thead", {}, el("tr", {}, el("th", {}, "Quant"), el("th", {}, "Hardware"), el("th", {}, "Backend"), el("th", { class: "num" }, "GPU layers"), el("th", { class: "num" }, "Prompt t/s"), el("th", { class: "num" }, "Generation t/s"))),
el("tbody", {}, c.bench_rows.map((b) => el("tr", {},
el("td", { class: "num" }, b.quant || "?"),
el("td", {}, b.gpu_name || b.gpu_model || (b.vram_class ? `${b.vram_class} GB GPU` : "CPU")),
el("td", {}, b.backend || "?"),
el("td", { class: "num" }, b.n_gpu_layers ?? "?"),
el("td", { class: "num" }, b.prompt_tps ? Math.round(b.prompt_tps) : "—"),
el("td", { class: "num" }, b.generation_tps ? b.generation_tps.toFixed(1) : "—")))))));
} else {
body.append(el("p", { class: "muted" }, "No benchmarks for this model yet. Run llama-bench and paste the result below: it is the only speed data this page shows."));
}
if (c && c.feedback) {
body.append(el("p", {}, `${c.feedback} report${c.feedback === 1 ? "" : "s"}` + (c.positive_share !== null ? `, ${Math.round(c.positive_share * 100)}% worked well.` : ".")));
}
body.append(el("div", { class: "two" }, benchForm(d, opts, () => opts[selected]), feedbackForm(d, () => opts[selected])));
}
function hardwareFields() {
const r = rig();
return {
hardware_kind: r.kind, gpu_model: r.kind === "gpu" ? r.gpu_model : null, gpu_count: r.kind === "gpu" ? r.gpus.length : null,
vram_gb: r.kind === "gpu" ? r.gpus.reduce((a, v) => a + v, 0) : null, ram_gb: r.ram_gb,
unified_system: r.kind === "unified" ? r.unified_system : null, hardware_source: customCard() ? "custom" : "preset",
};
}
function quantSelect(opts, current) {
const s = el("select", {});
opts.forEach((o, i) => s.append(el("option", { value: i, selected: o === current() }, `${o.quant} — ${o.repo}`)));
return s;
}
function benchForm(d, opts, current) {
const sel = quantSelect(opts, current);
const ta = el("textarea", { rows: "6", placeholder: "| model | size | params | backend | ngl | test | t/s |\n| ... | pp512 | ... |\n| ... | tg128 | ... |", maxlength: "40000" });
const status = el("p", { class: "status", role: "status" });
const btn = el("button", { type: "button", class: "btn primary" }, "Share benchmark");
btn.addEventListener("click", async () => {
const o = opts[+sel.value];
if (!o || !ta.value.trim()) { status.className = "status err"; status.textContent = "Pick the quant you ran and paste llama-bench's output."; return; }
btn.disabled = true;
const res = await Telemetry.submit("llama_bench", { selected_model: d.key, repo: o.repo, quant: o.quant, bench_output: ta.value, ...hardwareFields() });
btn.disabled = false;
if (!res.ok) { status.className = "status err"; status.textContent = res.message; return; }
const row = res.row || {};
if ((row.flags || []).includes("unparseable_benchmark")) {
status.className = "status err";
status.textContent = "Saved, but no llama-bench table was found in it. Paste the whole table, or run llama-bench with -o json.";
} else {
status.className = "status ok";
status.textContent = `Thanks. Recorded ${row.generation_tps ? `${row.generation_tps.toFixed(1)} t/s generation` : ""}${row.prompt_tps ? `, ${Math.round(row.prompt_tps)} t/s prompt` : ""} on ${row.backend || "your backend"}.`;
ta.value = "";
}
});
return el("div", { class: "panel" },
el("h4", { style: "margin:0 0 6px" }, "Share a llama-bench result"),
el("p", { class: "muted", style: "margin:0 0 8px;font-size:13px" }, "Run ", el("code", {}, "llama-bench -m model.gguf"), " and paste the output. Only the speeds and settings are kept; file paths are discarded. Your hardware settings on this page are sent with it."),
el("div", { class: "field" }, el("label", {}, "Quant you ran"), sel),
el("div", { class: "field" }, el("label", {}, "llama-bench output"), ta), btn, status);
}
function feedbackForm(d, current) {
const opts = d.options || [];
const sel = quantSelect(opts, current);
const pick = (name, choices) => el("select", { name }, el("option", { value: "" }, "—"), choices.map(([v, l]) => el("option", { value: v }, l)));
const tried = pick("tried", [["yes", "Yes"], ["planning", "Planning to"], ["no", "No"]]);
const how = pick("how", [["excellent", "Worked great"], ["good", "Worked well"], ["acceptable", "Usable"], ["too_slow", "Too slow"], ["out_of_memory", "Ran out of memory"], ["low_quality", "Poor output"], ["didnt_load", "Didn't load"]]);
const runtime = pick("runtime", [["llama.cpp", "llama.cpp"], ["ollama", "Ollama"], ["lm-studio", "LM Studio"], ["jan", "Jan"], ["koboldcpp", "KoboldCpp"], ["other", "Other"]]);
const tps = el("input", { type: "number", min: "0", max: "5000", step: "0.1", placeholder: "optional" });
const notes = el("input", { type: "text", maxlength: "280", placeholder: "optional, 280 characters" });
const status = el("p", { class: "status", role: "status" });
const btn = el("button", { type: "button", class: "btn primary" }, "Send report");
btn.addEventListener("click", async () => {
if (!tried.value) { status.className = "status err"; status.textContent = "Say whether you've tried it."; return; }
const o = opts[+sel.value];
const good = ["excellent", "good", "acceptable"].includes(how.value);
btn.disabled = true;
const res = await Telemetry.submit("feedback", {
selected_model: d.key, repo: o && o.repo, quant: o && o.quant, tried: tried.value,
quality_rating: good ? how.value : null, failure_reason: how.value && !good ? how.value : null,
runtime: runtime.value || null, reported_tps: tps.value ? +tps.value : null, reported_context: +$("#context").value,
notes: notes.value || null, ...hardwareFields(),
});
btn.disabled = false;
status.className = `status ${res.ok ? "ok" : "err"}`;
status.textContent = res.ok ? "Thanks, your report is in." : res.message;
});
const f = (label, input) => el("div", { class: "field" }, el("label", {}, label), input);
return el("div", { class: "panel" },
el("h4", { style: "margin:0 0 6px" }, "Have you run this model?"),
f("Quant", sel), el("div", { class: "row2" }, f("Tried it?", tried), f("How did it go?", how)),
el("div", { class: "row2" }, f("Runtime", runtime), f("Tokens/s", tps)), f("Notes", notes), btn, status);
}
// ------------------------------------------------------------------ boot
async function boot() {
try {
const r = await fetch("/api/meta");
META = await r.json();
} catch (e) {
$("#count").textContent = "Couldn't reach the server. Refresh the page to try again.";
return;
}
if (!META.collection_enabled) Telemetry.setEnabled(false);
const H = META.hardware;
const gpuOptions = () => [
...H.gpu_groups.map(([label, names]) => el("optgroup", { label }, ...names.map((n) => el("option", { value: n }, `${n.replace(/^(NVIDIA|AMD|Intel) /, "")} (${H.gpus[n]} GB)`)))),
el("option", { value: "custom" }, "Other: enter VRAM")];
$("#gpu").replaceChildren(...gpuOptions());
$("#gpu").value = "NVIDIA RTX 3090";
$("#gpu2").replaceChildren(...gpuOptions());
$("#gpu2").value = "NVIDIA RTX 3060 12GB";
$("#gpu-count").replaceChildren(...[1, 2, 3, 4, 6, 8].map((n) => el("option", { value: n }, n)));
$("#gpu2-count").replaceChildren(...[1, 2, 3, 4, 6, 8].map((n) => el("option", { value: n }, n)));
$("#ram").replaceChildren(...H.ram.map((v) => el("option", { value: v }, `${v} GB`)));
$("#ram").value = 64;
$("#unified-system").replaceChildren(...Object.keys(H.unified).map((n) => el("option", { value: n }, n)));
$("#context").replaceChildren(...H.contexts.map((c) => el("option", { value: c }, `${ctxLabel(c)} tokens`)));
$("#context").value = 16384;
$("#family").append(...META.families.map((f) => el("option", { value: f.family }, `${f.family} (${f.count})`)));
$("#size").append(...META.sizes.map((s) => el("option", { value: s }, s)));
const saved = store.get("lme-rig");
if (saved) {
const set = (sel, v) => { if (v !== undefined && v !== null && [...$(sel).options].some((o) => o.value === String(v))) $(sel).value = v; };
const kindInput = $(`input[name="kind"][value="${saved.kind}"]`);
if (kindInput) kindInput.checked = true;
set("#gpu", saved.gpu); set("#gpu-count", saved.count); set("#ram", saved.ram); set("#unified-system", saved.usys);
set("#context", saved.context); set("#kv", saved.kv); set("#min-bits", saved.minBits); set("#mmproj", saved.mmproj);
if (saved.vram) $("#custom-vram").value = saved.vram;
$("#gpu2-block").hidden = !saved.mixed;
set("#gpu2", saved.gpu2); set("#gpu2-count", saved.count2);
if (saved.vram2) $("#custom-vram2").value = saved.vram2;
const pr = $(`input[name="priority"][value="${saved.priority}"]`);
if (pr) pr.checked = true;
$("#fits-only").checked = !!saved.fits;
$("#vram-only").checked = !!saved.vramOnly;
syncKind();
set("#unified-mem", saved.umem);
} else {
syncKind();
detectHint();
}
renderCapacity();
$("#rig").addEventListener("change", () => { $("#detect-hint").hidden = true; syncKind(); saveRig(); schedule(); });
$("#custom-vram").addEventListener("input", () => { renderCapacity(); saveRig(); schedule(); });
$("#custom-vram2").addEventListener("input", () => { renderCapacity(); saveRig(); schedule(); });
$("#gpu2-toggle").addEventListener("click", () => {
$("#gpu2-block").hidden = !$("#gpu2-block").hidden;
syncKind(); saveRig(); schedule();
});
$("#filters").addEventListener("change", schedule);
$("#filters").addEventListener("submit", (e) => { e.preventDefault(); search(false); });
$("#search").addEventListener("input", schedule);
$("#more").addEventListener("click", () => search(true));
$("#d-close").addEventListener("click", () => $("#detail").close());
$("#detail").addEventListener("click", (e) => { if (e.target === $("#detail")) $("#detail").close(); });
$("#detail").addEventListener("close", () => { state.detailKey = null; });
const opt = $("#optout");
opt.checked = Telemetry.optedOut;
if (Telemetry.gpc) $("#gpc-note").hidden = false;
opt.addEventListener("change", () => Telemetry.setOptOut(opt.checked));
Telemetry.setBuilder(() => {
if (!META) return null;
const r = rig();
const q = query();
return {
...hardwareFields(), browser_family: browserFamily(), os_family: osFamily(), webgpu_vendor: DETECTED.vendor,
model_family: q.family, size_bucket: q.size, context: q.context, kv_type: q.kv_type, priority: q.priority, min_bits: q.min_bits,
sort: q.sort, fits_only: q.fits_only, result_count: visit.lastResults, families_searched: [...visit.families].slice(0, 5),
distinct_queries: visit.queries.size, searched: visit.searched,
top_model: visit.top && visit.top.key, top_quant: visit.top && visit.top.quant, top_fit: visit.top && visit.top.fit,
models_viewed: visit.viewed.slice(0, 10), repos_clicked: visit.clicked.slice(0, 5), commands_copied: [...visit.copied],
hardware_source: r.kind === "gpu" && customCard() ? "custom" : "preset",
};
});
search(false);
}
const DETECTED = { vendor: null };
async function detectHint() {
// Only a hint: browsers can't tell how much VRAM or memory there is.
try {
const plat = (navigator.userAgentData && navigator.userAgentData.platform) || navigator.platform || "";
if (/mac/i.test(plat)) {
$('input[name="kind"][value="unified"]').checked = true;
syncKind();
const h = $("#detect-hint");
h.hidden = false;
h.textContent = "This looks like a Mac. Set your memory size: browsers can't read it.";
}
if (navigator.gpu) {
const a = await navigator.gpu.requestAdapter();
const v = a && a.info && a.info.vendor;
if (v && /^[a-z0-9 ._+-]{1,24}$/i.test(v)) DETECTED.vendor = v.toLowerCase();
}
} catch (e) {}
}
function browserFamily() {
const ua = navigator.userAgent;
if (/Edg\//.test(ua)) return "edge";
if (/Firefox\//.test(ua)) return "firefox";
if (/Chrome\//.test(ua)) return "chrome";
if (/Safari\//.test(ua)) return "safari";
return "other";
}
function osFamily() {
const ua = navigator.userAgent;
if (/iPhone|iPad/.test(ua)) return "ios";
if (/Android/.test(ua)) return "android";
if (/Mac OS X/.test(ua)) return "macos";
if (/Windows/.test(ua)) return "windows";
if (/Linux/.test(ua)) return "linux";
return "other";
}
boot();
})();