tfrere HF Staff commited on
Commit
1ef1f14
·
1 Parent(s): a9ccb62

update author parts, add input label training embed and data packing embed

Browse files
app/src/components/Hero.astro CHANGED
@@ -405,7 +405,7 @@ const pdfFilename = `${slugify(pdfBase)}.pdf`;
405
  display: flex;
406
  flex-direction: column;
407
  gap: 8px;
408
- max-width: 250px;
409
  }
410
  .meta-container-cell h3 {
411
  margin: 0;
 
405
  display: flex;
406
  flex-direction: column;
407
  gap: 8px;
408
+ max-width: 400px;
409
  }
410
  .meta-container-cell h3 {
411
  margin: 0;
app/src/content/embeds/aws-bandwidth-bottleneck.html CHANGED
@@ -62,7 +62,7 @@
62
  }
63
 
64
  .aws-topology-container.fixed-height {
65
- height: 800px;
66
  }
67
 
68
  .aws-topology-container svg {
@@ -74,6 +74,12 @@
74
  transition: opacity 0.2s ease;
75
  }
76
 
 
 
 
 
 
 
77
  .aws-topology-controls {
78
  position: absolute;
79
  bottom: 10px;
@@ -115,6 +121,13 @@
115
  flex-shrink: 0;
116
  }
117
 
 
 
 
 
 
 
 
118
  .aws-topology-legend {
119
  position: absolute;
120
  bottom: 10px;
@@ -1183,12 +1196,15 @@
1183
  // ============================================================================
1184
  // DRAW SINGLE SYSTEM (variable number of ensembles)
1185
  // ============================================================================
1186
- function drawSystem(renderer, systemIndex, systemCenterX, cpuY, nvswitchY, ensembleCount = 1, drawEfaCrossLinks = false) {
 
 
 
1187
  // Calculate ensemble width (4 groups)
1188
  const ensembleWidth = CONFIG.groupCount * CONFIG.gaps.horizontal;
1189
 
1190
- // Calculate system bounding box
1191
- const systemWidth = ensembleCount * ensembleWidth + (ensembleCount - 1) * CONFIG.gaps.ensembleGap;
1192
  const systemHeight = CONFIG.sizes.cpu + CONFIG.gaps.cpuToPcie + CONFIG.sizes.pcie.height +
1193
  CONFIG.gaps.pcieToGpu + CONFIG.sizes.gpu.height +
1194
  CONFIG.gaps.gpuToNvswitch + CONFIG.sizes.nvswitch.height;
@@ -1227,11 +1243,11 @@
1227
  }
1228
 
1229
  // Draw each ensemble in the system
1230
- for (let ensIndex = 0; ensIndex < ensembleCount; ensIndex++) {
1231
  const ensembleGlobalIndex = systemIndex * CONFIG.ensembleCount + ensIndex;
1232
 
1233
  // Position ensemble within system
1234
- const ensembleOffsetX = (ensIndex - (ensembleCount - 1) / 2) * (ensembleWidth + CONFIG.gaps.ensembleGap);
1235
  const ensembleCenterX = systemCenterX + ensembleOffsetX;
1236
 
1237
  drawEnsemble(renderer, ensembleGlobalIndex, ensembleCenterX, cpuY, nvswitchY);
@@ -1239,8 +1255,8 @@
1239
 
1240
  // Draw NUMA node borders (one per ensemble) if 2 ensembles
1241
  if (ensembleCount === 2) {
1242
- for (let ensIndex = 0; ensIndex < ensembleCount; ensIndex++) {
1243
- const ensembleOffsetX = (ensIndex - (ensembleCount - 1) / 2) * (ensembleWidth + CONFIG.gaps.ensembleGap);
1244
  const ensembleCenterX = systemCenterX + ensembleOffsetX;
1245
 
1246
  // Calculate NUMA node bounding box (same as system but for single ensemble)
@@ -1285,8 +1301,8 @@
1285
  const offset = getLinkOffset(bw.width);
1286
 
1287
  // Connect all GPUs in the system to all NVSwitches in the system
1288
- const totalGpusInSystem = ensembleCount * CONFIG.groupCount;
1289
- const totalNVSwitchesInSystem = ensembleCount * CONFIG.nvswitchCount;
1290
 
1291
  for (let gpuIndex = 0; gpuIndex < totalGpusInSystem; gpuIndex++) {
1292
  const gpuGlobalIndex = systemIndex * CONFIG.ensembleCount * CONFIG.groupCount + gpuIndex;
@@ -1298,8 +1314,8 @@
1298
  }
1299
  }
1300
 
1301
- // Draw CPU-to-CPU link between ensembles (only if 2 ensembles)
1302
- if (ensembleCount === 2) {
1303
  const cpu0Id = systemIndex * CONFIG.ensembleCount === 0 ? 'cpu' : `cpu-${systemIndex * CONFIG.ensembleCount}`;
1304
  const cpu1Id = `cpu-${systemIndex * CONFIG.ensembleCount + 1}`;
1305
 
@@ -1310,8 +1326,8 @@
1310
 
1311
  renderer.drawLink(cpu0Id, cpu1Id, color, bw.width, 'right', 'left', offset, 0, 1, 0, 1, 'cpu', '16GB/s');
1312
 
1313
- // Draw EFA-to-EFA link between ensembles (only if explicitly requested)
1314
- if (drawEfaCrossLinks) {
1315
  const efaExt0Id = systemIndex * CONFIG.ensembleCount * CONFIG.groupCount === 0 ? 'efa-external' : `efa-external-${systemIndex * CONFIG.ensembleCount * CONFIG.groupCount}`;
1316
  const efaExt1Id = `efa-external-${systemIndex * CONFIG.ensembleCount * CONFIG.groupCount + CONFIG.groupCount}`;
1317
 
@@ -1498,7 +1514,7 @@
1498
 
1499
  // Only draw EFA cross-links for intranode EFA path
1500
  const drawEfaCrossLinks = currentActivePathId === 'gpu-gpu-efa-intranode';
1501
- drawSystem(renderer, sysIndex, centerX, cpuY, nvswitchY, ensembleCount, drawEfaCrossLinks);
1502
  }
1503
 
1504
  // Draw EFA cross-link between systems (for internode)
@@ -1563,10 +1579,35 @@
1563
  currentSystemCount = systemCount;
1564
  }
1565
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1566
  // ============================================================================
1567
  // HIGHLIGHT HELPERS
1568
  // ============================================================================
1569
- function highlightPath(path, pathLabel = '') {
1570
  const svg = getElement('aws-topology-container').querySelector('svg');
1571
  if (!svg) return;
1572
 
@@ -1587,6 +1628,20 @@
1587
  });
1588
  });
1589
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1590
  // Highlight path nodes
1591
  path.nodes.forEach(nodeId => {
1592
  let nodeEl = svg.querySelector(`g[id="${nodeId}"]`);
@@ -1630,6 +1685,23 @@
1630
  });
1631
  });
1632
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1633
  // Calculate and show bottleneck (minimum bandwidth in the path)
1634
  let minBandwidth = Infinity;
1635
  let minBandwidthValue = null;
@@ -1678,6 +1750,7 @@
1678
  const bottleneckEl = getElement('aws-topology-bottleneck');
1679
  const bottleneckValueEl = bottleneckEl.querySelector('.bottleneck-value');
1680
  const bottleneckPathEl = bottleneckEl.querySelector('.bottleneck-path');
 
1681
  const realBandwidthsEl = bottleneckEl.querySelector('.real-bandwidths');
1682
 
1683
  // Check if real bandwidths are enabled
@@ -1685,11 +1758,28 @@
1685
  const showRealBandwidths = embedConfig.showRealBandwidths;
1686
 
