Jonna Marie Matthiesen Claude Fable 5 commited on
Commit
c665bdc
Β·
1 Parent(s): 9962162

Default each family's chart to its best-improvement metric

Browse files

A configured chart default_metric (family or global) still wins, and an
explicitly picked metric (button click or #metric= link) is pinned across
family switches. Strip the stale ips defaults from the CV families so the
automatic pick applies there.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AGJFdqmf4AXcsYvb56LLCC

Files changed (4) hide show
  1. app.js +21 -4
  2. config.json +0 -8
  3. speedup.js +46 -2
  4. urlstate.js +2 -1
app.js CHANGED
@@ -410,6 +410,11 @@ const filters = { baseFamily: BASE_FAMILY_KEYS[0] || "", variant: null };
410
  config.filters.forEach(f => { filters[f.column] = ""; });
411
  filters.metric = CHART_CFG.default_metric || config.metrics[0]?.column || "";
412
 
 
 
 
 
 
413
  // ─── Render button groups ─────────────────────────────────────────────────────
414
 
415
  function renderBtnGroup(container, items, activeValue) {
@@ -489,6 +494,7 @@ function handleFilterClick(e) {
489
  btn.classList.add("active");
490
  const key = group.id.replace("filter-", "");
491
  filters[key] = btn.dataset.value;
 
492
  render();
493
  }
494
 
@@ -971,6 +977,7 @@ const urlstate = initUrlState({
971
  config, filters, BASE_FAMILIES, deriveBaseFamily, GROUP_BY,
972
  availableOptions, renderSidebar, updateDependentFilters,
973
  switchBaseFamily, render,
 
974
  });
975
 
976
  // ─── Embed SVG module ────────────────────────────────────────────────────────
@@ -1043,11 +1050,21 @@ async function switchBaseFamily(baseFamilyKey) {
1043
  // Fall back to a metric that has data in this family (e.g. LLM tps vs CV ips)
1044
  const hasData = (col) => DATA.some(r =>
1045
  r[col] !== undefined && r[col] !== null && r[col] !== 0 && r[col] !== "N/A");
 
 
 
 
 
 
 
 
 
 
 
 
 
1046
  if (!hasData(filters.metric)) {
1047
- const familyDefault = config.model_families?.[activeFamilyKey()]?.chart?.default_metric;
1048
- filters.metric = (familyDefault && hasData(familyDefault))
1049
- ? familyDefault
1050
- : (config.metrics.find(m => hasData(m.column))?.column || filters.metric);
1051
  }
1052
  render();
1053
  }
 
410
  config.filters.forEach(f => { filters[f.column] = ""; });
411
  filters.metric = CHART_CFG.default_metric || config.metrics[0]?.column || "";
412
 
413
+ // [speedup] Whether the current metric was chosen explicitly (metric button
414
+ // click or #metric= in a shared link). While unpinned, each family switch
415
+ // re-picks the metric with the best improvement over the baseline.
416
+ let metricPinned = false;
417
+
418
  // ─── Render button groups ─────────────────────────────────────────────────────
419
 
420
  function renderBtnGroup(container, items, activeValue) {
 
494
  btn.classList.add("active");
495
  const key = group.id.replace("filter-", "");
496
  filters[key] = btn.dataset.value;
497
+ if (key === "metric") metricPinned = true; // [speedup] user's explicit pick
498
  render();
499
  }
500
 
 
977
  config, filters, BASE_FAMILIES, deriveBaseFamily, GROUP_BY,
978
  availableOptions, renderSidebar, updateDependentFilters,
979
  switchBaseFamily, render,
980
+ onExplicitMetric: () => { metricPinned = true; }, // [speedup] linked metric wins
981
  });
982
 
983
  // ─── Embed SVG module ────────────────────────────────────────────────────────
 
1050
  // Fall back to a metric that has data in this family (e.g. LLM tps vs CV ips)
