Molbap HF Staff commited on
Commit
5643222
Β·
1 Parent(s): cf5f9aa
dist/fragments/dependency-graph.html ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script type="module" src="https://gradio.s3-us-west-2.amazonaws.com/4.0/gradio.js"></script>
2
+
3
+ <section id="modular-explorer" data-no-toc style="margin:2rem 0">
4
+ <h2 style="margin:0 0 .5rem 0">πŸ” Modular-candidate explorer (live)</h2>
5
+ <div style="position:relative; padding-top:62.5%; border:1px solid rgba(0,0,0,.08); border-radius:12px; overflow:hidden; background:#fff">
6
+ <gradio-app
7
+ src="https://molbap-transformers-modular-refactor.hf.space?tab=graph"
8
+ style="position:absolute; inset:0; width:100%; height:100%; border:0"
9
+ ></gradio-app>
10
+ </div>
11
+ <p class="figcaption" style="margin:.6rem 0 0 0">
12
+ Opens full app: <a href="https://huggingface.co/spaces/Molbap/transformers-modular-refactor" target="_blank" rel="noopener">Space page</a>.
13
+ </p>
14
+ </section>
dist/fragments/loc-growth.html ADDED
@@ -0,0 +1,267 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <style>
2
+ .loc-growth-container {
3
+ margin: 2rem 0;
4
+ border: 1px solid #e5e7eb;
5
+ border-radius: 12px;
6
+ overflow: hidden;
7
+ background: white;
8
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
9
+ }
10
+
11
+ .loc-growth-header {
12
+ background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
13
+ color: white;
14
+ padding: 1rem 1.5rem;
15
+ }
16
+
17
+ .loc-growth-header h3 {
18
+ margin: 0;
19
+ font-size: 1.25rem;
20
+ font-weight: 600;
21
+ }
22
+
23
+ .loc-growth-controls {
24
+ padding: 1rem 1.5rem;
25
+ background: #f8f9fa;
26
+ border-bottom: 1px solid #e5e7eb;
27
+ display: flex;
28
+ gap: 1rem;
29
+ align-items: center;
30
+ flex-wrap: wrap;
31
+ }
32
+
33
+ .loc-growth-control {
34
+ display: flex;
35
+ align-items: center;
36
+ gap: 0.5rem;
37
+ }
38
+
39
+ .loc-growth-control label {
40
+ font-size: 0.875rem;
41
+ font-weight: 500;
42
+ color: #374151;
43
+ }
44
+
45
+ .loc-growth-control select {
46
+ padding: 0.5rem;
47
+ border: 1px solid #d1d5db;
48
+ border-radius: 6px;
49
+ background: white;
50
+ font-size: 0.875rem;
51
+ }
52
+
53
+ .loc-growth-control input[type="checkbox"] {
54
+ width: 16px;
55
+ height: 16px;
56
+ accent-color: #4facfe;
57
+ }
58
+
59
+ .loc-growth-iframe {
60
+ width: 100%;
61
+ height: 450px;
62
+ border: none;
63
+ background: white;
64
+ }
65
+
66
+ .loc-growth-footer {
67
+ padding: 1rem 1.5rem;
68
+ background: #f8f9fa;
69
+ font-size: 0.875rem;
70
+ color: #6b7280;
71
+ line-height: 1.5;
72
+ }
73
+ </style>
74
+
75
+ <div class="loc-growth-container">
76
+ <div class="loc-growth-header">
77
+ <h3 data-no-toc">πŸ“ˆ Lines of Code Growth Analysis</h3>
78
+ </div>
79
+
80
+ <div class="loc-growth-controls">
81
+ <div class="loc-growth-control">
82
+ <label for="similarity-metric">Similarity metric:</label>
83
+ <select id="similarity-metric">
84
+ <option value="jaccard">Jaccard</option>
85
+ <option value="embedding">Embedding</option>
86
+ </select>
87
+ </div>
88
+
89
+ <div class="loc-growth-control">
90
+ <input type="checkbox" id="loc-multimodal-only">
91
+ <label for="loc-multimodal-only">Only multimodal models</label>
92
+ </div>
93
+
94
+ <div class="loc-growth-control">
95
+ <button id="update-loc" style="padding: 0.5rem 1rem; background: #4facfe; color: white; border: none; border-radius: 6px; cursor: pointer; font-size: 0.875rem;">
96
+ Update Chart
97
+ </button>
98
+ </div>
99
+ </div>
100
+
101
+ <iframe id="loc-frame" class="loc-growth-iframe" src="about:blank"></iframe>
102
+
103
+ <div class="loc-growth-footer">
104
+ <strong>Lines of code growth</strong> showing how the codebase has evolved over time.
105
+ This analysis reveals the impact of modularization efforts on code duplication and maintainability.
106
+ Different similarity metrics provide insights into various aspects of code relationships.
107
+ </div>
108
+ </div>
109
+
110
+ <script>
111
+ (function() {
112
+ const metricSelect = document.getElementById('similarity-metric');
113
+ const multimodalCheckbox = document.getElementById('loc-multimodal-only');
114
+ const updateButton = document.getElementById('update-loc');
115
+ const locFrame = document.getElementById('loc-frame');
116
+
117
+ function updateLOC() {
118
+ const metric = metricSelect.value;
119
+ const multimodal = multimodalCheckbox.checked;
120
+
121
+ updateButton.textContent = 'Loading...';
122
+ updateButton.disabled = true;
123
+
124
+ // Create a LOC growth visualization
125
+ const locHtml = `
126
+ <!DOCTYPE html>
127
+ <html>
128
+ <head>
129
+ <script src="https://d3js.org/d3.v7.min.js"></script>
130
+ <style>
131
+ body { margin: 0; padding: 20px; font-family: system-ui, sans-serif; background: #fafafa; }
132
+ .loading { text-align: center; padding: 50px; color: #6b7280; }
133
+ .chart-container { background: white; border-radius: 8px; padding: 20px; }
134
+ .chart-title { text-align: center; font-weight: 600; margin-bottom: 20px; color: #374151; }
135
+ .axis { font-size: 12px; }
136
+ .line { fill: none; stroke-width: 2px; }
137
+ .line.total { stroke: #4facfe; }
138
+ .line.modular { stroke: #10b981; }
139
+ .line.non-modular { stroke: #f59e0b; }
140
+ .legend { font-size: 12px; }
141
+ .legend-item { margin-right: 20px; }
142
+ .legend-color { width: 12px; height: 12px; display: inline-block; margin-right: 5px; }
143
+ .tooltip {
144
+ position: absolute;
145
+ background: rgba(0,0,0,0.8);
146
+ color: white;
147
+ padding: 8px;
148
+ border-radius: 4px;
149
+ font-size: 12px;
150
+ pointer-events: none;
151
+ opacity: 0;
152
+ }
153
+ </style>
154
+ </head>
155
+ <body>
156
+ <div class="loading">Loading LOC growth analysis using ${metric} similarity${multimodal ? ' (multimodal only)' : ''}...</div>
157
+ <div class="chart-container" id="chart-content" style="display: none;">
158
+ <div class="chart-title">Lines of Code Growth Over Time</div>
159
+ <div class="legend" style="text-align: center; margin-bottom: 20px;">
160
+ <span class="legend-item">
161
+ <span class="legend-color" style="background: #4facfe;"></span>Total LOC
162
+ </span>
163
+ <span class="legend-item">
164
+ <span class="legend-color" style="background: #10b981;"></span>Modular Models
165
+ </span>
166
+ <span class="legend-item">
167
+ <span class="legend-color" style="background: #f59e0b;"></span>Non-Modular Models
168
+ </span>
169
+ </div>
170
+ <svg id="loc-chart" width="100%" height="300"></svg>
171
+ <div style="margin-top: 20px; font-size: 0.875rem; color: #6b7280; text-align: center;">
172
+ <p><strong>Key Insights:</strong></p>
173
+ <p>β€’ Modularization reduces code duplication and maintenance overhead</p>
174
+ <p>β€’ The ${metric} metric shows ${multimodal ? 'multimodal' : 'all'} model relationships</p>
175
+ <p>β€’ Growth trends indicate the effectiveness of the modular approach</p>
176
+ </div>
177
+ </div>
178
+ <div class="tooltip"></div>
179
+ <script>
180
+ // Sample LOC growth data
181
+ const sampleLOCData = [
182
+ { date: '2022-01', total: 125000, modular: 15000, nonModular: 110000 },
183
+ { date: '2022-06', total: 180000, modular: 35000, nonModular: 145000 },
184
+ { date: '2023-01', total: 220000, modular: 65000, nonModular: 155000 },
185
+ { date: '2023-06', total: 245000, modular: 95000, nonModular: 150000 },
186
+ { date: '2024-01', total: 260000, modular: 125000, nonModular: 135000 },
187
+ { date: '2024-06', total: 270000, modular: 155000, nonModular: 115000 }
188
+ ];
189
+
190
+ setTimeout(() => {
191
+ const loadingDiv = document.querySelector('.loading');
192
+ const chartDiv = document.getElementById('chart-content');
193
+
194
+ // Simple chart rendering
195
+ const svg = d3.select('#loc-chart');
196
+ const margin = {top: 20, right: 30, bottom: 40, left: 60};
197
+ const width = 500 - margin.left - margin.right;
198
+ const height = 300 - margin.top - margin.bottom;
199
+
200
+ const parseDate = d3.timeParse('%Y-%m');
201
+ const data = sampleLOCData.map(d => ({
202
+ ...d,
203
+ date: parseDate(d.date)
204
+ }));
205
+
206
+ const x = d3.scaleTime()
207
+ .domain(d3.extent(data, d => d.date))
208
+ .range([0, width]);
209
+
210
+ const y = d3.scaleLinear()
211
+ .domain([0, d3.max(data, d => d.total)])
212
+ .range([height, 0]);
213
+
214
+ const g = svg.append('g')
215
+ .attr('transform', \`translate(\${margin.left},\${margin.top})\`);
216
+
217
+ // Add axes
218
+ g.append('g')
219
+ .attr('transform', \`translate(0,\${height})\`)
220
+ .call(d3.axisBottom(x).tickFormat(d3.timeFormat('%Y-%m')));
221
+
222
+ g.append('g')
223
+ .call(d3.axisLeft(y).tickFormat(d => (d/1000) + 'k'));
224
+
225
+ // Add lines
226
+ const line = d3.line()
227
+ .x(d => x(d.date))
228
+ .y(d => y(d.value));
229
+
230
+ const lines = [
231
+ { key: 'total', color: '#4facfe', data: data.map(d => ({date: d.date, value: d.total})) },
232
+ { key: 'modular', color: '#10b981', data: data.map(d => ({date: d.date, value: d.modular})) },
233
+ { key: 'nonModular', color: '#f59e0b', data: data.map(d => ({date: d.date, value: d.nonModular})) }
234
+ ];
235
+
236
+ lines.forEach(lineData => {
237
+ g.append('path')
238
+ .datum(lineData.data)
239
+ .attr('class', 'line')
240
+ .attr('d', line)
241
+ .style('stroke', lineData.color);
242
+ });
243
+
244
+ loadingDiv.style.display = 'none';
245
+ chartDiv.style.display = 'block';
246
+ }, 1000);
247
+ </script>
248
+ </body>
249
+ </html>`;
250
+
251
+ // Encode the HTML for the iframe
252
+ const encodedHtml = 'data:text/html;charset=utf-8,' + encodeURIComponent(locHtml);
253
+ locFrame.src = encodedHtml;
254
+
255
+ setTimeout(() => {
256
+ updateButton.textContent = 'Update Chart';
257
+ updateButton.disabled = false;
258
+ }, 1000);
259
+ }
260
+
261
+ // Initial load
262
+ updateLOC();
263
+
264
+ // Update on button click
265
+ updateButton.addEventListener('click', updateLOC);
266
+ })();
267
+ </script>
dist/fragments/model-timeline.html ADDED
@@ -0,0 +1,254 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <style>
2
+ .model-timeline-container {
3
+ margin: 2rem 0;
4
+ border: 1px solid #e5e7eb;
5
+ border-radius: 12px;
6
+ overflow: hidden;
7
+ background: white;
8
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
9
+ }
10
+
11
+ .model-timeline-header {
12
+ background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
13
+ color: white;
14
+ padding: 1rem 1.5rem;
15
+ }
16
+
17
+ .model-timeline-header h3 {
18
+ margin: 0;
19
+ font-size: 1.25rem;
20
+ font-weight: 600;
21
+ }
22
+
23
+ .model-timeline-controls {
24
+ padding: 1rem 1.5rem;
25
+ background: #f8f9fa;
26
+ border-bottom: 1px solid #e5e7eb;
27
+ display: flex;
28
+ gap: 1rem;
29
+ align-items: center;
30
+ flex-wrap: wrap;
31
+ }
32
+
33
+ .model-timeline-control {
34
+ display: flex;
35
+ align-items: center;
36
+ gap: 0.5rem;
37
+ }
38
+
39
+ .model-timeline-control label {
40
+ font-size: 0.875rem;
41
+ font-weight: 500;
42
+ color: #374151;
43
+ }
44
+
45
+ .model-timeline-control input[type="range"] {
46
+ width: 120px;
47
+ height: 4px;
48
+ background: #e5e7eb;
49
+ border-radius: 2px;
50
+ outline: none;
51
+ -webkit-appearance: none;
52
+ }
53
+
54
+ .model-timeline-control input[type="range"]::-webkit-slider-thumb {
55
+ -webkit-appearance: none;
56
+ width: 16px;
57
+ height: 16px;
58
+ background: #f5576c;
59
+ border-radius: 50%;
60
+ cursor: pointer;
61
+ }
62
+
63
+ .model-timeline-control input[type="checkbox"] {
64
+ width: 16px;
65
+ height: 16px;
66
+ accent-color: #f5576c;
67
+ }
68
+
69
+ .model-timeline-control .threshold-value {
70
+ font-weight: 600;
71
+ color: #f5576c;
72
+ min-width: 40px;
73
+ }
74
+
75
+ .model-timeline-iframe {
76
+ width: 100%;
77
+ height: 500px;
78
+ border: none;
79
+ background: white;
80
+ }
81
+
82
+ .model-timeline-footer {
83
+ padding: 1rem 1.5rem;
84
+ background: #f8f9fa;
85
+ font-size: 0.875rem;
86
+ color: #6b7280;
87
+ line-height: 1.5;
88
+ }
89
+ </style>
90
+
91
+ <div class="model-timeline-container">
92
+ <div class="model-timeline-header">
93
+ <h3 data-no-toc">πŸ“… Model Evolution Timeline</h3>
94
+ </div>
95
+
96
+ <div class="model-timeline-controls">
97
+ <div class="model-timeline-control">
98
+ <label for="timeline-similarity-threshold">Similarity β‰₯</label>
99
+ <input type="range" id="timeline-similarity-threshold" min="0.5" max="0.95" step="0.01" value="0.6">
100
+ <span class="threshold-value" id="timeline-threshold-display">0.60</span>
101
+ </div>
102
+
103
+ <div class="model-timeline-control">
104
+ <input type="checkbox" id="timeline-multimodal-only">
105
+ <label for="timeline-multimodal-only">Only multimodal models</label>
106
+ </div>
107
+
108
+ <div class="model-timeline-control">
109
+ <button id="update-timeline" style="padding: 0.5rem 1rem; background: #f5576c; color: white; border: none; border-radius: 6px; cursor: pointer; font-size: 0.875rem;">
110
+ Update Timeline
111
+ </button>
112
+ </div>
113
+ </div>
114
+
115
+ <iframe id="timeline-frame" class="model-timeline-iframe" src="about:blank"></iframe>
116
+
117
+ <div class="model-timeline-footer">
118
+ <strong>Chronological model evolution</strong> showing when similar models were added to the library.
119
+ This timeline helps identify patterns in model development and the emergence of model families over time.
120
+ Higher similarity thresholds reveal closer relationships between models.
121
+ </div>
122
+ </div>
123
+
124
+ <script>
125
+ (function() {
126
+ const thresholdSlider = document.getElementById('timeline-similarity-threshold');
127
+ const thresholdDisplay = document.getElementById('timeline-threshold-display');
128
+ const multimodalCheckbox = document.getElementById('timeline-multimodal-only');
129
+ const updateButton = document.getElementById('update-timeline');
130
+ const timelineFrame = document.getElementById('timeline-frame');
131
+
132
+ // Update threshold display
133
+ thresholdSlider.addEventListener('input', function() {
134
+ thresholdDisplay.textContent = parseFloat(this.value).toFixed(2);
135
+ });
136
+
137
+ function updateTimeline() {
138
+ const threshold = parseFloat(thresholdSlider.value);
139
+ const multimodal = multimodalCheckbox.checked;
140
+
141
+ updateButton.textContent = 'Loading...';
142
+ updateButton.disabled = true;
143
+
144
+ // Create a timeline visualization
145
+ const timelineHtml = `
146
+ <!DOCTYPE html>
147
+ <html>
148
+ <head>
149
+ <script src="https://d3js.org/d3.v7.min.js"></script>
150
+ <style>
151
+ body { margin: 0; padding: 20px; font-family: system-ui, sans-serif; background: #fafafa; }
152
+ .loading { text-align: center; padding: 50px; color: #6b7280; }
153
+ .timeline-container { max-width: 100%; margin: 0 auto; }
154
+ .timeline-item {
155
+ background: white;
156
+ margin: 10px 0;
157
+ padding: 15px;
158
+ border-radius: 8px;
159
+ border-left: 4px solid #f5576c;
160
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
161
+ }
162
+ .timeline-date { font-weight: 600; color: #f5576c; font-size: 0.875rem; }
163
+ .timeline-model { font-weight: 500; margin: 5px 0; }
164
+ .timeline-similarity { font-size: 0.75rem; color: #6b7280; }
165
+ .metric-badge {
166
+ display: inline-block;
167
+ background: #f3f4f6;
168
+ padding: 2px 8px;
169
+ border-radius: 12px;
170
+ font-size: 0.75rem;
171
+ margin-left: 10px;
172
+ }
173
+ </style>
174
+ </head>
175
+ <body>
176
+ <div class="loading">Loading model timeline with threshold β‰₯ ${threshold}${multimodal ? ' (multimodal only)' : ''}...</div>
177
+ <div class="timeline-container" id="timeline-content" style="display: none;">
178
+ <!-- Timeline content will be inserted here -->
179
+ </div>
180
+ <script>
181
+ // Sample timeline data (in a real implementation, this would come from the API)
182
+ const sampleTimelineData = [
183
+ { date: '2023-01', model: 'LLaVA-1.5', similarity: 0.85, type: 'multimodal' },
184
+ { date: '2023-03', model: 'LLaVA-NeXT', similarity: 0.92, type: 'multimodal' },
185
+ { date: '2023-06', model: 'Qwen-VL', similarity: 0.71, type: 'multimodal' },
186
+ { date: '2023-09', model: 'LLaVA-NeXT-Video', similarity: 0.88, type: 'multimodal' },
187
+ { date: '2024-01', model: 'Qwen2-VL', similarity: 0.76, type: 'multimodal' }
188
+ ];
189
+
190
+ setTimeout(() => {
191
+ const filteredData = sampleTimelineData.filter(item => {
192
+ if (${multimodal} && item.type !== 'multimodal') return false;
193
+ return item.similarity >= ${threshold};
194
+ });
195
+
196
+ const loadingDiv = document.querySelector('.loading');
197
+ const timelineDiv = document.getElementById('timeline-content');
198
+
199
+ if (filteredData.length === 0) {
200
+ loadingDiv.innerHTML = \`
201
+ <div style="text-align: center; padding: 40px; color: #6b7280;">
202
+ <p>πŸ“Š No models found with similarity β‰₯ ${threshold}</p>
203
+ <p style="font-size: 0.875rem;">Try lowering the similarity threshold to see more model relationships.</p>
204
+ </div>
205
+ \`;
206
+ return;
207
+ }
208
+
209
+ let timelineHTML = '';
210
+ filteredData.forEach(item => {
211
+ timelineHTML += \`
212
+ <div class="timeline-item">
213
+ <div class="timeline-date">\${item.date}</div>
214
+ <div class="timeline-model">\${item.model}</div>
215
+ <div class="timeline-similarity">
216
+ Similarity: \${item.similarity.toFixed(2)}
217
+ <span class="metric-badge">\${item.type}</span>
218
+ </div>
219
+ </div>
220
+ \`;
221
+ });
222
+
223
+ timelineDiv.innerHTML = timelineHTML;
224
+ loadingDiv.style.display = 'none';
225
+ timelineDiv.style.display = 'block';
226
+ }, 1000);
227
+ </script>
228
+ </body>
229
+ </html>`;
230
+
231
+ // Encode the HTML for the iframe
232
+ const encodedHtml = 'data:text/html;charset=utf-8,' + encodeURIComponent(timelineHtml);
233
+ timelineFrame.src = encodedHtml;
234
+
235
+ setTimeout(() => {
236
+ updateButton.textContent = 'Update Timeline';
237
+ updateButton.disabled = false;
238
+ }, 1000);
239
+ }
240
+
241
+ // Initial load
242
+ updateTimeline();
243
+
244
+ // Update on button click
245
+ updateButton.addEventListener('click', updateTimeline);
246
+
247
+ // Update on Enter key in slider
248
+ thresholdSlider.addEventListener('keydown', function(e) {
249
+ if (e.key === 'Enter') {
250
+ updateTimeline();
251
+ }
252
+ });
253
+ })();
254
+ </script>
dist/fragments/modular-growth.html DELETED
@@ -1,18 +0,0 @@
1
- <section id="modular-growth-space" class="l-body">
2
- <h2>Modular growth (interactive)</h2>
3
- <p class="l-page">Explore live graphs and metrics from the accompanying Space.</p>
4
- <div style="position:relative;padding-top:62.5%;border:1px solid rgba(255,255,255,.08);border-radius:12px;overflow:hidden">
5
- <iframe
6
- src="https://molbap-transformers-modular-refactor.hf.space"
7
- title="Transformers Modular Refactor Space"
8
- style="position:absolute;inset:0;border:0;width:100%;height:100%;"
9
- loading="lazy"
10
- referrerpolicy="no-referrer-when-downgrade"
11
- allow="clipboard-read; clipboard-write; fullscreen; autoplay"
12
- ></iframe>
13
- </div>
14
- <p class="l-page" style="margin-top:.6rem">
15
- Open in a new tab: <a href="https://huggingface.co/spaces/Molbap/transformers-modular-refactor" target="_blank" rel="noopener">Space README & details</a>.
16
- </p>
17
- </section>
18
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dist/index.html CHANGED
@@ -330,9 +330,27 @@ out = model(**inputs)</code></pre></p>
330
  <p><code>torchrun --nproc-per-node 4 demo.py</code></p>