1687
  if (showRealBandwidths) {
1688
- // When real bandwidths are shown, display contextual real bandwidths
1689
- displayContextualRealBandwidths(pathId, pathLabel);
1690
- bottleneckEl.classList.add('visible');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1691
  } else {
1692
  // Normal bottleneck display
 
1693
  if (minBandwidthValue) {
1694
  const value = minBandwidthValue.replace('GB/s', '');
1695
  // For EFA (12.5GB/s), add ×4 to indicate 4 links
@@ -1710,10 +1800,11 @@
1710
  const svg = getElement('aws-topology-container').querySelector('svg');
1711
  if (!svg) return;
1712
 
 
1713
  svg.querySelectorAll('g[data-node-type], g[data-link-type]').forEach(el => {
1714
  el.style.opacity = '1';
1715
  // Reset line opacity
1716
- el.querySelectorAll('line').forEach(line => {
1717
  line.style.opacity = '1';
1718
  });
1719
  // Reset circle opacity
@@ -1726,6 +1817,20 @@
1726
  });
1727
  });
1728
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1729
  // Reset legend opacity
1730
  const legendContainer = getElement('aws-topology-legend');
1731
  if (legendContainer) {
@@ -1736,17 +1841,21 @@
1736
 
1737
  // Hide bottleneck (unless real bandwidths are enabled)
1738
  const bottleneckEl = getElement('aws-topology-bottleneck');
 
1739
  const embedConfig = readEmbedConfig();
1740
  const showRealBandwidths = embedConfig.showRealBandwidths;
1741
 
1742
  if (!showRealBandwidths) {
 
1743
  bottleneckEl.classList.remove('visible');
1744
  } else {
1745
- // When real bandwidths are enabled, show all bandwidths when no path is active
 
 
 
1746
  const realBandwidthsEl = bottleneckEl.querySelector('.real-bandwidths');
1747
  if (realBandwidthsEl) {
1748
- realBandwidthsEl.style.display = 'block';
1749
- setupRealBandwidthsDisplay();
1750
  }
1751
  }
1752
  }
@@ -1900,12 +2009,18 @@
1900
  // Setup real bandwidths display if enabled
1901
  if (embedConfig.showRealBandwidths) {
1902
  const bottleneckEl = getElement('aws-topology-bottleneck');
 
1903
  const realBandwidthsEl = bottleneckEl.querySelector('.real-bandwidths');
 
 
 
 
 
1904
  if (realBandwidthsEl) {
1905
- realBandwidthsEl.style.display = 'block';
1906
- setupRealBandwidthsDisplay();
1907
  }
1908
- bottleneckEl.classList.add('visible');
 
1909
  }
1910
 
1911
  drawTopology();
@@ -2035,10 +2150,12 @@
2035
 
2036
  // Wait for fade out to complete, then redraw
2037
  setTimeout(() => {
 
 
2038
  drawTopology(path.requiredEnsembles, path.requiredSystems);
2039
 
2040
  // Highlight BEFORE fade in (while still invisible)
2041
- highlightPath(path, path.label);
2042
 
2043
  // Then fade in with highlight already applied
2044
  requestAnimationFrame(() => {
@@ -2046,14 +2163,20 @@
2046
  });
2047
  }, 150); // Wait for CSS transition to complete
2048
  } else {
 
 
2049
  // No redraw needed, just highlight immediately
2050
- highlightPath(path, path.label);
2051
  }
2052
  } else {
2053
  // Button was active, now deactivate: reset to default (2 ensembles, 1 system)
2054
  currentActivePathId = null; // Clear active path
2055
 
2056
- if (currentEnsembleCount !== 2 || currentSystemCount !== 1) {
 
 
 
 
2057
  const container = getElement('aws-topology-container');
2058
  container.style.opacity = '0';
2059
 
@@ -2094,7 +2217,7 @@
2094
  }
2095
 
2096
  // Apply highlight immediately (before fade in)
2097
- highlightPath(path, path.label);
2098
  }
2099
  }
2100
 
 
62
  }
63
 
64
  .aws-topology-container.fixed-height {
65
+ height: 850px;
66
  }
67
 
68
  .aws-topology-container svg {
 
74
  transition: opacity 0.2s ease;
75
  }
76
 
77
+ /* Add drop shadow to all links */
78
+ .aws-topology-container svg g[data-link-type] line,
79
+ .aws-topology-container svg g[data-link-type] path {
80
+ filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.2));
81
+ }
82
+
83
  .aws-topology-controls {
84
  position: absolute;
85
  bottom: 10px;
 
121
  flex-shrink: 0;
122
  }
123
 
124
+ /* Hide controls on mobile */
125
+ @media (max-width: 768px) {
126
+ .aws-topology-controls {
127
+ display: none;
128
+ }
129
+ }
130
+
131
  .aws-topology-legend {
132
  position: absolute;
133
  bottom: 10px;
 
1196
  // ============================================================================
1197
  // DRAW SINGLE SYSTEM (variable number of ensembles)
1198
  // ============================================================================
1199
+ function drawSystem(renderer, systemIndex, systemCenterX, cpuY, nvswitchY, ensembleCount = 1, systemCount = 1, drawEfaCrossLinks = false) {
1200
+ // For internode (2 systems), only show 1 ensemble per system for clarity
1201
+ const ensemblesToShow = (systemCount === 2) ? 1 : ensembleCount;
1202
+
1203
  // Calculate ensemble width (4 groups)
1204
  const ensembleWidth = CONFIG.groupCount * CONFIG.gaps.horizontal;
1205
 
1206
+ // Calculate system bounding box based on actual ensembles shown
1207
+ const systemWidth = ensemblesToShow * ensembleWidth + (ensemblesToShow - 1) * CONFIG.gaps.ensembleGap;
1208
  const systemHeight = CONFIG.sizes.cpu + CONFIG.gaps.cpuToPcie + CONFIG.sizes.pcie.height +
1209
  CONFIG.gaps.pcieToGpu + CONFIG.sizes.gpu.height +
1210
  CONFIG.gaps.gpuToNvswitch + CONFIG.sizes.nvswitch.height;
 
1243
  }
1244
 
1245
  // Draw each ensemble in the system
1246
+ for (let ensIndex = 0; ensIndex < ensemblesToShow; ensIndex++) {
1247
  const ensembleGlobalIndex = systemIndex * CONFIG.ensembleCount + ensIndex;
1248
 
1249
  // Position ensemble within system
1250
+ const ensembleOffsetX = (ensIndex - (ensemblesToShow - 1) / 2) * (ensembleWidth + CONFIG.gaps.ensembleGap);
1251
  const ensembleCenterX = systemCenterX + ensembleOffsetX;
1252
 
1253
  drawEnsemble(renderer, ensembleGlobalIndex, ensembleCenterX, cpuY, nvswitchY);
 
1255
 
1256
  // Draw NUMA node borders (one per ensemble) if 2 ensembles
1257
  if (ensembleCount === 2) {
1258
+ for (let ensIndex = 0; ensIndex < ensemblesToShow; ensIndex++) {
1259
+ const ensembleOffsetX = (ensIndex - (ensemblesToShow - 1) / 2) * (ensembleWidth + CONFIG.gaps.ensembleGap);
1260
  const ensembleCenterX = systemCenterX + ensembleOffsetX;
1261
 
1262
  // Calculate NUMA node bounding box (same as system but for single ensemble)
 
1301
  const offset = getLinkOffset(bw.width);
1302
 
1303
  // Connect all GPUs in the system to all NVSwitches in the system
1304
+ const totalGpusInSystem = ensemblesToShow * CONFIG.groupCount;
1305
+ const totalNVSwitchesInSystem = ensemblesToShow * CONFIG.nvswitchCount;
1306
 
1307
  for (let gpuIndex = 0; gpuIndex < totalGpusInSystem; gpuIndex++) {
1308
  const gpuGlobalIndex = systemIndex * CONFIG.ensembleCount * CONFIG.groupCount + gpuIndex;
 
1314
  }
1315
  }
1316
 
1317
+ // Draw CPU-to-CPU link between ensembles (only if 2 ensembles visible)
1318
+ if (ensemblesToShow === 2) {
1319
  const cpu0Id = systemIndex * CONFIG.ensembleCount === 0 ? 'cpu' : `cpu-${systemIndex * CONFIG.ensembleCount}`;
1320
  const cpu1Id = `cpu-${systemIndex * CONFIG.ensembleCount + 1}`;
1321
 
 
1326
 
1327
  renderer.drawLink(cpu0Id, cpu1Id, color, bw.width, 'right', 'left', offset, 0, 1, 0, 1, 'cpu', '16GB/s');
1328
 
1329
+ // Draw EFA-to-EFA link between ensembles (only if 2 ensembles visible and explicitly requested)
1330
+ if (ensemblesToShow === 2 && drawEfaCrossLinks) {
1331
  const efaExt0Id = systemIndex * CONFIG.ensembleCount * CONFIG.groupCount === 0 ? 'efa-external' : `efa-external-${systemIndex * CONFIG.ensembleCount * CONFIG.groupCount}`;
1332
  const efaExt1Id = `efa-external-${systemIndex * CONFIG.ensembleCount * CONFIG.groupCount + CONFIG.groupCount}`;
1333
 
 
1514
 
1515
  // Only draw EFA cross-links for intranode EFA path
1516
  const drawEfaCrossLinks = currentActivePathId === 'gpu-gpu-efa-intranode';
1517
+ drawSystem(renderer, sysIndex, centerX, cpuY, nvswitchY, ensembleCount, systemCount, drawEfaCrossLinks);
1518
  }
1519
 
1520
  // Draw EFA cross-link between systems (for internode)
 
1579
  currentSystemCount = systemCount;
1580
  }
1581
 
1582
+ // ============================================================================
1583
+ // REAL BANDWIDTH HELPERS
1584
+ // ============================================================================
1585
+ function getRealBandwidthForPath(pathId) {
1586
+ const pathToRealBandwidth = {
1587
+ 'cpu-gpu': { value: '14.2', unit: 'GB/s' },
1588
+ 'gpu-gpu-cpu': { value: '14.2', unit: 'GB/s' },
1589
+ 'gpu-gpu-nvswitch': { value: '786', unit: 'GB/s' },
1590
+ 'gpu-gpu-efa-intranode': { value: '480', unit: 'GB/s' },
1591
+ 'gpu-gpu-efa-internode': { value: '42', unit: 'GB/s' },
1592
+ 'gpu-storage': { value: '26', unit: 'GB/s' },
1593
+ 'cpu-storage': { value: '26', unit: 'GB/s' },
1594
+ 'gpu-cpu-storage': { value: '14.2', unit: 'GB/s' }
1595
+ };
1596
+
1597
+ const bandwidth = pathToRealBandwidth[pathId];
1598
+ if (bandwidth) {
1599
+ return {
1600
+ value: bandwidth.value,
1601
+ unit: bandwidth.unit
1602
+ };
1603
+ }
1604
+ return null;
1605
+ }
1606
+
1607
  // ============================================================================
1608
  // HIGHLIGHT HELPERS
1609
  // ============================================================================
1610
+ function highlightPath(path, pathLabel = '', pathId = '') {
1611
  const svg = getElement('aws-topology-container').querySelector('svg');
1612
  if (!svg) return;
1613
 
 
1628
  });
1629
  });