1051
  const hasData = (col) => DATA.some(r =>
1052
  r[col] !== undefined && r[col] !== null && r[col] !== 0 && r[col] !== "N/A");
1053
+ // [speedup] Default the chart metric, unless one was picked explicitly
1054
+ // (and still has data here). A configured default_metric β€” the family's
1055
+ // own chart config or the global one, same resolution buildChart uses β€”
1056
+ // overrides the automatic best-improvement-over-baseline pick.
1057
+ if (!hasData(filters.metric)) metricPinned = false;
1058
+ if (!metricPinned) {
1059
+ const chartCfg = config.model_families?.[activeFamilyKey()]?.chart || CHART_CFG;
1060
+ const cfgDefault = chartCfg.default_metric;
1061
+ const pick = (cfgDefault && hasData(cfgDefault))
1062
+ ? cfgDefault
1063
+ : speedup.bestMetric(DATA, metricsWithData(DATA));
1064
+ if (pick) filters.metric = pick;
1065
+ }
1066
  if (!hasData(filters.metric)) {
1067
+ filters.metric = config.metrics.find(m => hasData(m.column))?.column || filters.metric;
 
 
 
1068
  }
1069
  render();
1070
  }
config.json CHANGED
@@ -306,7 +306,6 @@
306
  "data_file": "data/DINOv3-ViT-B16.csv",
307
  "accuracy_url": "https://huggingface.co/embedl/dinov3-quantized-tensorrt",
308
  "chart": {
309
- "default_metric": "ips",
310
  "scenarios": []
311
  },
312
  "default_device": "agx_orin",
@@ -348,7 +347,6 @@
348
  "data_file": "data/SAM-3D-Body.csv",
349
  "accuracy_url": "https://huggingface.co/embedl/sam-3d-body",
350
  "chart": {
351
- "default_metric": "ips",
352
  "scenarios": []
353
  },
354
  "default_device": "l4",
@@ -363,7 +361,6 @@
363
  "data_file": "data/Parakeet-TDT-0.6B-v3.csv",
364
  "accuracy_url": "https://huggingface.co/embedl/parakeet-tdt-0.6b-v3-quantized-tensorrt",
365
  "chart": {
366
- "default_metric": "ips",
367
  "scenarios": []
368
  },
369
  "accuracy_higher_is_better": false,
@@ -379,7 +376,6 @@
379
  "data_file": "data/Chronos-2.csv",
380
  "accuracy_url": "https://huggingface.co/embedl/chronos-2-quantized-trt",
