spl16 commited on
Commit
62fdf7e
·
1 Parent(s): cbc3392

llama serve rename, 3-bit default floor, blank dominated warnings, band-worst heuristics, hide non-fits on best-sort

Browse files
Files changed (3) hide show
  1. fork.js +13 -3
  2. index.html +2 -2
  3. rankQuants.js +9 -9
fork.js CHANGED
@@ -6,7 +6,7 @@
6
  const API = "https://codelion-local-model-explorer.hf.space";
7
  const $ = (s, r = document) => r.querySelector(s);
8
  const $$ = (s, r = document) => [...r.querySelectorAll(s)];
9
- let META = null, SCORES = null, runId = 0, offset = 0, total = 0;
10
 
11
  function el(tag, cls, text) {
12
  const n = document.createElement(tag);
@@ -59,7 +59,7 @@ function query(append) {
59
  sort: $("#sort").value, family: $("#family").value || null, size: $("#size").value || null,
60
  search: $("#search").value.trim() || null,
61
  moe_only: $("#moe-only").checked, vision_only: $("#vision-only").checked,
62
- fits_only: $("#fits-only").checked,
63
  vram_only: r.kind === "gpu" && $("#vram-only").checked, mmproj: $("#mmproj").value,
64
  offset: append ? offset : 0, limit: 24,
65
  };
@@ -147,7 +147,8 @@ function renderDetail(m, body) {
147
  if (sel && sel.commands) {
148
  const row = el("div", "row");
149
  const copy = el("button", "btn ghost", "Copy command");
150
- const pre = el("pre", "cmd", sel.commands["llama.cpp"]);
 
151
  copy.addEventListener("click", async () => {
152
  try { await navigator.clipboard.writeText(pre.textContent); copy.textContent = "Copied"; }
153
  catch { copy.textContent = "Select and copy"; }
@@ -360,6 +361,10 @@ async function search(append) {
360
  $("#count").textContent = `${total.toLocaleString()} models`;
361
  $("#more").hidden = offset >= total;
362
  const r = rig();
 
 
 
 
363
 
364
  for (const m of res.results) {
365
  const ui = card(m);
@@ -395,6 +400,9 @@ async function search(append) {
395
  if (hr) ui.status.append(el("div", "muted", hr));
396
  const railEl = rail(pick.fit, r);
397
  if (railEl) ui.status.append(railEl);
 
 
 
398
  } else {
399
  ui.status.textContent = warnings[0] || "Doesn't fit this hardware.";
400
  }
@@ -405,6 +413,8 @@ async function search(append) {
405
  }
406
  }
407
  await Promise.all(Array.from({ length: 4 }, worker));
 
 
408
  }
409
 
410
  let deb;
 
6
  const API = "https://codelion-local-model-explorer.hf.space";
7
  const $ = (s, r = document) => r.querySelector(s);
8
  const $$ = (s, r = document) => [...r.querySelectorAll(s)];
9
+ let META = null, SCORES = null, runId = 0, offset = 0, total = 0, nofitDropped = 0;
10
 
11
  function el(tag, cls, text) {
12
  const n = document.createElement(tag);
 
59
  sort: $("#sort").value, family: $("#family").value || null, size: $("#size").value || null,
60
  search: $("#search").value.trim() || null,
61
  moe_only: $("#moe-only").checked, vision_only: $("#vision-only").checked,
62
+ fits_only: $("#fits-only").checked || $("#sort").value === "best",
63
  vram_only: r.kind === "gpu" && $("#vram-only").checked, mmproj: $("#mmproj").value,
64
  offset: append ? offset : 0, limit: 24,
65
  };
 
147
  if (sel && sel.commands) {
148
  const row = el("div", "row");
149
  const copy = el("button", "btn ghost", "Copy command");
150
+ // upstream still emits the old `llama-server` binary name; current llama.cpp renamed it.
151
+ const pre = el("pre", "cmd", (sel.commands["llama.cpp"] || "").replace(/llama-server/g, "llama serve"));
152
  copy.addEventListener("click", async () => {
153
  try { await navigator.clipboard.writeText(pre.textContent); copy.textContent = "Copied"; }
154
  catch { copy.textContent = "Select and copy"; }
 
361
  $("#count").textContent = `${total.toLocaleString()} models`;
362
  $("#more").hidden = offset >= total;
363
  const r = rig();
364
+ // best-sort promises fitting models, so non-fits are filtered server-side
365
+ // (fits_only above) and dropped client-side (headroom residuals) below.
366
+ const bestSort = q.sort === "best";
367
+ if (!append) nofitDropped = 0;
368
 
369
  for (const m of res.results) {
370
  const ui = card(m);
 
400
  if (hr) ui.status.append(el("div", "muted", hr));
401
  const railEl = rail(pick.fit, r);
402
  if (railEl) ui.status.append(railEl);
403
+ } else if (bestSort) {
404
+ ui.c.remove();
405
+ nofitDropped++;
406
  } else {
407
  ui.status.textContent = warnings[0] || "Doesn't fit this hardware.";
408
  }
 
413
  }
414
  }
415
  await Promise.all(Array.from({ length: 4 }, worker));
416
+ if (alive() && bestSort) $("#count").textContent =
417
+ `${(total - nofitDropped).toLocaleString()} models that fit your hardware`;
418
  }
419
 
420
  let deb;
index.html CHANGED
@@ -103,7 +103,7 @@
103
  <option value="q4_0">4-bit (q4_0) — bench: small KL cost</option>
104
  </select></div>
105
  <div class="field"><label for="mmproj">Vision projector (vision models)</label><select id="mmproj">
106
- <option value="gpu">On the GPU, llama-server default</option>
107
  <option value="ram">In system RAM (--no-mmproj-offload)</option>
108
  <option value="off">Don't load it, text only (--no-mmproj)</option>
109
  </select></div>
@@ -122,7 +122,7 @@
122
  <div class="field"><label for="min-bits">Lowest quant to consider</label><select id="min-bits">
123
  <option value="0">Any, down to 1-bit</option>
124
  <option value="2">2-bit and up</option>
125
- <option value="3">3-bit and up</option>
126
  <option value="4">4-bit and up (Q4, IQ4, MXFP4)</option>
127
  <option value="5">5-bit and up</option>
128
  <option value="6">6-bit and up</option>
 
103
  <option value="q4_0">4-bit (q4_0) — bench: small KL cost</option>
104
  </select></div>
105
  <div class="field"><label for="mmproj">Vision projector (vision models)</label><select id="mmproj">
106
+ <option value="gpu">On the GPU, llama serve default</option>
107
  <option value="ram">In system RAM (--no-mmproj-offload)</option>
108
  <option value="off">Don't load it, text only (--no-mmproj)</option>
109
  </select></div>
 
122
  <div class="field"><label for="min-bits">Lowest quant to consider</label><select id="min-bits">
123
  <option value="0">Any, down to 1-bit</option>
124
  <option value="2">2-bit and up</option>
125
+ <option value="3" selected>3-bit and up</option>
126
  <option value="4">4-bit and up (Q4, IQ4, MXFP4)</option>
127
  <option value="5">5-bit and up</option>
128
  <option value="6">6-bit and up</option>
rankQuants.js CHANGED
@@ -7,8 +7,8 @@
7
  * recommend/model handlers; fit estimation stays untouched.
8
  *
9
  * Single mode: best measured quality that sits fully on the hardware
10
- * wins, with warnings when nothing fits fully / only sub-4-bit fits /
11
- * the pick is a legacy format. no band caps: if Q8_0 fits, it wins.
12
  *
13
  * Fit awareness: full offloads (tier gpu/gpu_moe/cpu/unified/ram) always
14
  * outrank partial ones. A partial "quality" pick (e.g. 12 of 64 layers on
@@ -52,11 +52,14 @@ function scoreMap(scoresJson) {
52
  // measurement; ties break measured-first in the sort below.
53
  function classifyUnknown(quant) {
54
  const q = quant.toUpperCase();
55
- if (/Q4_0|Q4_1|Q3_K_S|Q3_K_M|Q5_K_S|Q4_K_S|Q4_K_L|Q5_0|Q3_0/.test(q)) return ["avoid", 0.10];
 
 
 
56
  const bit = q.match(/(\d(\.\d)?)\s*BIT/);
57
- if (bit) return parseFloat(bit[1]) < 4 ? ["emergency", 0.50] : ["tight", 0.1166];
58
- if (/IQ1|1BIT|_I1|TERNARY|Q1(?!\d)/.test(q)) return ["emergency", 0.60];
59
- if (/Q2|IQ2/.test(q)) return ["emergency", 0.40];
60
  if (/IQ3|Q3/.test(q)) return ["tight", 0.1166];
61
  if (/Q4|IQ4|MXFP4/.test(q)) return ["default", 0.0541];
62
  if (/Q5|Q6/.test(q)) return ["step", 0.0118];
@@ -164,9 +167,6 @@ function rankOptions(options, family, scoresJson) {
164
 
165
  // best measured quality that fits. no band caps.
166
  let pick = byKlThenPub(cands, family)[0];
167
- if (pick.band === "avoid") {
168
- warnings.push(`legacy pick: ${pick.quant} is an outdated format — nothing better in this repo`);
169
- }
170
 
171
  const ranked = byKlThenPub(cands, family);
172
  const twins = cands.filter((o) => o.quant.toUpperCase() === pick.quant.toUpperCase());
 
7
  * recommend/model handlers; fit estimation stays untouched.
8
  *
9
  * Single mode: best measured quality that sits fully on the hardware
10
+ * wins, with warnings when nothing fits fully / only sub-4-bit fits.
11
+ * no band caps: if Q8_0 fits, it wins.
12
  *
13
  * Fit awareness: full offloads (tier gpu/gpu_moe/cpu/unified/ram) always
14
  * outrank partial ones. A partial "quality" pick (e.g. 12 of 64 layers on
 
52
  // measurement; ties break measured-first in the sort below.
53
  function classifyUnknown(quant) {
54
  const q = quant.toUpperCase();
55
+ // heuristic kl must equal the WORST measured kl in its band (avoid
56
+ // 0.5345 = UD-Q2_K_XL, emergency 1.0 = UD-IQ2_XXS; see quant_scores.json)
57
+ // so a guess never outranks a measurement; ties break measured-first.
58
+ if (/Q4_0|Q4_1|Q3_K_S|Q3_K_M|Q5_K_S|Q4_K_S|Q4_K_L|Q5_0|Q3_0/.test(q)) return ["avoid", 0.5345];
59
  const bit = q.match(/(\d(\.\d)?)\s*BIT/);
60
+ if (bit) return parseFloat(bit[1]) < 4 ? ["emergency", 1.0] : ["tight", 0.1166];
61
+ if (/IQ1|1BIT|_I1|TERNARY|Q1(?!\d)/.test(q)) return ["emergency", 1.0];
62
+ if (/Q2|IQ2/.test(q)) return ["emergency", 1.0];
63
  if (/IQ3|Q3/.test(q)) return ["tight", 0.1166];
64
  if (/Q4|IQ4|MXFP4/.test(q)) return ["default", 0.0541];
65
  if (/Q5|Q6/.test(q)) return ["step", 0.0118];
 
167
 
168
  // best measured quality that fits. no band caps.
169
  let pick = byKlThenPub(cands, family)[0];
 
 
 
170
 
171
  const ranked = byKlThenPub(cands, family);
172
  const twins = cands.filter((o) => o.quant.toUpperCase() === pick.quant.toUpperCase());