1630
 
1631
+ // Dim all cross-link elements (EFA internode/intranode links)
1632
+ svg.querySelectorAll('g[data-link-type="efa-crosslink"], g[data-link-type="efa-crosslink-internode"]').forEach(el => {
1633
+ el.style.opacity = '0.5';
1634
+ el.querySelectorAll('line, path').forEach(linkElement => {
1635
+ linkElement.style.opacity = '0.2';
1636
+ });
1637
+ el.querySelectorAll('[data-link-circle]').forEach(circle => {
1638
+ circle.style.opacity = '0';
1639
+ });
1640
+ el.querySelectorAll('text').forEach(text => {
1641
+ text.style.opacity = '0.15';
1642
+ });
1643
+ });
1644
+
1645
  // Highlight path nodes
1646
  path.nodes.forEach(nodeId => {
1647
  let nodeEl = svg.querySelector(`g[id="${nodeId}"]`);
 
1685
  });
1686
  });
1687
 
1688
+ // Highlight cross-link elements if they match the current path
1689
+ const currentPathId = currentActivePathId;
1690
+ if (currentPathId === 'gpu-gpu-efa-intranode' || currentPathId === 'gpu-gpu-efa-internode') {
1691
+ svg.querySelectorAll('g[data-link-type="efa-crosslink"], g[data-link-type="efa-crosslink-internode"]').forEach(linkGroup => {
1692
+ linkGroup.style.opacity = '1';
1693
+ linkGroup.querySelectorAll('line, path').forEach(linkElement => {
1694
+ linkElement.style.opacity = '1';
1695
+ });
1696
+ linkGroup.querySelectorAll('[data-link-circle]').forEach(circle => {
1697
+ circle.style.opacity = '1';
1698
+ });
1699
+ linkGroup.querySelectorAll('text').forEach(text => {
1700
+ text.style.opacity = '1';
1701
+ });
1702
+ });
1703
+ }
1704
+
1705
  // Calculate and show bottleneck (minimum bandwidth in the path)
1706
  let minBandwidth = Infinity;
1707
  let minBandwidthValue = null;
 
1750
  const bottleneckEl = getElement('aws-topology-bottleneck');
1751
  const bottleneckValueEl = bottleneckEl.querySelector('.bottleneck-value');
1752
  const bottleneckPathEl = bottleneckEl.querySelector('.bottleneck-path');
1753
+ const bottleneckLabelEl = bottleneckEl.querySelector('.bottleneck-label');
1754
  const realBandwidthsEl = bottleneckEl.querySelector('.real-bandwidths');
1755
 
1756
  // Check if real bandwidths are enabled
 
1758
  const showRealBandwidths = embedConfig.showRealBandwidths;
1759
 
1760
  if (showRealBandwidths) {
1761
+ // When real bandwidths are shown, display real bandwidth value directly
1762
+ const realBandwidth = getRealBandwidthForPath(pathId);
1763
+ if (realBandwidth) {
1764
+ bottleneckValueEl.textContent = realBandwidth.value;
1765
+ bottleneckPathEl.textContent = `for ${pathLabel}`;
1766
+ bottleneckLabelEl.textContent = 'Real Bandwidth';
1767
+ bottleneckEl.classList.add('visible');
1768
+ } else {
1769
+ // Fallback if no real bandwidth found
1770
+ bottleneckValueEl.textContent = '?';
1771
+ bottleneckPathEl.textContent = `for ${pathLabel}`;
1772
+ bottleneckLabelEl.textContent = 'Real Bandwidth';
1773
+ bottleneckEl.classList.add('visible');
1774
+ }
1775
+ // Hide the detailed real bandwidths list
1776
+ const realBandwidthsEl = bottleneckEl.querySelector('.real-bandwidths');
1777
+ if (realBandwidthsEl) {
1778
+ realBandwidthsEl.style.display = 'none';
1779
+ }
1780
  } else {
1781
  // Normal bottleneck display
1782
+ bottleneckLabelEl.textContent = 'Bandwidth Max';
1783
  if (minBandwidthValue) {
1784
  const value = minBandwidthValue.replace('GB/s', '');
1785
  // For EFA (12.5GB/s), add ×4 to indicate 4 links
 
1800
  const svg = getElement('aws-topology-container').querySelector('svg');
1801
  if (!svg) return;
1802
 
1803
+ // Reset all node and link elements
1804
  svg.querySelectorAll('g[data-node-type], g[data-link-type]').forEach(el => {
1805
  el.style.opacity = '1';
1806
  // Reset line opacity
1807
+ el.querySelectorAll('line, path').forEach(line => {
1808
  line.style.opacity = '1';
1809
  });
1810
  // Reset circle opacity
 
1817
  });
1818
  });
