lvwerra HF Staff commited on
Commit
79054d7
·
verified ·
1 Parent(s): 0c519b9

Add per-token logprob sparkline under the legend, gradient-stroked to match colormap

Browse files
Files changed (1) hide show
  1. index.html +57 -4
index.html CHANGED
@@ -221,6 +221,10 @@
221
  border-radius: 1px;
222
  }
223
  .legend-row { display: flex; justify-content: space-between; }
 
 
 
 
224
 
225
  ::-webkit-scrollbar { width: 8px; height: 8px; }
226
  ::-webkit-scrollbar-thumb { background: #ccc; border-radius: 4px; }
@@ -299,6 +303,7 @@
299
  <div>token logprob</div>
300
  <div class="legend-bar" id="legend-bar"></div>
301
  <div class="legend-row"><span id="lp-min">—</span><span id="lp-mid">—</span><span id="lp-max">—</span></div>
 
302
  </div>
303
  </div>
304
  </div>
@@ -380,14 +385,62 @@ function updateLegend() {
380
  if (!lpRange) {
381
  minEl.textContent = midEl.textContent = maxEl.textContent = "—";
382
  bar.style.background = "linear-gradient(to right, #d83a2a, #888, #1a1a1a)";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
383
  return;
384
  }
 
385
  const { min, mid, max } = lpRange;
386
- minEl.textContent = min.toFixed(1);
387
- midEl.textContent = mid.toFixed(1);
388
- maxEl.textContent = max.toFixed(1);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
389
  const midPct = max > min ? ((mid - min) / (max - min)) * 100 : 50;
390
- bar.style.background = `linear-gradient(to right, #d83a2a 0%, #888 ${midPct.toFixed(1)}%, #1a1a1a 100%)`;
 
 
 
 
 
 
 
 
 
 
391
  }
392
  function logprobRgb(lp) {
393
  if (lp == null || isNaN(lp) || !lpRange) return DARK_RGB;
 
221
  border-radius: 1px;
222
  }
223
  .legend-row { display: flex; justify-content: space-between; }
224
+ .lp-chart {
225
+ display: block; width: 100%; height: 40px;
226
+ margin-top: 8px;
227
+ }
228
 
229
  ::-webkit-scrollbar { width: 8px; height: 8px; }
230
  ::-webkit-scrollbar-thumb { background: #ccc; border-radius: 4px; }
 
303
  <div>token logprob</div>
304
  <div class="legend-bar" id="legend-bar"></div>
305
  <div class="legend-row"><span id="lp-min">—</span><span id="lp-mid">—</span><span id="lp-max">—</span></div>
306
+ <svg id="lp-chart" class="lp-chart" preserveAspectRatio="none"></svg>
307
  </div>
308
  </div>
309
  </div>
 
385
  if (!lpRange) {
386
  minEl.textContent = midEl.textContent = maxEl.textContent = "—";
387
  bar.style.background = "linear-gradient(to right, #d83a2a, #888, #1a1a1a)";
388
+ } else {
389
+ const { min, mid, max } = lpRange;
390
+ minEl.textContent = min.toFixed(1);
391
+ midEl.textContent = mid.toFixed(1);
392
+ maxEl.textContent = max.toFixed(1);
393
+ const midPct = max > min ? ((mid - min) / (max - min)) * 100 : 50;
394
+ bar.style.background = `linear-gradient(to right, #d83a2a 0%, #888 ${midPct.toFixed(1)}%, #1a1a1a 100%)`;
395
+ }
396
+ updateLpChart();
397
+ }
398
+
399
+ function updateLpChart() {
400
+ const svg = document.getElementById("lp-chart");
401
+ if (!svg) return;
402
+ if (!lpRange || genTokens.length < 2) {
403
+ svg.innerHTML = "";
404
  return;
405
  }
406
+ const W = 200, H = 40, pad = 2;
407
  const { min, mid, max } = lpRange;
408
+ const yTop = pad, yBot = H - pad;
409
+ const yScale = (lp) => yTop + (1 - (lp - min) / Math.max(1e-9, max - min)) * (yBot - yTop);
410
+
411
+ // Subsample to ~W points so the path stays cheap to draw at long sequences.
412
+ const n = genTokens.length;
413
+ const step = Math.max(1, Math.ceil(n / W));
414
+ const xScale = (i) => (n === 1 ? W / 2 : pad + (i / (n - 1)) * (W - 2 * pad));
415
+
416
+ let d = "";
417
+ let started = false;
418
+ for (let i = 0; i < n; i += step) {
419
+ const lp = genTokens[i].logprob;
420
+ if (lp == null || isNaN(lp)) continue;
421
+ d += (started ? "L" : "M") + xScale(i).toFixed(1) + " " + yScale(lp).toFixed(1);
422
+ started = true;
423
+ }
424
+ // Always anchor the very last token, even if subsampling skipped it.
425
+ if ((n - 1) % step !== 0) {
426
+ const lp = genTokens[n - 1].logprob;
427
+ if (lp != null && !isNaN(lp)) {
428
+ d += "L" + xScale(n - 1).toFixed(1) + " " + yScale(lp).toFixed(1);
429
+ }
430
+ }
431
+
432
  const midPct = max > min ? ((mid - min) / (max - min)) * 100 : 50;
433
+ svg.setAttribute("viewBox", `0 0 ${W} ${H}`);
434
+ svg.innerHTML = `
435
+ <defs>
436
+ <linearGradient id="lp-grad" gradientUnits="userSpaceOnUse" x1="0" y1="${yBot}" x2="0" y2="${yTop}">
437
+ <stop offset="0%" stop-color="#d83a2a"/>
438
+ <stop offset="${midPct.toFixed(1)}%" stop-color="#888"/>
439
+ <stop offset="100%" stop-color="#1a1a1a"/>
440
+ </linearGradient>
441
+ </defs>
442
+ <path d="${d}" fill="none" stroke="url(#lp-grad)" stroke-width="1.2" stroke-linejoin="round" stroke-linecap="round"/>
443
+ `;
444
  }
445
  function logprobRgb(lp) {
446
  if (lp == null || isNaN(lp) || !lpRange) return DARK_RGB;