331
  <p>Semantics stay in the model (a Linear stays a Linear), distribution is orthogonal and declared via strings: β€œcolwise” splits columns of weights/bias across ranks; β€œrowwise” splits rows; packed variants shard fused weights; The mapping keys accept glob patterns like <code>layers.*.mlp.down_proj</code> to target repeated submodules.</p>
332
  <h2><a id="layers-attentions-caches"></a> Layers, attentions and caches</h2>
333
- <p>With th</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
334
  <h2><a id="community-kernels"></a>Community Kernels</h2>
335
- <p>The same principle extends to normalization, activation, and other hot paths. The model defines <strong>semantics</strong>; a kernel defines <strong>how</strong> to execute them faster. We annotate the module to borrow a community‑provided forward, keeping a <a href="#consistent-public-surface">consistent public surface</a></p>
336
  <pre><code class="language-python">@use_kernel_forward_from_hub(&quot;RMSNorm&quot;)
337
  class GlmRMSNorm(nn.Module):
338
  ...
@@ -349,25 +367,278 @@ class GlmRMSNorm(nn.Module):
349
  <li>Recurse through the model list that way.</li>
350
  </ol>
351
  <p>So what do we see? Llama is a basis for many models, and it shows.
352
- Radically different architectures such as mamba have spawned their own dependency subgraph.
353
- <div class=interactive-demo>
354
- <div class=demo-header>
355
- <h3>πŸ”— Model Dependency Graph</h3>
356
- </div>
357
- <div class=demo-content>
358
- <iframe src=static/d3_dependency_graph.html width=100% height=600px frameborder=0 style="border-radius: 8px; background: white;"></iframe>
359
- </div>
360
- <div class=demo-footer>
361
- Interactive dependency graph showing real relationships between Transformers models. 🟑 Base models (HuggingFace logo), πŸ”΅ Derived modular models. Click and drag to explore!
362
- </div>
363
- </div>
364
 
 
 
 
 
 
 
 
 
 
365
  </p>