1819
 
1820
+ // Reset all cross-link elements (EFA internode/intranode links)
1821
+ svg.querySelectorAll('g[data-link-type="efa-crosslink"], g[data-link-type="efa-crosslink-internode"]').forEach(el => {
1822
+ el.style.opacity = '1';
1823
+ el.querySelectorAll('line, path').forEach(line => {
1824
+ line.style.opacity = '1';
1825
+ });
1826
+ el.querySelectorAll('[data-link-circle]').forEach(circle => {
1827
+ circle.style.opacity = '1';
1828
+ });
1829
+ });
1830
+
1831
+ // Clear current active path to ensure EFA cross-links are not drawn
1832
+ currentActivePathId = null;
1833
+
1834
  // Reset legend opacity
1835
  const legendContainer = getElement('aws-topology-legend');
1836
  if (legendContainer) {
 
1841
 
1842
  // Hide bottleneck (unless real bandwidths are enabled)
1843
  const bottleneckEl = getElement('aws-topology-bottleneck');
1844
+ const bottleneckLabelEl = bottleneckEl.querySelector('.bottleneck-label');
1845
  const embedConfig = readEmbedConfig();
1846
  const showRealBandwidths = embedConfig.showRealBandwidths;
1847
 
1848
  if (!showRealBandwidths) {
1849
+ bottleneckLabelEl.textContent = 'Bandwidth Max';
1850
  bottleneckEl.classList.remove('visible');
1851
  } else {
1852
+ // When real bandwidths are enabled, hide the module when no path is active
1853
+ bottleneckLabelEl.textContent = 'Real Bandwidth';
1854
+ bottleneckEl.classList.remove('visible');
1855
+ // Hide the detailed real bandwidths list
1856
  const realBandwidthsEl = bottleneckEl.querySelector('.real-bandwidths');
1857
  if (realBandwidthsEl) {
1858
+ realBandwidthsEl.style.display = 'none';
 
1859
  }
1860
  }
1861
  }
 
2009
  // Setup real bandwidths display if enabled
2010
  if (embedConfig.showRealBandwidths) {
2011
  const bottleneckEl = getElement('aws-topology-bottleneck');
2012
+ const bottleneckLabelEl = bottleneckEl.querySelector('.bottleneck-label');
2013
  const realBandwidthsEl = bottleneckEl.querySelector('.real-bandwidths');
2014
+
2015
+ // Change label to "Real Bandwidth"
2016
+ bottleneckLabelEl.textContent = 'Real Bandwidth';
2017
+
2018
+ // Hide the detailed real bandwidths list initially
2019
  if (realBandwidthsEl) {
2020
+ realBandwidthsEl.style.display = 'none';
 
2021
  }
2022
+ // Don't show the module initially - only when a path is selected
2023
+ bottleneckEl.classList.remove('visible');
2024
  }
2025
 
2026
  drawTopology();
 
2150
 
2151
  // Wait for fade out to complete, then redraw
2152
  setTimeout(() => {
2153
+ // Set active path BEFORE drawing topology so EFA cross-links are created
2154
+ currentActivePathId = pathId;
2155
  drawTopology(path.requiredEnsembles, path.requiredSystems);
2156
 
2157
  // Highlight BEFORE fade in (while still invisible)
2158
+ highlightPath(path, path.label, pathId);
2159
 
2160
  // Then fade in with highlight already applied
2161
  requestAnimationFrame(() => {
 
2163
  });
2164
  }, 150); // Wait for CSS transition to complete
2165
  } else {
2166
+ // Set active path for EFA cross-links even without redraw
2167
+ currentActivePathId = pathId;
2168
  // No redraw needed, just highlight immediately
2169
+ highlightPath(path, path.label, pathId);
2170
  }
2171
  } else {
2172
  // Button was active, now deactivate: reset to default (2 ensembles, 1 system)
2173
  currentActivePathId = null; // Clear active path
2174
 
2175
+ // Always redraw when deactivating EFA paths to remove cross-links
2176
+ const isEfaPath = pathId === 'gpu-gpu-efa-intranode' || pathId === 'gpu-gpu-efa-internode';
2177
+ const needsRedraw = currentEnsembleCount !== 2 || currentSystemCount !== 1 || isEfaPath;
2178
+
2179
+ if (needsRedraw) {
2180
  const container = getElement('aws-topology-container');
2181
  container.style.opacity = '0';
2182
 
 
2217
  }
2218
 
2219
  // Apply highlight immediately (before fade in)
2220
+ highlightPath(path, path.label, initialPathId);
2221
  }
2222
  }
2223
 
app/src/content/embeds/data-packing.html CHANGED
@@ -3,37 +3,52 @@
3
  .d3-data-packing {
4
  font-family: 'Arial', sans-serif;
5
  margin: 0;
6
- padding: 20px;
7
- background-color: #f5f5f5;
8
  }
9
 
10
  .d3-data-packing .container {
11
  max-width: 1000px;
12
  margin: 0 auto;
13
- background: white;
14
  border-radius: 10px;
15
- padding: 30px;
16
- box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
 
 
 
 
 
 
 
 
 
 
17
  }
18
 
19
  .d3-data-packing .section {
20
- margin-bottom: 40px;
 
21
  }
22
 
23
  .d3-data-packing .section-title {
24
- font-size: 24px;
25
  font-weight: bold;
26
- margin-bottom: 20px;
 
27
  text-align: center;
28
- color: #333;
 
29
  }
30
 
31
  .d3-data-packing .dataset {
32
  display: flex;
33
- flex-wrap: wrap;
 
 
 
 
 
34
  gap: 3px;
35
  justify-content: center;
36
- margin-bottom: 20px;
37
  }
38
 
39
  .d3-data-packing .grid {
@@ -46,7 +61,7 @@
46
  .d3-data-packing .block {
47
  width: 30px;
48
  height: 30px;
49
- border: 2px solid #333;
50
  border-radius: 4px;
51
  display: flex;
52
  align-items: center;
@@ -54,39 +69,42 @@
54
  font-size: 10px;
55
  font-weight: bold;
56
  color: white;
57
- text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5);
58
  }
59
 
60
  .d3-data-packing .red {
61
- background-color: #e74c3c;
62
  }
63
 
64
  .d3-data-packing .orange {
65
- background-color: #f39c12;
66
  }
67
 
68
  .d3-data-packing .yellow {
69
- background-color: #f1c40f;
70
  }
71
 
72
  .d3-data-packing .green {
73
- background-color: #2ecc71;
 
 
 
 
74
  }
75
 
76
  .d3-data-packing .lightblue {
77
- background-color: #3498db;
78
  }
79
 
80
  .d3-data-packing .blue {
81
- background-color: #2980b9;
82
  }
83
 
84
  .d3-data-packing .purple {
85
- background-color: #9b59b6;
86
  }
87
 
88
  .d3-data-packing .pink {
89
- background-color: #e91e63;
90
  }
91
 
92
  .d3-data-packing .gray {
@@ -94,36 +112,17 @@
94
  }
95
 
96
  .d3-data-packing .packing-false {
 
97
  grid-template-columns: repeat(7, 1fr);
 
 
98
  }
99
 
100
  .d3-data-packing .packing-true {
 
101
  grid-template-columns: repeat(7, 1fr);
102
- }
103
-
104
- .d3-data-packing .description {
105
- text-align: center;
106
- margin-top: 15px;
107
- color: #666;
108
- font-size: 14px;
109
- }
110
-
111
- .d3-data-packing .efficiency {
112
- background: #ecf0f1;
113
- padding: 15px;
114
- border-radius: 8px;
115
- margin-top: 20px;
116
- text-align: center;
117
- }
118
-
119
- .d3-data-packing .efficiency h3 {
120
- margin: 0 0 10px 0;
121
- color: #2c3e50;
122
- }
123
-
124
- .d3-data-packing .efficiency p {
125
- margin: 5px 0;
126
- color: #34495e;
127
  }
