joelniklaus HF Staff commited on
Commit
d6bc164
Β·
1 Parent(s): 5df08f8

made various improvements to the verbosity plot

Browse files
Files changed (1) hide show
  1. app/src/content/embeds/verbosity.html +101 -72
app/src/content/embeds/verbosity.html CHANGED
@@ -1,4 +1,4 @@
1
- <div class="d3-verbosity" style="width:100%;margin:10px 0;aspect-ratio:3/1;min-height:260px;"></div>
2
  <script>
3
  (() => {
4
  const ensureD3 = (cb) => {
@@ -98,6 +98,9 @@
98
  outEdu: d.output_edu_score,
99
  inEdu: d.input_edu_score,
100
  compPerDoc: d.output_token_count_mean,
 
 
 
101
  phase: Math.random() * Math.PI * 2
102
  };
103
  });
@@ -106,12 +109,12 @@
106
  // MODEL FAMILIES
107
  // ═══════════════════════════════════════════════════════════
108
  const familyColors = {
109
- 'Gemma': '#4EA5B7',
110
- 'Qwen': '#8B7BE8',
111
- 'SmolLM2': '#E8C44A',
112
- 'Falcon': '#E889AB',
113
- 'Granite': '#5BC0A4',
114
- 'Llama': '#D09090',
115
  };
116
  const familyOrder = ['Gemma','Qwen','SmolLM2','Falcon','Granite','Llama'];
117
 
@@ -145,9 +148,11 @@
145
  `<span style="display:inline-block;width:8px;height:8px;border-radius:50%;background:${familyColors[d.family]};margin-right:4px;vertical-align:middle;"></span>` +
146
  `${d.model} \u00b7 ${d.source}</div>` +
147
  `<div style="padding-top:5px;border-top:1px solid var(--border-color);display:grid;grid-template-columns:auto 1fr;gap:2px 8px;font-size:11.5px;">` +
148
- `<span style="color:var(--muted-color);">Total output</span><span>${fmtB(d.compTokens)}</span>` +
149
  `<span style="color:var(--muted-color);">Output/doc</span><span>${Math.round(d.compPerDoc)} tokens</span>` +
 
150
  `<span style="color:var(--muted-color);">Docs</span><span>${d.numDocs.toFixed(1)}M</span>` +
 
151
  `</div>` +
152
  `<div style="margin-top:5px;padding-top:5px;border-top:1px solid var(--border-color);display:grid;grid-template-columns:auto 1fr;gap:2px 8px;font-size:11.5px;">` +
153
  `<span style="color:var(--muted-color);">DCLM</span>` +
@@ -168,38 +173,40 @@
168
 