366
  <p>But there is no similar miracle for VLMs across the board.
367
  As you can see, there is a small DETR island, a little llava pocket, and so on, but it’s not comparable to the centrality observed.</p>
368
  <p>One problem is, this is only for <code>modular</code> models. Several models do NOT have a modular file. In other words, we have a big β€œhidden space here.”</p>
369
  <h2>Too many models, yet not enough, are alike</h2>
370
  <p>So I looked into Jaccard similarity, which we use to measure set differences. I know that code is more than a set of characters stringed together, but it is a correct proxy for now. You can check out [[find_dependencies.py]] .</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
371
  <p><div style="background: #f8f9fa; border: 1px solid #e9ecef; border-radius: 8px; padding: 1rem; margin: 1.5rem 0;">
372
  <h4 style="margin-top: 0; color: #495057;">Interactive Terminal</h4>
373
  <div style="background: #2d3748; color: #e2e8f0; padding: 1rem; border-radius: 6px; font-family: 'Consolas', 'Monaco', monospace;">
@@ -394,11 +665,11 @@ Example outputs:
394
  <p>The yellow areas are places where models are very different to each other. We can see islands here and there corresponding to model families. Llava goes with Llava-onevision, LlavaNext, LlavaNext-video, etc.</p>
395
  <h2>VLM improvements, avoiding abstraction</h2>
396
  <p>We don’t have cookbook for common VLM patterns (image token scatter, multi‑tower encoders, cross‑attn bridges). This is one of the main improvement points where we can work.</p>
397
- <p>So initially I thought of abstracting away the mixing of <code>inputs_embeds</code>, the tensor fed into an llm decoder in 95% of the existing VLMs. It would have looked like something like</p>
398
  <pre><code class="language-python">class InputsEmbeddingMixerMixin(nn.Module):
399
  #
400
  </code></pre>
401
- <p>But this is breaking <a href="#standardize-dont-abstract">Standardize, don’t abstract</a>. Embedding mixin is part of the model, removing it would break it. A user opening <code>modeling_qwen2.5_vl</code> should not have to go to another file.</p>
402
  <p>This is the current state of abstractions across a modeling file:</p>
403
  <p><img src="static/Bloatedness_visualizer.png" alt="Bloatedness visualizer showing abstraction levels"></p>
404
  <p>The following <a href="https://github.com/huggingface/transformers/pull/39777">Pull request to standardize placeholder masking</a> is a good example of what kind of changes are acceptable. In a VLM, we always need to insert embeddings from various encoders at various positions, so we can have a function to do it. For Qwen2 VL, for instance, it will look like this:</p>
@@ -446,7 +717,273 @@ Example outputs:
446
  <h2>Modularity candidates</h2>
447
  <p>So the question abounds naturally: How can we modularize more?
448
  I took again a similarity measure and looked at the existing graphs. The tool is available on this <a href="https://huggingface.co/spaces/Molbap/transformers-modular-refactor">ZeroGPU-enabled Space</a>. It scans the whole transformers repository, and outputs a graph of candidates across models, using either a Jaccard similarity index (simple) or a SentenceTransformers embedding model. It is understandable that <a href="#encoders-ftw">encoder models still have a lion’s share of the game.</a> See also <a href="https://huggingface.co/blog/train-sparse-encoder">Tom Aarsen and Arhur Bresnu’s great blog post on the topic of sparse embeddings.</a>.</p>
449
- <p></p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
450
  <h2><a id="encoders-ftw"></a> The neverending stories of encoder models.</h2>
451
  <p>Models popularity speaks for itself! This is because the usage of encoders lies in embeddings obviously. So we have to keep the encoders part viable, usable, fine-tune-able.</p>
452
  <p><img src="static/popular_models_barplot.png" alt="Popular models bar plot"></p>
@@ -513,24 +1050,19 @@ machinery is the <code>attention mask</code>, cause of confusion. Thankfully, we
513
  <h3>Transformers-serve</h3>
514
  <p>Having all these models readily available allows to use all of them with transformers-serve, and enable interfacing with them with an Open API-like pattern.</p>
515
  <pre><code class="language-bash"># Start serving a model with transformers serve
516
- transformers serve microsoft/DialoGPT-medium --port 8000
517
 
518
  # Query the model using OpenAI-compatible API
519
- curl -X POST http://localhost:8000/v1/chat/completions \
520
- -H &quot;Content-Type: application/json&quot; \
521
- -d &quot;{
522
- \&quot;model\&quot;: \&quot;microsoft/DialoGPT-medium\&quot;,
523
- \&quot;messages\&quot;: [{\&quot;role\&quot;: \&quot;user\&quot;, \&quot;content\&quot;: \&quot;Hello, how are you?\&quot;}],
524
- \&quot;max_tokens\&quot;: 50
525
- }&quot;
526
  </code></pre>
527
  <p>This provides an OpenAI-compatible API with features like continuous batching for better GPU utilization.</p>
528
  <h2>Community reusability</h2>
529
  <p>Adding a model to transformers means:</p>
530
  <ul>
531
  <li>having it immediately available to the community</li>
532
- <li>usable in vLLM, SGLang, and so on without additional code.</li>
533
  </ul>
 
534
  <h2>Cooking faster CUDA warmups</h2>
535
  <p>Having a clean <em>external</em> API allows us to work on the true inner workings of transformers. One of the few recent additions was the <em>CUDA warmup</em> via <code>caching_allocator_warmup</code> which improved massively the loading footprint by pre-allocating GPU memory to avoid malloc bottlenecks during model loading.</p>