128
  </style>
129
  <script>
@@ -142,79 +141,121 @@
142
  container.dataset.mounted = 'true';
143
  }
144
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
  // Create the HTML structure
146
  container.innerHTML = `
147
  <div class="container">
148
- <div class="section">
149
- <h2 class="section-title">Dataset</h2>
150
- <div class="dataset">
151
- <!-- 7 red blocks -->
152
- <div class="block red">R</div><div class="block red">R</div><div class="block red">R</div><div class="block red">R</div><div class="block red">R</div><div class="block red">R</div><div class="block red">R</div>
153
- <!-- 3 orange blocks -->
154
- <div class="block orange">O</div><div class="block orange">O</div><div class="block orange">O</div>
155
- <!-- 4 yellow blocks -->
156
- <div class="block yellow">Y</div><div class="block yellow">Y</div><div class="block yellow">Y</div><div class="block yellow">Y</div>
157
- <!-- 7 green blocks -->
158
- <div class="block green">G</div><div class="block green">G</div><div class="block green">G</div><div class="block green">G</div><div class="block green">G</div><div class="block green">G</div><div class="block green">G</div>
159
- <!-- 10 light blue blocks -->
160
- <div class="block lightblue">L</div><div class="block lightblue">L</div><div class="block lightblue">L</div><div class="block lightblue">L</div><div class="block lightblue">L</div><div class="block lightblue">L</div><div class="block lightblue">L</div><div class="block lightblue">L</div><div class="block lightblue">L</div><div class="block lightblue">L</div>
161
- <!-- 3 blue blocks -->
162
- <div class="block blue">B</div><div class="block blue">B</div><div class="block blue">B</div>
163
- <!-- 5 purple blocks -->
164
- <div class="block purple">P</div><div class="block purple">P</div><div class="block purple">P</div><div class="block purple">P</div><div class="block purple">P</div>
165
- <!-- 3 pink blocks -->
166
- <div class="block pink">K</div><div class="block pink">K</div><div class="block pink">K</div>
167
  </div>
168
- <div class="description">42 unorganized data blocks</div>
169
- </div>
170
 
171
- <div class="section">
172
- <h2 class="section-title">packing=False</h2>
173
- <div class="grid packing-false">
174
- <!-- Row 1: 7 red blocks -->
175
- <div class="block red">R</div><div class="block red">R</div><div class="block red">R</div><div class="block red">R</div><div class="block red">R</div><div class="block red">R</div><div class="block red">R</div>
176
- <!-- Row 2: 3 orange + 4 gray -->
177
- <div class="block orange">O</div><div class="block orange">O</div><div class="block orange">O</div><div class="block gray">-</div><div class="block gray">-</div><div class="block gray">-</div><div class="block gray">-</div>
178
- <!-- Row 3: 4 yellow + 3 gray -->
179
- <div class="block yellow">Y</div><div class="block yellow">Y</div><div class="block yellow">Y</div><div class="block yellow">Y</div><div class="block gray">-</div><div class="block gray">-</div><div class="block gray">-</div>
180
- <!-- Row 4: 7 green -->
181
- <div class="block green">G</div><div class="block green">G</div><div class="block green">G</div><div class="block green">G</div><div class="block green">G</div><div class="block green">G</div><div class="block green">G</div>
182
- <!-- Row 5: 7 light blue -->
183
- <div class="block lightblue">L</div><div class="block lightblue">L</div><div class="block lightblue">L</div><div class="block lightblue">L</div><div class="block lightblue">L</div><div class="block lightblue">L</div><div class="block lightblue">L</div>
184
- <!-- Row 6: 3 light blue + 4 gray -->
185
- <div class="block lightblue">L</div><div class="block lightblue">L</div><div class="block lightblue">L</div><div class="block gray">-</div><div class="block gray">-</div><div class="block gray">-</div><div class="block gray">-</div>
186
- <!-- Row 7: 3 blue + 4 gray -->
187
- <div class="block blue">B</div><div class="block blue">B</div><div class="block blue">B</div><div class="block gray">-</div><div class="block gray">-</div><div class="block gray">-</div><div class="block gray">-</div>
188
- <!-- Row 8: 5 purple + 2 gray -->
189
- <div class="block purple">P</div><div class="block purple">P</div><div class="block purple">P</div><div class="block purple">P</div><div class="block purple">P</div><div class="block gray">-</div><div class="block gray">-</div>
190
  </div>
191
- <div class="description">Sequential placement with wasted space (17 empty cells)</div>
192
- </div>
193
 
194
- <div class="section">
195
- <h2 class="section-title">packing=True</h2>
196
- <div class="grid packing-true">
197
- <!-- Row 1: 7 light blue -->
198
- <div class="block lightblue">L</div><div class="block lightblue">L</div><div class="block lightblue">L</div><div class="block lightblue">L</div><div class="block lightblue">L</div><div class="block lightblue">L</div><div class="block lightblue">L</div>
199
- <!-- Row 2: 7 pink -->
200
- <div class="block pink">K</div><div class="block pink">K</div><div class="block pink">K</div><div class="block pink">K</div><div class="block pink">K</div><div class="block pink">K</div><div class="block pink">K</div>
201
- <!-- Row 3: 7 red -->
202
- <div class="block red">R</div><div class="block red">R</div><div class="block red">R</div><div class="block red">R</div><div class="block red">R</div><div class="block red">R</div><div class="block red">R</div>
203
- <!-- Row 4: 7 green -->
204
- <div class="block green">G</div><div class="block green">G</div><div class="block green">G</div><div class="block green">G</div><div class="block green">G</div><div class="block green">G</div><div class="block green">G</div>
205
- <!-- Row 5: 7 purple -->
206
- <div class="block purple">P</div><div class="block purple">P</div><div class="block purple">P</div><div class="block purple">P</div><div class="block purple">P</div><div class="block purple">P</div><div class="block purple">P</div>
207
- <!-- Row 6: 4 yellow + 3 orange -->
208
- <div class="block yellow">Y</div><div class="block yellow">Y</div><div class="block yellow">Y</div><div class="block yellow">Y</div><div class="block orange">O</div><div class="block orange">O</div><div class="block orange">O</div>
209
  </div>
210
- <div class="description">Complete optimization with no wasted space (0 empty cells)</div>
211
- </div>
212
-
213
- <div class="efficiency">
214
- <h3>Packing Efficiency</h3>
215
- <p><strong>packing=False:</strong> 39 blocks used / 56 cells = 69.6% efficiency</p>
216
- <p><strong>packing=True:</strong> 42 blocks used / 42 cells = 100% efficiency</p>
217
- <p><strong>Gain:</strong> +30.4% efficiency and 14 cells saved</p>
218
  </div>
219
  </div>
220
  `;
 
3
  .d3-data-packing {
4
  font-family: 'Arial', sans-serif;
5
  margin: 0;
 
 
6
  }
7
 
8
  .d3-data-packing .container {
9
  max-width: 1000px;
10
  margin: 0 auto;
 
11
  border-radius: 10px;
12
+ }
13
+
14
+ .d3-data-packing .sections-container {
15
+ display: flex;
16
+ gap: 20px;
17
+ }
18
+
19
+ @media (max-width: 768px) {
20
+ .d3-data-packing .sections-container {
21
+ flex-direction: column;
22
+ gap: 30px;
23
+ }
24
  }
25
 
26
  .d3-data-packing .section {
27
+ flex: 1;
28
+ margin-bottom: 0;
29
  }
30
 