169
  const render = () => {
170
  const width = container.clientWidth || 800;
171
- const height = Math.max(260, Math.round(width / 3));
172
  svg.attr('width', width).attr('height', height);
173
 
174
  const isDark = document.documentElement.getAttribute('data-theme') === 'dark';
175
- const textColor = isDark ? 'rgba(255,255,255,0.72)' : 'rgba(0,0,0,0.62)';
176
- const mutedText = isDark ? 'rgba(255,255,255,0.22)' : 'rgba(0,0,0,0.18)';
177
- const subtleText = isDark ? 'rgba(255,255,255,0.12)' : 'rgba(0,0,0,0.08)';
178
  const refLine = isDark ? 'rgba(255,255,255,0.10)' : 'rgba(0,0,0,0.07)';
179
  const bandEven = isDark ? 'rgba(255,255,255,0.022)' : 'rgba(0,0,0,0.018)';
180
  const glowColor = isDark ? 'rgba(255,255,255,0.35)' : 'rgba(0,0,0,0.25)';
181
- const smolHighlight = isDark ? 'rgba(232,196,74,0.18)' : 'rgba(232,196,74,0.12)';
182
 
183
- const fontSize = Math.max(8, Math.min(12, width / 80));
184
 
185
  // ─── LAYOUT ───
186
- const labelW = Math.max(68, width * 0.085);
187
- const pl = labelW + 12;
188
- const pr = width * 0.965;
189
- const pt = height * 0.20;
190
- const pb = height * 0.86;
191
  const plotH = pb - pt;
192
  const rowH = plotH / sortedPrompts.length;
193
 
194
  const rowCenter = {};
195
  sortedPrompts.forEach((p, i) => { rowCenter[p] = pt + (i + 0.5) * rowH; });
196
 
197
- // ─── X SCALE: completion tokens per document (log) ───
198
- const xScale = d3.scaleLog().base(10)
199
- .domain([15, 1000])
 
 
 
200
  .range([pl, pr]);
201
 
202
- const rBase = Math.max(3.5, Math.min(8, width * 0.007));
203
 
204
  // ─── FORCE SIMULATION ───
205
  filtered.forEach(d => {
@@ -260,23 +267,13 @@
260
  .attr('stroke', refLine).attr('stroke-width', 0.5);
261
  }
262
 
263
- // SmolLM2 highlight zone
264
- const smolExp = filtered.filter(d => d.prompt === p && d.family === 'SmolLM2');
265
- if (smolExp.length) {
266
- const smolX = smolExp[0].x;
267
- gRows.append('rect')
268
- .attr('x', smolX - rBase * 2.5).attr('y', y - rowH * 0.42)
269
- .attr('width', rBase * 5).attr('height', rowH * 0.84)
270
- .attr('fill', smolHighlight).attr('rx', rBase * 2);
271
- }
272
-
273
  // Label
274
  gRows.append('text')
275
  .attr('x', pl - 10).attr('y', y)
276
  .attr('text-anchor', 'end')
277
  .attr('dominant-baseline', 'central')
278
  .attr('fill', textColor)
279
- .attr('font-size', fontSize + 'px')
280
  .attr('font-weight', '700')
281
  .attr('font-family', 'system-ui, -apple-system, sans-serif')
282
  .attr('letter-spacing', '-0.2px')
@@ -287,19 +284,19 @@
287
  const gRef = svg.selectAll('g.ref').data([0]).join('g').attr('class', 'ref');
288
  gRef.selectAll('*').remove();
289
 
290
- [20, 50, 100, 200, 500].forEach(v => {
291
  const x = xScale(v);
292
- if (x > pl && x < pr) {
293
  gRef.append('line')
294
  .attr('x1', x).attr('x2', x)
295
- .attr('y1', pb).attr('y2', pb + 3)
296
  .attr('stroke', mutedText).attr('stroke-width', 0.7);
297
  gRef.append('text')
298
- .attr('x', x).attr('y', pb + 5)
299
  .attr('text-anchor', 'middle')
300
  .attr('dominant-baseline', 'hanging')
301
  .attr('fill', mutedText)
302
- .attr('font-size', (fontSize * 0.65) + 'px')
303
  .attr('font-family', 'system-ui, -apple-system, sans-serif')
304
  .text(v);
305
  gRef.append('line')
@@ -310,58 +307,90 @@
310
  }
311
  });
312
 
313
- // Axis label
 
314
  gRef.append('text')
315
- .attr('x', pr).attr('y', pb + 16)
316
- .attr('text-anchor', 'end')
317
  .attr('fill', mutedText)
318
- .attr('font-size', (fontSize * 0.72) + 'px')
319
  .attr('font-weight', '600')
320
  .attr('font-family', 'system-ui, -apple-system, sans-serif')
321
- .text('Output tokens / document \u2192');
322
 
323
- // "concise" / "verbose" labels
324
  gRef.append('text')
325
- .attr('x', pl + 6).attr('y', pt - 5)
326
- .attr('text-anchor', 'start')
327
  .attr('fill', subtleText)
328
- .attr('font-size', (fontSize * 0.62) + 'px')
329
  .attr('font-style', 'italic')
330
  .attr('font-family', 'system-ui, -apple-system, sans-serif')
331
  .text('\u2190 concise');
332
 
333
  gRef.append('text')
334
- .attr('x', pr - 6).attr('y', pt - 5)
335
- .attr('text-anchor', 'end')
336
  .attr('fill', subtleText)
337
- .attr('font-size', (fontSize * 0.62) + 'px')
338
  .attr('font-style', 'italic')
339
  .attr('font-family', 'system-ui, -apple-system, sans-serif')
340
  .text('verbose \u2192');
341
 
 
342
  // ─── MODEL FAMILY LEGEND ───
343
  const gLeg = svg.selectAll('g.legend').data([0]).join('g').attr('class', 'legend');
344
  gLeg.selectAll('*').remove();
345
- const legDotR = Math.max(3, fontSize * 0.35);
346
- const legGap = Math.max(68, width * 0.082);
347
- const totalLegW = familyOrder.length * legGap;
348
- const legStartX = Math.max(pl, (width - totalLegW) / 2);
349
- const legY = height * 0.055;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
350
 
 
351
  familyOrder.forEach((fam, i) => {
352
- const lx = legStartX + i * legGap;
353
- gLeg.append('circle')
354
  .attr('cx', lx).attr('cy', legY)
355
  .attr('r', legDotR)
356
  .attr('fill', familyColors[fam]).attr('fill-opacity', 0.85);
357
- gLeg.append('text')
358
- .attr('x', lx + legDotR + 4).attr('y', legY)
359
  .attr('dominant-baseline', 'central')
360
- .attr('fill', isDark ? 'rgba(255,255,255,0.48)' : 'rgba(0,0,0,0.42)')
361
- .attr('font-size', (fontSize * 0.72) + 'px')
362
- .attr('font-weight', fam === 'SmolLM2' ? '700' : '500')
363
  .attr('font-family', 'system-ui, -apple-system, sans-serif')
364
  .text(fam);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
365
  });
366
 
367
  // ─── TOOLTIP ───
@@ -401,10 +430,10 @@
401
  const gDots = svg.selectAll('g.dots').data([0]).join('g').attr('class', 'dots');
402
 
403
  const handleEnter = function (ev, d) {
404
- gDots.selectAll('circle').attr('fill-opacity', 0.12).attr('stroke-opacity', 0.05);
405
  gDots.selectAll('circle')
406
  .filter(c => c.family === d.family)
407
- .attr('fill-opacity', 0.60).attr('stroke-opacity', 0.4);
408
  d3.select(this)
409
  .raise()
410
  .attr('fill-opacity', 1)
@@ -426,7 +455,7 @@
426
  const handleLeave = function () {
427
  gDots.selectAll('circle')
428
  .attr('fill-opacity', 0.82)
429
- .attr('stroke-opacity', 0.30);
430
  d3.select(this)
431
  .style('filter', null)
432
  .transition().duration(90).ease(d3.easeCubicOut)
@@ -442,9 +471,9 @@
442
  .attr('r', rBase)
443
  .attr('fill', d => familyColors[d.family] || '#aaa')
444
  .attr('fill-opacity', 0.82)
445
- .attr('stroke', d => d.family === 'SmolLM2' ? '#fff' : (familyColors[d.family] || '#aaa'))
446
- .attr('stroke-width', d => d.family === 'SmolLM2' ? 1.5 : 0.9)
447
- .attr('stroke-opacity', d => d.family === 'SmolLM2' ? 0.5 : 0.30)
448
  .on('mouseenter', handleEnter)
449
  .on('mousemove', handleMove)
450
  .on('mouseleave', handleLeave),
@@ -453,9 +482,9 @@
453
  .attr('r', rBase)
454
  .attr('fill', d => familyColors[d.family] || '#aaa')
455
  .attr('fill-opacity', 0.82)
456
- .attr('stroke', d => d.family === 'SmolLM2' ? '#fff' : (familyColors[d.family] || '#aaa'))
457
- .attr('stroke-width', d => d.family === 'SmolLM2' ? 1.5 : 0.9)
458
- .attr('stroke-opacity', d => d.family === 'SmolLM2' ? 0.5 : 0.30)
459
  .on('mouseenter', handleEnter)
460
  .on('mousemove', handleMove)
461
  .on('mouseleave', handleLeave)
 
1
+ <div class="d3-verbosity" style="width:100%;margin:10px 0;aspect-ratio:2.2/1;min-height:320px;"></div>
2
  <script>
3
  (() => {
4
  const ensureD3 = (cb) => {
 
98
  outEdu: d.output_edu_score,
99
  inEdu: d.input_edu_score,
100
  compPerDoc: d.output_token_count_mean,
101
+ inputPerDoc: d.input_token_count_mean,
102
+ tokenReduction: d.token_reduction_mean,
103
+ compressionRatio: d.compression_ratio,
104
  phase: Math.random() * Math.PI * 2
105
  };
106
  });
 
109
  // MODEL FAMILIES
110
  // ═══════════════════════════════════════════════════════════
111
  const familyColors = {
112
+ 'Gemma': '#5b9bd5',
113
+ 'Qwen': '#e07b54',
114
+ 'SmolLM2': '#e06b9e',
115
+ 'Falcon': '#c9a046',
116
+ 'Granite': '#9a8ec2',
117
+ 'Llama': '#8bc474',
118
  };
119
  const familyOrder = ['Gemma','Qwen','SmolLM2','Falcon','Granite','Llama'];
120
 
 
148
  `<span style="display:inline-block;width:8px;height:8px;border-radius:50%;background:${familyColors[d.family]};margin-right:4px;vertical-align:middle;"></span>` +
149
  `${d.model} \u00b7 ${d.source}</div>` +
150
  `<div style="padding-top:5px;border-top:1px solid var(--border-color);display:grid;grid-template-columns:auto 1fr;gap:2px 8px;font-size:11.5px;">` +
151
+ `<span style="color:var(--muted-color);">Input/doc</span><span>${Math.round(d.inputPerDoc)} tokens</span>` +
152
  `<span style="color:var(--muted-color);">Output/doc</span><span>${Math.round(d.compPerDoc)} tokens</span>` +
153
+ `<span style="color:var(--muted-color);">Reduction</span><span>${Math.round(d.tokenReduction)} tokens (${(d.compressionRatio * 100).toFixed(0)}% ratio)</span>` +
154
  `<span style="color:var(--muted-color);">Docs</span><span>${d.numDocs.toFixed(1)}M</span>` +
155
+ `<span style="color:var(--muted-color);">Total output</span><span>${fmtB(d.compTokens)}</span>` +
156
  `</div>` +
157
  `<div style="margin-top:5px;padding-top:5px;border-top:1px solid var(--border-color);display:grid;grid-template-columns:auto 1fr;gap:2px 8px;font-size:11.5px;">` +
158
  `<span style="color:var(--muted-color);">DCLM</span>` +
 
173
 
174
  const render = () => {
175
  const width = container.clientWidth || 800;
176
+ const height = Math.max(320, Math.round(width / 2.2));
177
  svg.attr('width', width).attr('height', height);
178
 
179
  const isDark = document.documentElement.getAttribute('data-theme') === 'dark';
180
+ const textColor = isDark ? 'rgba(255,255,255,0.82)' : 'rgba(0,0,0,0.72)';
181
+ const mutedText = isDark ? 'rgba(255,255,255,0.40)' : 'rgba(0,0,0,0.35)';
182
+ const subtleText = isDark ? 'rgba(255,255,255,0.20)' : 'rgba(0,0,0,0.15)';
183
  const refLine = isDark ? 'rgba(255,255,255,0.10)' : 'rgba(0,0,0,0.07)';
184
  const bandEven = isDark ? 'rgba(255,255,255,0.022)' : 'rgba(0,0,0,0.018)';
185
  const glowColor = isDark ? 'rgba(255,255,255,0.35)' : 'rgba(0,0,0,0.25)';
 
186
 
187
+ const fontSize = Math.max(12, Math.min(15, width / 45));
188
 
189
  // ─── LAYOUT ───
190
+ const labelW = Math.max(70, width * 0.08);
191
+ const pl = labelW + 10;
192
+ const pr = width - 4;
193
+ const pt = fontSize * 2.8;
194
+ const pb = height - fontSize * 5;
195
  const plotH = pb - pt;
196
  const rowH = plotH / sortedPrompts.length;
197
 
198
  const rowCenter = {};
199
  sortedPrompts.forEach((p, i) => { rowCenter[p] = pt + (i + 0.5) * rowH; });
200
 
201
+ // ─── X SCALE: linear ───
202
+ const allVals = filtered.map(d => d.compPerDoc);
203
+ const xMin = Math.min(150, d3.min(allVals) - 50);
204
+ const xMax = Math.max(1150, d3.max(allVals) + 50);
205
+ const xScale = d3.scaleLinear()
206
+ .domain([xMin, xMax])
207
  .range([pl, pr]);
208
 
209
+ const rBase = Math.max(4.5, Math.min(10, width * 0.009));
210
 
211
  // ─── FORCE SIMULATION ───
212
  filtered.forEach(d => {
 
267
  .attr('stroke', refLine).attr('stroke-width', 0.5);
268
  }
269
 
 
 
 
 
 
 
 
 
 
 
270
  // Label
271
  gRows.append('text')
272
  .attr('x', pl - 10).attr('y', y)
273
  .attr('text-anchor', 'end')
274
  .attr('dominant-baseline', 'central')
275
  .attr('fill', textColor)
276
+ .attr('font-size', (fontSize * 1.05) + 'px')
277
  .attr('font-weight', '700')
278
  .attr('font-family', 'system-ui, -apple-system, sans-serif')
279
  .attr('letter-spacing', '-0.2px')
 
284
  const gRef = svg.selectAll('g.ref').data([0]).join('g').attr('class', 'ref');
285
  gRef.selectAll('*').remove();
286
 
287
+ [200, 500, 800, 1100].forEach(v => {
288
  const x = xScale(v);
289
+ if (x > pl + 10 && x < pr - 10) {
290
  gRef.append('line')
291
  .attr('x1', x).attr('x2', x)
292
+ .attr('y1', pb).attr('y2', pb + 4)
293
  .attr('stroke', mutedText).attr('stroke-width', 0.7);
294
  gRef.append('text')
295
+ .attr('x', x).attr('y', pb + 8)
296
  .attr('text-anchor', 'middle')
297
  .attr('dominant-baseline', 'hanging')
298
  .attr('fill', mutedText)
299
+ .attr('font-size', (fontSize * 0.9) + 'px')
300
  .attr('font-family', 'system-ui, -apple-system, sans-serif')
301
  .text(v);
302
  gRef.append('line')
 
307
  }
308
  });
309
 
310
+ // Axis label (centered below tick numbers)
311
+ const axisLabelY = pb + 8 + fontSize * 1.6;
312
  gRef.append('text')
313
+ .attr('x', (pl + pr) / 2).attr('y', axisLabelY)
314
+ .attr('text-anchor', 'middle')
315
  .attr('fill', mutedText)
316
+ .attr('font-size', (fontSize * 0.9) + 'px')
317
  .attr('font-weight', '600')
318
  .attr('font-family', 'system-ui, -apple-system, sans-serif')
319
+ .text('Output tokens / document');
320
 
321
+ // "concise" / "verbose" arrows (aligned below first/last tick)
322
  gRef.append('text')
323
+ .attr('x', xScale(200)).attr('y', axisLabelY)
324
+ .attr('text-anchor', 'middle')
325
  .attr('fill', subtleText)
326
+ .attr('font-size', (fontSize * 0.82) + 'px')
327
  .attr('font-style', 'italic')
328
  .attr('font-family', 'system-ui, -apple-system, sans-serif')
329
  .text('\u2190 concise');
330
 
331
  gRef.append('text')
332
+ .attr('x', xScale(1100)).attr('y', axisLabelY)
333
+ .attr('text-anchor', 'middle')
334
  .attr('fill', subtleText)
335
+ .attr('font-size', (fontSize * 0.82) + 'px')
336
  .attr('font-style', 'italic')
337
  .attr('font-family', 'system-ui, -apple-system, sans-serif')
338
  .text('verbose \u2192');
339
 
340
+
341
  // ─── MODEL FAMILY LEGEND ───
342
  const gLeg = svg.selectAll('g.legend').data([0]).join('g').attr('class', 'legend');
343
  gLeg.selectAll('*').remove();
344
+ const legDotR = Math.max(4, fontSize * 0.38);
345
+ const legFontSize = fontSize * 0.9;
346
+ const legY = fontSize * 1.1;
347
+ const legItemSpacing = legDotR * 2 + 6;
348
+
349
+ // Measure text widths to compute equal center-to-center gaps
350
+ const tempTexts = familyOrder.map(fam => {
351
+ const t = gLeg.append('text').attr('font-size', legFontSize + 'px')
352
+ .attr('font-weight', '500')
353
+ .attr('font-family', 'system-ui, -apple-system, sans-serif')
354
+ .text(fam);
355
+ const w = t.node().getComputedTextLength();
356
+ t.remove();
357
+ return w;
358
+ });
359
+ const itemWidths = tempTexts.map(tw => legItemSpacing + tw);
360
+ const totalLegW = itemWidths.reduce((a, b) => a + b, 0);
361
+ const legPadding = Math.max(12, (width - totalLegW) / (familyOrder.length + 1));
362
+ const totalWithPad = totalLegW + legPadding * (familyOrder.length - 1);
363
+ const legStartX = (width - totalWithPad) / 2;
364
 
365
+ let lx = legStartX;
366
  familyOrder.forEach((fam, i) => {
367
+ const ig = gLeg.append('g').style('cursor', 'pointer');
368
+ ig.append('circle')
369
  .attr('cx', lx).attr('cy', legY)
370
  .attr('r', legDotR)
371
  .attr('fill', familyColors[fam]).attr('fill-opacity', 0.85);
372
+ ig.append('text')
373
+ .attr('x', lx + legDotR + 5).attr('y', legY)
374
  .attr('dominant-baseline', 'central')
375
+ .attr('fill', isDark ? 'rgba(255,255,255,0.65)' : 'rgba(0,0,0,0.60)')
376
+ .attr('font-size', legFontSize + 'px')
377
+ .attr('font-weight', '500')
378
  .attr('font-family', 'system-ui, -apple-system, sans-serif')
379
  .text(fam);
380
+ // Hit area for easier hovering
381
+ ig.append('rect')
382
+ .attr('x', lx - legDotR - 4).attr('y', legY - legFontSize * 0.7)
383
+ .attr('width', itemWidths[i] + 8).attr('height', legFontSize * 1.4)
384
+ .attr('fill', 'transparent');
385
+ ig.on('mouseenter', () => {
386
+ gDots.selectAll('circle').transition().duration(80)
387
+ .attr('fill-opacity', d => d.family === fam ? 0.55 : 0.06)
388
+ .attr('stroke-opacity', d => d.family === fam ? 0.5 : 0.03);
389
+ }).on('mouseleave', () => {
390
+ gDots.selectAll('circle').transition().duration(160)
391
+ .attr('fill-opacity', 0.82).attr('stroke-opacity', 0.12);
392
+ });
393
+ lx += itemWidths[i] + legPadding;
394
  });
395
 
396
  // ─── TOOLTIP ───
 
430
  const gDots = svg.selectAll('g.dots').data([0]).join('g').attr('class', 'dots');
431
 
432
  const handleEnter = function (ev, d) {
433
+ gDots.selectAll('circle').attr('fill-opacity', 0.1).attr('stroke-opacity', 0.08);
434
  gDots.selectAll('circle')
435
  .filter(c => c.family === d.family)
436
+ .attr('fill-opacity', 0.55).attr('stroke-opacity', 0.5);
437
  d3.select(this)
438
  .raise()
439
  .attr('fill-opacity', 1)
 
455
  const handleLeave = function () {
456
  gDots.selectAll('circle')
457
  .attr('fill-opacity', 0.82)
458
+ .attr('stroke-opacity', 0.12);
459
  d3.select(this)
460
  .style('filter', null)
461
  .transition().duration(90).ease(d3.easeCubicOut)
 
471
  .attr('r', rBase)
472
  .attr('fill', d => familyColors[d.family] || '#aaa')
473
  .attr('fill-opacity', 0.82)
474
+ .attr('stroke', d => familyColors[d.family] || '#aaa')
475
+ .attr('stroke-width', 0.7)
476
+ .attr('stroke-opacity', 0.12)
477
  .on('mouseenter', handleEnter)
478
  .on('mousemove', handleMove)
479
  .on('mouseleave', handleLeave),
 
482
  .attr('r', rBase)
483
  .attr('fill', d => familyColors[d.family] || '#aaa')
484
  .attr('fill-opacity', 0.82)
485
+ .attr('stroke', d => familyColors[d.family] || '#aaa')
486
+ .attr('stroke-width', 0.7)
487
+ .attr('stroke-opacity', 0.12)
488
  .on('mouseenter', handleEnter)
489
  .on('mousemove', handleMove)
490
  .on('mouseleave', handleLeave)