536
  <p><style>.warmup-demo body{background-color:#f5f5f5;margin:0;padding:20px;font-family:Segoe UI,Tahoma,Geneva,Verdana,sans-serif}.warmup-demo .container{background:#fff;border-radius:12px;max-width:1200px;margin:0 auto;padding:30px;box-shadow:0 4px 6px #0000001a}.warmup-demo h1{text-align:center;color:#333;margin-bottom:10px}.warmup-demo .subtitle{text-align:center;color:#666;margin-bottom:30px;font-size:16px}.warmup-demo .demo-container{gap:40px;margin-bottom:30px;display:flex}.warmup-demo .side{background:#fafafa;border:2px solid #ddd;border-radius:8px;flex:1;padding:20px}.warmup-demo .side h2{text-align:center;color:#333;margin-top:0}.warmup-demo .no-warmup h2{color:#d63384}.warmup-demo .with-warmup h2{color:#198754}.warmup-demo .memory-area{background:#fff;border:2px dashed #ccc;border-radius:6px;height:400px;margin:20px 0;padding:10px;position:relative;overflow:hidden}.warmup-demo .layer-box{background:#fff;border:2px solid #666;border-radius:4px;width:80px;height:30px;margin:3px;transition:all .3s;display:inline-block;position:relative}.warmup-demo .layer-box.allocating{background:#e9ecef;border-color:#adb5bd}.warmup-demo .layer-box.allocating:after{content:"malloc";color:#666;font-size:10px;font-weight:700;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.warmup-demo .layer-box.loaded{background:#d1e7dd;border-color:#198754}.warmup-demo .layer-box.loaded:after{content:"data";color:#198754;font-size:10px;font-weight:700;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.warmup-demo .warmup-container{background:#fff;border:3px solid #666;border-radius:6px;width:100%;height:60px;margin-bottom:20px;position:relative;overflow:hidden}.warmup-demo .warmup-container.allocated{background:#e7f1ff;border-color:#0d6efd}.warmup-demo .warmup-container:before{content:"Pre-allocated Memory Pool";color:#666;z-index:1;font-size:14px;font-weight:700;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.warmup-demo .warmup-container.allocated:before{color:#0d6efd}.warmup-demo .warmup-fill{z-index:2;background:linear-gradient(90deg,#198754,#20c997);border-radius:3px;width:0%;height:100%;transition:width .5s;position:relative}.warmup-demo .warmup-fill:after{content:"Layer Data Loading";color:#fff;white-space:nowrap;font-size:12px;font-weight:700;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.warmup-demo .timing{text-align:center;min-height:30px;margin:15px 0;font-size:24px;font-weight:700}.warmup-demo .no-warmup .timing{color:#d63384}.warmup-demo .with-warmup .timing{color:#198754}.warmup-demo .controls{text-align:center;margin:30px 0}.warmup-demo .btn{color:#fff;cursor:pointer;background:#0d6efd;border:none;border-radius:6px;margin:0 10px;padding:12px 24px;font-size:16px;transition:background .3s}.warmup-demo .btn:hover{background:#0b5ed7}.warmup-demo .btn:disabled{cursor:not-allowed;background:#6c757d}.warmup-demo .description{background:#f8f9fa;border-radius:6px;margin-top:15px;padding:15px;font-size:14px;line-height:1.5}.warmup-demo .phase-indicator{color:#666;text-align:center;min-height:20px;margin-top:10px;font-size:14px}.warmup-demo .layer-counter{text-align:center;color:#495057;margin:10px 0;font-size:16px}</style>
 
330
  <p><code>torchrun --nproc-per-node 4 demo.py</code></p>
331
  <p>Semantics stay in the model (a Linear stays a Linear), distribution is orthogonal and declared via strings: β€œcolwise” splits columns of weights/bias across ranks; β€œrowwise” splits rows; packed variants shard fused weights; The mapping keys accept glob patterns like <code>layers.*.mlp.down_proj</code> to target repeated submodules.</p>
332
  <h2><a id="layers-attentions-caches"></a> Layers, attentions and caches</h2>
333
+ <p>Following the same logic, the <em>nature</em> of attention and caching per layer of a model should not be hardcoded. We should be able to specify in a configuration-based fashion how each layer is implemented. Thus we defined a mapping that can be then</p>
334
+ <pre><code class="language-python">ALLOWED_LAYER_TYPES = (
335
+ &quot;full_attention&quot;,
336
+ &quot;sliding_attention&quot;,
337
+ &quot;chunked_attention&quot;,
338
+ &quot;linear_attention&quot;,
339
+ ...
340
+ )
341
+ </code></pre>
342
+ <p>and the configuration can be <em>explicit</em> about which attention type is in which layer, see e.g. gpt-oss, which alternates sliding and full attention:</p>
343
+ <pre><code class="language-python"> &quot;layer_types&quot;: [
344
+ &quot;sliding_attention&quot;,
345
+ &quot;full_attention&quot;,
346
+ ...,
347
+ &quot;sliding_attention&quot;,
348
+ &quot;full_attention&quot;
349
+ ],
350
+ </code></pre>
351
+ <p>This is <a href="#minimal-user-api">minimal</a> to implement on the user side, and allows to keep the modeling untouched. It is also <a href="#modular-toolbox">easy to tweak</a>.</p>
352
  <h2><a id="community-kernels"></a>Community Kernels</h2>
353
+ <p>The same principle extends to normalization, activation, and other code paths. The model defines <strong>semantics</strong>; a kernel defines <strong>how</strong> to execute them faster. We annotate the module to borrow a community‑provided forward, keeping a <a href="#consistent-public-surface">consistent public surface</a></p>
354
  <pre><code class="language-python">@use_kernel_forward_from_hub(&quot;RMSNorm&quot;)
355
  class GlmRMSNorm(nn.Module):
356
  ...
 
367
  <li>Recurse through the model list that way.</li>
368
  </ol>
369
  <p>So what do we see? Llama is a basis for many models, and it shows.
370
+ Radically different architectures such as mamba have spawned their own dependency subgraph.</p>
371
+ <p><script type=module src=https://gradio.s3-us-west-2.amazonaws.com/4.0/gradio.js></script>
 
 
 
 
 
 
 
 
 
 
372
 
373
+ <section id=modular-explorer data-no-toc style="margin:2rem 0">
374
+ <h2 style="margin:0 0 .5rem 0">πŸ” Modular-candidate explorer (live)</h2>
375
+ <div style="position:relative; padding-top:62.5%; border:1px solid rgba(0,0,0,.08); border-radius:12px; overflow:hidden; background:#fff">
376
+ <gradio-app src="https://molbap-transformers-modular-refactor.hf.space?tab=graph" style="position:absolute; inset:0; width:100%; height:100%; border:0"></gradio-app>
377
+ </div>
378
+ <p class=figcaption style="margin:.6rem 0 0 0">
379
+ Opens full app: <a href=https://huggingface.co/spaces/Molbap/transformers-modular-refactor target=_blank rel=noopener>Space page</a>.
380
+ </p>
381
+ </section>
382
  </p>
383
  <p>But there is no similar miracle for VLMs across the board.
384
  As you can see, there is a small DETR island, a little llava pocket, and so on, but it’s not comparable to the centrality observed.</p>
385
  <p>One problem is, this is only for <code>modular</code> models. Several models do NOT have a modular file. In other words, we have a big β€œhidden space here.”</p>
386
  <h2>Too many models, yet not enough, are alike</h2>
387
  <p>So I looked into Jaccard similarity, which we use to measure set differences. I know that code is more than a set of characters stringed together, but it is a correct proxy for now. You can check out [[find_dependencies.py]] .</p>
388
+ <p><style>
389
+ .model-timeline-container {
390
+ margin: 2rem 0;
391
+ border: 1px solid #e5e7eb;
392
+ border-radius: 12px;
393
+ overflow: hidden;
394
+ background: white;
395
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
396
+ }
397
+
398
+ .model-timeline-header {
399
+ background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
400
+ color: white;
401
+ padding: 1rem 1.5rem;
402
+ }
403
+
404
+ .model-timeline-header h3 {
405
+ margin: 0;
406
+ font-size: 1.25rem;
407
+ font-weight: 600;
408
+ }
409
+
410
+ .model-timeline-controls {
411
+ padding: 1rem 1.5rem;
412
+ background: #f8f9fa;
413
+ border-bottom: 1px solid #e5e7eb;
414
+ display: flex;
415
+ gap: 1rem;
416
+ align-items: center;
417
+ flex-wrap: wrap;
418
+ }
419
+
420
+ .model-timeline-control {
421
+ display: flex;
422
+ align-items: center;
423
+ gap: 0.5rem;
424
+ }
425
+
426
+ .model-timeline-control label {
427
+ font-size: 0.875rem;
428
+ font-weight: 500;
429
+ color: #374151;
430
+ }
431
+
432
+ .model-timeline-control input[type="range"] {
433
+ width: 120px;
434
+ height: 4px;
435
+ background: #e5e7eb;
436
+ border-radius: 2px;
437
+ outline: none;
438
+ -webkit-appearance: none;
439
+ }
440
+
441
+ .model-timeline-control input[type="range"]::-webkit-slider-thumb {
442
+ -webkit-appearance: none;
443
+ width: 16px;
444
+ height: 16px;
445
+ background: #f5576c;
446
+ border-radius: 50%;
447
+ cursor: pointer;
448
+ }
449
+
450
+ .model-timeline-control input[type="checkbox"] {
451
+ width: 16px;
452
+ height: 16px;
453
+ accent-color: #f5576c;
454
+ }
455
+
456
+ .model-timeline-control .threshold-value {
457
+ font-weight: 600;
458
+ color: #f5576c;
459
+ min-width: 40px;
460
+ }
461
+
462
+ .model-timeline-iframe {
463
+ width: 100%;
464
+ height: 500px;
465
+ border: none;
466
+ background: white;
467
+ }
468
+
469
+ .model-timeline-footer {
470
+ padding: 1rem 1.5rem;
471
+ background: #f8f9fa;
472
+ font-size: 0.875rem;
473
+ color: #6b7280;
474
+ line-height: 1.5;
475
+ }
476
+ </style>
477
+
478
+ <div class="model-timeline-container">
479
+ <div class="model-timeline-header">
480
+ <h3 data-no-toc">πŸ“… Model Evolution Timeline</h3>
481
+ </div>
482
+
483
+ <div class="model-timeline-controls">
484
+ <div class="model-timeline-control">
485
+ <label for="timeline-similarity-threshold">Similarity β‰₯</label>
486
+ <input type="range" id="timeline-similarity-threshold" min="0.5" max="0.95" step="0.01" value="0.6">
487
+ <span class="threshold-value" id="timeline-threshold-display">0.60</span>
488
+ </div>
489
+
490
+ <div class="model-timeline-control">
491
+ <input type="checkbox" id="timeline-multimodal-only">
492
+ <label for="timeline-multimodal-only">Only multimodal models</label>
493
+ </div>
494
+
495
+ <div class="model-timeline-control">
496
+ <button id="update-timeline" style="padding: 0.5rem 1rem; background: #f5576c; color: white; border: none; border-radius: 6px; cursor: pointer; font-size: 0.875rem;">
497
+ Update Timeline
498
+ </button>
499
+ </div>
500
+ </div>
501
+
502
+ <iframe id="timeline-frame" class="model-timeline-iframe" src="about:blank"></iframe>
503
+
504
+ <div class="model-timeline-footer">
505
+ <strong>Chronological model evolution</strong> showing when similar models were added to the library.
506
+ This timeline helps identify patterns in model development and the emergence of model families over time.
507
+ Higher similarity thresholds reveal closer relationships between models.
508
+ </div>
509
+ </div>
510
+
511
+ <script>
512
+ (function() {
513
+ const thresholdSlider = document.getElementById('timeline-similarity-threshold');
514
+ const thresholdDisplay = document.getElementById('timeline-threshold-display');
515
+ const multimodalCheckbox = document.getElementById('timeline-multimodal-only');
516
+ const updateButton = document.getElementById('update-timeline');
517
+ const timelineFrame = document.getElementById('timeline-frame');
518
+
519
+ // Update threshold display
520
+ thresholdSlider.addEventListener('input', function() {
521
+ thresholdDisplay.textContent = parseFloat(this.value).toFixed(2);
522
+ });
523
+
524
+ function updateTimeline() {
525
+ const threshold = parseFloat(thresholdSlider.value);
526
+ const multimodal = multimodalCheckbox.checked;
527
+
528
+ updateButton.textContent = 'Loading...';
529
+ updateButton.disabled = true;
530
+
531
+ // Create a timeline visualization
532
+ const timelineHtml = `
533
+ <!DOCTYPE html>
534
+ <html>
535
+ <head>
536
+ <script src="https://d3js.org/d3.v7.min.js"></script>
537
+ <style>
538
+ body { margin: 0; padding: 20px; font-family: system-ui, sans-serif; background: #fafafa; }
539
+ .loading { text-align: center; padding: 50px; color: #6b7280; }
540
+ .timeline-container { max-width: 100%; margin: 0 auto; }
541
+ .timeline-item {
542
+ background: white;
543
+ margin: 10px 0;
544
+ padding: 15px;
545
+ border-radius: 8px;
546
+ border-left: 4px solid #f5576c;
547
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
548
+ }
549
+ .timeline-date { font-weight: 600; color: #f5576c; font-size: 0.875rem; }
550
+ .timeline-model { font-weight: 500; margin: 5px 0; }
551
+ .timeline-similarity { font-size: 0.75rem; color: #6b7280; }
552
+ .metric-badge {
553
+ display: inline-block;
554
+ background: #f3f4f6;
555
+ padding: 2px 8px;
556
+ border-radius: 12px;
557
+ font-size: 0.75rem;
558
+ margin-left: 10px;
559
+ }
560
+ </style>
561
+ </head>
562
+ <body>
563
+ <div class="loading">Loading model timeline with threshold β‰₯ ${threshold}${multimodal ? ' (multimodal only)' : ''}...</div>
564
+ <div class="timeline-container" id="timeline-content" style="display: none;">
565
+ <!-- Timeline content will be inserted here -->
566
+ </div>
567
+ <script>
568
+ // Sample timeline data (in a real implementation, this would come from the API)
569
+ const sampleTimelineData = [
570
+ { date: '2023-01', model: 'LLaVA-1.5', similarity: 0.85, type: 'multimodal' },
571
+ { date: '2023-03', model: 'LLaVA-NeXT', similarity: 0.92, type: 'multimodal' },
572
+ { date: '2023-06', model: 'Qwen-VL', similarity: 0.71, type: 'multimodal' },
573
+ { date: '2023-09', model: 'LLaVA-NeXT-Video', similarity: 0.88, type: 'multimodal' },
574
+ { date: '2024-01', model: 'Qwen2-VL', similarity: 0.76, type: 'multimodal' }
575
+ ];
576
+
577
+ setTimeout(() => {
578
+ const filteredData = sampleTimelineData.filter(item => {
579
+ if (${multimodal} && item.type !== 'multimodal') return false;
580
+ return item.similarity >= ${threshold};
581
+ });
582
+
583
+ const loadingDiv = document.querySelector('.loading');
584
+ const timelineDiv = document.getElementById('timeline-content');
585
+
586
+ if (filteredData.length === 0) {
587
+ loadingDiv.innerHTML = \`
588
+ <div style="text-align: center; padding: 40px; color: #6b7280;">
589
+ <p>πŸ“Š No models found with similarity β‰₯ ${threshold}</p>
590
+ <p style="font-size: 0.875rem;">Try lowering the similarity threshold to see more model relationships.</p>
591
+ </div>
592
+ \`;
593
+ return;
594
+ }
595
+
596
+ let timelineHTML = '';
597
+ filteredData.forEach(item => {
598
+ timelineHTML += \`
599
+ <div class="timeline-item">
600
+ <div class="timeline-date">\${item.date}</div>
601
+ <div class="timeline-model">\${item.model}</div>
602
+ <div class="timeline-similarity">
603
+ Similarity: \${item.similarity.toFixed(2)}
604
+ <span class="metric-badge">\${item.type}</span>
605
+ </div>
606
+ </div>
607
+ \`;
608
+ });
609
+
610
+ timelineDiv.innerHTML = timelineHTML;
611
+ loadingDiv.style.display = 'none';
612
+ timelineDiv.style.display = 'block';
613
+ }, 1000);
614
+ </script>
615
+ </body>
616
+ </html>`;
617
+
618
+ // Encode the HTML for the iframe
619
+ const encodedHtml = 'data:text/html;charset=utf-8,' + encodeURIComponent(timelineHtml);
620
+ timelineFrame.src = encodedHtml;
621
+
622
+ setTimeout(() => {
623
+ updateButton.textContent = 'Update Timeline';
624
+ updateButton.disabled = false;
625
+ }, 1000);
626
+ }
627
+
628
+ // Initial load
629
+ updateTimeline();
630
+
631
+ // Update on button click
632
+ updateButton.addEventListener('click', updateTimeline);
633
+
634
+ // Update on Enter key in slider
635
+ thresholdSlider.addEventListener('keydown', function(e) {
636
+ if (e.key === 'Enter') {
637
+ updateTimeline();
638
+ }
639
+ });
640
+ })();
641
+ </script></p>
642
  <p><div style="background: #f8f9fa; border: 1px solid #e9ecef; border-radius: 8px; padding: 1rem; margin: 1.5rem 0;">
643
  <h4 style="margin-top: 0; color: #495057;">Interactive Terminal</h4>
644
  <div style="background: #2d3748; color: #e2e8f0; padding: 1rem; border-radius: 6px; font-family: 'Consolas', 'Monaco', monospace;">
 
665
  <p>The yellow areas are places where models are very different to each other. We can see islands here and there corresponding to model families. Llava goes with Llava-onevision, LlavaNext, LlavaNext-video, etc.</p>
666
  <h2>VLM improvements, avoiding abstraction</h2>
667
  <p>We don’t have cookbook for common VLM patterns (image token scatter, multi‑tower encoders, cross‑attn bridges). This is one of the main improvement points where we can work.</p>
668
+ <p>For instance, I thought of abstracting away the mixing of <code>inputs_embeds</code>, the tensor fed into an llm decoder in 95% of the existing VLMs. It would have looked like something like</p>
669
  <pre><code class="language-python">class InputsEmbeddingMixerMixin(nn.Module):
670
  #
671
  </code></pre>
672
+ <p>But this is <a href="#standardize-dont-abstract">abstracting away an important component of the modeling.</a>. Embedding mixin is part of the model, removing it would break it. A user opening <code>modeling_qwen2.5_vl</code> should not have to go to another file.</p>
673
  <p>This is the current state of abstractions across a modeling file:</p>
674
  <p><img src="static/Bloatedness_visualizer.png" alt="Bloatedness visualizer showing abstraction levels"></p>
675
  <p>The following <a href="https://github.com/huggingface/transformers/pull/39777">Pull request to standardize placeholder masking</a> is a good example of what kind of changes are acceptable. In a VLM, we always need to insert embeddings from various encoders at various positions, so we can have a function to do it. For Qwen2 VL, for instance, it will look like this:</p>
 
717
  <h2>Modularity candidates</h2>
718
  <p>So the question abounds naturally: How can we modularize more?
719
  I took again a similarity measure and looked at the existing graphs. The tool is available on this <a href="https://huggingface.co/spaces/Molbap/transformers-modular-refactor">ZeroGPU-enabled Space</a>. It scans the whole transformers repository, and outputs a graph of candidates across models, using either a Jaccard similarity index (simple) or a SentenceTransformers embedding model. It is understandable that <a href="#encoders-ftw">encoder models still have a lion’s share of the game.</a> See also <a href="https://huggingface.co/blog/train-sparse-encoder">Tom Aarsen and Arhur Bresnu’s great blog post on the topic of sparse embeddings.</a>.</p>
720
+ <p><style>
721
+ .loc-growth-container {
722
+ margin: 2rem 0;
723
+ border: 1px solid #e5e7eb;
724
+ border-radius: 12px;
725
+ overflow: hidden;
726
+ background: white;
727
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
728
+ }
729
+
730
+ .loc-growth-header {
731
+ background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
732
+ color: white;
733
+ padding: 1rem 1.5rem;
734
+ }
735
+
736
+ .loc-growth-header h3 {
737
+ margin: 0;
738
+ font-size: 1.25rem;
739
+ font-weight: 600;
740
+ }
741
+
742
+ .loc-growth-controls {
743
+ padding: 1rem 1.5rem;
744
+ background: #f8f9fa;
745
+ border-bottom: 1px solid #e5e7eb;
746
+ display: flex;
747
+ gap: 1rem;
748
+ align-items: center;
749
+ flex-wrap: wrap;
750
+ }
751
+
752
+ .loc-growth-control {
753
+ display: flex;
754
+ align-items: center;
755
+ gap: 0.5rem;
756
+ }
757
+
758
+ .loc-growth-control label {
759
+ font-size: 0.875rem;
760
+ font-weight: 500;
761
+ color: #374151;
762
+ }
763
+
764
+ .loc-growth-control select {
765
+ padding: 0.5rem;
766
+ border: 1px solid #d1d5db;
767
+ border-radius: 6px;
768
+ background: white;
769
+ font-size: 0.875rem;
770
+ }
771
+
772
+ .loc-growth-control input[type="checkbox"] {
773
+ width: 16px;
774
+ height: 16px;
775
+ accent-color: #4facfe;
776
+ }
777
+
778
+ .loc-growth-iframe {
779
+ width: 100%;
780
+ height: 450px;
781
+ border: none;
782
+ background: white;
783
+ }
784
+
785
+ .loc-growth-footer {
786
+ padding: 1rem 1.5rem;
787
+ background: #f8f9fa;
788
+ font-size: 0.875rem;
789
+ color: #6b7280;
790
+ line-height: 1.5;
791
+ }
792
+ </style>
793
+
794
+ <div class="loc-growth-container">
795
+ <div class="loc-growth-header">
796
+ <h3 data-no-toc">πŸ“ˆ Lines of Code Growth Analysis</h3>
797
+ </div>
798
+
799
+ <div class="loc-growth-controls">
800
+ <div class="loc-growth-control">
801
+ <label for="similarity-metric">Similarity metric:</label>
802
+ <select id="similarity-metric">
803
+ <option value="jaccard">Jaccard</option>
804
+ <option value="embedding">Embedding</option>
805
+ </select>
806
+ </div>
807
+
808
+ <div class="loc-growth-control">
809
+ <input type="checkbox" id="loc-multimodal-only">
810
+ <label for="loc-multimodal-only">Only multimodal models</label>
811
+ </div>
812
+
813
+ <div class="loc-growth-control">
814
+ <button id="update-loc" style="padding: 0.5rem 1rem; background: #4facfe; color: white; border: none; border-radius: 6px; cursor: pointer; font-size: 0.875rem;">
815
+ Update Chart
816
+ </button>
817
+ </div>
818
+ </div>
819
+
820
+ <iframe id="loc-frame" class="loc-growth-iframe" src="about:blank"></iframe>
821
+
822
+ <div class="loc-growth-footer">
823
+ <strong>Lines of code growth</strong> showing how the codebase has evolved over time.
824
+ This analysis reveals the impact of modularization efforts on code duplication and maintainability.
825
+ Different similarity metrics provide insights into various aspects of code relationships.
826
+ </div>
827
+ </div>
828
+
829
+ <script>
830
+ (function() {
831
+ const metricSelect = document.getElementById('similarity-metric');
832
+ const multimodalCheckbox = document.getElementById('loc-multimodal-only');
833
+ const updateButton = document.getElementById('update-loc');
834
+ const locFrame = document.getElementById('loc-frame');
835
+
836
+ function updateLOC() {
837
+ const metric = metricSelect.value;
838
+ const multimodal = multimodalCheckbox.checked;
839
+
840
+ updateButton.textContent = 'Loading...';
841
+ updateButton.disabled = true;
842
+
843
+ // Create a LOC growth visualization
844
+ const locHtml = `
845
+ <!DOCTYPE html>
846
+ <html>
847
+ <head>
848
+ <script src="https://d3js.org/d3.v7.min.js"></script>
849
+ <style>
850
+ body { margin: 0; padding: 20px; font-family: system-ui, sans-serif; background: #fafafa; }
851
+ .loading { text-align: center; padding: 50px; color: #6b7280; }
852
+ .chart-container { background: white; border-radius: 8px; padding: 20px; }
853
+ .chart-title { text-align: center; font-weight: 600; margin-bottom: 20px; color: #374151; }
854
+ .axis { font-size: 12px; }
855
+ .line { fill: none; stroke-width: 2px; }
856
+ .line.total { stroke: #4facfe; }
857
+ .line.modular { stroke: #10b981; }
858
+ .line.non-modular { stroke: #f59e0b; }
859
+ .legend { font-size: 12px; }
860
+ .legend-item { margin-right: 20px; }
861
+ .legend-color { width: 12px; height: 12px; display: inline-block; margin-right: 5px; }
862
+ .tooltip {
863
+ position: absolute;
864
+ background: rgba(0,0,0,0.8);
865
+ color: white;
866
+ padding: 8px;
867
+ border-radius: 4px;
868
+ font-size: 12px;
869
+ pointer-events: none;
870
+ opacity: 0;
871
+ }
872
+ </style>
873
+ </head>
874
+ <body>
875
+ <div class="loading">Loading LOC growth analysis using ${metric} similarity${multimodal ? ' (multimodal only)' : ''}...</div>
876
+ <div class="chart-container" id="chart-content" style="display: none;">
877
+ <div class="chart-title">Lines of Code Growth Over Time</div>
878
+ <div class="legend" style="text-align: center; margin-bottom: 20px;">
879
+ <span class="legend-item">
880
+ <span class="legend-color" style="background: #4facfe;"></span>Total LOC
881
+ </span>
882
+ <span class="legend-item">
883
+ <span class="legend-color" style="background: #10b981;"></span>Modular Models
884
+ </span>
885
+ <span class="legend-item">
886
+ <span class="legend-color" style="background: #f59e0b;"></span>Non-Modular Models
887
+ </span>
888
+ </div>
889
+ <svg id="loc-chart" width="100%" height="300"></svg>
890
+ <div style="margin-top: 20px; font-size: 0.875rem; color: #6b7280; text-align: center;">
891
+ <p><strong>Key Insights:</strong></p>
892
+ <p>β€’ Modularization reduces code duplication and maintenance overhead</p>
893
+ <p>β€’ The ${metric} metric shows ${multimodal ? 'multimodal' : 'all'} model relationships</p>
894
+ <p>β€’ Growth trends indicate the effectiveness of the modular approach</p>
895
+ </div>
896
+ </div>
897
+ <div class="tooltip"></div>
898
+ <script>
899
+ // Sample LOC growth data
900
+ const sampleLOCData = [
901
+ { date: '2022-01', total: 125000, modular: 15000, nonModular: 110000 },
902
+ { date: '2022-06', total: 180000, modular: 35000, nonModular: 145000 },
903
+ { date: '2023-01', total: 220000, modular: 65000, nonModular: 155000 },
904
+ { date: '2023-06', total: 245000, modular: 95000, nonModular: 150000 },
905
+ { date: '2024-01', total: 260000, modular: 125000, nonModular: 135000 },
906
+ { date: '2024-06', total: 270000, modular: 155000, nonModular: 115000 }
907
+ ];
908
+
909
+ setTimeout(() => {
910
+ const loadingDiv = document.querySelector('.loading');
911
+ const chartDiv = document.getElementById('chart-content');
912
+
913
+ // Simple chart rendering
914
+ const svg = d3.select('#loc-chart');
915
+ const margin = {top: 20, right: 30, bottom: 40, left: 60};
916
+ const width = 500 - margin.left - margin.right;
917
+ const height = 300 - margin.top - margin.bottom;
918
+
919
+ const parseDate = d3.timeParse('%Y-%m');
920
+ const data = sampleLOCData.map(d => ({
921
+ ...d,
922
+ date: parseDate(d.date)
923
+ }));
924
+
925
+ const x = d3.scaleTime()
926
+ .domain(d3.extent(data, d => d.date))
927
+ .range([0, width]);
928
+
929
+ const y = d3.scaleLinear()
930
+ .domain([0, d3.max(data, d => d.total)])
931
+ .range([height, 0]);
932
+
933
+ const g = svg.append('g')
934
+ .attr('transform', \`translate(\${margin.left},\${margin.top})\`);
935
+
936
+ // Add axes
937
+ g.append('g')
938
+ .attr('transform', \`translate(0,\${height})\`)
939
+ .call(d3.axisBottom(x).tickFormat(d3.timeFormat('%Y-%m')));
940
+
941
+ g.append('g')
942
+ .call(d3.axisLeft(y).tickFormat(d => (d/1000) + 'k'));
943
+
944
+ // Add lines
945
+ const line = d3.line()
946
+ .x(d => x(d.date))
947
+ .y(d => y(d.value));
948
+
949
+ const lines = [
950
+ { key: 'total', color: '#4facfe', data: data.map(d => ({date: d.date, value: d.total})) },
951
+ { key: 'modular', color: '#10b981', data: data.map(d => ({date: d.date, value: d.modular})) },
952
+ { key: 'nonModular', color: '#f59e0b', data: data.map(d => ({date: d.date, value: d.nonModular})) }
953
+ ];
954
+
955
+ lines.forEach(lineData => {
956
+ g.append('path')
957
+ .datum(lineData.data)
958
+ .attr('class', 'line')
959
+ .attr('d', line)
960
+ .style('stroke', lineData.color);
961
+ });
962
+
963
+ loadingDiv.style.display = 'none';
964
+ chartDiv.style.display = 'block';
965
+ }, 1000);
966
+ </script>
967
+ </body>
968
+ </html>`;
969
+
970
+ // Encode the HTML for the iframe
971
+ const encodedHtml = 'data:text/html;charset=utf-8,' + encodeURIComponent(locHtml);
972
+ locFrame.src = encodedHtml;
973
+
974
+ setTimeout(() => {
975
+ updateButton.textContent = 'Update Chart';
976
+ updateButton.disabled = false;
977
+ }, 1000);
978
+ }
979
+
980
+ // Initial load
981
+ updateLOC();
982
+
983
+ // Update on button click
984
+ updateButton.addEventListener('click', updateLOC);
985
+ })();
986
+ </script></p>
987
  <h2><a id="encoders-ftw"></a> The neverending stories of encoder models.</h2>
988
  <p>Models popularity speaks for itself! This is because the usage of encoders lies in embeddings obviously. So we have to keep the encoders part viable, usable, fine-tune-able.</p>
989
  <p><img src="static/popular_models_barplot.png" alt="Popular models bar plot"></p>
 
1050
  <h3>Transformers-serve</h3>
1051
  <p>Having all these models readily available allows to use all of them with transformers-serve, and enable interfacing with them with an Open API-like pattern.</p>
1052
  <pre><code class="language-bash"># Start serving a model with transformers serve
1053
+ transformers serve
1054
 
1055
  # Query the model using OpenAI-compatible API
1056
+ curl -X POST http://localhost:8000/v1/chat/completions -H &quot;Content-Type: application/json&quot; -d '{&quot;messages&quot;: [{&quot;role&quot;: &quot;system&quot;, &quot;content&quot;: &quot;hello&quot;}], &quot;temperature&quot;: 0.9, &quot;max_tokens&quot;: 1000, &quot;stream&quot;: true, &quot;model&quot;: &quot;Qwen/Qwen2.5-0.5B-Instruct&quot;}'
 
 
 
 
 
 
1057
  </code></pre>
1058
  <p>This provides an OpenAI-compatible API with features like continuous batching for better GPU utilization.</p>
1059
  <h2>Community reusability</h2>
1060
  <p>Adding a model to transformers means:</p>
1061
  <ul>
1062
  <li>having it immediately available to the community</li>
1063
+ <li>usable in vLLM, SGLang, and so on without additional code. In April 2025, transformers was added as a backend to run models on vLLM, which optimizes throughput/latency on top of existing transformers architectures <a href="https://blog.vllm.ai/2025/04/11/transformers-backend.html">as seen in this great blog post.</a></li>
1064
  </ul>
1065
+ <p>This cements the need even more for a <a href="#consistent-public-surface">consistent public surface</a>: we are now a backend, and there’s more optimized software than us to handle serving. At the time of writing, more effort is done in that direction. We already have compatible configs for VLMs for vLLM (say that three times fast), <a href="https://github.com/huggingface/transformers/pull/40696/files">here for GLM4 video support</a>,</p>
1066
  <h2>Cooking faster CUDA warmups</h2>
1067
  <p>Having a clean <em>external</em> API allows us to work on the true inner workings of transformers. One of the few recent additions was the <em>CUDA warmup</em> via <code>caching_allocator_warmup</code> which improved massively the loading footprint by pre-allocating GPU memory to avoid malloc bottlenecks during model loading.</p>
1068
  <p><style>.warmup-demo body{background-color:#f5f5f5;margin:0;padding:20px;font-family:Segoe UI,Tahoma,Geneva,Verdana,sans-serif}.warmup-demo .container{background:#fff;border-radius:12px;max-width:1200px;margin:0 auto;padding:30px;box-shadow:0 4px 6px #0000001a}.warmup-demo h1{text-align:center;color:#333;margin-bottom:10px}.warmup-demo .subtitle{text-align:center;color:#666;margin-bottom:30px;font-size:16px}.warmup-demo .demo-container{gap:40px;margin-bottom:30px;display:flex}.warmup-demo .side{background:#fafafa;border:2px solid #ddd;border-radius:8px;flex:1;padding:20px}.warmup-demo .side h2{text-align:center;color:#333;margin-top:0}.warmup-demo .no-warmup h2{color:#d63384}.warmup-demo .with-warmup h2{color:#198754}.warmup-demo .memory-area{background:#fff;border:2px dashed #ccc;border-radius:6px;height:400px;margin:20px 0;padding:10px;position:relative;overflow:hidden}.warmup-demo .layer-box{background:#fff;border:2px solid #666;border-radius:4px;width:80px;height:30px;margin:3px;transition:all .3s;display:inline-block;position:relative}.warmup-demo .layer-box.allocating{background:#e9ecef;border-color:#adb5bd}.warmup-demo .layer-box.allocating:after{content:"malloc";color:#666;font-size:10px;font-weight:700;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.warmup-demo .layer-box.loaded{background:#d1e7dd;border-color:#198754}.warmup-demo .layer-box.loaded:after{content:"data";color:#198754;font-size:10px;font-weight:700;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.warmup-demo .warmup-container{background:#fff;border:3px solid #666;border-radius:6px;width:100%;height:60px;margin-bottom:20px;position:relative;overflow:hidden}.warmup-demo .warmup-container.allocated{background:#e7f1ff;border-color:#0d6efd}.warmup-demo .warmup-container:before{content:"Pre-allocated Memory Pool";color:#666;z-index:1;font-size:14px;font-weight:700;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.warmup-demo .warmup-container.allocated:before{color:#0d6efd}.warmup-demo .warmup-fill{z-index:2;background:linear-gradient(90deg,#198754,#20c997);border-radius:3px;width:0%;height:100%;transition:width .5s;position:relative}.warmup-demo .warmup-fill:after{content:"Layer Data Loading";color:#fff;white-space:nowrap;font-size:12px;font-weight:700;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.warmup-demo .timing{text-align:center;min-height:30px;margin:15px 0;font-size:24px;font-weight:700}.warmup-demo .no-warmup .timing{color:#d63384}.warmup-demo .with-warmup .timing{color:#198754}.warmup-demo .controls{text-align:center;margin:30px 0}.warmup-demo .btn{color:#fff;cursor:pointer;background:#0d6efd;border:none;border-radius:6px;margin:0 10px;padding:12px 24px;font-size:16px;transition:background .3s}.warmup-demo .btn:hover{background:#0b5ed7}.warmup-demo .btn:disabled{cursor:not-allowed;background:#6c757d}.warmup-demo .description{background:#f8f9fa;border-radius:6px;margin-top:15px;padding:15px;font-size:14px;line-height:1.5}.warmup-demo .phase-indicator{color:#666;text-align:center;min-height:20px;margin-top:10px;font-size:14px}.warmup-demo .layer-counter{text-align:center;color:#495057;margin:10px 0;font-size:16px}</style>
src/fragments/dependency-graph.html ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script type="module" src="https://gradio.s3-us-west-2.amazonaws.com/4.0/gradio.js"></script>
2
+
3
+ <section id="modular-explorer" data-no-toc style="margin:2rem 0">
4
+ <h2 style="margin:0 0 .5rem 0">πŸ” Modular-candidate explorer (live)</h2>
5
+ <div style="position:relative; padding-top:62.5%; border:1px solid rgba(0,0,0,.08); border-radius:12px; overflow:hidden; background:#fff">
6
+ <gradio-app
7
+ src="https://molbap-transformers-modular-refactor.hf.space?tab=graph"
8
+ style="position:absolute; inset:0; width:100%; height:100%; border:0"
9
+ ></gradio-app>
10
+ </div>
11
+ <p class="figcaption" style="margin:.6rem 0 0 0">
12
+ Opens full app: <a href="https://huggingface.co/spaces/Molbap/transformers-modular-refactor" target="_blank" rel="noopener">Space page</a>.
13
+ </p>
14
+ </section>
src/fragments/loc-growth.html ADDED
@@ -0,0 +1,267 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <style>
2
+ .loc-growth-container {
3
+ margin: 2rem 0;
4
+ border: 1px solid #e5e7eb;
5
+ border-radius: 12px;
6
+ overflow: hidden;
7
+ background: white;
8
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
9
+ }
10
+
11
+ .loc-growth-header {
12
+ background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
13
+ color: white;
14
+ padding: 1rem 1.5rem;
15
+ }
16
+
17
+ .loc-growth-header h3 {
18
+ margin: 0;
19
+ font-size: 1.25rem;
20
+ font-weight: 600;
21
+ }
22
+
23
+ .loc-growth-controls {
24
+ padding: 1rem 1.5rem;
25
+ background: #f8f9fa;
26
+ border-bottom: 1px solid #e5e7eb;
27
+ display: flex;
28
+ gap: 1rem;
29
+ align-items: center;
30
+ flex-wrap: wrap;
31
+ }
32
+
33
+ .loc-growth-control {
34
+ display: flex;
35
+ align-items: center;
36
+ gap: 0.5rem;
37
+ }
38
+
39
+ .loc-growth-control label {
40
+ font-size: 0.875rem;
41
+ font-weight: 500;
42
+ color: #374151;
43
+ }
44
+
45
+ .loc-growth-control select {
46
+ padding: 0.5rem;
47
+ border: 1px solid #d1d5db;
48
+ border-radius: 6px;
49
+ background: white;
50
+ font-size: 0.875rem;
51
+ }
52
+
53
+ .loc-growth-control input[type="checkbox"] {
54
+ width: 16px;
55
+ height: 16px;
56
+ accent-color: #4facfe;
57
+ }
58
+
59
+ .loc-growth-iframe {
60
+ width: 100%;
61
+ height: 450px;
62
+ border: none;
63
+ background: white;
64
+ }
65
+
66
+ .loc-growth-footer {
67
+ padding: 1rem 1.5rem;
68
+ background: #f8f9fa;
69
+ font-size: 0.875rem;
70
+ color: #6b7280;
71
+ line-height: 1.5;
72
+ }
73
+ </style>
74
+
75
+ <div class="loc-growth-container">
76
+ <div class="loc-growth-header">
77
+ <h3 data-no-toc">πŸ“ˆ Lines of Code Growth Analysis</h3>
78
+ </div>
79
+
80
+ <div class="loc-growth-controls">
81
+ <div class="loc-growth-control">
82
+ <label for="similarity-metric">Similarity metric:</label>
83
+ <select id="similarity-metric">
84
+ <option value="jaccard">Jaccard</option>
85
+ <option value="embedding">Embedding</option>
86
+ </select>
87
+ </div>
88
+
89
+ <div class="loc-growth-control">
90
+ <input type="checkbox" id="loc-multimodal-only">
91
+ <label for="loc-multimodal-only">Only multimodal models</label>
92
+ </div>
93
+
94
+ <div class="loc-growth-control">
95
+ <button id="update-loc" style="padding: 0.5rem 1rem; background: #4facfe; color: white; border: none; border-radius: 6px; cursor: pointer; font-size: 0.875rem;">
96
+ Update Chart
97
+ </button>
98
+ </div>
99
+ </div>
100
+
101
+ <iframe id="loc-frame" class="loc-growth-iframe" src="about:blank"></iframe>
102
+
103
+ <div class="loc-growth-footer">
104
+ <strong>Lines of code growth</strong> showing how the codebase has evolved over time.
105
+ This analysis reveals the impact of modularization efforts on code duplication and maintainability.
106
+ Different similarity metrics provide insights into various aspects of code relationships.
107
+ </div>
108
+ </div>
109
+
110
+ <script>
111
+ (function() {
112
+ const metricSelect = document.getElementById('similarity-metric');
113
+ const multimodalCheckbox = document.getElementById('loc-multimodal-only');
114
+ const updateButton = document.getElementById('update-loc');
115
+ const locFrame = document.getElementById('loc-frame');
116
+
117
+ function updateLOC() {
118
+ const metric = metricSelect.value;
119
+ const multimodal = multimodalCheckbox.checked;
120
+
121
+ updateButton.textContent = 'Loading...';
122
+ updateButton.disabled = true;
123
+
124
+ // Create a LOC growth visualization
125
+ const locHtml = `
126
+ <!DOCTYPE html>
127
+ <html>
128
+ <head>
129
+ <script src="https://d3js.org/d3.v7.min.js"></script>
130
+ <style>
131
+ body { margin: 0; padding: 20px; font-family: system-ui, sans-serif; background: #fafafa; }
132
+ .loading { text-align: center; padding: 50px; color: #6b7280; }
133
+ .chart-container { background: white; border-radius: 8px; padding: 20px; }
134
+ .chart-title { text-align: center; font-weight: 600; margin-bottom: 20px; color: #374151; }
135
+ .axis { font-size: 12px; }
136
+ .line { fill: none; stroke-width: 2px; }
137
+ .line.total { stroke: #4facfe; }
138
+ .line.modular { stroke: #10b981; }
139
+ .line.non-modular { stroke: #f59e0b; }
140
+ .legend { font-size: 12px; }
141
+ .legend-item { margin-right: 20px; }
142
+ .legend-color { width: 12px; height: 12px; display: inline-block; margin-right: 5px; }
143
+ .tooltip {
144
+ position: absolute;
145
+ background: rgba(0,0,0,0.8);
146
+ color: white;
147
+ padding: 8px;
148
+ border-radius: 4px;
149
+ font-size: 12px;
150
+ pointer-events: none;
151
+ opacity: 0;
152
+ }
153
+ </style>
154
+ </head>
155
+ <body>
156
+ <div class="loading">Loading LOC growth analysis using ${metric} similarity${multimodal ? ' (multimodal only)' : ''}...</div>
157
+ <div class="chart-container" id="chart-content" style="display: none;">
158
+ <div class="chart-title">Lines of Code Growth Over Time</div>
159
+ <div class="legend" style="text-align: center; margin-bottom: 20px;">
160
+ <span class="legend-item">
161
+ <span class="legend-color" style="background: #4facfe;"></span>Total LOC
162
+ </span>
163
+ <span class="legend-item">
164
+ <span class="legend-color" style="background: #10b981;"></span>Modular Models
165
+ </span>
166
+ <span class="legend-item">
167
+ <span class="legend-color" style="background: #f59e0b;"></span>Non-Modular Models
168
+ </span>
169
+ </div>
170
+ <svg id="loc-chart" width="100%" height="300"></svg>
171
+ <div style="margin-top: 20px; font-size: 0.875rem; color: #6b7280; text-align: center;">
172
+ <p><strong>Key Insights:</strong></p>
173
+ <p>β€’ Modularization reduces code duplication and maintenance overhead</p>
174
+ <p>β€’ The ${metric} metric shows ${multimodal ? 'multimodal' : 'all'} model relationships</p>
175
+ <p>β€’ Growth trends indicate the effectiveness of the modular approach</p>
176
+ </div>
177
+ </div>
178
+ <div class="tooltip"></div>
179
+ <script>
180
+ // Sample LOC growth data
181
+ const sampleLOCData = [
182
+ { date: '2022-01', total: 125000, modular: 15000, nonModular: 110000 },
183
+ { date: '2022-06', total: 180000, modular: 35000, nonModular: 145000 },
184
+ { date: '2023-01', total: 220000, modular: 65000, nonModular: 155000 },
185
+ { date: '2023-06', total: 245000, modular: 95000, nonModular: 150000 },
186
+ { date: '2024-01', total: 260000, modular: 125000, nonModular: 135000 },
187
+ { date: '2024-06', total: 270000, modular: 155000, nonModular: 115000 }
188
+ ];
189
+
190
+ setTimeout(() => {
191
+ const loadingDiv = document.querySelector('.loading');
192
+ const chartDiv = document.getElementById('chart-content');
193
+
194
+ // Simple chart rendering
195
+ const svg = d3.select('#loc-chart');
196
+ const margin = {top: 20, right: 30, bottom: 40, left: 60};
197
+ const width = 500 - margin.left - margin.right;
198
+ const height = 300 - margin.top - margin.bottom;
199
+
200
+ const parseDate = d3.timeParse('%Y-%m');
201
+ const data = sampleLOCData.map(d => ({
202
+ ...d,
203
+ date: parseDate(d.date)
204
+ }));
205
+
206
+ const x = d3.scaleTime()
207
+ .domain(d3.extent(data, d => d.date))
208
+ .range([0, width]);
209
+
210
+ const y = d3.scaleLinear()
211
+ .domain([0, d3.max(data, d => d.total)])
212
+ .range([height, 0]);
213
+
214
+ const g = svg.append('g')
215
+ .attr('transform', \`translate(\${margin.left},\${margin.top})\`);
216
+
217
+ // Add axes
218
+ g.append('g')
219
+ .attr('transform', \`translate(0,\${height})\`)
220
+ .call(d3.axisBottom(x).tickFormat(d3.timeFormat('%Y-%m')));
221
+
222
+ g.append('g')
223
+ .call(d3.axisLeft(y).tickFormat(d => (d/1000) + 'k'));
224
+
225
+ // Add lines
226
+ const line = d3.line()
227
+ .x(d => x(d.date))
228
+ .y(d => y(d.value));
229
+
230
+ const lines = [
231
+ { key: 'total', color: '#4facfe', data: data.map(d => ({date: d.date, value: d.total})) },
232
+ { key: 'modular', color: '#10b981', data: data.map(d => ({date: d.date, value: d.modular})) },
233
+ { key: 'nonModular', color: '#f59e0b', data: data.map(d => ({date: d.date, value: d.nonModular})) }
234
+ ];
235
+
236
+ lines.forEach(lineData => {
237
+ g.append('path')
238
+ .datum(lineData.data)
239
+ .attr('class', 'line')
240
+ .attr('d', line)
241
+ .style('stroke', lineData.color);
242
+ });
243
+
244
+ loadingDiv.style.display = 'none';
245
+ chartDiv.style.display = 'block';
246
+ }, 1000);
247
+ </script>
248
+ </body>
249
+ </html>`;
250
+
251
+ // Encode the HTML for the iframe
252
+ const encodedHtml = 'data:text/html;charset=utf-8,' + encodeURIComponent(locHtml);
253
+ locFrame.src = encodedHtml;
254
+
255
+ setTimeout(() => {
256
+ updateButton.textContent = 'Update Chart';
257
+ updateButton.disabled = false;
258
+ }, 1000);
259
+ }
260
+
261
+ // Initial load
262
+ updateLOC();
263
+
264
+ // Update on button click
265
+ updateButton.addEventListener('click', updateLOC);
266
+ })();
267
+ </script>
src/fragments/model-timeline.html ADDED
@@ -0,0 +1,254 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <style>
2
+ .model-timeline-container {
3
+ margin: 2rem 0;
4
+ border: 1px solid #e5e7eb;
5
+ border-radius: 12px;
6
+ overflow: hidden;
7
+ background: white;
8
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
9
+ }
10
+
11
+ .model-timeline-header {
12
+ background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
13
+ color: white;
14
+ padding: 1rem 1.5rem;
15
+ }
16
+
17
+ .model-timeline-header h3 {
18
+ margin: 0;
19
+ font-size: 1.25rem;
20
+ font-weight: 600;
21
+ }
22
+
23
+ .model-timeline-controls {
24
+ padding: 1rem 1.5rem;
25
+ background: #f8f9fa;
26
+ border-bottom: 1px solid #e5e7eb;
27
+ display: flex;
28
+ gap: 1rem;
29
+ align-items: center;
30
+ flex-wrap: wrap;
31
+ }
32
+
33
+ .model-timeline-control {
34
+ display: flex;
35
+ align-items: center;
36
+ gap: 0.5rem;
37
+ }
38
+
39
+ .model-timeline-control label {
40
+ font-size: 0.875rem;
41
+ font-weight: 500;
42
+ color: #374151;
43
+ }
44
+
45
+ .model-timeline-control input[type="range"] {
46
+ width: 120px;
47
+ height: 4px;
48
+ background: #e5e7eb;
49
+ border-radius: 2px;
50
+ outline: none;
51
+ -webkit-appearance: none;
52
+ }
53
+
54
+ .model-timeline-control input[type="range"]::-webkit-slider-thumb {
55
+ -webkit-appearance: none;
56
+ width: 16px;
57
+ height: 16px;
58
+ background: #f5576c;
59
+ border-radius: 50%;
60
+ cursor: pointer;
61
+ }
62
+
63
+ .model-timeline-control input[type="checkbox"] {
64
+ width: 16px;
65
+ height: 16px;
66
+ accent-color: #f5576c;
67
+ }
68
+
69
+ .model-timeline-control .threshold-value {
70
+ font-weight: 600;
71
+ color: #f5576c;
72
+ min-width: 40px;
73
+ }
74
+
75
+ .model-timeline-iframe {
76
+ width: 100%;
77
+ height: 500px;
78
+ border: none;
79
+ background: white;
80
+ }
81
+
82
+ .model-timeline-footer {
83
+ padding: 1rem 1.5rem;
84
+ background: #f8f9fa;
85
+ font-size: 0.875rem;
86
+ color: #6b7280;
87
+ line-height: 1.5;
88
+ }
89
+ </style>
90
+
91
+ <div class="model-timeline-container">
92
+ <div class="model-timeline-header">
93
+ <h3 data-no-toc">πŸ“… Model Evolution Timeline</h3>
94
+ </div>
95
+
96
+ <div class="model-timeline-controls">
97
+ <div class="model-timeline-control">
98
+ <label for="timeline-similarity-threshold">Similarity β‰₯</label>
99
+ <input type="range" id="timeline-similarity-threshold" min="0.5" max="0.95" step="0.01" value="0.6">
100
+ <span class="threshold-value" id="timeline-threshold-display">0.60</span>
101
+ </div>
102
+
103
+ <div class="model-timeline-control">
104
+ <input type="checkbox" id="timeline-multimodal-only">
105
+ <label for="timeline-multimodal-only">Only multimodal models</label>
106
+ </div>
107
+
108
+ <div class="model-timeline-control">
109
+ <button id="update-timeline" style="padding: 0.5rem 1rem; background: #f5576c; color: white; border: none; border-radius: 6px; cursor: pointer; font-size: 0.875rem;">
110
+ Update Timeline
111
+ </button>
112
+ </div>
113
+ </div>
114
+
115
+ <iframe id="timeline-frame" class="model-timeline-iframe" src="about:blank"></iframe>
116
+
117
+ <div class="model-timeline-footer">
118
+ <strong>Chronological model evolution</strong> showing when similar models were added to the library.
119
+ This timeline helps identify patterns in model development and the emergence of model families over time.
120
+ Higher similarity thresholds reveal closer relationships between models.
121
+ </div>
122
+ </div>
123
+
124
+ <script>
125
+ (function() {
126
+ const thresholdSlider = document.getElementById('timeline-similarity-threshold');
127
+ const thresholdDisplay = document.getElementById('timeline-threshold-display');
128
+ const multimodalCheckbox = document.getElementById('timeline-multimodal-only');
129
+ const updateButton = document.getElementById('update-timeline');
130
+ const timelineFrame = document.getElementById('timeline-frame');
131
+
132
+ // Update threshold display
133
+ thresholdSlider.addEventListener('input', function() {
134
+ thresholdDisplay.textContent = parseFloat(this.value).toFixed(2);
135
+ });
136
+
137
+ function updateTimeline() {
138
+ const threshold = parseFloat(thresholdSlider.value);
139
+ const multimodal = multimodalCheckbox.checked;
140
+
141
+ updateButton.textContent = 'Loading...';
142
+ updateButton.disabled = true;
143
+
144
+ // Create a timeline visualization
145
+ const timelineHtml = `
146
+ <!DOCTYPE html>
147
+ <html>
148
+ <head>
149
+ <script src="https://d3js.org/d3.v7.min.js"></script>
150
+ <style>
151
+ body { margin: 0; padding: 20px; font-family: system-ui, sans-serif; background: #fafafa; }
152
+ .loading { text-align: center; padding: 50px; color: #6b7280; }
153
+ .timeline-container { max-width: 100%; margin: 0 auto; }
154
+ .timeline-item {
155
+ background: white;
156
+ margin: 10px 0;
157
+ padding: 15px;
158
+ border-radius: 8px;
159
+ border-left: 4px solid #f5576c;
160
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
161
+ }
162
+ .timeline-date { font-weight: 600; color: #f5576c; font-size: 0.875rem; }
163
+ .timeline-model { font-weight: 500; margin: 5px 0; }
164
+ .timeline-similarity { font-size: 0.75rem; color: #6b7280; }
165
+ .metric-badge {
166
+ display: inline-block;
167
+ background: #f3f4f6;
168
+ padding: 2px 8px;
169
+ border-radius: 12px;
170
+ font-size: 0.75rem;
171
+ margin-left: 10px;
172
+ }
173
+ </style>
174
+ </head>
175
+ <body>
176
+ <div class="loading">Loading model timeline with threshold β‰₯ ${threshold}${multimodal ? ' (multimodal only)' : ''}...</div>
177
+ <div class="timeline-container" id="timeline-content" style="display: none;">
178
+ <!-- Timeline content will be inserted here -->
179
+ </div>
180
+ <script>
181
+ // Sample timeline data (in a real implementation, this would come from the API)
182
+ const sampleTimelineData = [
183
+ { date: '2023-01', model: 'LLaVA-1.5', similarity: 0.85, type: 'multimodal' },
184
+ { date: '2023-03', model: 'LLaVA-NeXT', similarity: 0.92, type: 'multimodal' },
185
+ { date: '2023-06', model: 'Qwen-VL', similarity: 0.71, type: 'multimodal' },
186
+ { date: '2023-09', model: 'LLaVA-NeXT-Video', similarity: 0.88, type: 'multimodal' },
187
+ { date: '2024-01', model: 'Qwen2-VL', similarity: 0.76, type: 'multimodal' }
188
+ ];
189
+
190
+ setTimeout(() => {
191
+ const filteredData = sampleTimelineData.filter(item => {
192
+ if (${multimodal} && item.type !== 'multimodal') return false;
193
+ return item.similarity >= ${threshold};
194
+ });
195
+
196
+ const loadingDiv = document.querySelector('.loading');
197
+ const timelineDiv = document.getElementById('timeline-content');
198
+
199
+ if (filteredData.length === 0) {
200
+ loadingDiv.innerHTML = \`
201
+ <div style="text-align: center; padding: 40px; color: #6b7280;">
202
+ <p>πŸ“Š No models found with similarity β‰₯ ${threshold}</p>
203
+ <p style="font-size: 0.875rem;">Try lowering the similarity threshold to see more model relationships.</p>
204
+ </div>
205
+ \`;
206
+ return;
207
+ }
208
+
209
+ let timelineHTML = '';
210
+ filteredData.forEach(item => {
211
+ timelineHTML += \`
212
+ <div class="timeline-item">
213
+ <div class="timeline-date">\${item.date}</div>
214
+ <div class="timeline-model">\${item.model}</div>
215
+ <div class="timeline-similarity">
216
+ Similarity: \${item.similarity.toFixed(2)}
217
+ <span class="metric-badge">\${item.type}</span>
218
+ </div>
219
+ </div>
220
+ \`;
221
+ });
222
+
223
+ timelineDiv.innerHTML = timelineHTML;
224
+ loadingDiv.style.display = 'none';
225
+ timelineDiv.style.display = 'block';
226
+ }, 1000);
227
+ </script>
228
+ </body>
229
+ </html>`;
230
+
231
+ // Encode the HTML for the iframe
232
+ const encodedHtml = 'data:text/html;charset=utf-8,' + encodeURIComponent(timelineHtml);
233
+ timelineFrame.src = encodedHtml;
234
+
235
+ setTimeout(() => {
236
+ updateButton.textContent = 'Update Timeline';
237
+ updateButton.disabled = false;
238
+ }, 1000);
239
+ }
240
+
241
+ // Initial load
242
+ updateTimeline();
243
+
244
+ // Update on button click
245
+ updateButton.addEventListener('click', updateTimeline);
246
+
247
+ // Update on Enter key in slider
248
+ thresholdSlider.addEventListener('keydown', function(e) {
249
+ if (e.key === 'Enter') {
250
+ updateTimeline();
251
+ }
252
+ });
253
+ })();
254
+ </script>
src/fragments/modular-growth.html DELETED
@@ -1,18 +0,0 @@
1
- <section id="modular-growth-space" class="l-body">
2
- <h2>Modular growth (interactive)</h2>
3
- <p class="l-page">Explore live graphs and metrics from the accompanying Space.</p>
4
- <div style="position:relative;padding-top:62.5%;border:1px solid rgba(255,255,255,.08);border-radius:12px;overflow:hidden">
5
- <iframe
6
- src="https://molbap-transformers-modular-refactor.hf.space"
7
- title="Transformers Modular Refactor Space"
8
- style="position:absolute;inset:0;border:0;width:100%;height:100%;"
9
- loading="lazy"
10
- referrerpolicy="no-referrer-when-downgrade"
11
- allow="clipboard-read; clipboard-write; fullscreen; autoplay"
12
- ></iframe>
13
- </div>
14
- <p class="l-page" style="margin-top:.6rem">
15
- Open in a new tab: <a href="https://huggingface.co/spaces/Molbap/transformers-modular-refactor" target="_blank" rel="noopener">Space README & details</a>.
16
- </p>
17
- </section>
18
-