31
  .d3-data-packing .section-title {
32
+ font-size: 16px;
33
  font-weight: bold;
34
+ color: var(--text-color, #333);
35
+ margin: 0 auto 20px auto;
36
  text-align: center;
37
+ width: 100%;
38
+ display: block;
39
  }
40
 
41
  .d3-data-packing .dataset {
42
  display: flex;
43
+ flex-direction: column;
44
+ gap: 3px;
45
+ }
46
+
47
+ .d3-data-packing .dataset-row {
48
+ display: flex;
49
  gap: 3px;
50
  justify-content: center;
51
+ flex-wrap: wrap;
52
  }
53
 
54
  .d3-data-packing .grid {
 
61
  .d3-data-packing .block {
62
  width: 30px;
63
  height: 30px;
64
+ border: none;
65
  border-radius: 4px;
66
  display: flex;
67
  align-items: center;
 
69
  font-size: 10px;
70
  font-weight: bold;
71
  color: white;
 
72
  }
73
 
74
  .d3-data-packing .red {
75
+ background-color: var(--color-0);
76
  }
77
 
78
  .d3-data-packing .orange {
79
+ background-color: var(--color-1);
80
  }
81
 
82
  .d3-data-packing .yellow {
83
+ background-color: var(--color-2);
84
  }
85
 
86
  .d3-data-packing .green {
87
+ background-color: var(--color-3);
88
+ }
89
+
90
+ .d3-data-packing .lightgreen {
91
+ background-color: var(--color-4);
92
  }
93
 
94
  .d3-data-packing .lightblue {
95
+ background-color: var(--color-5);
96
  }
97
 
98
  .d3-data-packing .blue {
99
+ background-color: var(--color-6);
100
  }
101
 
102
  .d3-data-packing .purple {
103
+ background-color: var(--color-7);
104
  }
105
 
106
  .d3-data-packing .pink {
107
+ background-color: var(--color-8);
108
  }
109
 
110
  .d3-data-packing .gray {
 
112
  }
113
 
114
  .d3-data-packing .packing-false {
115
+ display: grid;
116
  grid-template-columns: repeat(7, 1fr);
117
+ gap: 3px;
118
+ max-width: calc(7 * 30px + 6 * 3px);
119
  }
120
 
121
  .d3-data-packing .packing-true {
122
+ display: grid;
123
  grid-template-columns: repeat(7, 1fr);
124
+ gap: 3px;
125
+ max-width: calc(7 * 30px + 6 * 3px);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
  }
127
  </style>
128
  <script>
 
141
  container.dataset.mounted = 'true';
142
  }
143
 
144
+ // Apply categorical color palette
145
+ const applyColorPalette = () => {
146
+ try {
147
+ if (window.ColorPalettes && typeof window.ColorPalettes.getColors === 'function') {
148
+ const colors = window.ColorPalettes.getColors('categorical', 9);
149
+ colors.forEach((color, index) => {
150
+ document.documentElement.style.setProperty(`--color-${index}`, color);
151
+ });
152
+ } else {
153
+ // Fallback to CSS variables or default colors
154
+ const fallbackColors = [
155
+ 'var(--primary-color, #E889AB)',
156
+ '#4EA5B7', '#E38A42', '#CEC0FA', '#9B59B6',
157
+ '#16A085', '#1f77b4', '#ff7f0e', '#2ca02c'
158
+ ];
159
+ fallbackColors.forEach((color, index) => {
160
+ document.documentElement.style.setProperty(`--color-${index}`, color);
161
+ });
162
+ }
163
+ } catch (e) {
164
+ console.warn('ColorPalettes not available, using fallback colors');
165
+ }
166
+ };
167
+
168
+ // Apply colors immediately and on theme changes
169
+ applyColorPalette();
170
+ if (window.ColorPalettes && typeof window.ColorPalettes.refresh === 'function') {
171
+ window.ColorPalettes.refresh();
172
+ }
173
+
174
+ // Data structure - only colored blocks, no gray blocks
175
+ const dataset = [
176
+ { color: 'red', count: 7, label: 'R' },
177
+ { color: 'orange', count: 3, label: 'O' },
178
+ { color: 'yellow', count: 4, label: 'Y' },
179
+ { color: 'lightgreen', count: 6, label: 'G' },
180
+ { color: 'lightblue', count: 12, label: 'L' },
181
+ { color: 'purple', count: 6, label: 'P' },
182
+ { color: 'pink', count: 4, label: 'K' }
183
+ ];
184
+
185
+ const packingFalse = [
186
+ { color: 'red', count: 7, label: 'R' },
187
+ { color: 'orange', count: 3, label: 'O' },
188
+ { color: 'gray', count: 4, label: '-' },
189
+ { color: 'yellow', count: 4, label: 'Y' },
190
+ { color: 'gray', count: 3, label: '-' },
191
+ { color: 'lightgreen', count: 6, label: 'G' },
192
+ { color: 'gray', count: 1, label: '-' },
193
+ { color: 'lightblue', count: 7, label: 'L' },
194
+ { color: 'lightblue', count: 3, label: 'L' },
195
+ { color: 'gray', count: 4, label: '-' },
196
+ { color: 'purple', count: 6, label: 'P' },
197
+ { color: 'gray', count: 1, label: '-' },
198
+ { color: 'pink', count: 4, label: 'K' },
199
+ { color: 'gray', count: 3, label: '-' }
200
+ ];
201
+
202
+ const packingTrue = [
203
+ // Ligne 1: 7 R
204
+ { color: 'red', count: 7, label: 'R' },
205
+ // Ligne 2: 3 O + 4 Y (combinaison optimisée)
206
+ { color: 'orange', count: 3, label: 'O' },
207
+ { color: 'yellow', count: 4, label: 'Y' },
208
+ // Ligne 3: 6 G + 1 gris
209
+ { color: 'lightgreen', count: 6, label: 'G' },
210
+ { color: 'gray', count: 1, label: '-' },
211
+ // Ligne 4: 7 L (rangée complète)
212
+ { color: 'lightblue', count: 7, label: 'L' },
213
+ // Ligne 5: 3 L + 4 K (combinaison optimisée)
214
+ { color: 'lightblue', count: 3, label: 'L' },
215
+ { color: 'pink', count: 4, label: 'K' },
216
+ // Ligne 6: 6 P + 1 gris
217
+ { color: 'purple', count: 6, label: 'P' },
218
+ { color: 'gray', count: 1, label: '-' }
219
+ ];
220
+
221
+ // Helper function to create blocks
222
+ const createBlocks = (blocks) => {
223
+ return blocks.map(block =>
224
+ block.count > 0 ? `<div class="block ${block.color}"></div>`.repeat(block.count) : ''
225
+ ).join('');
226
+ };
227
+
228
+ // Helper function to create dataset rows
229
+ const createDatasetRows = (dataset) => {
230
+ return dataset.map(item =>
231
+ `<div class="dataset-row">${createBlocks([item])}</div>`
232
+ ).join('');
233
+ };
234
+
235
  // Create the HTML structure
236
  container.innerHTML = `
237
  <div class="container">
238
+ <div class="sections-container">
239
+ <div class="section">
240
+ <label class="section-title">Dataset</label>
241
+ <div class="dataset">
242
+ ${createDatasetRows(dataset)}
243
+ </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
244
  </div>
 
 
245
 
246
+ <div class="section">
247
+ <label class="section-title">packing=False</label>
248
+ <div class="grid packing-false">
249
+ ${createBlocks(packingFalse)}
250
+ </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
251
  </div>
 
 
252
 
253
+ <div class="section">
254
+ <label class="section-title">packing=True</label>
255
+ <div class="grid packing-true">
256
+ ${createBlocks(packingTrue)}
257
+ </div>
 
 
 
 
 
 
 
 
 
 
258
  </div>
 
 
 
 
 
 
 
 
259
  </div>
260
  </div>
261
  `;
app/src/content/embeds/input-labels-training.html CHANGED
@@ -1,60 +1,66 @@
1
  <div class="d3-input-labels"></div>
2
  <style>
3
  .d3-input-labels {
4
- font-family: 'Arial', sans-serif;
5
  margin: 0;
6
- padding: 20px;
7
- background-color: #f5f5f5;
8
  }
9
 
10
  .d3-input-labels .container {
11
- max-width: 1200px;
12
  margin: 0 auto;
13
- background: white;
14
  border-radius: 10px;
15
- padding: 30px;
16
- box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
17
  }
18
 
19
- .d3-input-labels .title {
20
- font-size: 28px;
21
- font-weight: bold;
22
- text-align: center;
23
- margin-bottom: 30px;
24
- color: #2c3e50;
25
  }
26
 
27
- .d3-input-labels .conversation-container {
28
  display: flex;
29
  flex-direction: column;
30
- gap: 20px;
 
 
 
 
31
  margin-bottom: 30px;
32
  }
33
 
34
- .d3-input-labels .row {
35
- display: flex;
36
- align-items: center;
37
- gap: 20px;
 
 
 
 
 
 
38
  }
39
 
40
- .d3-input-labels .row-label {
41
- font-size: 18px;
42
  font-weight: bold;
43
- min-width: 120px;
44
- color: #34495e;
 
45
  }
46
 
47
- .d3-input-labels .tokens-container {
48
  display: flex;
49
- flex-wrap: wrap;
50
  gap: 3px;
 
 
51
  flex: 1;
52
  }
53
 
54
  .d3-input-labels .token {
55
- width: 35px;
56
- height: 35px;
57
- border: 2px solid #333;
58
  border-radius: 4px;
59
  display: flex;
60
  align-items: center;
@@ -62,28 +68,28 @@
62
  font-size: 10px;
63
  font-weight: bold;
64
  color: white;
65
- text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5);
66
  position: relative;
67
  }