381
  "chart": {
382
- "default_metric": "ips",
383
  "scenarios": [
384
  {
385
  "label": "Context 512",
@@ -407,7 +403,6 @@
407
  "data_file": "data/MobileViT-Small.csv",
408
  "accuracy_url": "https://huggingface.co/embedl/mobilevit-small-quantized",
409
  "chart": {
410
- "default_metric": "ips",
411
  "scenarios": []
412
  },
413
  "default_device": "agx_orin",
@@ -421,7 +416,6 @@
421
  "data_file": "data/all-MiniLM-L6-v2.csv",
422
  "accuracy_url": "https://huggingface.co/embedl/all-MiniLM-L6-v2-quantized-trt",
423
  "chart": {
424
- "default_metric": "ips",
425
  "scenarios": []
426
  },
427
  "default_device": "agx_orin",
@@ -435,7 +429,6 @@
435
  "data_file": "data/paraphrase-multilingual-MiniLM-L12-v2.csv",
436
  "accuracy_url": "https://huggingface.co/embedl/paraphrase-multilingual-MiniLM-L12-v2-quantized-trt",
437
  "chart": {
438
- "default_metric": "ips",
439
  "scenarios": []
440
  },
441
  "default_device": "agx_orin",
@@ -449,7 +442,6 @@
449
  "data_file": "data/RF-DETR-Base.csv",
450
  "accuracy_url": "https://huggingface.co/embedl/rf-detr-base-quantized-tensorrt",
451
  "chart": {
452
- "default_metric": "ips",
453
  "scenarios": []
454
  },
455
  "default_device": "orin_nano_super",
 
306
  "data_file": "data/DINOv3-ViT-B16.csv",
307
  "accuracy_url": "https://huggingface.co/embedl/dinov3-quantized-tensorrt",
308
  "chart": {
 
309
  "scenarios": []
310
  },
311
  "default_device": "agx_orin",
 
347
  "data_file": "data/SAM-3D-Body.csv",
348
  "accuracy_url": "https://huggingface.co/embedl/sam-3d-body",
349
  "chart": {
 
350
  "scenarios": []
351
  },
352
  "default_device": "l4",
 
361
  "data_file": "data/Parakeet-TDT-0.6B-v3.csv",
362
  "accuracy_url": "https://huggingface.co/embedl/parakeet-tdt-0.6b-v3-quantized-tensorrt",
363
  "chart": {
 
364
  "scenarios": []
365
  },
366
  "accuracy_higher_is_better": false,
 
376
  "data_file": "data/Chronos-2.csv",
377
  "accuracy_url": "https://huggingface.co/embedl/chronos-2-quantized-trt",
378
  "chart": {
 
379
  "scenarios": [
380
  {
381
  "label": "Context 512",
 
403
  "data_file": "data/MobileViT-Small.csv",
404
  "accuracy_url": "https://huggingface.co/embedl/mobilevit-small-quantized",
405
  "chart": {
 
406
  "scenarios": []
407
  },
408
  "default_device": "agx_orin",
 
416
  "data_file": "data/all-MiniLM-L6-v2.csv",
417
  "accuracy_url": "https://huggingface.co/embedl/all-MiniLM-L6-v2-quantized-trt",
418
  "chart": {
 
419
  "scenarios": []
420
  },
421
  "default_device": "agx_orin",
 
429
  "data_file": "data/paraphrase-multilingual-MiniLM-L12-v2.csv",
430
  "accuracy_url": "https://huggingface.co/embedl/paraphrase-multilingual-MiniLM-L12-v2-quantized-trt",
431
  "chart": {
 
432
  "scenarios": []
433
  },
434
  "default_device": "agx_orin",
 
442
  "data_file": "data/RF-DETR-Base.csv",
443
  "accuracy_url": "https://huggingface.co/embedl/rf-detr-base-quantized-tensorrt",
444
  "chart": {
 
445
  "scenarios": []
446
  },
447
  "default_device": "orin_nano_super",
speedup.js CHANGED
@@ -1,7 +1,7 @@
1
  // ─── Speedup vs Baseline Column ──────────────────────────────────────────────
2
  //
3
  // Extracted module. Call initSpeedup(deps) from the main app once globals are
4
- // ready. Returns { prepare, headerHtml, cellHtml, metricCol }.
5
  //
6
  // The benchmark data is inherently paired: an external baseline model (e.g.
7
  // meta-llama/Llama-3.2-1B-Instruct) and the optimized embedl variants of it
@@ -45,6 +45,50 @@ function formatRatio(ratio) {
45
  // Per-table state, rebuilt by prepare() before each table is rendered.
46
  let state = null;
47
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  // ─── Pairing ─────────────────────────────────────────────────────────────────
49
 
50
  /**
@@ -128,6 +172,6 @@ function cellHtml(row) {
128
  + `<span class="speedup-val${down}">${formatRatio(ratio)}</span></td>`;
129
  }
130
 
131
- return { prepare, headerHtml, cellHtml, metricCol };
132
 
133
  }
 
1
  // ─── Speedup vs Baseline Column ──────────────────────────────────────────────
2
  //
3
  // Extracted module. Call initSpeedup(deps) from the main app once globals are
4
+ // ready. Returns { prepare, headerHtml, cellHtml, metricCol, bestMetric }.
5
  //
6
  // The benchmark data is inherently paired: an external baseline model (e.g.
7
  // meta-llama/Llama-3.2-1B-Instruct) and the optimized embedl variants of it
 
45
  // Per-table state, rebuilt by prepare() before each table is rendered.
46
  let state = null;
47
 
48
+ // ─── Best metric ─────────────────────────────────────────────────────────────
49
+
50
+ /**
51
+ * The metric whose optimized-vs-baseline improvement is largest across `rows`,
52
+ * so the chart can lead with the model's strongest result (highest speedup,
53
+ * biggest memory/latency reduction, …). Ratios are oriented so that > 1 always
54
+ * means "better than baseline", making metrics directly comparable.
55
+ * @param rows all rows of the loaded family
56
+ * @param metrics candidate metric configs (usually the ones with data)
57
+ * @returns the winning metric column, or null when nothing pairs
58
+ */
59
+ function bestMetric(rows, metrics) {
60
+ if (!ENABLED || !rows || !rows.length) return null;
61
+
62
+ const baselines = {};
63
+ rows.forEach(r => {
64
+ if (!isExternalModel(r[MODEL_COL])) return;
65
+ const k = pairKey(r, KEY_COLS);
66
+ (baselines[k] = baselines[k] || []).push(r);
67
+ });
68
+
69
+ let best = null;
70
+ (metrics || []).forEach(m => {
71
+ const hib = m.higher_is_better !== false;
72
+ let top;
73
+ rows.forEach(r => {
74
+ if (isExternalModel(r[MODEL_COL])) return;
75
+ const cands = baselines[pairKey(r, KEY_COLS)];
76
+ if (!cands || !cands.length) return;
77
+ if (new Set(cands.map(c => c[MODEL_COL])).size > 1) return;
78
+ const b = usable(cands[0][m.column]);
79
+ const o = usable(r[m.column]);
80
+ if (b === undefined || o === undefined) return;
81
+ const ratio = hib ? o / b : b / o;
82
+ if (!isFinite(ratio) || ratio <= 0) return;
83
+ if (top === undefined || ratio > top) top = ratio;
84
+ });
85
+ if (top !== undefined && (!best || top > best.ratio)) {
86
+ best = { column: m.column, ratio: top };
87
+ }
88
+ });
89
+ return best ? best.column : null;
90
+ }
91
+
92
  // ─── Pairing ─────────────────────────────────────────────────────────────────
93
 
94
  /**
 
172
  + `<span class="speedup-val${down}">${formatRatio(ratio)}</span></td>`;
173
  }
174
 
175
+ return { prepare, headerHtml, cellHtml, metricCol, bestMetric };
176
 
177
  }
urlstate.js CHANGED
@@ -18,7 +18,7 @@ function initUrlState(deps) {
18
  const {
19
  config, filters, BASE_FAMILIES, deriveBaseFamily, GROUP_BY,
20
  availableOptions, renderSidebar, updateDependentFilters,
21
- switchBaseFamily, render,
22
  } = deps;
23
 
24
  const ENABLED = config.url_state !== false;
@@ -92,6 +92,7 @@ function applyParams(params) {
92
 
93
  if (params.metric && METRIC_COLS.includes(params.metric)) {
94
  filters.metric = params.metric;
 
95
  }
96
 
97
  pending = {};
 
18
  const {
19
  config, filters, BASE_FAMILIES, deriveBaseFamily, GROUP_BY,
20
  availableOptions, renderSidebar, updateDependentFilters,
21
+ switchBaseFamily, render, onExplicitMetric,
22
  } = deps;
23
 
24
  const ENABLED = config.url_state !== false;
 
92
 
93
  if (params.metric && METRIC_COLS.includes(params.metric)) {
94
  filters.metric = params.metric;
95
+ onExplicitMetric?.(); // a linked metric beats the best-improvement default
96
  }
97
 
98
  pending = {};