tfrere HF Staff commited on
Commit
2f8d35b
·
1 Parent(s): f3cbfb7

add some new embeds

Browse files
app/src/content/embeds/aws-bandwidth-bottleneck.html CHANGED
@@ -1499,6 +1499,12 @@
1499
  let viewboxWidth = maxEnsembleWidthForViewbox + CONFIG.gaps.ensembleGap + 200;
1500
  let viewboxHeight = singleSystemHeight;
1501
 
 
 
 
 
 
 
1502
  // For 2 systems in vertical layout, use scaled dimensions
1503
  if (systemCount === 2 && !isInternodeLayout) {
1504
  viewboxHeight = singleSystemHeight * 2 + CONFIG.gaps.systemGap;
@@ -1538,6 +1544,11 @@
1538
  viewboxY = -verticalPadding / 2 + 100;
1539
  paddedViewboxHeight = viewboxHeight + verticalPadding;
1540
 
 
 
 
 
 
1541
  const draw = SVG().addTo(container).size('100%', '100%').viewbox(0, viewboxY, viewboxWidth, paddedViewboxHeight);
1542
  const renderer = new TopologyRenderer(draw);
1543
 
 
1499
  let viewboxWidth = maxEnsembleWidthForViewbox + CONFIG.gaps.ensembleGap + 200;
1500
  let viewboxHeight = singleSystemHeight;
1501
 
1502
+ // For single ensemble (CPU-GPU, GPU-GPU via CPU, storage paths), zoom in more
1503
+ if (ensembleCount === 1 && systemCount === 1) {
1504
+ viewboxWidth *= 0.75; // Zoom in by reducing viewbox width
1505
+ viewboxHeight *= 0.75; // Zoom in by reducing viewbox height
1506
+ }
1507
+
1508
  // For 2 systems in vertical layout, use scaled dimensions
1509
  if (systemCount === 2 && !isInternodeLayout) {
1510
  viewboxHeight = singleSystemHeight * 2 + CONFIG.gaps.systemGap;
 
1544
  viewboxY = -verticalPadding / 2 + 100;
1545
  paddedViewboxHeight = viewboxHeight + verticalPadding;
1546
 
1547
+ // For single ensemble, shift content up slightly
1548
+ if (ensembleCount === 1 && systemCount === 1) {
1549
+ viewboxY += 80; // Shift up by reducing viewboxY
1550
+ }
1551
+
1552
  const draw = SVG().addTo(container).size('100%', '100%').viewbox(0, viewboxY, viewboxWidth, paddedViewboxHeight);
1553
  const renderer = new TopologyRenderer(draw);
1554
 
app/src/content/embeds/banner.html CHANGED
@@ -77,7 +77,7 @@
77
  /* Hand-drawn annotation */
78
  .d3-loss-curves .annotation {
79
  position: absolute;
80
- top: 54px;
81
  right: 120px;
82
  display: flex;
83
  align-items: flex-start;
@@ -87,7 +87,7 @@
87
 
88
  .d3-loss-curves .annotation-text {
89
  font-family: 'Caveat', cursive, var(--default-font-family);
90
- font-size: 22px;
91
  font-weight: 600;
92
  color: var(--text-color);
93
  line-height: 1.1;
@@ -236,7 +236,7 @@
236
  stroke-linecap="round"/>
237
  </svg>
238
  <div class="annotation-text">
239
- Just a few<br/>attempts
240
  </div>
241
  `;
242
  container.appendChild(annotation);
@@ -374,28 +374,46 @@
374
  return /^baseline$/i.test(config);
375
  }
376
 
377
- // Helper function to darken a color
378
- function darkenColor(color, factor = 0.2) {
379
  // Handle different color formats
380
- if (color.startsWith('#')) {
381
- // Hex color
382
- const hex = color.replace('#', '');
383
- const r = parseInt(hex.substr(0, 2), 16);
384
- const g = parseInt(hex.substr(2, 2), 16);
385
- const b = parseInt(hex.substr(4, 2), 16);
386
- const newR = Math.max(0, Math.floor(r * (1 - factor)));
387
- const newG = Math.max(0, Math.floor(g * (1 - factor)));
388
- const newB = Math.max(0, Math.floor(b * (1 - factor)));
389
- return `#${newR.toString(16).padStart(2, '0')}${newG.toString(16).padStart(2, '0')}${newB.toString(16).padStart(2, '0')}`;
390
- } else if (color.startsWith('hsl(')) {
391
- // HSL color
392
  const match = color.match(/hsl\((\d+),\s*(\d+)%,\s*(\d+)%\)/);
393
  if (match) {
394
  const h = parseInt(match[1]);
395
- const s = parseInt(match[2]);
396
- const l = Math.max(0, parseInt(match[3]) * (1 - factor));
397
- return `hsl(${h}, ${s}%, ${Math.floor(l)}%)`;
398
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
399
  }
400
  // Fallback: return original color
401
  return color;
@@ -703,19 +721,19 @@
703
  solidPaths.exit().remove();
704
  }
705
 
706
- // Then, add all lines (dashed baselines will be on top)
707
  const paths = gLines.selectAll('path.run').data(series, d => d.run);
708
  const pathsEnter = paths.enter().append('path')
709
  .attr('class', 'run')
710
  .attr('fill', 'none')
711
  .attr('stroke-width', 2)
712
- .attr('stroke', d => isBaselineRun(d.run) ? darkenColor(d.color) : d.color)
713
- .attr('stroke-dasharray', d => isBaselineRun(d.run) ? '4,2' : null)
714
  .attr('d', d => lineGen(d.values));
715
 
716
  pathsEnter.merge(paths)
717
- .attr('stroke', d => isBaselineRun(d.run) ? darkenColor(d.color) : d.color)
718
- .attr('stroke-dasharray', d => isBaselineRun(d.run) ? '4,2' : null)
719
  .attr('d', d => lineGen(d.values)); // No transition for performance
720
  paths.exit().remove();
721
 
 
77
  /* Hand-drawn annotation */
78
  .d3-loss-curves .annotation {
79
  position: absolute;
80
+ top: 70px;
81
  right: 120px;
82
  display: flex;
83
  align-items: flex-start;
 
87
 
88
  .d3-loss-curves .annotation-text {
89
  font-family: 'Caveat', cursive, var(--default-font-family);
90
+ font-size: 32px;
91
  font-weight: 600;
92
  color: var(--text-color);
93
  line-height: 1.1;
 
236
  stroke-linecap="round"/>
237
  </svg>
238
  <div class="annotation-text">
239
+ YOLO
240
  </div>
241
  `;
242
  container.appendChild(annotation);
 
374
  return /^baseline$/i.test(config);
375
  }
376
 
377
+ // Helper function to saturate a color slightly
378
+ function saturateColor(color) {
379
  // Handle different color formats
380
+ if (color.startsWith('hsl(')) {
381
+ // HSL color - boost saturation slightly and reduce lightness a bit
 
 
 
 
 
 
 
 
 
 
382
  const match = color.match(/hsl\((\d+),\s*(\d+)%,\s*(\d+)%\)/);
383
  if (match) {
384
  const h = parseInt(match[1]);
385
+ const s = Math.min(100, parseInt(match[2]) + 25); // +10% saturation
386
+ const l = Math.max(0, parseInt(match[3])); // -5% lightness
387
+ return `hsl(${h}, ${s}%, ${l}%)`;
388
  }
389
+ } else if (color.startsWith('#')) {
390
+ // Convert hex to RGB then to HSL
391
+ const hex = color.replace('#', '');
392
+ const r = parseInt(hex.substr(0, 2), 16) / 255;
393
+ const g = parseInt(hex.substr(2, 2), 16) / 255;
394
+ const b = parseInt(hex.substr(4, 2), 16) / 255;
395
+
396
+ const max = Math.max(r, g, b);
397
+ const min = Math.min(r, g, b);
398
+ let h, s, l = (max + min) / 2;
399
+
400
+ if (max === min) {
401
+ h = s = 0;
402
+ } else {
403
+ const d = max - min;
404
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
405
+ switch (max) {
406
+ case r: h = ((g - b) / d + (g < b ? 6 : 0)) / 6; break;
407
+ case g: h = ((b - r) / d + 2) / 6; break;
408
+ case b: h = ((r - g) / d + 4) / 6; break;
409
+ }
410
+ }
411
+
412
+ h = Math.round(h * 360);
413
+ s = Math.min(100, Math.round(s * 100) + 10);
414
+ l = Math.max(0, Math.round(l * 100) - 5);
415
+
416
+ return `hsl(${h}, ${s}%, ${l}%)`;
417
  }
418
  // Fallback: return original color
419
  return color;
 
721
  solidPaths.exit().remove();
722
  }
723
 
724
+ // Then, add all lines (saturated baselines will be on top)
725
  const paths = gLines.selectAll('path.run').data(series, d => d.run);
726
  const pathsEnter = paths.enter().append('path')
727
  .attr('class', 'run')
728
  .attr('fill', 'none')
729
  .attr('stroke-width', 2)
730
+ .attr('stroke', d => isBaselineRun(d.run) ? saturateColor(d.color) : d.color)
731
+ .attr('stroke-dasharray', null)
732
  .attr('d', d => lineGen(d.values));
733
 
734
  pathsEnter.merge(paths)
735
+ .attr('stroke', d => isBaselineRun(d.run) ? saturateColor(d.color) : d.color)
736
+ .attr('stroke-dasharray', null)
737
  .attr('d', d => lineGen(d.values)); // No transition for performance
738
  paths.exit().remove();
739
 
app/src/content/embeds/rl-training-sync.html ADDED
@@ -0,0 +1,633 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="rl-training-sync"></div>
2
+ <style>
3
+ .rl-training-sync {
4
+ font-family: 'Arial', sans-serif;
5
+ margin: 20px 0;
6
+ padding: 0;
7
+ }
8
+
9
+ .rl-training-sync .container {
10
+ display: flex;
11
+ gap: 30px;
12
+ align-items: stretch;
13
+ justify-content: center;
14
+ flex-wrap: wrap;
15
+ }
16
+
17
+ .rl-training-sync .left-section {
18
+ flex: 0 0 auto;
19
+ display: flex;
20
+ align-items: center;
21
+ gap: 20px;
22
+ }
23
+
24
+ .rl-training-sync .left-diagram {
25
+ position: relative;
26
+ width: 280px;
27
+ height: 320px;
28
+ background: var(--surface-bg, #fafafa);
29
+ border-radius: 12px;
30
+ padding: 10px;
31
+ }
32
+
33
+ .rl-training-sync .diagram-separator {
34
+ width: 1px;
35
+ background: linear-gradient(to bottom, transparent, var(--border-color, #ddd) 20%, var(--border-color, #ddd) 80%, transparent);
36
+ align-self: stretch;
37
+ }
38
+
39
+ .rl-training-sync .right-modes {
40
+ flex: 1;
41
+ min-width: 400px;
42
+ display: flex;
43
+ align-items: center;
44
+ gap: 0;
45
+ }
46
+
47
+ .rl-training-sync .box {
48
+ padding: 8px 14px;
49
+ border-radius: 8px;
50
+ font-weight: 600;
51
+ font-size: 11px;
52
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
53
+ text-align: center;
54
+ position: absolute;
55
+ z-index: 2;
56
+ line-height: 1.3;
57
+ transition: transform 0.2s ease, box-shadow 0.2s ease;
58
+ cursor: default;
59
+ }
60
+
61
+ .rl-training-sync .rewards {
62
+ background: var(--color-0, #E889AB);
63
+ color: #000;
64
+ top: 10px;
65
+ left: 10px;
66
+ }
67
+
68
+ .rl-training-sync .verifier {
69
+ background: var(--color-1, #4EA5B7);
70
+ color: #000;
71
+ top: 10px;
72
+ right: 10px;
73
+ }
74
+
75
+ .rl-training-sync .rollouts {
76
+ background: var(--color-2, #E38A42);
77
+ color: #000;
78
+ top: 50%;
79
+ right: 10px;
80
+ transform: translateY(-50%);
81
+ }
82
+
83
+ .rl-training-sync .trainer {
84
+ background: var(--color-3, #CEC0FA);
85
+ color: #000;
86
+ bottom: 60px;
87
+ left: 10px;
88
+ }
89
+
90
+ .rl-training-sync .generator {
91
+ background: var(--color-0, #E889AB);
92
+ color: #000;
93
+ bottom: 60px;
94
+ right: 10px;
95
+ }
96
+
97
+ .rl-training-sync .prompt {
98
+ background: var(--color-1, #4EA5B7);
99
+ color: #000;
100
+ bottom: 10px;
101
+ left: 50%;
102
+ transform: translateX(-50%);
103
+ }
104
+
105
+ /* Arrows */
106
+ .rl-training-sync .arrow {
107
+ stroke: var(--text-color, #666);
108
+ stroke-width: 1.5;
109
+ fill: none;
110
+ opacity: 0.6;
111
+ }
112
+
113
+ .rl-training-sync .mode-column {
114
+ flex: 1;
115
+ min-width: 120px;
116
+ padding: 0 15px;
117
+ border-right: 1px solid var(--border-color, #ddd);
118
+ transition: background-color 0.2s ease;
119
+ }
120
+
121
+ .rl-training-sync .mode-column:last-child {
122
+ border-right: none;
123
+ }
124
+
125
+ .rl-training-sync .mode-header {
126
+ font-size: 13px;
127
+ font-weight: 700;
128
+ text-align: center;
129
+ margin-bottom: 15px;
130
+ color: var(--text-color, #333);
131
+ padding-bottom: 10px;
132
+ }
133
+
134
+ .rl-training-sync .step-row {
135
+ display: flex;
136
+ gap: 8px;
137
+ align-items: center;
138
+ margin-bottom: 12px;
139
+ justify-content: center;
140
+ }
141
+
142
+ .rl-training-sync .step-label {
143
+ font-size: 11px;
144
+ font-weight: 600;
145
+ min-width: 60px;
146
+ text-align: right;
147
+ color: var(--muted-color, #666);
148
+ }
149
+
150
+ .rl-training-sync .node {
151
+ padding: 7px 15px;
152
+ border-radius: 14px;
153
+ font-weight: 600;
154
+ font-size: 11px;
155
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
156
+ min-width: 38px;
157
+ text-align: center;
158
+ transition: transform 0.2s ease, box-shadow 0.2s ease;
159
+ }
160
+
161
+ .rl-training-sync .node-t {
162
+ background: var(--color-3, #CEC0FA);
163
+ color: #000;
164
+ }
165
+
166
+ .rl-training-sync .node-g {
167
+ background: var(--color-0, #E889AB);
168
+ color: #000;
169
+ }
170
+
171
+ .rl-training-sync .sync-arrow {
172
+ position: relative;
173
+ display: inline-flex;
174
+ flex-direction: column;
175
+ align-items: center;
176
+ gap: 0px;
177
+ margin-top: -12px;
178
+ }
179
+
180
+ .rl-training-sync .sync-label {
181
+ transform: translateY(10px);
182
+ font-size: 8px;
183
+ color: var(--text-color, #666);
184
+ font-weight: 600;
185
+ text-transform: lowercase;
186
+ }
187
+
188
+ .rl-training-sync .sync-symbol {
189
+ font-size: 14px;
190
+ color: var(--muted-color, #999);
191
+ font-weight: normal;
192
+ }
193
+
194
+ .rl-training-sync .dots {
195
+ text-align: center;
196
+ font-size: 16px;
197
+ font-weight: bold;
198
+ color: var(--muted-color, #ccc);
199
+ margin: 8px 0;
200
+ }
201
+
202
+ @media (max-width: 1100px) {
203
+ .rl-training-sync .left-section {
204
+ flex-direction: column;
205
+ }
206
+
207
+ .rl-training-sync .diagram-separator {
208
+ width: 100%;
209
+ height: 1px;
210
+ background: linear-gradient(to right, transparent, var(--border-color, #ddd) 20%, var(--border-color, #ddd) 80%, transparent);
211
+ }
212
+ }
213
+
214
+ @media (max-width: 1000px) {
215
+ .rl-training-sync .container {
216
+ flex-direction: column;
217
+ }
218
+
219
+ .rl-training-sync .left-diagram {
220
+ max-width: 100%;
221
+ }
222
+
223
+ .rl-training-sync .right-modes {
224
+ min-width: 100%;
225
+ }
226
+ }
227
+
228
+ @media (max-width: 600px) {
229
+ .rl-training-sync .right-modes {
230
+ flex-direction: column;
231
+ }
232
+
233
+ .rl-training-sync .mode-column {
234
+ width: 100%;
235
+ border-right: none;
236
+ border-bottom: 1px solid var(--border-color, #ddd);
237
+ padding: 15px;
238
+ }
239
+
240
+ .rl-training-sync .mode-column:last-child {
241
+ border-bottom: none;
242
+ }
243
+ }
244
+ </style>
245
+
246
+ <script>
247
+ (() => {
248
+ const bootstrap = () => {
249
+ const scriptEl = document.currentScript;
250
+ let container = scriptEl ? scriptEl.previousElementSibling : null;
251
+ if (!(container && container.classList && container.classList.contains('rl-training-sync'))) {
252
+ const candidates = Array.from(document.querySelectorAll('.rl-training-sync'))
253
+ .filter((el) => !(el.dataset && el.dataset.mounted === 'true'));
254
+ container = candidates[candidates.length - 1] || null;
255
+ }
256
+ if (!container) return;
257
+ if (container.dataset) {
258
+ if (container.dataset.mounted === 'true') return;
259
+ container.dataset.mounted = 'true';
260
+ }
261
+
262
+ // Apply categorical color palette
263
+ const applyColorPalette = () => {
264
+ try {
265
+ if (window.ColorPalettes && typeof window.ColorPalettes.getColors === 'function') {
266
+ const colors = window.ColorPalettes.getColors('categorical', 4);
267
+ colors.forEach((color, index) => {
268
+ document.documentElement.style.setProperty(`--color-${index}`, color);
269
+ });
270
+ } else {
271
+ const fallbackColors = ['#E889AB', '#4EA5B7', '#E38A42', '#CEC0FA'];
272
+ fallbackColors.forEach((color, index) => {
273
+ document.documentElement.style.setProperty(`--color-${index}`, color);
274
+ });
275
+ }
276
+ } catch (e) {
277
+ console.warn('ColorPalettes not available, using fallback colors');
278
+ }
279
+ };
280
+
281
+ applyColorPalette();
282
+ if (window.ColorPalettes && typeof window.ColorPalettes.refresh === 'function') {
283
+ window.ColorPalettes.refresh();
284
+ }
285
+
286
+ // Node positions and sizes (calculated from CSS positions)
287
+ // Container is 280x320
288
+ // Box CSS: padding: 8px 14px, font-size: 11px, line-height: 1.3
289
+ const containerWidth = 280;
290
+ const containerHeight = 320;
291
+ const padding = { x: 14, y: 8 };
292
+
293
+ // Estimated text widths + padding (approximate)
294
+ const boxWidth = {
295
+ rewards: 58 + padding.x * 2, // ~58px text
296
+ verifier: 90 + padding.x * 2, // ~90px text (2 lines)
297
+ rollouts: 58 + padding.x * 2, // ~58px text
298
+ trainer: 70 + padding.x * 2, // ~70px text
299
+ generator: 75 + padding.x * 2, // ~75px text
300
+ prompt: 48 + padding.x * 2 // ~48px text
301
+ };
302
+
303
+ // Height: single line ≈ 14px, double line ≈ 28px + padding
304
+ const boxHeight = {
305
+ rewards: 14 + padding.y * 2, // 1 line
306
+ verifier: 28 + padding.y * 2, // 2 lines (with <br/>)
307
+ rollouts: 14 + padding.y * 2, // 1 line
308
+ trainer: 14 + padding.y * 2, // 1 line
309
+ generator: 14 + padding.y * 2, // 1 line
310
+ prompt: 14 + padding.y * 2 // 1 line
311
+ };
312
+
313
+ const nodes = {
314
+ // top: 10px, left: 10px
315
+ rewards: {
316
+ x: 10 + boxWidth.rewards / 2,
317
+ y: 10 + boxHeight.rewards / 2,
318
+ width: boxWidth.rewards,
319
+ height: boxHeight.rewards
320
+ },
321
+ // top: 10px, right: 10px
322
+ verifier: {
323
+ x: containerWidth - 10 - boxWidth.verifier / 2,
324
+ y: 10 + boxHeight.verifier / 2,
325
+ width: boxWidth.verifier,
326
+ height: boxHeight.verifier
327
+ },
328
+ // top: 50%, right: 10px, transform: translateY(-50%)
329
+ rollouts: {
330
+ x: containerWidth - 10 - boxWidth.rollouts / 2,
331
+ y: containerHeight / 2,
332
+ width: boxWidth.rollouts,
333
+ height: boxHeight.rollouts
334
+ },
335
+ // bottom: 60px, left: 10px
336
+ trainer: {
337
+ x: 10 + boxWidth.trainer / 2,
338
+ y: containerHeight - 60 - boxHeight.trainer / 2,
339
+ width: boxWidth.trainer,
340
+ height: boxHeight.trainer
341
+ },
342
+ // bottom: 60px, right: 10px
343
+ generator: {
344
+ x: containerWidth - 10 - boxWidth.generator / 2,
345
+ y: containerHeight - 60 - boxHeight.generator / 2,
346
+ width: boxWidth.generator,
347
+ height: boxHeight.generator
348
+ },
349
+ // bottom: 10px, left: 50%, transform: translateX(-50%)
350
+ prompt: {
351
+ x: containerWidth / 2,
352
+ y: containerHeight - 10 - boxHeight.prompt / 2,
353
+ width: boxWidth.prompt,
354
+ height: boxHeight.prompt
355
+ }
356
+ };
357
+
358
+ // Get connection point on a node's side (like bottleneck)
359
+ // node.x and node.y are the CENTER of the box
360
+ // We calculate the edge point, then add offset to move away from the box
361
+ // linkIndex and totalLinks allow spacing multiple connections on the same side
362
+ const getPoint = (nodeId, side, offset = 8, linkIndex = 0, totalLinks = 1) => {
363
+ const node = nodes[nodeId];
364
+ if (!node) return { x: 0, y: 0 };
365
+
366
+ const points = {
367
+ top: { x: node.x, y: node.y - node.height / 2 - offset },
368
+ right: { x: node.x + node.width / 2 + offset, y: node.y },
369
+ bottom: { x: node.x, y: node.y + node.height / 2 + offset },
370
+ left: { x: node.x - node.width / 2 - offset, y: node.y }
371
+ };
372
+
373
+ let basePoint = points[side] || { x: node.x, y: node.y };
374
+
375
+ // Apply spacing for multiple links to the same anchor
376
+ if (totalLinks > 1) {
377
+ const isVerticalAnchor = (side === 'top' || side === 'bottom');
378
+
379
+ // Vertical anchors (top/bottom) space horizontally, horizontal anchors (left/right) space vertically
380
+ // Reduced gap: use fixed spacing instead of proportional
381
+ const spacing = 8; // Fixed gap of 8px between links
382
+ const linkOffset = (linkIndex - (totalLinks - 1) / 2) * spacing;
383
+
384
+ // Apply offset in the perpendicular direction to the anchor
385
+ if (isVerticalAnchor) {
386
+ basePoint.x += linkOffset; // Horizontal offset for vertical anchors
387
+ } else {
388
+ basePoint.y += linkOffset; // Vertical offset for horizontal anchors
389
+ }
390
+ }
391
+
392
+ return basePoint;
393
+ };
394
+
395
+ // Create SVG paths with arrow markers (simple version)
396
+ const createPath = (from, to, dashed = false, color = 'currentColor') => {
397
+ return `<line x1="${from.x}" y1="${from.y}" x2="${to.x}" y2="${to.y}"
398
+ stroke="${color}" stroke-width="2"
399
+ ${dashed ? 'stroke-dasharray="4,4"' : ''}
400
+ opacity="0.6"
401
+ marker-end="url(#arrowhead)" />`;
402
+ };
403
+
404
+ // Build all connections
405
+ let connections = '';
406
+ const linkColor = 'var(--text-color, #666)';
407
+
408
+ // 1. Rewards → Trainer (dashed, vertical)
409
+ // Trainer top receives 2 links, this is link 0
410
+ connections += createPath(
411
+ getPoint('rewards', 'bottom'),
412
+ getPoint('trainer', 'top', 8, 0, 2),
413
+ true, linkColor
414
+ );
415
+
416
+ // 2. Verifier → Rewards (horizontal)
417
+ connections += createPath(
418
+ getPoint('verifier', 'left'),
419
+ getPoint('rewards', 'right'),
420
+ false, linkColor
421
+ );
422
+
423
+ // 3. Verifier → Rollouts (vertical)
424
+ connections += createPath(
425
+ getPoint('verifier', 'bottom'),
426
+ getPoint('rollouts', 'top'),
427
+ false, linkColor
428
+ );
429
+
430
+ // 4. Rollouts → Generator (vertical, single arrow)
431
+ connections += createPath(
432
+ getPoint('rollouts', 'bottom'),
433
+ getPoint('generator', 'top'),
434
+ false, linkColor
435
+ );
436
+
437
+ // 5. Rollouts → Trainer (diagonal: left of rollouts to top of trainer)
438
+ // Trainer top receives 2 links, this is link 1
439
+ connections += createPath(
440
+ getPoint('rollouts', 'left'),
441
+ getPoint('trainer', 'top', 8, 1, 2),
442
+ false, linkColor
443
+ );
444
+
445
+ // 6. Trainer → Generator sync (dashed, horizontal)
446
+ const trainerRight = getPoint('trainer', 'right');
447
+ const generatorLeft = getPoint('generator', 'left');
448
+ connections += createPath(trainerRight, generatorLeft, true, linkColor);
449
+ const syncMidX = (trainerRight.x + generatorLeft.x) / 2;
450
+ connections += `<text x="${syncMidX}" y="${trainerRight.y - 8}" font-size="8" fill="currentColor" opacity="0.6" font-weight="600" text-anchor="middle">sync</text>`;
451
+ connections += `<text x="${syncMidX}" y="${trainerRight.y + 13}" font-size="8" fill="currentColor" opacity="0.6" font-weight="600" text-anchor="middle">weights</text>`;
452
+
453
+ // 7. Prompt → Trainer (diagonal: left of prompt to bottom of trainer)
454
+ connections += createPath(
455
+ getPoint('prompt', 'left'),
456
+ getPoint('trainer', 'bottom'),
457
+ false, linkColor
458
+ );
459
+
460
+ // 8. Prompt → Generator (diagonal: right of prompt to bottom of generator)
461
+ connections += createPath(
462
+ getPoint('prompt', 'right'),
463
+ getPoint('generator', 'bottom'),
464
+ false, linkColor
465
+ );
466
+
467
+ container.innerHTML = `
468
+ <div class="container">
469
+ <!-- LEFT SECTION WITH DIAGRAM -->
470
+ <div class="left-section">
471
+ <div class="left-diagram">
472
+ <!-- SVG for arrows -->
473
+ <svg width="100%" height="100%" style="position: absolute; top: 0; left: 0; pointer-events: none;">
474
+ <defs>
475
+ <marker id="arrowhead" markerWidth="6" markerHeight="6"
476
+ refX="4" refY="2" orient="auto" markerUnits="strokeWidth">
477
+ <path d="M0,0 L4,2 L0,4"
478
+ fill="none"
479
+ stroke="var(--text-color, #666)"
480
+ stroke-width="1"
481
+ stroke-linecap="round"
482
+ stroke-linejoin="round" />
483
+ </marker>
484
+ </defs>
485
+ ${connections}
486
+ </svg>
487
+
488
+ <!-- Boxes -->
489
+ <div class="box rewards">Rewards</div>
490
+ <div class="box verifier">Reward/Verifier<br/>Model</div>
491
+ <div class="box rollouts">Rollouts</div>
492
+ <div class="box trainer">Trainer (T)</div>
493
+ <div class="box generator">Generator (G)</div>
494
+ <div class="box prompt">Prompt</div>
495
+ </div>
496
+
497
+ <div class="diagram-separator"></div>
498
+ </div>
499
+
500
+ <!-- RIGHT MODES -->
501
+ <div class="right-modes">
502
+ <!-- OFFLINE -->
503
+ <div class="mode-column">
504
+ <div class="mode-header">Offline (s=∞)</div>
505
+
506
+ <div class="step-row">
507
+ <span class="step-label">Step k+1:</span>
508
+ <span class="node node-t">T</span>
509
+ <span class="node node-g">G</span>
510
+ </div>
511
+
512
+ <div class="step-row">
513
+ <span class="step-label">Step k:</span>
514
+ <span class="node node-t">T</span>
515
+ <span class="node node-g">G</span>
516
+ </div>
517
+
518
+ <div class="dots">⋯</div>
519
+
520
+ <div class="step-row">
521
+ <span class="step-label">Step 1:</span>
522
+ <span class="node node-t">T</span>
523
+ <span class="node node-g">G</span>
524
+ </div>
525
+
526
+ <div class="step-row">
527
+ <span class="step-label">Step 0:</span>
528
+ <span class="node node-t">T</span>
529
+ <span class="sync-arrow">
530
+ <span class="sync-label">sync</span>
531
+ <span class="sync-symbol">⟶</span>
532
+ </span>
533
+ <span class="node node-g">G</span>
534
+ </div>
535
+ </div>
536
+
537
+ <!-- SEMI-ONLINE -->
538
+ <div class="mode-column">
539
+ <div class="mode-header">Semi-Online (s=k)</div>
540
+
541
+ <div class="step-row">
542
+ <span class="step-label">Step k+1:</span>
543
+ <span class="node node-t">T</span>
544
+ <span class="node node-g">G</span>
545
+ </div>
546
+
547
+ <div class="step-row">
548
+ <span class="step-label">Step k:</span>
549
+ <span class="node node-t">T</span>
550
+ <span class="sync-arrow">
551
+ <span class="sync-label">sync</span>
552
+ <span class="sync-symbol">⟶</span>
553
+ </span>
554
+ <span class="node node-g">G</span>
555
+ </div>
556
+
557
+ <div class="dots">⋯</div>
558
+
559
+ <div class="step-row">
560
+ <span class="step-label">Step 1:</span>
561
+ <span class="node node-t">T</span>
562
+ <span class="node node-g">G</span>
563
+ </div>
564
+
565
+ <div class="step-row">
566
+ <span class="step-label">Step 0:</span>
567
+ <span class="node node-t">T</span>
568
+ <span class="sync-arrow">
569
+ <span class="sync-label">sync</span>
570
+ <span class="sync-symbol">⟶</span>
571
+ </span>
572
+ <span class="node node-g">G</span>
573
+ </div>
574
+ </div>
575
+
576
+ <!-- ONLINE -->
577
+ <div class="mode-column">
578
+ <div class="mode-header">Online (s=1)</div>
579
+
580
+ <div class="step-row">
581
+ <span class="step-label">Step k+1:</span>
582
+ <span class="node node-t">T</span>
583
+ <span class="sync-arrow">
584
+ <span class="sync-label">sync</span>
585
+ <span class="sync-symbol">⟶</span>
586
+ </span>
587
+ <span class="node node-g">G</span>
588
+ </div>
589
+
590
+ <div class="step-row">
591
+ <span class="step-label">Step k:</span>
592
+ <span class="node node-t">T</span>
593
+ <span class="sync-arrow">
594
+ <span class="sync-label">sync</span>
595
+ <span class="sync-symbol">⟶</span>
596
+ </span>
597
+ <span class="node node-g">G</span>
598
+ </div>
599
+
600
+ <div class="dots">⋯</div>
601
+
602
+ <div class="step-row">
603
+ <span class="step-label">Step 1:</span>
604
+ <span class="node node-t">T</span>
605
+ <span class="sync-arrow">
606
+ <span class="sync-label">sync</span>
607
+ <span class="sync-symbol">⟶</span>
608
+ </span>
609
+ <span class="node node-g">G</span>
610
+ </div>
611
+
612
+ <div class="step-row">
613
+ <span class="step-label">Step 0:</span>
614
+ <span class="node node-t">T</span>
615
+ <span class="sync-arrow">
616
+ <span class="sync-label">sync</span>
617
+ <span class="sync-symbol">⟶</span>
618
+ </span>
619
+ <span class="node node-g">G</span>
620
+ </div>
621
+ </div>
622
+ </div>
623
+ </div>
624
+ `;
625
+ };
626
+
627
+ if (document.readyState === 'loading') {
628
+ document.addEventListener('DOMContentLoaded', bootstrap, { once: true });
629
+ } else {
630
+ bootstrap();
631
+ }
632
+ })();
633
+ </script>
app/src/content/embeds/tokenizer-comparison.html CHANGED
@@ -6,7 +6,7 @@
6
  .tables-container {
7
  display: flex;
8
  gap: 20px;
9
- margin-top: 20px;
10
  }
11
 
12
  .table-wrapper {
@@ -14,6 +14,7 @@
14
  }
15
 
16
  table {
 
17
  background-color: var(--page-bg);
18
  border: 1px solid var(--border-color);
19
  border-radius: 3px !important;
 
6
  .tables-container {
7
  display: flex;
8
  gap: 20px;
9
+ margin-top: 0px;
10
  }
11
 
12
  .table-wrapper {
 
14
  }
15
 
16
  table {
17
+ width: 100%;
18
  background-color: var(--page-bg);
19
  border: 1px solid var(--border-color);
20
  border-radius: 3px !important;
app/src/content/embeds/training-pipeline.html ADDED
@@ -0,0 +1,242 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="training-pipeline"></div>
2
+ <style>
3
+ .training-pipeline {
4
+ font-family: 'Arial', sans-serif;
5
+ margin: 20px 0;
6
+ padding: 0;
7
+ }
8
+
9
+ .training-pipeline .container {
10
+ display: flex;
11
+ gap: 30px;
12
+ align-items: center;
13
+ justify-content: center;
14
+ flex-wrap: nowrap;
15
+ }
16
+
17
+ .training-pipeline .phase {
18
+ flex: 0 1 auto;
19
+ border: 1px dashed #7d7d7d;
20
+ border-radius: 8px;
21
+ padding: 15px;
22
+ }
23
+
24
+ .training-pipeline .phase-header {
25
+ font-size: 14px;
26
+ font-weight: bold;
27
+ color: var(--text-color, #333);
28
+ margin-bottom: 20px;
29
+ text-align: center;
30
+ letter-spacing: 1px;
31
+ text-transform: uppercase;
32
+ opacity: 0.6;
33
+ }
34
+
35
+ .training-pipeline .steps-row {
36
+ display: flex;
37
+ gap: 15px;
38
+ align-items: flex-start;
39
+ justify-content: center;
40
+ flex-wrap: nowrap;
41
+ }
42
+
43
+ .training-pipeline .step-wrapper {
44
+ display: flex;
45
+ flex-direction: column;
46
+ align-items: center;
47
+ flex: 0 1 auto;
48
+ min-width: 150px;
49
+ max-width: 240px;
50
+ }
51
+
52
+ .training-pipeline .step {
53
+ width: 100%;
54
+ padding: 16px;
55
+ border-radius: 8px;
56
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
57
+ display: flex;
58
+ flex-direction: column;
59
+ gap: 8px;
60
+ }
61
+
62
+ .training-pipeline .step-title {
63
+ font-size: 13px;
64
+ font-weight: 600;
65
+ line-height: 1.4;
66
+ margin-bottom: 5px;
67
+ }
68
+
69
+ .training-pipeline .step-info {
70
+ font-size: 11px;
71
+ opacity: 0.9;
72
+ }
73
+
74
+ .training-pipeline .arrow-right {
75
+ font-size: 24px;
76
+ color: #999;
77
+ display: flex;
78
+ align-items: center;
79
+ flex-shrink: 0;
80
+ margin-top: 30px;
81
+ }
82
+
83
+ .training-pipeline .arrow-between {
84
+ font-size: 32px;
85
+ color: #999;
86
+ display: flex;
87
+ align-items: center;
88
+ flex-shrink: 0;
89
+ }
90
+
91
+ .training-pipeline .model-badge {
92
+ display: flex;
93
+ align-items: center;
94
+ justify-content: center;
95
+ gap: 6px;
96
+ padding: 8px 16px;
97
+ background: linear-gradient(135deg, #FFB6B6, #FF9999);
98
+ border-radius: 20px;
99
+ font-weight: 600;
100
+ font-size: 11px;
101
+ color: #333;
102
+ box-shadow: 0 2px 6px rgba(255, 182, 182, 0.3);
103
+ position: relative;
104
+ margin-top: 15px;
105
+ white-space: nowrap;
106
+ }
107
+
108
+ .training-pipeline .model-badge::before {
109
+ content: '';
110
+ position: absolute;
111
+ top: -15px;
112
+ left: 50%;
113
+ transform: translateX(-50%);
114
+ width: 2px;
115
+ height: 15px;
116
+ border-left: 2px dashed #FFB6B6;
117
+ }
118
+
119
+ .training-pipeline .model-icon {
120
+ font-size: 16px;
121
+ font-weight: bold;
122
+ }
123
+
124
+ .training-pipeline .pre-training {
125
+ background: linear-gradient(135deg, #87CEEB, #6AB8DB);
126
+ color: #000;
127
+ }
128
+
129
+ .training-pipeline .sft {
130
+ background: linear-gradient(135deg, #F4C28F, #E6A966);
131
+ color: #000;
132
+ }
133
+
134
+ .training-pipeline .rl {
135
+ background: linear-gradient(135deg, #E6B8E6, #D69FD6);
136
+ color: #000;
137
+ }
138
+
139
+ @media (max-width: 1100px) {
140
+ .training-pipeline .container {
141
+ flex-direction: column;
142
+ align-items: stretch;
143
+ }
144
+
145
+ .training-pipeline .phase {
146
+ width: 100%;
147
+ max-width: 100%;
148
+ }
149
+
150
+ .training-pipeline .arrow-between {
151
+ transform: rotate(90deg);
152
+ margin: 10px 0;
153
+ align-self: center;
154
+ }
155
+ }
156
+
157
+ @media (max-width: 768px) {
158
+ .training-pipeline .steps-row {
159
+ flex-direction: column;
160
+ align-items: center;
161
+ }
162
+
163
+ .training-pipeline .arrow-right {
164
+ transform: rotate(90deg);
165
+ margin: 10px 0;
166
+ }
167
+
168
+ .training-pipeline .step-wrapper {
169
+ max-width: 100%;
170
+ width: 100%;
171
+ }
172
+ }
173
+ </style>
174
+
175
+ <script>
176
+ document.addEventListener('DOMContentLoaded', function () {
177
+ const container = document.querySelector('.training-pipeline');
178
+
179
+ container.innerHTML = `
180
+ <div class="container">
181
+ <!-- PRE-TRAINING -->
182
+ <div class="phase">
183
+ <div class="phase-header">Pre-Training</div>
184
+ <div class="steps-row">
185
+ <div class="step-wrapper">
186
+ <div class="step pre-training">
187
+ <div class="step-title">General<br/>Pre-training</div>
188
+ <div class="step-info">8T tokens<br/>8k context</div>
189
+ </div>
190
+ </div>
191
+
192
+ <div class="arrow-right">→</div>
193
+
194
+ <div class="step-wrapper">
195
+ <div class="step pre-training">
196
+ <div class="step-title">Code World Modeling<br/>Mid-training</div>
197
+ <div class="step-info">5T tokens<br/>131k context</div>
198
+ </div>
199
+ <div class="model-badge">
200
+ <span class="model-icon">📦</span>
201
+ <span>CWM pretrained</span>
202
+ </div>
203
+ </div>
204
+ </div>
205
+ </div>
206
+
207
+ <!-- ARROW BETWEEN PHASES -->
208
+ <div class="arrow-between">→</div>
209
+
210
+ <!-- POST-TRAINING -->
211
+ <div class="phase">
212
+ <div class="phase-header">Post-Training</div>
213
+ <div class="steps-row">
214
+ <div class="step-wrapper">
215
+ <div class="step sft">
216
+ <div class="step-title">Supervised Fine-tuning<br/>Instruction and Reasoning</div>
217
+ <div class="step-info">100B tokens<br/>32k context</div>
218
+ </div>
219
+ <div class="model-badge">
220
+ <span class="model-icon">📦</span>
221
+ <span>CWM sft</span>
222
+ </div>
223
+ </div>
224
+
225
+ <div class="arrow-right">→</div>
226
+
227
+ <div class="step-wrapper">
228
+ <div class="step rl">
229
+ <div class="step-title">Joint Reinforcement Learning<br/>Agentic and Reasoning</div>
230
+ <div class="step-info">172B tokens<br/>131k context</div>
231
+ </div>
232
+ <div class="model-badge">
233
+ <span class="model-icon">📦</span>
234
+ <span>CWM</span>
235
+ </div>
236
+ </div>
237
+ </div>
238
+ </div>
239
+ </div>
240
+ `;
241
+ });
242
+ </script>
app/src/pages/index.astro CHANGED
@@ -12,7 +12,10 @@ import "katex/dist/katex.min.css";
12
  import "../styles/global.css";
13
  const articleFM = (ArticleMod as any).frontmatter ?? {};
14
  const Article = (ArticleMod as any).default;
15
- const docTitle = articleFM?.title ?? "Untitled article";
 
 
 
16
  // Allow explicit line breaks in the title via "\n" or YAML newlines
17
  const docTitleHtml = (articleFM?.title ?? "Untitled article")
18
  .replace(/\\n/g, "<br/>")
@@ -121,7 +124,6 @@ const imageAbs: string =
121
  : (fmOg ?? ogDefaultUrl);
122
 
123
  // ---- Build citation text & BibTeX from frontmatter ----
124
- const stripHtml = (text: string) => String(text || "").replace(/<[^>]*>/g, "");
125
  const rawTitle = articleFM?.title ?? "Untitled article";
126
  const titleFlat = stripHtml(String(rawTitle))
127
  .replace(/\\n/g, " ")
 
12
  import "../styles/global.css";
13
  const articleFM = (ArticleMod as any).frontmatter ?? {};
14
  const Article = (ArticleMod as any).default;
15
+ // Helper to strip HTML tags
16
+ const stripHtml = (text: string) => String(text || "").replace(/<[^>]*>/g, "");
17
+ // docTitle without HTML tags for SEO/meta
18
+ const docTitle = stripHtml(articleFM?.title ?? "Untitled article");
19
  // Allow explicit line breaks in the title via "\n" or YAML newlines
20
  const docTitleHtml = (articleFM?.title ?? "Untitled article")
21
  .replace(/\\n/g, "<br/>")
 
124
  : (fmOg ?? ogDefaultUrl);
125
 
126
  // ---- Build citation text & BibTeX from frontmatter ----
 
127
  const rawTitle = articleFM?.title ?? "Untitled article";
128
  const titleFlat = stripHtml(String(rawTitle))
129
  .replace(/\\n/g, " ")
app/src/styles/_base.css CHANGED
@@ -46,7 +46,7 @@ html {
46
  }
47
 
48
  /* External links with arrow indicator */
49
- .content-grid main a[href^="http"]:not([href*="localhost"]):not([href*="127.0.0.1"]):not([href*="0.0.0.0"])::after {
50
  content: "↗";
51
  display: inline-block;
52
  margin-left: 2px;
@@ -55,7 +55,7 @@ html {
55
  transition: opacity 0.2s ease, transform 0.2s ease;
56
  transform: translateY(-5px);
57
  font-weight: 600;
58
- }
59
 
60
  /* External links with arrow indicator */
61
  .content-grid main a[href^="http"]:not([href*="localhost"]):not([href*="127.0.0.1"]):not([href*="0.0.0.0"]) {
 
46
  }
47
 
48
  /* External links with arrow indicator */
49
+ /* .content-grid main a[href^="http"]:not([href*="localhost"]):not([href*="127.0.0.1"]):not([href*="0.0.0.0"])::after {
50
  content: "↗";
51
  display: inline-block;
52
  margin-left: 2px;
 
55
  transition: opacity 0.2s ease, transform 0.2s ease;
56
  transform: translateY(-5px);
57
  font-weight: 600;
58
+ } */
59
 
60
  /* External links with arrow indicator */
61
  .content-grid main a[href^="http"]:not([href*="localhost"]):not([href*="127.0.0.1"]):not([href*="0.0.0.0"]) {