68
 
69
  .d3-input-labels .user-token {
70
- background-color: #e74c3c;
71
  }
72
 
73
  .d3-input-labels .assistant-token {
74
- background-color: #27ae60;
75
  }
76
 
77
  .d3-input-labels .label-token {
78
- background-color: #3498db;
79
  }
80
 
81
  .d3-input-labels .label-masked {
82
  background: repeating-linear-gradient(45deg,
83
- #3498db,
84
- #3498db 3px,
85
- #2980b9 3px,
86
- #2980b9 6px);
 
87
  }
88
 
89
  .d3-input-labels .turn-label {
@@ -91,68 +97,21 @@
91
  top: -25px;
92
  left: 50%;
93
  transform: translateX(-50%);
94
- font-size: 12px;
95
  font-weight: bold;
96
- color: #2c3e50;
97
- background: white;
98
- padding: 2px 6px;
99
- border-radius: 3px;
100
- border: 1px solid #bdc3c7;
101
  }
102
 
103
  .d3-input-labels .user-label {
104
- color: #e74c3c;
105
  }
106
 
107
  .d3-input-labels .assistant-label {
108
- color: #27ae60;
109
- }
110
-
111
- .d3-input-labels .explanation {
112
- background: #ecf0f1;
113
- padding: 20px;
114
- border-radius: 8px;
115
- margin-top: 20px;
116
- }
117
-
118
- .d3-input-labels .explanation h3 {
119
- margin: 0 0 15px 0;
120
- color: #2c3e50;
121
- }
122
-
123
- .d3-input-labels .explanation p {
124
- margin: 8px 0;
125
- color: #34495e;
126
- line-height: 1.5;
127
- }
128
-
129
- .d3-input-labels .legend {
130
- display: flex;
131
- justify-content: center;
132
- gap: 30px;
133
- margin: 20px 0;
134
- flex-wrap: wrap;
135
- }
136
-
137
- .d3-input-labels .legend-item {
138
- display: flex;
139
- align-items: center;
140
- gap: 8px;
141
- }
142
-
143
- .d3-input-labels .legend-color {
144
- width: 20px;
145
- height: 20px;
146
- border: 2px solid #333;
147
- border-radius: 3px;
148
- }
149
-
150
- .d3-input-labels .legend-masked {
151
- background: repeating-linear-gradient(45deg,
152
- #3498db,
153
- #3498db 2px,
154
- #2980b9 2px,
155
- #2980b9 4px);
156
  }
157
  </style>
158
  <script>
@@ -171,116 +130,94 @@
171
  container.dataset.mounted = 'true';
172
  }
173
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
174
  // Create the HTML structure
175
  container.innerHTML = `
176
- <div class="container">
177
- <h1 class="title">Input IDs and Labels in Conversational Training</h1>
178
-
179
- <div class="legend">
180
- <div class="legend-item">
181
- <div class="legend-color user-token"></div>
182
- <span>User Tokens</span>
183
- </div>
184
- <div class="legend-item">
185
- <div class="legend-color assistant-token"></div>
186
- <span>Assistant Tokens</span>
187
- </div>
188
- <div class="legend-item">
189
- <div class="legend-color label-token"></div>
190
- <span>Active Labels</span>
191
- </div>
192
- <div class="legend-item">
193
- <div class="legend-color legend-masked"></div>
194
- <span>Masked Labels (-100)</span>
195
- </div>
196
- </div>
197
-
198
- <div class="conversation-container">
199
- <div class="row">
200
- <div class="row-label">input_ids</div>
201
- <div class="tokens-container">
202
- <!-- First user turn: 5 tokens -->
203
- <div class="token user-token">
204
- <div class="turn-label user-label">user</div>
205
- U1
206
- </div>
207
- <div class="token user-token">U2</div>
208
- <div class="token user-token">U3</div>
209
- <div class="token user-token">U4</div>
210
- <div class="token user-token">U5</div>
211
-
212
- <!-- First assistant turn: 4 tokens -->
213
- <div class="token assistant-token">
214
- <div class="turn-label assistant-label">assistant</div>
215
- A1
216
- </div>
217
- <div class="token assistant-token">A2</div>
218
- <div class="token assistant-token">A3</div>
219
- <div class="token assistant-token">A4</div>
220
-
221
- <!-- Second user turn: 5 tokens -->
222
- <div class="token user-token">
223
- <div class="turn-label user-label">user</div>
224
- U6
225
- </div>
226
- <div class="token user-token">U7</div>
227
- <div class="token user-token">U8</div>
228
- <div class="token user-token">U9</div>
229
- <div class="token user-token">U10</div>
230
-
231
- <!-- Second assistant turn: 4 tokens -->
232
- <div class="token assistant-token">
233
- <div class="turn-label assistant-label">assistant</div>
234
- A5
235
  </div>
236
- <div class="token assistant-token">A6</div>
237
- <div class="token assistant-token">A7</div>
238
- <div class="token assistant-token">A8</div>
239
- </div>
240
- </div>
241
-
242
- <div class="row">
243
- <div class="row-label">labels</div>
244
- <div class="tokens-container">
245
- <!-- Masked labels for first user turn (5 tokens) -->
246
- <div class="token label-masked">-100</div>
247
- <div class="token label-masked">-100</div>
248
- <div class="token label-masked">-100</div>
249
- <div class="token label-masked">-100</div>
250
- <div class="token label-masked">-100</div>
251
-
252
- <!-- Active labels for first assistant turn (4 tokens) -->
253
- <div class="token label-token">A1</div>
254
- <div class="token label-token">A2</div>
255
- <div class="token label-token">A3</div>
256
- <div class="token label-token">A4</div>
257
-
258
- <!-- Masked labels for second user turn (5 tokens) -->
259
- <div class="token label-masked">-100</div>
260
- <div class="token label-masked">-100</div>
261
- <div class="token label-masked">-100</div>
262
- <div class="token label-masked">-100</div>
263
- <div class="token label-masked">-100</div>
264
-
265
- <!-- Active labels for second assistant turn (4 tokens) -->
266
- <div class="token label-token">A5</div>
267
- <div class="token label-token">A6</div>
268
- <div class="token label-token">A7</div>
269
- <div class="token label-token">A8</div>
270
- </div>
271
- </div>
272
- </div>
273
-
274
- <div class="explanation">
275
- <h3>How it works:</h3>
276
- <p><strong>input_ids:</strong> Complete sequence of input tokens (user + assistant)</p>
277
- <p><strong>labels:</strong> Target tokens for training</p>
278
- <p><strong>Masked labels (-100):</strong> User tokens are masked because the model should not learn to predict them</p>
279
- <p><strong>Active labels:</strong> Only assistant tokens are used to calculate training loss</p>
280
- <p><strong>Goal:</strong> The model learns to generate coherent assistant responses based on user context</p>
281
- </div>
282
- </div>
283
- `;
284
  };
