push
Browse files- dist/fragments/dependency-graph.html +14 -0
- dist/fragments/loc-growth.html +267 -0
- dist/fragments/model-timeline.html +254 -0
- dist/fragments/modular-growth.html +0 -18
- dist/index.html +558 -26
- src/fragments/dependency-graph.html +14 -0
- src/fragments/loc-growth.html +267 -0
- src/fragments/model-timeline.html +254 -0
- src/fragments/modular-growth.html +0 -18
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>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 334 |
<h2><a id="community-kernels"></a>Community Kernels</h2>
|
| 335 |
-
<p>The same principle extends to normalization, activation, and other
|
| 336 |
<pre><code class="language-python">@use_kernel_forward_from_hub("RMSNorm")
|
| 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 |
-
<
|
| 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>
|
| 398 |
<pre><code class="language-python">class InputsEmbeddingMixerMixin(nn.Module):
|
| 399 |
#
|
| 400 |
</code></pre>
|
| 401 |
-
<p>But this is
|
| 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
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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
|
| 517 |
|
| 518 |
# Query the model using OpenAI-compatible API
|
| 519 |
-
curl -X POST http://localhost:8000/v1/chat/completions
|
| 520 |
-
-H "Content-Type: application/json" \
|
| 521 |
-
-d "{
|
| 522 |
-
\"model\": \"microsoft/DialoGPT-medium\",
|
| 523 |
-
\"messages\": [{\"role\": \"user\", \"content\": \"Hello, how are you?\"}],
|
| 524 |
-
\"max_tokens\": 50
|
| 525 |
-
}"
|
| 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 |
+
"full_attention",
|
| 336 |
+
"sliding_attention",
|
| 337 |
+
"chunked_attention",
|
| 338 |
+
"linear_attention",
|
| 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"> "layer_types": [
|
| 344 |
+
"sliding_attention",
|
| 345 |
+
"full_attention",
|
| 346 |
+
...,
|
| 347 |
+
"sliding_attention",
|
| 348 |
+
"full_attention"
|
| 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("RMSNorm")
|
| 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 "Content-Type: application/json" -d '{"messages": [{"role": "system", "content": "hello"}], "temperature": 0.9, "max_tokens": 1000, "stream": true, "model": "Qwen/Qwen2.5-0.5B-Instruct"}'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|