285
 
286
  if (document.readyState === 'loading') {
 
1
  <div class="d3-input-labels"></div>
2
  <style>
3
  .d3-input-labels {
 
4
  margin: 0;
5
+ padding: 10px 0;
 
6
  }
7
 
8
  .d3-input-labels .container {
9
+ max-width: 1000px;
10
  margin: 0 auto;
 
11
  border-radius: 10px;
 
 
12
  }
13
 
14
+ .d3-input-labels .sections-container {
15
+ display: flex;
16
+ flex-direction: column;
17
+ gap: 20px;
18
+ align-items: center;
 
19
  }
20
 
21
+ .d3-input-labels .section {
22
  display: flex;
23
  flex-direction: column;
24
+ align-items: flex-start;
25
+ gap: 10px;
26
+ }
27
+
28
+ .d3-input-labels .section:first-child {
29
  margin-bottom: 30px;
30
  }
31
 
32
+ @media (max-width: 768px) {
33
+ .d3-input-labels .sections-container {
34
+ flex-direction: column;
35
+ gap: 30px;
36
+ }
37
+ }
38
+
39
+ .d3-input-labels .section {
40
+ flex: 1;
41
+ margin-bottom: 0;
42
  }
43
 
44
+ .d3-input-labels .section-title {
45
+ font-size: 16px;
46
  font-weight: bold;
47
+ color: var(--text-color, #333);
48
+ text-align: left;
49
+ margin-bottom: 15px;
50
  }
51
 
52
+ .d3-input-labels .tokens-row {
53
  display: flex;
 
54
  gap: 3px;
55
+ justify-content: flex-start;
56
+ flex-wrap: wrap;
57
  flex: 1;
58
  }
59
 
60
  .d3-input-labels .token {
61
+ width: 30px;
62
+ height: 30px;
63
+ border: 1px solid rgba(0, 0, 0, 0.1);
64
  border-radius: 4px;
65
  display: flex;
66
  align-items: center;
 
68
  font-size: 10px;
69
  font-weight: bold;
70
  color: white;
 
71
  position: relative;
72
  }
73
 
74
  .d3-input-labels .user-token {
75
+ background-color: var(--color-0);
76
  }
77
 
78
  .d3-input-labels .assistant-token {
79
+ background-color: var(--color-1);
80
  }
81
 
82
  .d3-input-labels .label-token {
83
+ background-color: var(--color-2);
84
  }
85
 
86
  .d3-input-labels .label-masked {
87
  background: repeating-linear-gradient(45deg,
88
+ var(--color-2),
89
+ var(--color-2) 3px,
90
+ transparent 3px,
91
+ transparent 6px);
92
+ opacity: 0.6;
93
  }
94
 
95
  .d3-input-labels .turn-label {
 
97
  top: -25px;
98
  left: 50%;
99
  transform: translateX(-50%);
100
+ font-size: 10px;
101
  font-weight: bold;
102
+ color: var(--text-color, #333);
103
+ background: var(--surface-bg, #fafafa);
104
+ padding: 2px 4px;
105
+ white-space: nowrap;
106
+ border-radius: 2px;
107
  }
108
 
109
  .d3-input-labels .user-label {
110
+ color: var(--color-0);
111
  }
112
 
113
  .d3-input-labels .assistant-label {
114
+ color: var(--color-1);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
  }
116
  </style>
117
  <script>
 
130
  container.dataset.mounted = 'true';
131
  }
132
 
133
+ // Apply categorical color palette
134
+ const applyColorPalette = () => {
135
+ try {
136
+ if (window.ColorPalettes && typeof window.ColorPalettes.getColors === 'function') {
137
+ const colors = window.ColorPalettes.getColors('categorical', 4);
138
+ colors.forEach((color, index) => {
139
+ document.documentElement.style.setProperty(`--color-${index}`, color);
140
+ });
141
+ } else {
142
+ // Fallback colors
143
+ const fallbackColors = [
144
+ '#E889AB', '#4EA5B7', '#E38A42', '#CEC0FA'
145
+ ];
146
+ fallbackColors.forEach((color, index) => {
147
+ document.documentElement.style.setProperty(`--color-${index}`, color);
148
+ });
149
+ }
150
+ } catch (e) {
151
+ console.warn('ColorPalettes not available, using fallback colors');
152
+ }
153
+ };
154
+
155
+ // Apply colors immediately and on theme changes
156
+ applyColorPalette();
157
+ if (window.ColorPalettes && typeof window.ColorPalettes.refresh === 'function') {
158
+ window.ColorPalettes.refresh();
159
+ }
160
+
161
+ // Data structure for input_ids and labels
162
+ const inputIds = [
163
+ { type: 'user', count: 5, label: 'U' },
164
+ { type: 'assistant', count: 4, label: 'A' },
165
+ { type: 'user', count: 5, label: 'U' },
166
+ { type: 'assistant', count: 4, label: 'A' }
167
+ ];
168
+
169
+ const labels = [
170
+ { type: 'masked', count: 5, label: '-100' },
171
+ { type: 'active', count: 4, label: 'A' },
172
+ { type: 'masked', count: 5, label: '-100' },
173
+ { type: 'active', count: 4, label: 'A' }
174
+ ];
175
+
176
+ // Helper function to create tokens
177
+ const createTokens = (tokens, rowType) => {
178
+ let tokenIndex = 1;
179
+ return tokens.map((token, groupIndex) => {
180
+ const tokens = [];
181
+ for (let i = 0; i < token.count; i++) {
182
+ const isFirst = i === 0;
183
+ const tokenClass = token.type === 'user' ? 'user-token' :
184
+ token.type === 'assistant' ? 'assistant-token' :
185
+ token.type === 'active' ? 'label-token' : 'label-masked';
186
+
187
+ const labelClass = token.type === 'user' ? 'user-label' : 'assistant-label';
188
+ const labelText = token.type === 'user' ? 'user' : 'assistant';
189
+
190
+ tokens.push(`
191
+ <div class="token ${tokenClass}">
192
+ ${isFirst && rowType === 'input_ids' ? `<div class="turn-label ${labelClass}">${labelText}</div>` : ''}
193
+ </div>
194
+ `);
195
+ tokenIndex++;
196
+ }
197
+ return tokens.join('');
198
+ }).join('');
199
+ };
200
+
201
  // Create the HTML structure
202
  container.innerHTML = `
203
+ <div class="container">
204
+ <div class="sections-container">
205
+ <div class="section">
206
+ <label class="section-title">input_ids</label>
207
+ <div class="tokens-row">
208
+ ${createTokens(inputIds, 'input_ids')}
209
+ </div>
210
+ </div>
211
+
212
+ <div class="section">
213
+ <label class="section-title">labels</label>
214
+ <div class="tokens-row">
215
+ ${createTokens(labels, 'labels')}
216
+ </div>
217
+ </div>
218
+ </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
219
  </div>
220
+ `;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
221
  };
222
 
223
  if (document.readyState === 'loading') {