big update
Browse files- content/article.md +15 -3
- dist/distill.bundle.js.map +0 -0
- dist/fragments/attention-visualizer.html +64 -8
- dist/fragments/d3-graph.html +5 -5
- dist/fragments/glm-compare.html +7 -7
- dist/fragments/modular-growth.html +18 -0
- dist/fragments/terminal.html +32 -11
- dist/fragments/tp-plan.html +24 -0
- dist/fragments/warmup_demo.html +398 -0
- dist/index.html +98 -38
- dist/main.bundle.js +4 -4
- dist/main.bundle.js.map +0 -0
- dist/style.css +1 -1
- src/fragments/tp-plan.html +22 -25
- src/fragments/warmup_demo.html +341 -364
- webpack.config.js +12 -8
content/article.md
CHANGED
|
@@ -2,13 +2,24 @@
|
|
| 2 |
## Introduction
|
| 3 |
|
| 4 |
The `transformers` library, built with `PyTorch`, supports all state-of-the-art LLMs, many VLMs, task-specific vision language models, video models, audio models, table models, classical encoders, to a global count of almost 400 models.
|
|
|
|
| 5 |
The name of the library itself is mostly majority driven as many models are not even transformers architectures, like Mamba, Zamba, RWKV, and convolution-based models.
|
|
|
|
| 6 |
Regardless, each of these is wrought by the research and engineering team that created them, then harmonized into a now famous interface, and callable with a simple `.from_pretrained` command.
|
|
|
|
| 7 |
Inference works for all models, training is functional for most. The library is a foundation for many machine learning courses, cookbooks, and overall, several thousands other open-source libraries depend on it. All models are tested as part of a daily CI ensuring their preservation and reproducibility. Most importantly, it is _open-source_ and has been written by the community for a large part.
|
| 8 |
This isn't really to brag but to set the stakes: what does it take to keep such a ship afloat, made of so many moving, unrelated parts?
|
|
|
|
| 9 |
The ML wave has not stopped, there's more and more models being added, at a steadily growing rate. `Transformers` is widely used, and we read the feedback that users post online. Whether it's about a function that had 300+ keyword arguments, duplicated code and helpers, and mentions of `Copied from ... ` everywhere, along with optimisation concerns. Text-only models are relatively tamed, but multimodal models remain to be harmonized.
|
| 10 |
|
| 11 |
-
Here we will dissect what is the new design philosophy of transformers, as a continuation from the existing older [philosophy](https://huggingface.co/docs/transformers/en/philosophy) page, and an accompanying [blog post from 2022](https://huggingface.co/blog/transformers-design-philosophy)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12 |
|
| 13 |
### What you will learn
|
| 14 |
|
|
@@ -325,14 +336,15 @@ curl -X POST http://localhost:8000/v1/chat/completions \
|
|
| 325 |
```
|
| 326 |
|
| 327 |
This provides an OpenAI-compatible API with features like continuous batching for better GPU utilization.
|
|
|
|
| 328 |
## Community reusability
|
| 329 |
|
| 330 |
|
| 331 |
Adding a model to transformers means:
|
| 332 |
- having it immediately available to the community
|
| 333 |
-
- usable in vLLM, SGLang, and so on without additional code.
|
| 334 |
|
| 335 |
-
##
|
| 336 |
|
| 337 |
Having a clean _external_ API allows us to work on the true inner workings of transformers. One of the few recent additions was the _CUDA warmup_ via `caching_allocator_warmup` which improved massively the loading footprint by pre-allocating GPU memory to avoid malloc bottlenecks during model loading.
|
| 338 |
|
|
|
|
| 2 |
## Introduction
|
| 3 |
|
| 4 |
The `transformers` library, built with `PyTorch`, supports all state-of-the-art LLMs, many VLMs, task-specific vision language models, video models, audio models, table models, classical encoders, to a global count of almost 400 models.
|
| 5 |
+
|
| 6 |
The name of the library itself is mostly majority driven as many models are not even transformers architectures, like Mamba, Zamba, RWKV, and convolution-based models.
|
| 7 |
+
|
| 8 |
Regardless, each of these is wrought by the research and engineering team that created them, then harmonized into a now famous interface, and callable with a simple `.from_pretrained` command.
|
| 9 |
+
|
| 10 |
Inference works for all models, training is functional for most. The library is a foundation for many machine learning courses, cookbooks, and overall, several thousands other open-source libraries depend on it. All models are tested as part of a daily CI ensuring their preservation and reproducibility. Most importantly, it is _open-source_ and has been written by the community for a large part.
|
| 11 |
This isn't really to brag but to set the stakes: what does it take to keep such a ship afloat, made of so many moving, unrelated parts?
|
| 12 |
+
|
| 13 |
The ML wave has not stopped, there's more and more models being added, at a steadily growing rate. `Transformers` is widely used, and we read the feedback that users post online. Whether it's about a function that had 300+ keyword arguments, duplicated code and helpers, and mentions of `Copied from ... ` everywhere, along with optimisation concerns. Text-only models are relatively tamed, but multimodal models remain to be harmonized.
|
| 14 |
|
| 15 |
+
Here we will dissect what is the new design philosophy of transformers, as a continuation from the existing older [philosophy](https://huggingface.co/docs/transformers/en/philosophy) page, and an accompanying [blog post from 2022](https://huggingface.co/blog/transformers-design-philosophy).
|
| 16 |
+
|
| 17 |
+
More recently, and I recommend the read if it's not done yet, a blog post about [recent upgrades to transformers](https://huggingface.co/blog/faster-transformers) was written, explaining in particular what makes the library faster today.
|
| 18 |
+
|
| 19 |
+
Some time ago I dare not say how long, we discussed with transformers maintainers about the state of features in transformers. A lot of recent developments were satisfactory, but if we were only talking about these, self-congratulation would be the only goalpost.
|
| 20 |
+
|
| 21 |
+
Reflecting on this philosophy now, as models pile up, is essential and will drive new developments.
|
| 22 |
+
|
| 23 |
|
| 24 |
### What you will learn
|
| 25 |
|
|
|
|
| 336 |
```
|
| 337 |
|
| 338 |
This provides an OpenAI-compatible API with features like continuous batching for better GPU utilization.
|
| 339 |
+
|
| 340 |
## Community reusability
|
| 341 |
|
| 342 |
|
| 343 |
Adding a model to transformers means:
|
| 344 |
- having it immediately available to the community
|
| 345 |
+
- usable in vLLM, SGLang, and so on without additional code.
|
| 346 |
|
| 347 |
+
## Cooking faster CUDA warmups
|
| 348 |
|
| 349 |
Having a clean _external_ API allows us to work on the true inner workings of transformers. One of the few recent additions was the _CUDA warmup_ via `caching_allocator_warmup` which improved massively the loading footprint by pre-allocating GPU memory to avoid malloc bottlenecks during model loading.
|
| 350 |
|
dist/distill.bundle.js.map
CHANGED
|
The diff for this file is too large to render.
See raw diff
|
|
|
dist/fragments/attention-visualizer.html
CHANGED
|
@@ -10,16 +10,16 @@
|
|
| 10 |
<div style="display: grid; grid-template-columns: 1fr auto; gap: 1rem; align-items: start; margin-bottom: 1rem;">
|
| 11 |
<div>
|
| 12 |
<label style="display: block; font-weight: 600; margin-bottom: 0.5rem; color: #374151;">Model:</label>
|
| 13 |
-
<select id=model-select style="width: 100%; padding: 0.5rem; border: 1px solid #d1d5db; border-radius: 6px; background: white;">
|
| 14 |
-
<option value=openai-community/gpt2>openai-community/gpt2</option>
|
| 15 |
-
<option value=google/gemma-2-2b>google/gemma-2-2b</option>
|
| 16 |
-
<option value=microsoft/DialoGPT-small>microsoft/DialoGPT-small</option>
|
| 17 |
</select>
|
| 18 |
</div>
|
| 19 |
|
| 20 |
<div>
|
| 21 |
<label style="display: block; font-weight: 600; margin-bottom: 0.5rem; color: #374151;">Action:</label>
|
| 22 |
-
<button id=visualize-btn style="padding: 0.5rem 1rem; background: #3b82f6; color: white; border: none; border-radius: 6px; cursor: pointer; font-weight: 500;">
|
| 23 |
🚀 Visualize
|
| 24 |
</button>
|
| 25 |
</div>
|
|
@@ -27,10 +27,13 @@
|
|
| 27 |
|
| 28 |
<div style="margin-bottom: 1rem;">
|
| 29 |
<label style="display: block; font-weight: 600; margin-bottom: 0.5rem; color: #374151;">Prompt:</label>
|
| 30 |
-
<textarea id=prompt-input
|
|
|
|
|
|
|
|
|
|
| 31 |
</div>
|
| 32 |
|
| 33 |
-
<div id=attention-output style="min-height: 200px; background: #f8f9fa; border: 1px solid #e9ecef; border-radius: 6px; padding: 1rem;">
|
| 34 |
<div style="text-align: center; color: #6c757d; font-style: italic;">
|
| 35 |
Click "Visualize" to generate attention visualization
|
| 36 |
</div>
|
|
@@ -43,4 +46,57 @@
|
|
| 43 |
</div>
|
| 44 |
</div>
|
| 45 |
|
| 46 |
-
<script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
<div style="display: grid; grid-template-columns: 1fr auto; gap: 1rem; align-items: start; margin-bottom: 1rem;">
|
| 11 |
<div>
|
| 12 |
<label style="display: block; font-weight: 600; margin-bottom: 0.5rem; color: #374151;">Model:</label>
|
| 13 |
+
<select id="model-select" style="width: 100%; padding: 0.5rem; border: 1px solid #d1d5db; border-radius: 6px; background: white;">
|
| 14 |
+
<option value="openai-community/gpt2">openai-community/gpt2</option>
|
| 15 |
+
<option value="google/gemma-2-2b">google/gemma-2-2b</option>
|
| 16 |
+
<option value="microsoft/DialoGPT-small">microsoft/DialoGPT-small</option>
|
| 17 |
</select>
|
| 18 |
</div>
|
| 19 |
|
| 20 |
<div>
|
| 21 |
<label style="display: block; font-weight: 600; margin-bottom: 0.5rem; color: #374151;">Action:</label>
|
| 22 |
+
<button id="visualize-btn" style="padding: 0.5rem 1rem; background: #3b82f6; color: white; border: none; border-radius: 6px; cursor: pointer; font-weight: 500;">
|
| 23 |
🚀 Visualize
|
| 24 |
</button>
|
| 25 |
</div>
|
|
|
|
| 27 |
|
| 28 |
<div style="margin-bottom: 1rem;">
|
| 29 |
<label style="display: block; font-weight: 600; margin-bottom: 0.5rem; color: #374151;">Prompt:</label>
|
| 30 |
+
<textarea id="prompt-input"
|
| 31 |
+
style="width: 100%; padding: 0.75rem; border: 1px solid #d1d5db; border-radius: 6px; resize: vertical; font-family: monospace; font-size: 0.9em;"
|
| 32 |
+
rows="3"
|
| 33 |
+
placeholder="You are an assistant. Make sure you print me."></textarea>
|
| 34 |
</div>
|
| 35 |
|
| 36 |
+
<div id="attention-output" style="min-height: 200px; background: #f8f9fa; border: 1px solid #e9ecef; border-radius: 6px; padding: 1rem;">
|
| 37 |
<div style="text-align: center; color: #6c757d; font-style: italic;">
|
| 38 |
Click "Visualize" to generate attention visualization
|
| 39 |
</div>
|
|
|
|
| 46 |
</div>
|
| 47 |
</div>
|
| 48 |
|
| 49 |
+
<script>
|
| 50 |
+
document.addEventListener('DOMContentLoaded', function() {
|
| 51 |
+
const modelSelect = document.getElementById('model-select');
|
| 52 |
+
const promptInput = document.getElementById('prompt-input');
|
| 53 |
+
const visualizeBtn = document.getElementById('visualize-btn');
|
| 54 |
+
const output = document.getElementById('attention-output');
|
| 55 |
+
|
| 56 |
+
// Set default prompt
|
| 57 |
+
promptInput.value = "You are an assistant. Make sure you print me.";
|
| 58 |
+
|
| 59 |
+
visualizeBtn.addEventListener('click', function() {
|
| 60 |
+
const model = modelSelect.value;
|
| 61 |
+
const prompt = promptInput.value.trim();
|
| 62 |
+
|
| 63 |
+
if (!prompt) {
|
| 64 |
+
output.innerHTML = '<div style="color: #e53e3e;">Please enter a prompt</div>';
|
| 65 |
+
return;
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
// Show loading state
|
| 69 |
+
visualizeBtn.disabled = true;
|
| 70 |
+
visualizeBtn.textContent = 'Processing...';
|
| 71 |
+
output.innerHTML = '<div style="text-align: center; color: #6c757d;"><em>Generating attention visualization...</em></div>';
|
| 72 |
+
|
| 73 |
+
// Simulate processing time
|
| 74 |
+
setTimeout(() => {
|
| 75 |
+
// Generate mock attention visualization
|
| 76 |
+
const tokens = prompt.split(' ').slice(0, 8); // Limit tokens for demo
|
| 77 |
+
let html = '<div style="margin-bottom: 1rem;"><strong>Model:</strong> ' + model + '</div>';
|
| 78 |
+
html += '<div style="margin-bottom: 1rem;"><strong>Tokens:</strong> ' + tokens.join(' • ') + '</div>';
|
| 79 |
+
html += '<div><strong>Attention Matrix (Layer 0, Head 0):</strong></div>';
|
| 80 |
+
html += '<table style="margin-top: 0.5rem; border-collapse: collapse; font-family: monospace; font-size: 0.8em;">';
|
| 81 |
+
|
| 82 |
+
// Generate attention matrix visualization
|
| 83 |
+
for (let i = 0; i < tokens.length; i++) {
|
| 84 |
+
html += '<tr>';
|
| 85 |
+
for (let j = 0; j < tokens.length; j++) {
|
| 86 |
+
const attention = Math.random();
|
| 87 |
+
const opacity = attention;
|
| 88 |
+
const color = `rgba(59, 130, 246, ${opacity})`;
|
| 89 |
+
html += `<td style="border: 1px solid #ddd; padding: 4px; background: ${color}; text-align: center; min-width: 40px;">${attention.toFixed(2)}</td>`;
|
| 90 |
+
}
|
| 91 |
+
html += '</tr>';
|
| 92 |
+
}
|
| 93 |
+
html += '</table>';
|
| 94 |
+
html += '<div style="margin-top: 1rem; font-size: 0.9em; color: #6c757d;"><em>Darker blue = higher attention weight</em></div>';
|
| 95 |
+
|
| 96 |
+
output.innerHTML = html;
|
| 97 |
+
visualizeBtn.disabled = false;
|
| 98 |
+
visualizeBtn.textContent = '🚀 Visualize';
|
| 99 |
+
}, 2000);
|
| 100 |
+
});
|
| 101 |
+
});
|
| 102 |
+
</script>
|
dist/fragments/d3-graph.html
CHANGED
|
@@ -1,11 +1,11 @@
|
|
| 1 |
-
<div class=interactive-demo>
|
| 2 |
-
<div class=demo-header>
|
| 3 |
<h3>🔗 Model Dependency Graph</h3>
|
| 4 |
</div>
|
| 5 |
-
<div class=demo-content>
|
| 6 |
-
<iframe src=static/d3_dependency_graph.html width=100% height=600px frameborder=0 style="border-radius: 8px; background: white;"></iframe>
|
| 7 |
</div>
|
| 8 |
-
<div class=demo-footer>
|
| 9 |
Interactive dependency graph showing real relationships between Transformers models. 🟡 Base models (HuggingFace logo), 🔵 Derived modular models. Click and drag to explore!
|
| 10 |
</div>
|
| 11 |
</div>
|
|
|
|
| 1 |
+
<div class="interactive-demo">
|
| 2 |
+
<div class="demo-header">
|
| 3 |
<h3>🔗 Model Dependency Graph</h3>
|
| 4 |
</div>
|
| 5 |
+
<div class="demo-content">
|
| 6 |
+
<iframe src="static/d3_dependency_graph.html" width="100%" height="600px" frameborder="0" style="border-radius: 8px; background: white;"></iframe>
|
| 7 |
</div>
|
| 8 |
+
<div class="demo-footer">
|
| 9 |
Interactive dependency graph showing real relationships between Transformers models. 🟡 Base models (HuggingFace logo), 🔵 Derived modular models. Click and drag to explore!
|
| 10 |
</div>
|
| 11 |
</div>
|
dist/fragments/glm-compare.html
CHANGED
|
@@ -1,9 +1,9 @@
|
|
| 1 |
-
<div class=code-compare style="display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; margin: 1.5rem 0;">
|
| 2 |
-
<div class=code-column style="border: 1px solid #e2e8f0; border-radius: 8px; overflow: hidden;">
|
| 3 |
-
<div class=code-header style="background: #f8f9fa; padding: 0.75rem 1rem; font-weight: 600; color: #495057; border-bottom: 1px solid #e2e8f0;">
|
| 4 |
modular_glm.py
|
| 5 |
</div>
|
| 6 |
-
<pre style="margin: 0; padding: 1rem; background: #ffffff; overflow-x: auto; font-size: 0.9em;"><code class=language-python>class GlmMLP(Phi3MLP):
|
| 7 |
pass
|
| 8 |
|
| 9 |
class GlmAttention(LlamaAttention):
|
|
@@ -19,11 +19,11 @@ class GlmForCausalLM(LlamaForCausalLM):
|
|
| 19 |
pass</code></pre>
|
| 20 |
</div>
|
| 21 |
|
| 22 |
-
<div class=code-column style="border: 1px solid #e2e8f0; border-radius: 8px; overflow: hidden;">
|
| 23 |
-
<div class=code-header style="background: #f8f9fa; padding: 0.75rem 1rem; font-weight: 600; color: #495057; border-bottom: 1px solid #e2e8f0;">
|
| 24 |
modeling_glm.py (auto-expanded)
|
| 25 |
</div>
|
| 26 |
-
<pre style="margin: 0; padding: 1rem; background: #ffffff; overflow-x: auto; font-size: 0.9em; max-height: 400px;"><code class=language-python>class GlmMLP(nn.Module):
|
| 27 |
def __init__(self, config):
|
| 28 |
super().__init__()
|
| 29 |
self.config = config
|
|
|
|
| 1 |
+
<div class="code-compare" style="display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; margin: 1.5rem 0;">
|
| 2 |
+
<div class="code-column" style="border: 1px solid #e2e8f0; border-radius: 8px; overflow: hidden;">
|
| 3 |
+
<div class="code-header" style="background: #f8f9fa; padding: 0.75rem 1rem; font-weight: 600; color: #495057; border-bottom: 1px solid #e2e8f0;">
|
| 4 |
modular_glm.py
|
| 5 |
</div>
|
| 6 |
+
<pre style="margin: 0; padding: 1rem; background: #ffffff; overflow-x: auto; font-size: 0.9em;"><code class="language-python">class GlmMLP(Phi3MLP):
|
| 7 |
pass
|
| 8 |
|
| 9 |
class GlmAttention(LlamaAttention):
|
|
|
|
| 19 |
pass</code></pre>
|
| 20 |
</div>
|
| 21 |
|
| 22 |
+
<div class="code-column" style="border: 1px solid #e2e8f0; border-radius: 8px; overflow: hidden;">
|
| 23 |
+
<div class="code-header" style="background: #f8f9fa; padding: 0.75rem 1rem; font-weight: 600; color: #495057; border-bottom: 1px solid #e2e8f0;">
|
| 24 |
modeling_glm.py (auto-expanded)
|
| 25 |
</div>
|
| 26 |
+
<pre style="margin: 0; padding: 1rem; background: #ffffff; overflow-x: auto; font-size: 0.9em; max-height: 400px;"><code class="language-python">class GlmMLP(nn.Module):
|
| 27 |
def __init__(self, config):
|
| 28 |
super().__init__()
|
| 29 |
self.config = config
|
dist/fragments/modular-growth.html
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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/fragments/terminal.html
CHANGED
|
@@ -2,21 +2,42 @@
|
|
| 2 |
<h4 style="margin-top: 0; color: #495057;">Interactive Terminal</h4>
|
| 3 |
<div style="background: #2d3748; color: #e2e8f0; padding: 1rem; border-radius: 6px; font-family: 'Consolas', 'Monaco', monospace;">
|
| 4 |
<div style="margin-bottom: 1rem;">
|
| 5 |
-
<input type=text
|
| 6 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
</div>
|
| 8 |
-
<pre id=terminal-output style="background: #1a202c; padding: 1rem; border-radius: 4px; min-height: 100px; margin: 0; overflow-x: auto;">$ Ready to run commands...</pre>
|
| 9 |
</div>
|
| 10 |
<p style="font-size: 0.9em; color: #6c757d; margin-top: 0.5rem;">
|
| 11 |
<em>Note: This is a simulated terminal. In the original Gradio app, this would execute real Python commands with proper security restrictions.</em>
|
| 12 |
</p>
|
| 13 |
</div>
|
| 14 |
|
| 15 |
-
<script>
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
<h4 style="margin-top: 0; color: #495057;">Interactive Terminal</h4>
|
| 3 |
<div style="background: #2d3748; color: #e2e8f0; padding: 1rem; border-radius: 6px; font-family: 'Consolas', 'Monaco', monospace;">
|
| 4 |
<div style="margin-bottom: 1rem;">
|
| 5 |
+
<input type="text"
|
| 6 |
+
id="terminal-input"
|
| 7 |
+
placeholder="python -c 'import torch; print(torch.__version__)'"
|
| 8 |
+
style="width: calc(100% - 80px); padding: 0.5rem; background: #1a202c; border: 1px solid #4a5568; color: #e2e8f0; border-radius: 4px;">
|
| 9 |
+
<button id="terminal-run"
|
| 10 |
+
style="width: 70px; padding: 0.5rem; margin-left: 8px; background: #3182ce; color: white; border: none; border-radius: 4px; cursor: pointer;">Run</button>
|
| 11 |
</div>
|
| 12 |
+
<pre id="terminal-output" style="background: #1a202c; padding: 1rem; border-radius: 4px; min-height: 100px; margin: 0; overflow-x: auto;">$ Ready to run commands...</pre>
|
| 13 |
</div>
|
| 14 |
<p style="font-size: 0.9em; color: #6c757d; margin-top: 0.5rem;">
|
| 15 |
<em>Note: This is a simulated terminal. In the original Gradio app, this would execute real Python commands with proper security restrictions.</em>
|
| 16 |
</p>
|
| 17 |
</div>
|
| 18 |
|
| 19 |
+
<script>
|
| 20 |
+
document.addEventListener('DOMContentLoaded', function() {
|
| 21 |
+
const input = document.getElementById('terminal-input');
|
| 22 |
+
const button = document.getElementById('terminal-run');
|
| 23 |
+
const output = document.getElementById('terminal-output');
|
| 24 |
+
|
| 25 |
+
function runCommand() {
|
| 26 |
+
const command = input.value.trim();
|
| 27 |
+
if (!command) return;
|
| 28 |
+
|
| 29 |
+
// Simulate command execution
|
| 30 |
+
output.textContent = `$ ${command}\nSimulated output for: ${command}\n\n` +
|
| 31 |
+
`This would execute the command in the original app.\n` +
|
| 32 |
+
`Example outputs:\n` +
|
| 33 |
+
`- torch version: 2.0.1+cu117\n` +
|
| 34 |
+
`- import checks: Success\n` +
|
| 35 |
+
`- memory info: Available`;
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
button.addEventListener('click', runCommand);
|
| 39 |
+
input.addEventListener('keypress', function(e) {
|
| 40 |
+
if (e.key === 'Enter') runCommand();
|
| 41 |
+
});
|
| 42 |
+
});
|
| 43 |
+
</script>
|
dist/fragments/tp-plan.html
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<pre><code class="language-python"># In the model's config (example: ERNIE 4.5-style decoder blocks)
|
| 2 |
+
base_model_tp_plan = {
|
| 3 |
+
"layers.*.self_attn.q_proj": "colwise",
|
| 4 |
+
"layers.*.self_attn.k_proj": "colwise",
|
| 5 |
+
"layers.*.self_attn.v_proj": "colwise",
|
| 6 |
+
"layers.*.self_attn.o_proj": "rowwise",
|
| 7 |
+
"layers.*.mlp.gate_proj": "colwise",
|
| 8 |
+
"layers.*.mlp.up_proj": "colwise",
|
| 9 |
+
"layers.*.mlp.down_proj": "rowwise",
|
| 10 |
+
}
|
| 11 |
+
|
| 12 |
+
# Runtime
|
| 13 |
+
import torch
|
| 14 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 15 |
+
|
| 16 |
+
model_id = "your/model-or-local-checkpoint"
|
| 17 |
+
model = AutoModelForCausalLM.from_pretrained(
|
| 18 |
+
model_id,
|
| 19 |
+
dtype=torch.bfloat16,
|
| 20 |
+
tp_plan=base_model_tp_plan, # <-- plan defined above
|
| 21 |
+
)
|
| 22 |
+
tok = AutoTokenizer.from_pretrained(model_id)
|
| 23 |
+
inputs = tok("Hello", return_tensors="pt").to(model.device)
|
| 24 |
+
out = model(**inputs)</code></pre>
|
dist/fragments/warmup_demo.html
ADDED
|
@@ -0,0 +1,398 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<style>
|
| 2 |
+
.warmup-demo body {
|
| 3 |
+
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
| 4 |
+
margin: 0;
|
| 5 |
+
padding: 20px;
|
| 6 |
+
background-color: #f5f5f5;
|
| 7 |
+
}
|
| 8 |
+
|
| 9 |
+
.warmup-demo .container {
|
| 10 |
+
max-width: 1200px;
|
| 11 |
+
margin: 0 auto;
|
| 12 |
+
background: white;
|
| 13 |
+
border-radius: 12px;
|
| 14 |
+
padding: 30px;
|
| 15 |
+
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
| 16 |
+
}
|
| 17 |
+
|
| 18 |
+
.warmup-demo h1 {
|
| 19 |
+
text-align: center;
|
| 20 |
+
color: #333;
|
| 21 |
+
margin-bottom: 10px;
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
.warmup-demo .subtitle {
|
| 25 |
+
text-align: center;
|
| 26 |
+
color: #666;
|
| 27 |
+
margin-bottom: 30px;
|
| 28 |
+
font-size: 16px;
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
.warmup-demo .demo-container {
|
| 32 |
+
display: flex;
|
| 33 |
+
gap: 40px;
|
| 34 |
+
margin-bottom: 30px;
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
.warmup-demo .side {
|
| 38 |
+
flex: 1;
|
| 39 |
+
border: 2px solid #ddd;
|
| 40 |
+
border-radius: 8px;
|
| 41 |
+
padding: 20px;
|
| 42 |
+
background: #fafafa;
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
.warmup-demo .side h2 {
|
| 46 |
+
text-align: center;
|
| 47 |
+
margin-top: 0;
|
| 48 |
+
color: #333;
|
| 49 |
+
}
|
| 50 |
+
|
| 51 |
+
.warmup-demo .no-warmup h2 {
|
| 52 |
+
color: #d63384;
|
| 53 |
+
}
|
| 54 |
+
|
| 55 |
+
.warmup-demo .with-warmup h2 {
|
| 56 |
+
color: #198754;
|
| 57 |
+
}
|
| 58 |
+
|
| 59 |
+
.warmup-demo .memory-area {
|
| 60 |
+
height: 400px;
|
| 61 |
+
border: 2px dashed #ccc;
|
| 62 |
+
border-radius: 6px;
|
| 63 |
+
padding: 10px;
|
| 64 |
+
margin: 20px 0;
|
| 65 |
+
background: #fff;
|
| 66 |
+
position: relative;
|
| 67 |
+
overflow: hidden;
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
.warmup-demo .layer-box {
|
| 71 |
+
width: 80px;
|
| 72 |
+
height: 30px;
|
| 73 |
+
border: 2px solid #666;
|
| 74 |
+
border-radius: 4px;
|
| 75 |
+
margin: 3px;
|
| 76 |
+
display: inline-block;
|
| 77 |
+
position: relative;
|
| 78 |
+
background: #fff;
|
| 79 |
+
transition: all 0.3s ease;
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
.warmup-demo .layer-box.allocating {
|
| 83 |
+
background: #e9ecef;
|
| 84 |
+
border-color: #adb5bd;
|
| 85 |
+
}
|
| 86 |
+
|
| 87 |
+
.warmup-demo .layer-box.allocating::after {
|
| 88 |
+
content: "malloc";
|
| 89 |
+
position: absolute;
|
| 90 |
+
top: 50%;
|
| 91 |
+
left: 50%;
|
| 92 |
+
transform: translate(-50%, -50%);
|
| 93 |
+
font-size: 10px;
|
| 94 |
+
color: #666;
|
| 95 |
+
font-weight: bold;
|
| 96 |
+
}
|
| 97 |
+
|
| 98 |
+
.warmup-demo .layer-box.loaded {
|
| 99 |
+
background: #d1e7dd;
|
| 100 |
+
border-color: #198754;
|
| 101 |
+
}
|
| 102 |
+
|
| 103 |
+
.warmup-demo .layer-box.loaded::after {
|
| 104 |
+
content: "data";
|
| 105 |
+
position: absolute;
|
| 106 |
+
top: 50%;
|
| 107 |
+
left: 50%;
|
| 108 |
+
transform: translate(-50%, -50%);
|
| 109 |
+
font-size: 10px;
|
| 110 |
+
color: #198754;
|
| 111 |
+
font-weight: bold;
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
.warmup-demo .warmup-container {
|
| 115 |
+
width: 100%;
|
| 116 |
+
height: 60px;
|
| 117 |
+
border: 3px solid #666;
|
| 118 |
+
border-radius: 6px;
|
| 119 |
+
margin-bottom: 20px;
|
| 120 |
+
background: #fff;
|
| 121 |
+
position: relative;
|
| 122 |
+
overflow: hidden;
|
| 123 |
+
}
|
| 124 |
+
|
| 125 |
+
.warmup-demo .warmup-container.allocated {
|
| 126 |
+
border-color: #0d6efd;
|
| 127 |
+
background: #e7f1ff;
|
| 128 |
+
}
|
| 129 |
+
|
| 130 |
+
.warmup-demo .warmup-container::before {
|
| 131 |
+
content: "Pre-allocated Memory Pool";
|
| 132 |
+
position: absolute;
|
| 133 |
+
top: 50%;
|
| 134 |
+
left: 50%;
|
| 135 |
+
transform: translate(-50%, -50%);
|
| 136 |
+
font-size: 14px;
|
| 137 |
+
color: #666;
|
| 138 |
+
font-weight: bold;
|
| 139 |
+
z-index: 1;
|
| 140 |
+
}
|
| 141 |
+
|
| 142 |
+
.warmup-demo .warmup-container.allocated::before {
|
| 143 |
+
color: #0d6efd;
|
| 144 |
+
}
|
| 145 |
+
|
| 146 |
+
.warmup-demo .warmup-fill {
|
| 147 |
+
height: 100%;
|
| 148 |
+
background: linear-gradient(90deg, #198754, #20c997);
|
| 149 |
+
width: 0%;
|
| 150 |
+
transition: width 0.5s ease;
|
| 151 |
+
border-radius: 3px;
|
| 152 |
+
position: relative;
|
| 153 |
+
z-index: 2;
|
| 154 |
+
}
|
| 155 |
+
|
| 156 |
+
.warmup-demo .warmup-fill::after {
|
| 157 |
+
content: "Layer Data Loading";
|
| 158 |
+
position: absolute;
|
| 159 |
+
top: 50%;
|
| 160 |
+
left: 50%;
|
| 161 |
+
transform: translate(-50%, -50%);
|
| 162 |
+
font-size: 12px;
|
| 163 |
+
color: white;
|
| 164 |
+
font-weight: bold;
|
| 165 |
+
white-space: nowrap;
|
| 166 |
+
}
|
| 167 |
+
|
| 168 |
+
.warmup-demo .timing {
|
| 169 |
+
text-align: center;
|
| 170 |
+
font-size: 24px;
|
| 171 |
+
font-weight: bold;
|
| 172 |
+
margin: 15px 0;
|
| 173 |
+
min-height: 30px;
|
| 174 |
+
}
|
| 175 |
+
|
| 176 |
+
.warmup-demo .no-warmup .timing {
|
| 177 |
+
color: #d63384;
|
| 178 |
+
}
|
| 179 |
+
|
| 180 |
+
.warmup-demo .with-warmup .timing {
|
| 181 |
+
color: #198754;
|
| 182 |
+
}
|
| 183 |
+
|
| 184 |
+
.warmup-demo .controls {
|
| 185 |
+
text-align: center;
|
| 186 |
+
margin: 30px 0;
|
| 187 |
+
}
|
| 188 |
+
|
| 189 |
+
.warmup-demo .btn {
|
| 190 |
+
background: #0d6efd;
|
| 191 |
+
color: white;
|
| 192 |
+
border: none;
|
| 193 |
+
padding: 12px 24px;
|
| 194 |
+
border-radius: 6px;
|
| 195 |
+
font-size: 16px;
|
| 196 |
+
cursor: pointer;
|
| 197 |
+
margin: 0 10px;
|
| 198 |
+
transition: background 0.3s ease;
|
| 199 |
+
}
|
| 200 |
+
|
| 201 |
+
.warmup-demo .btn:hover {
|
| 202 |
+
background: #0b5ed7;
|
| 203 |
+
}
|
| 204 |
+
|
| 205 |
+
.warmup-demo .btn:disabled {
|
| 206 |
+
background: #6c757d;
|
| 207 |
+
cursor: not-allowed;
|
| 208 |
+
}
|
| 209 |
+
|
| 210 |
+
.warmup-demo .description {
|
| 211 |
+
background: #f8f9fa;
|
| 212 |
+
padding: 15px;
|
| 213 |
+
border-radius: 6px;
|
| 214 |
+
margin-top: 15px;
|
| 215 |
+
font-size: 14px;
|
| 216 |
+
line-height: 1.5;
|
| 217 |
+
}
|
| 218 |
+
|
| 219 |
+
.warmup-demo .phase-indicator {
|
| 220 |
+
font-size: 14px;
|
| 221 |
+
color: #666;
|
| 222 |
+
text-align: center;
|
| 223 |
+
margin-top: 10px;
|
| 224 |
+
min-height: 20px;
|
| 225 |
+
}
|
| 226 |
+
|
| 227 |
+
.warmup-demo .layer-counter {
|
| 228 |
+
text-align: center;
|
| 229 |
+
font-size: 16px;
|
| 230 |
+
color: #495057;
|
| 231 |
+
margin: 10px 0;
|
| 232 |
+
}
|
| 233 |
+
</style>
|
| 234 |
+
|
| 235 |
+
<div class="warmup-demo">
|
| 236 |
+
<div class="container">
|
| 237 |
+
<p class="subtitle">Mem allocation patterns during model loading</p>
|
| 238 |
+
|
| 239 |
+
<div class="controls">
|
| 240 |
+
<button class="btn" id="startBtn" onclick="startDemo()">Start Animation</button>
|
| 241 |
+
<button class="btn" id="resetBtn" onclick="resetDemo()">Reset</button>
|
| 242 |
+
</div>
|
| 243 |
+
|
| 244 |
+
<div class="demo-container">
|
| 245 |
+
<div class="side no-warmup">
|
| 246 |
+
<h2 data-no-toc>❌ Without Warmup</h2>
|
| 247 |
+
<div class="timing" id="noWarmupTime">0.00s</div>
|
| 248 |
+
<div class="layer-counter" id="noWarmupCounter">Layers loaded: 0/10</div>
|
| 249 |
+
<div class="phase-indicator" id="noWarmupPhase"></div>
|
| 250 |
+
<div class="memory-area" id="noWarmupArea"></div>
|
| 251 |
+
<div class="description">
|
| 252 |
+
<strong>Individual Allocations:</strong><br>
|
| 253 |
+
Each model layer triggers a separate cudaMalloc() call, creating memory fragmentation and allocation overhead.
|
| 254 |
+
<br><br>
|
| 255 |
+
📦 <strong>Grey "malloc"</strong> = Memory allocation overhead<br>
|
| 256 |
+
✅ <strong>Green "data"</strong> = Actual layer data loading
|
| 257 |
+
</div>
|
| 258 |
+
</div>
|
| 259 |
+
|
| 260 |
+
<div class="side with-warmup">
|
| 261 |
+
<h2 data-no-toc>✅ With Warmup</h2>
|
| 262 |
+
<div class="timing" id="warmupTime">0.00s</div>
|
| 263 |
+
<div class="layer-counter" id="warmupCounter">Layers loaded: 0/10</div>
|
| 264 |
+
<div class="phase-indicator" id="warmupPhase"></div>
|
| 265 |
+
<div class="memory-area" id="warmupArea">
|
| 266 |
+
<div class="warmup-container" id="warmupContainer">
|
| 267 |
+
<div class="warmup-fill" id="warmupFill"></div>
|
| 268 |
+
</div>
|
| 269 |
+
<div id="warmupLayers"></div>
|
| 270 |
+
</div>
|
| 271 |
+
<div class="description">
|
| 272 |
+
<strong>Pre-allocated Pool:</strong><br>
|
| 273 |
+
The warmup function calculates total memory needed and makes ONE large allocation. Subsequent layers load directly into this pool, eliminating malloc overhead.
|
| 274 |
+
<br><br>
|
| 275 |
+
🔵 <strong>Blue container</strong> = Single large malloc (warmup)<br>
|
| 276 |
+
🟢 <strong>Green progress bar</strong> = Layer data loading (no malloc needed)
|
| 277 |
+
</div>
|
| 278 |
+
</div>
|
| 279 |
+
</div>
|
| 280 |
+
</div>
|
| 281 |
+
</div>
|
| 282 |
+
|
| 283 |
+
<script>
|
| 284 |
+
let animationSpeed = 1 / 2.4;
|
| 285 |
+
let isRunning = false;
|
| 286 |
+
const totalLayers = 10;
|
| 287 |
+
|
| 288 |
+
function startDemo() {
|
| 289 |
+
if (isRunning) return;
|
| 290 |
+
isRunning = true;
|
| 291 |
+
|
| 292 |
+
document.getElementById('startBtn').disabled = true;
|
| 293 |
+
document.getElementById('resetBtn').disabled = true;
|
| 294 |
+
|
| 295 |
+
Promise.all([
|
| 296 |
+
animateNoWarmup(),
|
| 297 |
+
animateWithWarmup()
|
| 298 |
+
]).then(() => {
|
| 299 |
+
isRunning = false;
|
| 300 |
+
document.getElementById('startBtn').disabled = false;
|
| 301 |
+
document.getElementById('resetBtn').disabled = false;
|
| 302 |
+
});
|
| 303 |
+
}
|
| 304 |
+
|
| 305 |
+
function resetDemo() {
|
| 306 |
+
if (isRunning) return;
|
| 307 |
+
|
| 308 |
+
document.getElementById('noWarmupArea').innerHTML = '';
|
| 309 |
+
document.getElementById('warmupLayers').innerHTML = '';
|
| 310 |
+
document.getElementById('warmupFill').style.width = '0%';
|
| 311 |
+
document.getElementById('warmupContainer').classList.remove('allocated');
|
| 312 |
+
|
| 313 |
+
document.getElementById('noWarmupTime').textContent = '0.00s';
|
| 314 |
+
document.getElementById('warmupTime').textContent = '0.00s';
|
| 315 |
+
|
| 316 |
+
document.getElementById('noWarmupCounter').textContent = 'Layers loaded: 0/10';
|
| 317 |
+
document.getElementById('warmupCounter').textContent = 'Layers loaded: 0/10';
|
| 318 |
+
|
| 319 |
+
document.getElementById('noWarmupPhase').textContent = '';
|
| 320 |
+
document.getElementById('warmupPhase').textContent = '';
|
| 321 |
+
}
|
| 322 |
+
|
| 323 |
+
async function animateNoWarmup() {
|
| 324 |
+
const container = document.getElementById('noWarmupArea');
|
| 325 |
+
const timeEl = document.getElementById('noWarmupTime');
|
| 326 |
+
const counterEl = document.getElementById('noWarmupCounter');
|
| 327 |
+
const phaseEl = document.getElementById('noWarmupPhase');
|
| 328 |
+
|
| 329 |
+
let currentTime = 0;
|
| 330 |
+
const baseDelay = 200 / animationSpeed;
|
| 331 |
+
|
| 332 |
+
phaseEl.textContent = 'Loading model layers...';
|
| 333 |
+
|
| 334 |
+
for (let i = 0; i < totalLayers; i++) {
|
| 335 |
+
const layerBox = document.createElement('div');
|
| 336 |
+
layerBox.className = 'layer-box';
|
| 337 |
+
container.appendChild(layerBox);
|
| 338 |
+
|
| 339 |
+
await sleep(baseDelay * 0.3);
|
| 340 |
+
layerBox.classList.add('allocating');
|
| 341 |
+
currentTime += 0.08;
|
| 342 |
+
timeEl.textContent = currentTime.toFixed(2) + 's';
|
| 343 |
+
|
| 344 |
+
await sleep(baseDelay * 0.7);
|
| 345 |
+
layerBox.classList.remove('allocating');
|
| 346 |
+
layerBox.classList.add('loaded');
|
| 347 |
+
currentTime += 0.12;
|
| 348 |
+
timeEl.textContent = currentTime.toFixed(2) + 's';
|
| 349 |
+
|
| 350 |
+
counterEl.textContent = `Layers loaded: ${i + 1}/${totalLayers}`;
|
| 351 |
+
}
|
| 352 |
+
|
| 353 |
+
phaseEl.textContent = 'Complete!';
|
| 354 |
+
}
|
| 355 |
+
|
| 356 |
+
async function animateWithWarmup() {
|
| 357 |
+
const container = document.getElementById('warmupLayers');
|
| 358 |
+
const timeEl = document.getElementById('warmupTime');
|
| 359 |
+
const counterEl = document.getElementById('warmupCounter');
|
| 360 |
+
const phaseEl = document.getElementById('warmupPhase');
|
| 361 |
+
const warmupContainer = document.getElementById('warmupContainer');
|
| 362 |
+
const warmupFill = document.getElementById('warmupFill');
|
| 363 |
+
|
| 364 |
+
let currentTime = 0;
|
| 365 |
+
const baseDelay = 200 / animationSpeed;
|
| 366 |
+
|
| 367 |
+
phaseEl.textContent = 'Warming up allocator...';
|
| 368 |
+
await sleep(baseDelay * 2);
|
| 369 |
+
warmupContainer.classList.add('allocated');
|
| 370 |
+
currentTime += 0.3;
|
| 371 |
+
timeEl.textContent = currentTime.toFixed(2) + 's';
|
| 372 |
+
|
| 373 |
+
phaseEl.textContent = 'Loading model layers...';
|
| 374 |
+
|
| 375 |
+
for (let i = 0; i < totalLayers; i++) {
|
| 376 |
+
const layerBox = document.createElement('div');
|
| 377 |
+
layerBox.className = 'layer-box loaded';
|
| 378 |
+
layerBox.style.width = '40px';
|
| 379 |
+
layerBox.style.height = '20px';
|
| 380 |
+
container.appendChild(layerBox);
|
| 381 |
+
|
| 382 |
+
const progress = ((i + 1) / totalLayers) * 100;
|
| 383 |
+
warmupFill.style.width = progress + '%';
|
| 384 |
+
|
| 385 |
+
await sleep(baseDelay * 0.5);
|
| 386 |
+
currentTime += 0.08;
|
| 387 |
+
timeEl.textContent = currentTime.toFixed(2) + 's';
|
| 388 |
+
|
| 389 |
+
counterEl.textContent = `Layers loaded: ${i + 1}/${totalLayers}`;
|
| 390 |
+
}
|
| 391 |
+
|
| 392 |
+
phaseEl.textContent = 'Complete!';
|
| 393 |
+
}
|
| 394 |
+
|
| 395 |
+
function sleep(ms) {
|
| 396 |
+
return new Promise(resolve => setTimeout(resolve, ms));
|
| 397 |
+
}
|
| 398 |
+
</script>
|
dist/index.html
CHANGED
|
@@ -8,21 +8,21 @@
|
|
| 8 |
<script src="https://d3js.org/d3.v7.min.js"></script>
|
| 9 |
<meta name="viewport" content="width=device-width, initial-scale=1">
|
| 10 |
<meta charset="utf8">
|
| 11 |
-
<title>Scaling
|
| 12 |
<link rel="stylesheet" href="style.css">
|
| 13 |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism.min.css">
|
| 14 |
</head>
|
| 15 |
<body>
|
| 16 |
<d-front-matter>
|
| 17 |
<script id='distill-front-matter' type="text/json">{
|
| 18 |
-
"title": "Scaling
|
| 19 |
"description": "A peek into software engineering for the transformers library",
|
| 20 |
"published": "Aug 21, 2025",
|
| 21 |
"authors": [{"author": "Pablo Montalvo", "authorURL": "https://huggingface.co/Molbap"}]
|
| 22 |
}</script>
|
| 23 |
</d-front-matter>
|
| 24 |
<d-title>
|
| 25 |
-
<h1>Scaling
|
| 26 |
<p>A peek into software engineering for the transformers library</p>
|
| 27 |
</d-title>
|
| 28 |
<d-byline></d-byline>
|
|
@@ -48,13 +48,16 @@
|
|
| 48 |
</nav>
|
| 49 |
</d-contents>
|
| 50 |
<h2>Introduction</h2>
|
| 51 |
-
<p>The <code>transformers</code> library, built with <code>PyTorch</code>, supports all state-of-the-art LLMs, many VLMs, task-specific vision language models, video models, audio models, table models, classical encoders, to a global count of almost 400 models
|
| 52 |
-
The name of the library itself is mostly majority driven as many models are not even transformers architectures, like Mamba, Zamba, RWKV, and convolution-based models
|
| 53 |
-
Regardless, each of these is wrought by the research and engineering team that created them, then harmonized into a now famous interface, and callable with a simple <code>.from_pretrained</code> command
|
| 54 |
-
Inference works for all models, training is functional for most. The library is a foundation for many machine learning courses, cookbooks, and overall, several thousands other open-source libraries depend on it. All models are tested as part of a daily CI ensuring their preservation and reproducibility. Most importantly, it is <em>open-source</em> and has been written by the community for a large part.
|
| 55 |
-
This isn’t really to brag but to set the stakes: what does it take to keep such a ship afloat, made of so many moving, unrelated parts
|
| 56 |
-
The ML wave has not stopped, there’s more and more models being added, at a steadily growing rate. <code>Transformers</code> is widely used, and we read the feedback that users post online. Whether it
|
| 57 |
-
<p>Here we will dissect what is the new design philosophy of transformers, as a continuation from the existing older <a href="https://huggingface.co/docs/transformers/en/philosophy">philosophy</a> page, and an accompanying <a href="https://huggingface.co/blog/transformers-design-philosophy">blog post from 2022</a
|
|
|
|
|
|
|
|
|
|
| 58 |
<h3>What you will learn</h3>
|
| 59 |
<p>Every reader, whether an OSS maintainer, power user, or casual fine-tuner, will walk away knowing how to reason about the <code>transformers</code> code base, how to use it better, how to meaningfully contribute to it.
|
| 60 |
This will also showcase new features you might have missed so you’ll be up-to-date.</p>
|
|
@@ -113,7 +116,7 @@ This will also showcase new features you might have missed so you’ll be up-to-
|
|
| 113 |
</li>
|
| 114 |
<li class="tenet">
|
| 115 |
<a id="modular-toolbox"></a>
|
| 116 |
-
<strong>Modular Toolbox (Not Framework)</strong>
|
| 117 |
<p>We ARE a toolbox. What we are not is a framework: you should not be FORCED to rewrite every modeling, but it is <em>better</em> for your model to be able to inherit from PreTrainedModel and have enabled TensorParallel, from_pretrained, sharding, push_to_hub, loss, as well as PEFT/TRL/SGLang/vLLM.</p>
|
| 118 |
<em>This is the largest change. Provide tools and utilities, but don't force users into a rigid framework.</em>
|
| 119 |
</li>
|
|
@@ -297,6 +300,35 @@ if self.config._attn_implementation != "eager":
|
|
| 297 |
<p>For better <em>information</em>, we plan to use <code>python</code> features such as <code>Annotated</code> for example, to inform users of what we expect typically in an argument. That way, higher-level information could be included directly in the type annotations.</p>
|
| 298 |
<h2><a id="simpler-tensor-parallelism"></a> Simpler Tensor Parallelism</h2>
|
| 299 |
<p>We want to touch minimally to the modeling code, and only modify it when <em>architectural changes</em> are involved. For instance, for tensor parallelism, we instead now specify a simple <code>tp_plan</code>.</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 300 |
<h2><a id="layers-attentions-caches"></a> Layers, attentions and caches</h2>
|
| 301 |
<p>With th</p>
|
| 302 |
<h2><a id="community-kernels"></a>Community Kernels</h2>
|
|
@@ -331,7 +363,6 @@ Radically different architectures such as mamba have spawned their own dependenc
|
|
| 331 |
</div>
|
| 332 |
|
| 333 |
</p>
|
| 334 |
-
<p><img src="static/graph_modular_related_models.png" alt="Graph showing modular related models"></p>
|
| 335 |
<p>But there is no similar miracle for VLMs across the board.
|
| 336 |
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>
|
| 337 |
<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>
|
|
@@ -415,7 +446,7 @@ Example outputs:
|
|
| 415 |
<h2>Modularity candidates</h2>
|
| 416 |
<p>So the question abounds naturally: How can we modularize more?
|
| 417 |
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>
|
| 418 |
-
<p
|
| 419 |
<h2><a id="encoders-ftw"></a> The neverending stories of encoder models.</h2>
|
| 420 |
<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>
|
| 421 |
<p><img src="static/popular_models_barplot.png" alt="Popular models bar plot"></p>
|
|
@@ -500,32 +531,61 @@ curl -X POST http://localhost:8000/v1/chat/completions \
|
|
| 500 |
<li>having it immediately available to the community</li>
|
| 501 |
<li>usable in vLLM, SGLang, and so on without additional code.</li>
|
| 502 |
</ul>
|
| 503 |
-
<
|
| 504 |
<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>
|
| 505 |
-
<p><
|
| 506 |
-
|
| 507 |
-
|
| 508 |
-
|
| 509 |
-
|
| 510 |
-
|
| 511 |
-
|
| 512 |
-
|
| 513 |
-
|
| 514 |
-
|
| 515 |
-
|
| 516 |
-
|
| 517 |
-
|
| 518 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 519 |
</div>
|
| 520 |
-
</div
|
| 521 |
-
|
| 522 |
-
<
|
| 523 |
-
<
|
| 524 |
-
<p>
|
| 525 |
-
<p>modular_*.py fixes the trade‑off, by auto-generating the modeling file from a modular file, which can use inheritance.</p>
|
| 526 |
-
<p>With a small analyser I’ve mapped which models already share modular pieces and which 100‑plus still repeat themselves. Red nodes in the graph = lowest‑hanging fruit for refactor; blue = already modular.</p>
|
| 527 |
-
<p>The result: contributors can focus on novel layers instead of boilerplate, reviews shrink from “new file diff” to “does this override make sense?”, and the codebase stays something you can actually open and read.</p>
|
| 528 |
-
<p>If you maintain or ship models on top of Transformers, take a look at modular, in 2025 it’s how we keep shipping breadth without the bloat. 🛠️</p>
|
| 529 |
|
| 530 |
</d-article>
|
| 531 |
|
|
@@ -534,7 +594,7 @@ curl -X POST http://localhost:8000/v1/chat/completions \
|
|
| 534 |
const article = document.querySelector('d-article');
|
| 535 |
const toc = document.querySelector('d-contents');
|
| 536 |
if (toc) {
|
| 537 |
-
const headings = article.querySelectorAll('h1, h2, h3, h4');
|
| 538 |
let ToC = '<nav role="navigation" class="l-text figcaption">';
|
| 539 |
ToC += '<div class="toc-header"><span class="toc-title">Table of Contents</span></div>';
|
| 540 |
ToC += '<div class="toc-content">';
|
|
|
|
| 8 |
<script src="https://d3js.org/d3.v7.min.js"></script>
|
| 9 |
<meta name="viewport" content="width=device-width, initial-scale=1">
|
| 10 |
<meta charset="utf8">
|
| 11 |
+
<title>Scaling Insanity: maintaining hundreds of model definitions</title>
|
| 12 |
<link rel="stylesheet" href="style.css">
|
| 13 |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism.min.css">
|
| 14 |
</head>
|
| 15 |
<body>
|
| 16 |
<d-front-matter>
|
| 17 |
<script id='distill-front-matter' type="text/json">{
|
| 18 |
+
"title": "Scaling Insanity: maintaining hundreds of model definitions",
|
| 19 |
"description": "A peek into software engineering for the transformers library",
|
| 20 |
"published": "Aug 21, 2025",
|
| 21 |
"authors": [{"author": "Pablo Montalvo", "authorURL": "https://huggingface.co/Molbap"}]
|
| 22 |
}</script>
|
| 23 |
</d-front-matter>
|
| 24 |
<d-title>
|
| 25 |
+
<h1>Scaling Insanity: maintaining hundreds of model definitions</h1>
|
| 26 |
<p>A peek into software engineering for the transformers library</p>
|
| 27 |
</d-title>
|
| 28 |
<d-byline></d-byline>
|
|
|
|
| 48 |
</nav>
|
| 49 |
</d-contents>
|
| 50 |
<h2>Introduction</h2>
|
| 51 |
+
<p>The <code>transformers</code> library, built with <code>PyTorch</code>, supports all state-of-the-art LLMs, many VLMs, task-specific vision language models, video models, audio models, table models, classical encoders, to a global count of almost 400 models.</p>
|
| 52 |
+
<p>The name of the library itself is mostly majority driven as many models are not even transformers architectures, like Mamba, Zamba, RWKV, and convolution-based models.</p>
|
| 53 |
+
<p>Regardless, each of these is wrought by the research and engineering team that created them, then harmonized into a now famous interface, and callable with a simple <code>.from_pretrained</code> command.</p>
|
| 54 |
+
<p>Inference works for all models, training is functional for most. The library is a foundation for many machine learning courses, cookbooks, and overall, several thousands other open-source libraries depend on it. All models are tested as part of a daily CI ensuring their preservation and reproducibility. Most importantly, it is <em>open-source</em> and has been written by the community for a large part.
|
| 55 |
+
This isn’t really to brag but to set the stakes: what does it take to keep such a ship afloat, made of so many moving, unrelated parts?</p>
|
| 56 |
+
<p>The ML wave has not stopped, there’s more and more models being added, at a steadily growing rate. <code>Transformers</code> is widely used, and we read the feedback that users post online. Whether it��s about a function that had 300+ keyword arguments, duplicated code and helpers, and mentions of <code>Copied from ... </code> everywhere, along with optimisation concerns. Text-only models are relatively tamed, but multimodal models remain to be harmonized.</p>
|
| 57 |
+
<p>Here we will dissect what is the new design philosophy of transformers, as a continuation from the existing older <a href="https://huggingface.co/docs/transformers/en/philosophy">philosophy</a> page, and an accompanying <a href="https://huggingface.co/blog/transformers-design-philosophy">blog post from 2022</a>.</p>
|
| 58 |
+
<p>More recently, and I recommend the read if it’s not done yet, a blog post about <a href="https://huggingface.co/blog/faster-transformers">recent upgrades to transformers</a> was written, explaining in particular what makes the library faster today.</p>
|
| 59 |
+
<p>Some time ago I dare not say how long, we discussed with transformers maintainers about the state of features in transformers. A lot of recent developments were satisfactory, but if we were only talking about these, self-congratulation would be the only goalpost.</p>
|
| 60 |
+
<p>Reflecting on this philosophy now, as models pile up, is essential and will drive new developments.</p>
|
| 61 |
<h3>What you will learn</h3>
|
| 62 |
<p>Every reader, whether an OSS maintainer, power user, or casual fine-tuner, will walk away knowing how to reason about the <code>transformers</code> code base, how to use it better, how to meaningfully contribute to it.
|
| 63 |
This will also showcase new features you might have missed so you’ll be up-to-date.</p>
|
|
|
|
| 116 |
</li>
|
| 117 |
<li class="tenet">
|
| 118 |
<a id="modular-toolbox"></a>
|
| 119 |
+
<strong>Modular Toolbox (Not A Framework)</strong>
|
| 120 |
<p>We ARE a toolbox. What we are not is a framework: you should not be FORCED to rewrite every modeling, but it is <em>better</em> for your model to be able to inherit from PreTrainedModel and have enabled TensorParallel, from_pretrained, sharding, push_to_hub, loss, as well as PEFT/TRL/SGLang/vLLM.</p>
|
| 121 |
<em>This is the largest change. Provide tools and utilities, but don't force users into a rigid framework.</em>
|
| 122 |
</li>
|
|
|
|
| 300 |
<p>For better <em>information</em>, we plan to use <code>python</code> features such as <code>Annotated</code> for example, to inform users of what we expect typically in an argument. That way, higher-level information could be included directly in the type annotations.</p>
|
| 301 |
<h2><a id="simpler-tensor-parallelism"></a> Simpler Tensor Parallelism</h2>
|
| 302 |
<p>We want to touch minimally to the modeling code, and only modify it when <em>architectural changes</em> are involved. For instance, for tensor parallelism, we instead now specify a simple <code>tp_plan</code>.</p>
|
| 303 |
+
<p>It is written once in the config and passed to <code>.from_pretrained()</code>.</p>
|
| 304 |
+
<p>The plan maps module name patterns to partitioning strategies. Strategies are resolved by the internal <code>ParallelInterface</code>, which wires to sharding implementations <code>ColwiseParallel</code>, <code>RowwiseParallel</code>, packed variants, and so on.</p>
|
| 305 |
+
<p><pre><code class="language-python"># In the model's config (example: ERNIE 4.5-style decoder blocks)
|
| 306 |
+
base_model_tp_plan = {
|
| 307 |
+
"layers.*.self_attn.q_proj": "colwise",
|
| 308 |
+
"layers.*.self_attn.k_proj": "colwise",
|
| 309 |
+
"layers.*.self_attn.v_proj": "colwise",
|
| 310 |
+
"layers.*.self_attn.o_proj": "rowwise",
|
| 311 |
+
"layers.*.mlp.gate_proj": "colwise",
|
| 312 |
+
"layers.*.mlp.up_proj": "colwise",
|
| 313 |
+
"layers.*.mlp.down_proj": "rowwise",
|
| 314 |
+
}
|
| 315 |
+
|
| 316 |
+
# Runtime
|
| 317 |
+
import torch
|
| 318 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 319 |
+
|
| 320 |
+
model_id = "your/model-or-local-checkpoint"
|
| 321 |
+
model = AutoModelForCausalLM.from_pretrained(
|
| 322 |
+
model_id,
|
| 323 |
+
dtype=torch.bfloat16,
|
| 324 |
+
tp_plan=base_model_tp_plan, # <-- plan defined above
|
| 325 |
+
)
|
| 326 |
+
tok = AutoTokenizer.from_pretrained(model_id)
|
| 327 |
+
inputs = tok("Hello", return_tensors="pt").to(model.device)
|
| 328 |
+
out = model(**inputs)</code></pre></p>
|
| 329 |
+
<p>Which allows a user to run with multiple processes per node, e.g. 4 GPUs:</p>
|
| 330 |
+
<p><code>torchrun --nproc-per-node 4 demo.py</code></p>
|
| 331 |
+
<p>Semantics stay in the model (a Linear stays a Linear), distribution is orthogonal and declared via strings: “colwise” splits columns of weights/bias across ranks; “rowwise” splits rows; packed variants shard fused weights; The mapping keys accept glob patterns like <code>layers.*.mlp.down_proj</code> to target repeated submodules.</p>
|
| 332 |
<h2><a id="layers-attentions-caches"></a> Layers, attentions and caches</h2>
|
| 333 |
<p>With th</p>
|
| 334 |
<h2><a id="community-kernels"></a>Community Kernels</h2>
|
|
|
|
| 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>
|
|
|
|
| 446 |
<h2>Modularity candidates</h2>
|
| 447 |
<p>So the question abounds naturally: How can we modularize more?
|
| 448 |
I took again a similarity measure and looked at the existing graphs. The tool is available on this <a href="https://huggingface.co/spaces/Molbap/transformers-modular-refactor">ZeroGPU-enabled Space</a>. It scans the whole transformers repository, and outputs a graph of candidates across models, using either a Jaccard similarity index (simple) or a SentenceTransformers embedding model. It is understandable that <a href="#encoders-ftw">encoder models still have a lion’s share of the game.</a> See also <a href="https://huggingface.co/blog/train-sparse-encoder">Tom Aarsen and Arhur Bresnu’s great blog post on the topic of sparse embeddings.</a>.</p>
|
| 449 |
+
<p></p>
|
| 450 |
<h2><a id="encoders-ftw"></a> The neverending stories of encoder models.</h2>
|
| 451 |
<p>Models popularity speaks for itself! This is because the usage of encoders lies in embeddings obviously. So we have to keep the encoders part viable, usable, fine-tune-able.</p>
|
| 452 |
<p><img src="static/popular_models_barplot.png" alt="Popular models bar plot"></p>
|
|
|
|
| 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>
|
| 537 |
+
|
| 538 |
+
<div class=warmup-demo>
|
| 539 |
+
<div class=container>
|
| 540 |
+
<p class=subtitle>Mem allocation patterns during model loading</p>
|
| 541 |
+
|
| 542 |
+
<div class=controls>
|
| 543 |
+
<button class=btn id=startBtn onclick=startDemo()>Start Animation</button>
|
| 544 |
+
<button class=btn id=resetBtn onclick=resetDemo()>Reset</button>
|
| 545 |
+
</div>
|
| 546 |
+
|
| 547 |
+
<div class=demo-container>
|
| 548 |
+
<div class="no-warmup side">
|
| 549 |
+
<h2 data-no-toc>❌ Without Warmup</h2>
|
| 550 |
+
<div class=timing id=noWarmupTime>0.00s</div>
|
| 551 |
+
<div class=layer-counter id=noWarmupCounter>Layers loaded: 0/10</div>
|
| 552 |
+
<div class=phase-indicator id=noWarmupPhase></div>
|
| 553 |
+
<div class=memory-area id=noWarmupArea></div>
|
| 554 |
+
<div class=description>
|
| 555 |
+
<strong>Individual Allocations:</strong><br>
|
| 556 |
+
Each model layer triggers a separate cudaMalloc() call, creating memory fragmentation and allocation overhead.
|
| 557 |
+
<br><br>
|
| 558 |
+
📦 <strong>Grey "malloc"</strong> = Memory allocation overhead<br>
|
| 559 |
+
✅ <strong>Green "data"</strong> = Actual layer data loading
|
| 560 |
+
</div>
|
| 561 |
+
</div>
|
| 562 |
+
|
| 563 |
+
<div class="side with-warmup">
|
| 564 |
+
<h2 data-no-toc>✅ With Warmup</h2>
|
| 565 |
+
<div class=timing id=warmupTime>0.00s</div>
|
| 566 |
+
<div class=layer-counter id=warmupCounter>Layers loaded: 0/10</div>
|
| 567 |
+
<div class=phase-indicator id=warmupPhase></div>
|
| 568 |
+
<div class=memory-area id=warmupArea>
|
| 569 |
+
<div class=warmup-container id=warmupContainer>
|
| 570 |
+
<div class=warmup-fill id=warmupFill></div>
|
| 571 |
+
</div>
|
| 572 |
+
<div id=warmupLayers></div>
|
| 573 |
+
</div>
|
| 574 |
+
<div class=description>
|
| 575 |
+
<strong>Pre-allocated Pool:</strong><br>
|
| 576 |
+
The warmup function calculates total memory needed and makes ONE large allocation. Subsequent layers load directly into this pool, eliminating malloc overhead.
|
| 577 |
+
<br><br>
|
| 578 |
+
🔵 <strong>Blue container</strong> = Single large malloc (warmup)<br>
|
| 579 |
+
🟢 <strong>Green progress bar</strong> = Layer data loading (no malloc needed)
|
| 580 |
+
</div>
|
| 581 |
+
</div>
|
| 582 |
+
</div>
|
| 583 |
</div>
|
| 584 |
+
</div>
|
| 585 |
+
|
| 586 |
+
<script>let animationSpeed=1/2.4,isRunning=!1,totalLayers=10;function startDemo(){isRunning||(isRunning=!0,document.getElementById("startBtn").disabled=!0,document.getElementById("resetBtn").disabled=!0,Promise.all([animateNoWarmup(),animateWithWarmup()]).then(()=>{isRunning=!1,document.getElementById("startBtn").disabled=!1,document.getElementById("resetBtn").disabled=!1}))}function resetDemo(){isRunning||(document.getElementById("noWarmupArea").innerHTML="",document.getElementById("warmupLayers").innerHTML="",document.getElementById("warmupFill").style.width="0%",document.getElementById("warmupContainer").classList.remove("allocated"),document.getElementById("noWarmupTime").textContent="0.00s",document.getElementById("warmupTime").textContent="0.00s",document.getElementById("noWarmupCounter").textContent="Layers loaded: 0/10",document.getElementById("warmupCounter").textContent="Layers loaded: 0/10",document.getElementById("noWarmupPhase").textContent="",document.getElementById("warmupPhase").textContent="")}async function animateNoWarmup(){let e=document.getElementById("noWarmupArea"),t=document.getElementById("noWarmupTime"),n=document.getElementById("noWarmupCounter"),a=document.getElementById("noWarmupPhase"),m=0,o=200/animationSpeed;a.textContent="Loading model layers...";for(let a=0;a<10;a++){let d=document.createElement("div");d.className="layer-box",e.appendChild(d),await sleep(.3*o),d.classList.add("allocating"),t.textContent=(m+=.08).toFixed(2)+"s",await sleep(.7*o),d.classList.remove("allocating"),d.classList.add("loaded"),t.textContent=(m+=.12).toFixed(2)+"s",n.textContent=`Layers loaded: ${a+1}/10`}a.textContent="Complete!"}async function animateWithWarmup(){let e=document.getElementById("warmupLayers"),t=document.getElementById("warmupTime"),n=document.getElementById("warmupCounter"),a=document.getElementById("warmupPhase"),m=document.getElementById("warmupContainer"),o=document.getElementById("warmupFill"),d=0,l=200/animationSpeed;a.textContent="Warming up allocator...",await sleep(2*l),m.classList.add("allocated"),t.textContent=(d+=.3).toFixed(2)+"s",a.textContent="Loading model layers...";for(let a=0;a<10;a++){let m=document.createElement("div");m.className="layer-box loaded",m.style.width="40px",m.style.height="20px",e.appendChild(m);let i=(a+1)/10*100;o.style.width=i+"%",await sleep(.5*l),t.textContent=(d+=.08).toFixed(2)+"s",n.textContent=`Layers loaded: ${a+1}/10`}a.textContent="Complete!"}function sleep(e){return new Promise(t=>setTimeout(t,e))}</script></p>
|
| 587 |
+
<h2>What is coming next</h2>
|
| 588 |
+
<p>It sounds dumb, but it’s true: the future is very soon. One tenet that will be broken when the next major version is released, v5, <a href="#backwards-compatibility">backwards compatibility</a> will be heavily broken. Instead, what we aim to be is way more of a <a href="#modular-toolbox">modular toolbox</a>, while maintaining a <a href="#consistent-public-surface">consistent public surface</a>.</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
| 589 |
|
| 590 |
</d-article>
|
| 591 |
|
|
|
|
| 594 |
const article = document.querySelector('d-article');
|
| 595 |
const toc = document.querySelector('d-contents');
|
| 596 |
if (toc) {
|
| 597 |
+
const headings = [...article.querySelectorAll('h1, h2, h3, h4')].filter(h => !h.hasAttribute('data-no-toc'));
|
| 598 |
let ToC = '<nav role="navigation" class="l-text figcaption">';
|
| 599 |
ToC += '<div class="toc-header"><span class="toc-title">Table of Contents</span></div>';
|
| 600 |
ToC += '<div class="toc-content">';
|
dist/main.bundle.js
CHANGED
|
@@ -146,7 +146,7 @@ module.exports = styleTagTransform;
|
|
| 146 |
var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));
|
| 147 |
___CSS_LOADER_EXPORT___.i(_node_modules_css_loader_dist_cjs_js_transformers_custom_css__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A);
|
| 148 |
// Module
|
| 149 |
-
___CSS_LOADER_EXPORT___.push([module.id, `/* style.css -
|
| 150 |
|
| 151 |
/* Import ultrascale-playbook base styles and add transformers-specific styling */
|
| 152 |
/* Define colors */
|
|
@@ -885,7 +885,7 @@ iframe, .js-plotly-plot {
|
|
| 885 |
margin-right: 0px;
|
| 886 |
}
|
| 887 |
|
| 888 |
-
/* Import transformers-specific styles */`, "",{"version":3,"sources":["webpack://./src/style.css"],"names":[],"mappings":"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","sourcesContent":["/* style.css - Transformers Playthrough */\n\n/* Import ultrascale-playbook base styles and add transformers-specific styling */\n/* Define colors */\n:root {\n --distill-gray: rgb(107, 114, 128);\n --distill-gray-light: rgb(185, 185, 185);\n --distill-gray-lighter: rgb(228, 228, 228);\n --distill-gray-lightest: rgb(245, 245, 245);\n --distill-blue: #007BFF;\n}\n\n/* Container for the controls */\n[id^=\"plot-\"] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 15px; /* Adjust the gap between controls as needed */\n}\n[id^=\"plot-\"] figure {\n margin-bottom: 0px;\n margin-top: 0px;\n padding: 0px;\n}\n.plotly_caption {\n font-style: italic;\n margin-top: 10px;\n}\n\n.plotly_controls {\n display: flex;\n flex-wrap: wrap;\n flex-direction: row;\n justify-content: center;\n align-items: flex-start;\n gap: 30px;\n}\n\n\n.plotly_input_container {\n display: flex;\n align-items: center;\n flex-direction: column;\n gap: 10px;\n}\n\n/* Style for the select dropdown */\n.plotly_input_container > select {\n padding: 2px 4px;\n /* border: 1px solid #ccc; */\n line-height: 1.5em;\n text-align: center;\n border-radius: 4px;\n font-size: 12px;\n background-color: var(--distill-gray-lightest);\n outline: none;\n}\n\n/* Style for the range input */\n\n.plotly_slider {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.plotly_slider > input[type=\"range\"] {\n -webkit-appearance: none;\n height: 2px;\n background: var(--distill-gray-light);\n border-radius: 5px;\n outline: none;\n}\n\n.plotly_slider > span {\n font-size: 14px;\n line-height: 1.6em;\n min-width: 16px;\n}\n\n.plotly_slider > input[type=\"range\"]::-webkit-slider-thumb {\n -webkit-appearance: none;\n appearance: none;\n width: 18px;\n height: 18px;\n border-radius: 50%;\n background: var(--distill-blue);\n cursor: pointer;\n}\n\n.plotly_slider > input[type=\"range\"]::-moz-range-thumb {\n width: 18px;\n height: 18px;\n border-radius: 50%;\n background: var(--distill-blue);\n cursor: pointer;\n}\n\n/* Style for the labels */\n.plotly_input_container > label {\n font-size: 14px;\n font-weight: bold;\n}\n\n.main-plot-container {\n margin-top: 21px;\n margin-bottom: 35px;\n}\n\n.main-plot-container > figure {\n display: block !important;\n /* Let this be handled by graph-container */\n margin-bottom: 0px;\n margin-top: 0px;\n}\n.main-plot-container > div {\n display: none !important;\n}\n\n\n@media (min-width: 768px) {\n .main-plot-container > figure {\n display: none !important;\n }\n .main-plot-container > div {\n display: flex !important;\n }\n}\n\nd-byline .byline {\n grid-template-columns: 1fr;\n grid-column: text;\n font-size: 0.9rem;\n line-height: 1.8em;\n}\n\n@media (min-width: 768px) {\n d-byline .byline {\n grid-template-columns: 5fr 1fr 1fr;\n }\n}\n\n#title-plot {\n margin-top: 0px;\n margin-bottom: 0px;\n}\n\nd-contents > nav a.active {\n text-decoration: underline;\n}\n\n@media (max-width: 1199px) {\n d-contents {\n display: none;\n background: white;\n justify-self: start;\n align-self: start;\n padding-bottom: 0.5em;\n margin-bottom: 1em;\n padding-left: 0.25em;\n border-bottom: 1px solid rgba(0, 0, 0, 0.1);\n border-bottom-width: 1px;\n border-bottom-style: solid;\n border-bottom-color: rgba(0, 0, 0, 0.1);\n overflow-y: scroll;\n height: calc(100vh - 40px);\n scrollbar-width: none;\n z-index: -100;\n }\n}\n\nd-contents a:hover {\n border-bottom: none;\n}\n\ntoc-title {\n font-weight: bold;\n font-size: 1.2em;\n color: #333;\n}\n\ntoggle-icon {\n transition: transform 0.3s;\n}\n\ntoggle-icon.collapsed {\n transform: rotate(90deg);\n}\n\n.toc-content {\n margin-top: 15px;\n overflow: hidden;\n /* max-height: 1000px; */\n transition: max-height 0.3s ease-out;\n}\n\n.toc-content.collapsed {\n max-height: 0;\n margin-top: 0;\n}\n\n@media (min-width: 1200px) {\n d-article {\n /* Ensure d-article does not prevent sticky positioning */\n overflow: visible;\n }\n\n d-contents {\n align-self: start;\n background: white;\n grid-column-start: 1 !important;\n grid-column-end: 4 !important;\n grid-row: auto / span 6;\n justify-self: end;\n margin-top: 0em;\n padding-right: 3em;\n padding-left: 2em;\n /* border-right: 1px solid rgba(0, 0, 0, 0.1);\n border-right-width: 1px;\n border-right-style: solid;\n border-right-color: rgba(0, 0, 0, 0.1); */\n position: -webkit-sticky; /* For Safari */\n position: sticky;\n top: 10px; /* Adjust this value if needed */\n overflow-y: auto;\n height: calc(100vh - 40px);\n scrollbar-width: none;\n transition: max-height 0.3s ease-out;\n z-index: -100;\n }\n}\n\nd-contents nav h3 {\n margin-top: 0;\n margin-bottom: 1em;\n}\n\nd-contents nav div div {\n color: rgba(0, 0, 0, 0.8);\n font-weight: bold;\n}\n\nd-contents nav a {\n color: rgba(0, 0, 0, 0.8);\n border-bottom: none;\n text-decoration: none;\n}\n\nd-contents li {\n list-style-type: none;\n}\n\nd-contents ul, d-article d-contents ul {\n padding-left: 1em;\n}\n\nd-contents nav ul li {\n margin-bottom: .25em;\n}\n\nd-contents nav a:hover {\n text-decoration: underline solid rgba(0, 0, 0, 0.6);\n}\n\nd-contents nav ul {\n margin-top: 0;\n margin-bottom: 6px;\n}\n\n\nd-contents nav > div {\n display: block;\n outline: none;\n margin-bottom: 0.5em;\n}\n\nd-contents nav > div > a {\n font-size: 13px;\n font-weight: 600;\n}\n\nd-article aside {\n margin-bottom: 1em;\n}\n\nd-article img {\n max-width: 100%;\n}\n\n@media (min-width: 768px) {\n d-article aside {\n margin-bottom: 0;\n }\n}\n\nd-contents nav > div > a:hover,\nd-contents nav > ul > li > a:hover {\n text-decoration: none;\n}\n\n.note-box {\n background-color: #f6f8fa;\n border-left: 4px solid #444444;\n padding: 1rem;\n margin: 1rem 0; /* Keep this modest margin */\n border-radius: 6px;\n /* Add this to ensure the box only takes up needed space */\n display: inline-block;\n}\n\n.note-box-title {\n margin: 0;\n color: #444444;\n font-weight: 600;\n font-size: 1em;\n}\n\n.note-box-content {\n margin-top: 0.5rem;\n margin-bottom: 0; /* Ensure no bottom margin */\n color: #24292f;\n font-size: 0.9em;\n line-height: 1.5em;\n}\n\n/* For dark mode support */\n@media (prefers-color-scheme: dark) {\n .note-box {\n background-color: #1c1c1c;\n border-left-color: #888888;\n }\n .note-box-title {\n color: #888888;\n }\n .note-box-content {\n color: #d4d4d4;\n }\n}\n\nd-article {\n font-size: 1.0em;\n}\n\n.figure-legend {\n font-size: 0.9em;\n font-style: italic;\n color: var(--distill-gray);\n line-height: 1.5em;\n}\n\nd-code {\n font-size: 12px;\n}\n\n.large-image-background {\n width: 100vw;\n padding-top: 10px;\n padding-bottom: 10px;\n margin-left: calc(-50vw + 50%);\n margin-right: calc(-50vw + 50%);\n background: white;\n height: fit-content; /* This will make it match the image height */\n display: flex;\n justify-content: center; /* This will center your image */\n}\n\n.large-image-background-transparent {\n /* width: 100vw; */\n padding-top: 10px;\n padding-bottom: 10px;\n /* margin-left: calc(-50vw + 50%); */\n margin-left:-100px;\n margin-right: -100px;\n /* margin-right: calc(-50vw + 50%); */\n /* background: white; */\n height: fit-content; /* This will make it match the image height */\n display: flex;\n justify-content: center; /* This will center your image */\n}\n\n.boxed-image {\n padding: 0.5rem;\n background: white;\n border-radius: 12px;\n border: 1px solid #e5e7eb;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n}\n\nd-article li {\n margin-bottom: 0.0em;\n}\n\nd-article ul ul {\n margin-bottom: 0.0em;\n}\n\nd-article ol ol {\n margin-bottom: 0.0em;\n}\n\nd-article hr {\n grid-column: text;\n}\n\n/* Memory visualization */\n#graph-all {\n min-width: 500px;\n margin-right: 10px;\n margin-bottom: 2rem;\n padding: 0.5rem;\n background: #f9fafb;\n border-radius: 12px;\n border: 1px solid #e5e7eb;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n}\n\n\n/* Main container styles */\n#controls {\n max-width: 1200px;\n /* margin: 2rem auto; */\n margin-bottom: 2rem;\n margin-left: 10px;\n padding: 0.6rem;\n background: #f9fafb;\n border-radius: 12px;\n border: 1px solid #e5e7eb;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n}\n\n/* Grid layout */\n#controls {\n display: grid;\n grid-template-columns: 1fr 1fr;\n /* gap: 2rem; */\n}\n\n/* Cell styles */\n.cell {\n margin-bottom: 0.2rem;\n}\n\n/* Label styles */\nlabel {\n display: block;\n /* margin-bottom: 0.5rem; */\n font-size: 0.8rem;\n font-weight: 500;\n color: #374151;\n}\n\n/* Input container for range + number combination */\n.input-container {\n display: flex;\n gap: 1rem;\n align-items: center;\n}\n\n/* Range input styling */\ninput[type=\"range\"] {\n flex: 1;\n height: 6px;\n background: #e5e7eb;\n border-radius: 3px;\n appearance: none;\n outline: none;\n}\n\ninput[type=\"range\"]::-webkit-slider-thumb {\n appearance: none;\n width: 16px;\n height: 16px;\n background: #3b82f6;\n border-radius: 50%;\n cursor: pointer;\n transition: background 0.15s ease;\n}\n\ninput[type=\"range\"]::-webkit-slider-thumb:hover {\n background: #2563eb;\n}\n\n/* Number input styling */\ninput[type=\"number\"] {\n width: 80px;\n padding: 0.5rem;\n border: 1px solid #e5e7eb;\n border-radius: 6px;\n font-size: 0.9rem;\n color: #374151;\n}\n\n/* Select styling */\nselect {\n width: 100%;\n padding: 0.5rem;\n border: 1px solid #e5e7eb;\n border-radius: 6px;\n background: white;\n font-size: 0.9rem;\n color: #374151;\n cursor: pointer;\n}\n\n/* Checkbox styling */\ninput[type=\"checkbox\"] {\n width: 1.2rem;\n height: 1.2rem;\n margin-right: 0.5rem;\n border: 2px solid #e5e7eb;\n border-radius: 4px;\n cursor: pointer;\n}\n\n/* Column specific styles */\n.column-1 {\n padding-right: 0.5rem;\n}\n\n.column-2 {\n padding-left: 0.5rem;\n}\n\n/* Checkbox container */\n.checkbox-container {\n display: flex;\n align-items: center;\n margin-bottom: 1rem;\n}\n\n/* Memory visualization styles */\n.memory-block {\n background: #fff;\n border-radius: 8px;\n padding: 1rem;\n margin-bottom: 1rem;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);\n}\n\n.memory-title {\n font-size: 1.1rem;\n font-weight: 500;\n color: #374151;\n margin-bottom: 0.5rem;\n}\n\n.memory-value {\n font-size: 1.5rem;\n font-weight: 600;\n color: #3b82f6;\n}\n\n/* Responsive adjustments */\n@media (max-width: 768px) {\n #controls {\n grid-template-columns: 1fr;\n padding: 1rem;\n }\n\n .column-1, .column-2 {\n padding: 0;\n }\n}\n\n/* Hover states and transitions */\ninput:hover, select:hover {\n border-color: #3b82f6;\n}\n\ninput:focus, select:focus {\n border-color: #2563eb;\n outline: none;\n box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1);\n}\n\n/* Add smooth transitions */\ninput, select, button {\n transition: all 0.15s ease;\n}\n\n/* Preset dropdown special styling */\nselect[name=\"presets\"] {\n background-color: #f3f4f6;\n font-weight: 500;\n}\n\n/* Memory graph enhancements */\n.activation-memory {\n background: #dbeafe;\n padding: 1rem;\n border-radius: 8px;\n margin-bottom: 1rem;\n}\n\n.gradient-memory {\n background: #ede9fe;\n padding: 1rem;\n border-radius: 8px;\n}\n\n.order-button-second {\n background: linear-gradient(135deg, #6DB4C4, #D4A5B8);\n color: white;\n font-size: 18px;\n font-weight: 600;\n padding: 20px 20px;\n border: none;\n border-radius: 12px;\n cursor: pointer;\n text-transform: uppercase;\n letter-spacing: 1px;\n box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);\n transition: all 0.3s ease;\n position: relative;\n overflow: hidden;\n }\n.order-button-second:hover {\n transform: translateY(-2px);\n box-shadow: 0 6px 20px rgba(0, 0, 0, 0.25);\n}\n\n.order-button:active {\n transform: translateY(0);\n box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);\n}\n\n.order-button-second::before {\n content: '';\n position: absolute;\n top: 0;\n left: -100%;\n width: 100%;\n height: 100%;\n background: linear-gradient(135deg, rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0));\n transition: left 0.5s ease;\n}\n\n.order-button-second:hover::before {\n left: 100%;\n}\n\n.order-button {\n background: linear-gradient(135deg, #6DB4C4, #D4A5B8);\n color: white;\n font-size: 18px;\n font-weight: 600;\n padding: 16px 32px;\n border: none;\n border-radius: 12px;\n cursor: pointer;\n text-transform: uppercase;\n letter-spacing: 1px;\n box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);\n transition: all 0.3s ease;\n position: relative;\n overflow: hidden;\n }\n\n.order-button:hover {\n transform: translateY(-2px);\n box-shadow: 0 6px 20px rgba(0, 0, 0, 0.25);\n}\n\n.order-button:active {\n transform: translateY(0);\n box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);\n}\n\n.order-button::before {\n content: '';\n position: absolute;\n top: 0;\n left: -100%;\n width: 100%;\n height: 100%;\n background: linear-gradient(135deg, rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0));\n transition: left 0.5s ease;\n}\n\n.order-button:hover::before {\n left: 100%;\n}\n.order-button-container-second {\n /* display: flex; */\n justify-content: center;\n margin: 0px 0;\n}\n\n.order-button-container {\n display: flex;\n justify-content: center;\n margin: 0px 0 40px 0;\n}\n\nd-article img {\n width: 100%!important;\n}\n\n\niframe, .js-plotly-plot {\n width: 100%!important;\n margin-bottom: 20px;\n}\n\n.modebar-container {\n display: none;\n}\n\n#graph-container {\n display: grid; grid-template-columns: 1fr 1fr; align-items: center;\n}\n\n@media (max-width: 768px) {\n #graph-container {\n grid-template-columns: 1fr;\n }\n}\n\n@media (max-width: 1024px) {\n #graph-container {\n grid-template-columns: 1fr;\n }\n #graph-all {\n margin-right: 0px;\n }\n #controls {\n margin-left: 0px;\n }\n}\n\n.main-plot-container svg {\n background: transparent !important;\n}\n\n.large-image-background-transparent {\n margin-left: 0px;\n margin-right: 0px;\n}\n\n/* Import transformers-specific styles */\n@import url('./transformers-custom.css');"],"sourceRoot":""}]);
|
| 889 |
// Exports
|
| 890 |
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
|
| 891 |
|
|
@@ -1973,11 +1973,11 @@ var update = injectStylesIntoStyleTag_default()(style/* default */.A, options);
|
|
| 1973 |
/* harmony default export */ const src_style = (style/* default */.A && style/* default */.A.locals ? style/* default */.A.locals : undefined);
|
| 1974 |
|
| 1975 |
;// ./src/index.js
|
| 1976 |
-
// Main JavaScript file for
|
| 1977 |
|
| 1978 |
|
| 1979 |
// Import any additional functionality
|
| 1980 |
-
console.log('
|
| 1981 |
|
| 1982 |
// Add any custom JavaScript functionality here
|
| 1983 |
document.addEventListener('DOMContentLoaded', function () {
|
|
|
|
| 146 |
var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));
|
| 147 |
___CSS_LOADER_EXPORT___.i(_node_modules_css_loader_dist_cjs_js_transformers_custom_css__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A);
|
| 148 |
// Module
|
| 149 |
+
___CSS_LOADER_EXPORT___.push([module.id, `/* style.css - Scaling Insanity */
|
| 150 |
|
| 151 |
/* Import ultrascale-playbook base styles and add transformers-specific styling */
|
| 152 |
/* Define colors */
|
|
|
|
| 885 |
margin-right: 0px;
|
| 886 |
}
|
| 887 |
|
| 888 |
+
/* Import transformers-specific styles */`, "",{"version":3,"sources":["webpack://./src/style.css"],"names":[],"mappings":"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","sourcesContent":["/* style.css - Scaling Insanity */\n\n/* Import ultrascale-playbook base styles and add transformers-specific styling */\n/* Define colors */\n:root {\n --distill-gray: rgb(107, 114, 128);\n --distill-gray-light: rgb(185, 185, 185);\n --distill-gray-lighter: rgb(228, 228, 228);\n --distill-gray-lightest: rgb(245, 245, 245);\n --distill-blue: #007BFF;\n}\n\n/* Container for the controls */\n[id^=\"plot-\"] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 15px; /* Adjust the gap between controls as needed */\n}\n[id^=\"plot-\"] figure {\n margin-bottom: 0px;\n margin-top: 0px;\n padding: 0px;\n}\n.plotly_caption {\n font-style: italic;\n margin-top: 10px;\n}\n\n.plotly_controls {\n display: flex;\n flex-wrap: wrap;\n flex-direction: row;\n justify-content: center;\n align-items: flex-start;\n gap: 30px;\n}\n\n\n.plotly_input_container {\n display: flex;\n align-items: center;\n flex-direction: column;\n gap: 10px;\n}\n\n/* Style for the select dropdown */\n.plotly_input_container > select {\n padding: 2px 4px;\n /* border: 1px solid #ccc; */\n line-height: 1.5em;\n text-align: center;\n border-radius: 4px;\n font-size: 12px;\n background-color: var(--distill-gray-lightest);\n outline: none;\n}\n\n/* Style for the range input */\n\n.plotly_slider {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.plotly_slider > input[type=\"range\"] {\n -webkit-appearance: none;\n height: 2px;\n background: var(--distill-gray-light);\n border-radius: 5px;\n outline: none;\n}\n\n.plotly_slider > span {\n font-size: 14px;\n line-height: 1.6em;\n min-width: 16px;\n}\n\n.plotly_slider > input[type=\"range\"]::-webkit-slider-thumb {\n -webkit-appearance: none;\n appearance: none;\n width: 18px;\n height: 18px;\n border-radius: 50%;\n background: var(--distill-blue);\n cursor: pointer;\n}\n\n.plotly_slider > input[type=\"range\"]::-moz-range-thumb {\n width: 18px;\n height: 18px;\n border-radius: 50%;\n background: var(--distill-blue);\n cursor: pointer;\n}\n\n/* Style for the labels */\n.plotly_input_container > label {\n font-size: 14px;\n font-weight: bold;\n}\n\n.main-plot-container {\n margin-top: 21px;\n margin-bottom: 35px;\n}\n\n.main-plot-container > figure {\n display: block !important;\n /* Let this be handled by graph-container */\n margin-bottom: 0px;\n margin-top: 0px;\n}\n.main-plot-container > div {\n display: none !important;\n}\n\n\n@media (min-width: 768px) {\n .main-plot-container > figure {\n display: none !important;\n }\n .main-plot-container > div {\n display: flex !important;\n }\n}\n\nd-byline .byline {\n grid-template-columns: 1fr;\n grid-column: text;\n font-size: 0.9rem;\n line-height: 1.8em;\n}\n\n@media (min-width: 768px) {\n d-byline .byline {\n grid-template-columns: 5fr 1fr 1fr;\n }\n}\n\n#title-plot {\n margin-top: 0px;\n margin-bottom: 0px;\n}\n\nd-contents > nav a.active {\n text-decoration: underline;\n}\n\n@media (max-width: 1199px) {\n d-contents {\n display: none;\n background: white;\n justify-self: start;\n align-self: start;\n padding-bottom: 0.5em;\n margin-bottom: 1em;\n padding-left: 0.25em;\n border-bottom: 1px solid rgba(0, 0, 0, 0.1);\n border-bottom-width: 1px;\n border-bottom-style: solid;\n border-bottom-color: rgba(0, 0, 0, 0.1);\n overflow-y: scroll;\n height: calc(100vh - 40px);\n scrollbar-width: none;\n z-index: -100;\n }\n}\n\nd-contents a:hover {\n border-bottom: none;\n}\n\ntoc-title {\n font-weight: bold;\n font-size: 1.2em;\n color: #333;\n}\n\ntoggle-icon {\n transition: transform 0.3s;\n}\n\ntoggle-icon.collapsed {\n transform: rotate(90deg);\n}\n\n.toc-content {\n margin-top: 15px;\n overflow: hidden;\n /* max-height: 1000px; */\n transition: max-height 0.3s ease-out;\n}\n\n.toc-content.collapsed {\n max-height: 0;\n margin-top: 0;\n}\n\n@media (min-width: 1200px) {\n d-article {\n /* Ensure d-article does not prevent sticky positioning */\n overflow: visible;\n }\n\n d-contents {\n align-self: start;\n background: white;\n grid-column-start: 1 !important;\n grid-column-end: 4 !important;\n grid-row: auto / span 6;\n justify-self: end;\n margin-top: 0em;\n padding-right: 3em;\n padding-left: 2em;\n /* border-right: 1px solid rgba(0, 0, 0, 0.1);\n border-right-width: 1px;\n border-right-style: solid;\n border-right-color: rgba(0, 0, 0, 0.1); */\n position: -webkit-sticky; /* For Safari */\n position: sticky;\n top: 10px; /* Adjust this value if needed */\n overflow-y: auto;\n height: calc(100vh - 40px);\n scrollbar-width: none;\n transition: max-height 0.3s ease-out;\n z-index: -100;\n }\n}\n\nd-contents nav h3 {\n margin-top: 0;\n margin-bottom: 1em;\n}\n\nd-contents nav div div {\n color: rgba(0, 0, 0, 0.8);\n font-weight: bold;\n}\n\nd-contents nav a {\n color: rgba(0, 0, 0, 0.8);\n border-bottom: none;\n text-decoration: none;\n}\n\nd-contents li {\n list-style-type: none;\n}\n\nd-contents ul, d-article d-contents ul {\n padding-left: 1em;\n}\n\nd-contents nav ul li {\n margin-bottom: .25em;\n}\n\nd-contents nav a:hover {\n text-decoration: underline solid rgba(0, 0, 0, 0.6);\n}\n\nd-contents nav ul {\n margin-top: 0;\n margin-bottom: 6px;\n}\n\n\nd-contents nav > div {\n display: block;\n outline: none;\n margin-bottom: 0.5em;\n}\n\nd-contents nav > div > a {\n font-size: 13px;\n font-weight: 600;\n}\n\nd-article aside {\n margin-bottom: 1em;\n}\n\nd-article img {\n max-width: 100%;\n}\n\n@media (min-width: 768px) {\n d-article aside {\n margin-bottom: 0;\n }\n}\n\nd-contents nav > div > a:hover,\nd-contents nav > ul > li > a:hover {\n text-decoration: none;\n}\n\n.note-box {\n background-color: #f6f8fa;\n border-left: 4px solid #444444;\n padding: 1rem;\n margin: 1rem 0; /* Keep this modest margin */\n border-radius: 6px;\n /* Add this to ensure the box only takes up needed space */\n display: inline-block;\n}\n\n.note-box-title {\n margin: 0;\n color: #444444;\n font-weight: 600;\n font-size: 1em;\n}\n\n.note-box-content {\n margin-top: 0.5rem;\n margin-bottom: 0; /* Ensure no bottom margin */\n color: #24292f;\n font-size: 0.9em;\n line-height: 1.5em;\n}\n\n/* For dark mode support */\n@media (prefers-color-scheme: dark) {\n .note-box {\n background-color: #1c1c1c;\n border-left-color: #888888;\n }\n .note-box-title {\n color: #888888;\n }\n .note-box-content {\n color: #d4d4d4;\n }\n}\n\nd-article {\n font-size: 1.0em;\n}\n\n.figure-legend {\n font-size: 0.9em;\n font-style: italic;\n color: var(--distill-gray);\n line-height: 1.5em;\n}\n\nd-code {\n font-size: 12px;\n}\n\n.large-image-background {\n width: 100vw;\n padding-top: 10px;\n padding-bottom: 10px;\n margin-left: calc(-50vw + 50%);\n margin-right: calc(-50vw + 50%);\n background: white;\n height: fit-content; /* This will make it match the image height */\n display: flex;\n justify-content: center; /* This will center your image */\n}\n\n.large-image-background-transparent {\n /* width: 100vw; */\n padding-top: 10px;\n padding-bottom: 10px;\n /* margin-left: calc(-50vw + 50%); */\n margin-left:-100px;\n margin-right: -100px;\n /* margin-right: calc(-50vw + 50%); */\n /* background: white; */\n height: fit-content; /* This will make it match the image height */\n display: flex;\n justify-content: center; /* This will center your image */\n}\n\n.boxed-image {\n padding: 0.5rem;\n background: white;\n border-radius: 12px;\n border: 1px solid #e5e7eb;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n}\n\nd-article li {\n margin-bottom: 0.0em;\n}\n\nd-article ul ul {\n margin-bottom: 0.0em;\n}\n\nd-article ol ol {\n margin-bottom: 0.0em;\n}\n\nd-article hr {\n grid-column: text;\n}\n\n/* Memory visualization */\n#graph-all {\n min-width: 500px;\n margin-right: 10px;\n margin-bottom: 2rem;\n padding: 0.5rem;\n background: #f9fafb;\n border-radius: 12px;\n border: 1px solid #e5e7eb;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n}\n\n\n/* Main container styles */\n#controls {\n max-width: 1200px;\n /* margin: 2rem auto; */\n margin-bottom: 2rem;\n margin-left: 10px;\n padding: 0.6rem;\n background: #f9fafb;\n border-radius: 12px;\n border: 1px solid #e5e7eb;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n}\n\n/* Grid layout */\n#controls {\n display: grid;\n grid-template-columns: 1fr 1fr;\n /* gap: 2rem; */\n}\n\n/* Cell styles */\n.cell {\n margin-bottom: 0.2rem;\n}\n\n/* Label styles */\nlabel {\n display: block;\n /* margin-bottom: 0.5rem; */\n font-size: 0.8rem;\n font-weight: 500;\n color: #374151;\n}\n\n/* Input container for range + number combination */\n.input-container {\n display: flex;\n gap: 1rem;\n align-items: center;\n}\n\n/* Range input styling */\ninput[type=\"range\"] {\n flex: 1;\n height: 6px;\n background: #e5e7eb;\n border-radius: 3px;\n appearance: none;\n outline: none;\n}\n\ninput[type=\"range\"]::-webkit-slider-thumb {\n appearance: none;\n width: 16px;\n height: 16px;\n background: #3b82f6;\n border-radius: 50%;\n cursor: pointer;\n transition: background 0.15s ease;\n}\n\ninput[type=\"range\"]::-webkit-slider-thumb:hover {\n background: #2563eb;\n}\n\n/* Number input styling */\ninput[type=\"number\"] {\n width: 80px;\n padding: 0.5rem;\n border: 1px solid #e5e7eb;\n border-radius: 6px;\n font-size: 0.9rem;\n color: #374151;\n}\n\n/* Select styling */\nselect {\n width: 100%;\n padding: 0.5rem;\n border: 1px solid #e5e7eb;\n border-radius: 6px;\n background: white;\n font-size: 0.9rem;\n color: #374151;\n cursor: pointer;\n}\n\n/* Checkbox styling */\ninput[type=\"checkbox\"] {\n width: 1.2rem;\n height: 1.2rem;\n margin-right: 0.5rem;\n border: 2px solid #e5e7eb;\n border-radius: 4px;\n cursor: pointer;\n}\n\n/* Column specific styles */\n.column-1 {\n padding-right: 0.5rem;\n}\n\n.column-2 {\n padding-left: 0.5rem;\n}\n\n/* Checkbox container */\n.checkbox-container {\n display: flex;\n align-items: center;\n margin-bottom: 1rem;\n}\n\n/* Memory visualization styles */\n.memory-block {\n background: #fff;\n border-radius: 8px;\n padding: 1rem;\n margin-bottom: 1rem;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);\n}\n\n.memory-title {\n font-size: 1.1rem;\n font-weight: 500;\n color: #374151;\n margin-bottom: 0.5rem;\n}\n\n.memory-value {\n font-size: 1.5rem;\n font-weight: 600;\n color: #3b82f6;\n}\n\n/* Responsive adjustments */\n@media (max-width: 768px) {\n #controls {\n grid-template-columns: 1fr;\n padding: 1rem;\n }\n\n .column-1, .column-2 {\n padding: 0;\n }\n}\n\n/* Hover states and transitions */\ninput:hover, select:hover {\n border-color: #3b82f6;\n}\n\ninput:focus, select:focus {\n border-color: #2563eb;\n outline: none;\n box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1);\n}\n\n/* Add smooth transitions */\ninput, select, button {\n transition: all 0.15s ease;\n}\n\n/* Preset dropdown special styling */\nselect[name=\"presets\"] {\n background-color: #f3f4f6;\n font-weight: 500;\n}\n\n/* Memory graph enhancements */\n.activation-memory {\n background: #dbeafe;\n padding: 1rem;\n border-radius: 8px;\n margin-bottom: 1rem;\n}\n\n.gradient-memory {\n background: #ede9fe;\n padding: 1rem;\n border-radius: 8px;\n}\n\n.order-button-second {\n background: linear-gradient(135deg, #6DB4C4, #D4A5B8);\n color: white;\n font-size: 18px;\n font-weight: 600;\n padding: 20px 20px;\n border: none;\n border-radius: 12px;\n cursor: pointer;\n text-transform: uppercase;\n letter-spacing: 1px;\n box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);\n transition: all 0.3s ease;\n position: relative;\n overflow: hidden;\n }\n.order-button-second:hover {\n transform: translateY(-2px);\n box-shadow: 0 6px 20px rgba(0, 0, 0, 0.25);\n}\n\n.order-button:active {\n transform: translateY(0);\n box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);\n}\n\n.order-button-second::before {\n content: '';\n position: absolute;\n top: 0;\n left: -100%;\n width: 100%;\n height: 100%;\n background: linear-gradient(135deg, rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0));\n transition: left 0.5s ease;\n}\n\n.order-button-second:hover::before {\n left: 100%;\n}\n\n.order-button {\n background: linear-gradient(135deg, #6DB4C4, #D4A5B8);\n color: white;\n font-size: 18px;\n font-weight: 600;\n padding: 16px 32px;\n border: none;\n border-radius: 12px;\n cursor: pointer;\n text-transform: uppercase;\n letter-spacing: 1px;\n box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);\n transition: all 0.3s ease;\n position: relative;\n overflow: hidden;\n }\n\n.order-button:hover {\n transform: translateY(-2px);\n box-shadow: 0 6px 20px rgba(0, 0, 0, 0.25);\n}\n\n.order-button:active {\n transform: translateY(0);\n box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);\n}\n\n.order-button::before {\n content: '';\n position: absolute;\n top: 0;\n left: -100%;\n width: 100%;\n height: 100%;\n background: linear-gradient(135deg, rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0));\n transition: left 0.5s ease;\n}\n\n.order-button:hover::before {\n left: 100%;\n}\n.order-button-container-second {\n /* display: flex; */\n justify-content: center;\n margin: 0px 0;\n}\n\n.order-button-container {\n display: flex;\n justify-content: center;\n margin: 0px 0 40px 0;\n}\n\nd-article img {\n width: 100%!important;\n}\n\n\niframe, .js-plotly-plot {\n width: 100%!important;\n margin-bottom: 20px;\n}\n\n.modebar-container {\n display: none;\n}\n\n#graph-container {\n display: grid; grid-template-columns: 1fr 1fr; align-items: center;\n}\n\n@media (max-width: 768px) {\n #graph-container {\n grid-template-columns: 1fr;\n }\n}\n\n@media (max-width: 1024px) {\n #graph-container {\n grid-template-columns: 1fr;\n }\n #graph-all {\n margin-right: 0px;\n }\n #controls {\n margin-left: 0px;\n }\n}\n\n.main-plot-container svg {\n background: transparent !important;\n}\n\n.large-image-background-transparent {\n margin-left: 0px;\n margin-right: 0px;\n}\n\n/* Import transformers-specific styles */\n@import url('./transformers-custom.css');"],"sourceRoot":""}]);
|
| 889 |
// Exports
|
| 890 |
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
|
| 891 |
|
|
|
|
| 1973 |
/* harmony default export */ const src_style = (style/* default */.A && style/* default */.A.locals ? style/* default */.A.locals : undefined);
|
| 1974 |
|
| 1975 |
;// ./src/index.js
|
| 1976 |
+
// Main JavaScript file for Scaling Insanity
|
| 1977 |
|
| 1978 |
|
| 1979 |
// Import any additional functionality
|
| 1980 |
+
console.log('Scaling Insanity loaded');
|
| 1981 |
|
| 1982 |
// Add any custom JavaScript functionality here
|
| 1983 |
document.addEventListener('DOMContentLoaded', function () {
|
dist/main.bundle.js.map
CHANGED
|
The diff for this file is too large to render.
See raw diff
|
|
|
dist/style.css
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
/* style.css -
|
| 2 |
|
| 3 |
/* Import ultrascale-playbook base styles and add transformers-specific styling */
|
| 4 |
/* Define colors */
|
|
|
|
| 1 |
+
/* style.css - Scaling Insanity */
|
| 2 |
|
| 3 |
/* Import ultrascale-playbook base styles and add transformers-specific styling */
|
| 4 |
/* Define colors */
|
src/fragments/tp-plan.html
CHANGED
|
@@ -1,27 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
"layers.*.self_attn.k_proj": "colwise",
|
| 6 |
-
"layers.*.self_attn.v_proj": "colwise",
|
| 7 |
-
"layers.*.self_attn.o_proj": "rowwise",
|
| 8 |
-
"layers.*.mlp.gate_proj": "colwise",
|
| 9 |
-
"layers.*.mlp.up_proj": "colwise",
|
| 10 |
-
"layers.*.mlp.down_proj": "rowwise",
|
| 11 |
-
}
|
| 12 |
-
|
| 13 |
-
# Runtime
|
| 14 |
-
import torch
|
| 15 |
-
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 16 |
-
|
| 17 |
-
model_id = "your/model-or-local-checkpoint"
|
| 18 |
-
model = AutoModelForCausalLM.from_pretrained(
|
| 19 |
-
model_id,
|
| 20 |
-
dtype=torch.bfloat16,
|
| 21 |
-
tp_plan=base_model_tp_plan, # <-- plan defined above
|
| 22 |
-
)
|
| 23 |
-
tok = AutoTokenizer.from_pretrained(model_id)
|
| 24 |
-
inputs = tok("Hello", return_tensors="pt").to(model.device)
|
| 25 |
-
out = model(**inputs)</code></pre>
|
| 26 |
|
| 27 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<pre><code class="language-python"># In the model's config (example: ERNIE 4.5-style decoder blocks)
|
| 2 |
+
base_model_tp_plan = {
|
| 3 |
+
"layers.*.self_attn.q_proj": "colwise",
|
| 4 |
+
"layers.*.self_attn.k_proj": "colwise",
|
| 5 |
+
"layers.*.self_attn.v_proj": "colwise",
|
| 6 |
+
"layers.*.self_attn.o_proj": "rowwise",
|
| 7 |
+
"layers.*.mlp.gate_proj": "colwise",
|
| 8 |
+
"layers.*.mlp.up_proj": "colwise",
|
| 9 |
+
"layers.*.mlp.down_proj": "rowwise",
|
| 10 |
+
}
|
| 11 |
|
| 12 |
+
# Runtime
|
| 13 |
+
import torch
|
| 14 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 15 |
|
| 16 |
+
model_id = "your/model-or-local-checkpoint"
|
| 17 |
+
model = AutoModelForCausalLM.from_pretrained(
|
| 18 |
+
model_id,
|
| 19 |
+
dtype=torch.bfloat16,
|
| 20 |
+
tp_plan=base_model_tp_plan, # <-- plan defined above
|
| 21 |
+
)
|
| 22 |
+
tok = AutoTokenizer.from_pretrained(model_id)
|
| 23 |
+
inputs = tok("Hello", return_tensors="pt").to(model.device)
|
| 24 |
+
out = model(**inputs)</code></pre>
|
src/fragments/warmup_demo.html
CHANGED
|
@@ -1,247 +1,240 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
|
| 125 |
-
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
|
| 156 |
-
|
| 157 |
-
|
| 158 |
-
|
| 159 |
-
|
| 160 |
-
|
| 161 |
-
|
| 162 |
-
|
| 163 |
-
|
| 164 |
-
|
| 165 |
-
|
| 166 |
-
|
| 167 |
-
|
| 168 |
-
|
| 169 |
-
|
| 170 |
-
|
| 171 |
-
|
| 172 |
-
|
| 173 |
-
|
| 174 |
-
|
| 175 |
-
|
| 176 |
-
|
| 177 |
-
|
| 178 |
-
|
| 179 |
-
|
| 180 |
-
|
| 181 |
-
|
| 182 |
-
|
| 183 |
-
|
| 184 |
-
|
| 185 |
-
|
| 186 |
-
|
| 187 |
-
|
| 188 |
-
|
| 189 |
-
|
| 190 |
-
|
| 191 |
-
|
| 192 |
-
|
| 193 |
-
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
|
| 197 |
-
|
| 198 |
-
|
| 199 |
-
|
| 200 |
-
|
| 201 |
-
|
| 202 |
-
|
| 203 |
-
|
| 204 |
-
|
| 205 |
-
|
| 206 |
-
|
| 207 |
-
|
| 208 |
-
|
| 209 |
-
|
| 210 |
-
|
| 211 |
-
|
| 212 |
-
|
| 213 |
-
|
| 214 |
-
|
| 215 |
-
|
| 216 |
-
.
|
| 217 |
-
|
| 218 |
-
|
| 219 |
-
|
| 220 |
-
|
| 221 |
-
|
| 222 |
-
|
| 223 |
-
|
| 224 |
-
|
| 225 |
-
|
| 226 |
-
|
| 227 |
-
|
| 228 |
-
|
| 229 |
-
|
| 230 |
-
|
| 231 |
-
|
| 232 |
-
|
| 233 |
-
|
| 234 |
-
|
| 235 |
-
|
| 236 |
-
color: #495057;
|
| 237 |
-
margin: 10px 0;
|
| 238 |
-
}
|
| 239 |
-
</style>
|
| 240 |
-
</head>
|
| 241 |
-
<body>
|
| 242 |
<div class="container">
|
| 243 |
-
<
|
| 244 |
-
<p class="subtitle">Demonstrating memory allocation patterns during model loading</p>
|
| 245 |
|
| 246 |
<div class="controls">
|
| 247 |
<button class="btn" id="startBtn" onclick="startDemo()">Start Animation</button>
|
|
@@ -285,137 +278,121 @@
|
|
| 285 |
</div>
|
| 286 |
</div>
|
| 287 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 288 |
|
| 289 |
-
|
| 290 |
-
|
| 291 |
-
|
| 292 |
-
|
| 293 |
-
|
| 294 |
-
function startDemo() {
|
| 295 |
-
if (isRunning) return;
|
| 296 |
-
isRunning = true;
|
| 297 |
-
|
| 298 |
-
document.getElementById('startBtn').disabled = true;
|
| 299 |
-
document.getElementById('resetBtn').disabled = true;
|
| 300 |
-
|
| 301 |
-
// Start both animations simultaneously
|
| 302 |
-
Promise.all([
|
| 303 |
-
animateNoWarmup(),
|
| 304 |
-
animateWithWarmup()
|
| 305 |
-
]).then(() => {
|
| 306 |
-
isRunning = false;
|
| 307 |
-
document.getElementById('startBtn').disabled = false;
|
| 308 |
-
document.getElementById('resetBtn').disabled = false;
|
| 309 |
-
});
|
| 310 |
-
}
|
| 311 |
-
|
| 312 |
-
function resetDemo() {
|
| 313 |
-
if (isRunning) return;
|
| 314 |
-
|
| 315 |
-
// Clear containers
|
| 316 |
-
document.getElementById('noWarmupArea').innerHTML = '';
|
| 317 |
-
document.getElementById('warmupLayers').innerHTML = '';
|
| 318 |
-
document.getElementById('warmupFill').style.width = '0%';
|
| 319 |
-
document.getElementById('warmupContainer').classList.remove('allocated');
|
| 320 |
-
|
| 321 |
-
// Reset timers
|
| 322 |
-
document.getElementById('noWarmupTime').textContent = '0.00s';
|
| 323 |
-
document.getElementById('warmupTime').textContent = '0.00s';
|
| 324 |
-
|
| 325 |
-
// Reset counters
|
| 326 |
-
document.getElementById('noWarmupCounter').textContent = 'Layers loaded: 0/10';
|
| 327 |
-
document.getElementById('warmupCounter').textContent = 'Layers loaded: 0/10';
|
| 328 |
|
| 329 |
-
|
| 330 |
-
document.getElementById('noWarmupPhase').textContent = '';
|
| 331 |
-
document.getElementById('warmupPhase').textContent = '';
|
| 332 |
}
|
| 333 |
|
| 334 |
-
|
| 335 |
-
|
| 336 |
-
const timeEl = document.getElementById('noWarmupTime');
|
| 337 |
-
const counterEl = document.getElementById('noWarmupCounter');
|
| 338 |
-
const phaseEl = document.getElementById('noWarmupPhase');
|
| 339 |
-
|
| 340 |
-
let currentTime = 0;
|
| 341 |
-
const baseDelay = 200 / animationSpeed; // Base delay between operations
|
| 342 |
-
|
| 343 |
-
phaseEl.textContent = 'Loading model layers...';
|
| 344 |
-
|
| 345 |
-
for (let i = 0; i < totalLayers; i++) {
|
| 346 |
-
// Create layer box
|
| 347 |
-
const layerBox = document.createElement('div');
|
| 348 |
-
layerBox.className = 'layer-box';
|
| 349 |
-
container.appendChild(layerBox);
|
| 350 |
-
|
| 351 |
-
// Malloc phase (grey)
|
| 352 |
-
await sleep(baseDelay * 0.3);
|
| 353 |
-
layerBox.classList.add('allocating');
|
| 354 |
-
currentTime += 0.08; // malloc overhead
|
| 355 |
-
timeEl.textContent = currentTime.toFixed(2) + 's';
|
| 356 |
-
|
| 357 |
-
// Data loading phase (green)
|
| 358 |
-
await sleep(baseDelay * 0.7);
|
| 359 |
-
layerBox.classList.remove('allocating');
|
| 360 |
-
layerBox.classList.add('loaded');
|
| 361 |
-
currentTime += 0.12; // data transfer time
|
| 362 |
-
timeEl.textContent = currentTime.toFixed(2) + 's';
|
| 363 |
-
|
| 364 |
-
// Update counter
|
| 365 |
-
counterEl.textContent = `Layers loaded: ${i + 1}/${totalLayers}`;
|
| 366 |
-
}
|
| 367 |
-
|
| 368 |
-
phaseEl.textContent = 'Complete!';
|
| 369 |
-
}
|
| 370 |
|
| 371 |
-
|
| 372 |
-
|
| 373 |
-
|
| 374 |
-
|
| 375 |
-
|
| 376 |
-
|
| 377 |
-
|
| 378 |
-
|
| 379 |
-
let currentTime = 0;
|
| 380 |
-
const baseDelay = 200 / animationSpeed;
|
| 381 |
-
|
| 382 |
-
// Warmup phase
|
| 383 |
-
phaseEl.textContent = 'Warming up allocator...';
|
| 384 |
-
await sleep(baseDelay * 2);
|
| 385 |
-
warmupContainer.classList.add('allocated');
|
| 386 |
-
currentTime += 0.3; // warmup overhead
|
| 387 |
-
timeEl.textContent = currentTime.toFixed(2) + 's';
|
| 388 |
|
| 389 |
-
|
|
|
|
| 390 |
|
| 391 |
-
|
| 392 |
-
|
| 393 |
-
|
| 394 |
-
|
| 395 |
-
|
| 396 |
-
layerBox.style.width = '40px';
|
| 397 |
-
layerBox.style.height = '20px';
|
| 398 |
-
container.appendChild(layerBox);
|
| 399 |
|
| 400 |
-
|
| 401 |
-
const progress = ((i + 1) / totalLayers) * 100;
|
| 402 |
-
warmupFill.style.width = progress + '%';
|
| 403 |
|
| 404 |
-
|
| 405 |
-
|
| 406 |
-
|
| 407 |
-
|
|
|
|
|
|
|
| 408 |
|
| 409 |
-
|
| 410 |
-
|
| 411 |
-
}
|
| 412 |
|
| 413 |
-
|
| 414 |
-
|
|
|
|
| 415 |
|
| 416 |
-
|
| 417 |
-
return new Promise(resolve => setTimeout(resolve, ms));
|
| 418 |
}
|
| 419 |
-
|
| 420 |
-
|
| 421 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<style>
|
| 2 |
+
.warmup-demo body {
|
| 3 |
+
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
| 4 |
+
margin: 0;
|
| 5 |
+
padding: 20px;
|
| 6 |
+
background-color: #f5f5f5;
|
| 7 |
+
}
|
| 8 |
+
|
| 9 |
+
.warmup-demo .container {
|
| 10 |
+
max-width: 1200px;
|
| 11 |
+
margin: 0 auto;
|
| 12 |
+
background: white;
|
| 13 |
+
border-radius: 12px;
|
| 14 |
+
padding: 30px;
|
| 15 |
+
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
| 16 |
+
}
|
| 17 |
+
|
| 18 |
+
.warmup-demo h1 {
|
| 19 |
+
text-align: center;
|
| 20 |
+
color: #333;
|
| 21 |
+
margin-bottom: 10px;
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
.warmup-demo .subtitle {
|
| 25 |
+
text-align: center;
|
| 26 |
+
color: #666;
|
| 27 |
+
margin-bottom: 30px;
|
| 28 |
+
font-size: 16px;
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
.warmup-demo .demo-container {
|
| 32 |
+
display: flex;
|
| 33 |
+
gap: 40px;
|
| 34 |
+
margin-bottom: 30px;
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
.warmup-demo .side {
|
| 38 |
+
flex: 1;
|
| 39 |
+
border: 2px solid #ddd;
|
| 40 |
+
border-radius: 8px;
|
| 41 |
+
padding: 20px;
|
| 42 |
+
background: #fafafa;
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
.warmup-demo .side h2 {
|
| 46 |
+
text-align: center;
|
| 47 |
+
margin-top: 0;
|
| 48 |
+
color: #333;
|
| 49 |
+
}
|
| 50 |
+
|
| 51 |
+
.warmup-demo .no-warmup h2 {
|
| 52 |
+
color: #d63384;
|
| 53 |
+
}
|
| 54 |
+
|
| 55 |
+
.warmup-demo .with-warmup h2 {
|
| 56 |
+
color: #198754;
|
| 57 |
+
}
|
| 58 |
+
|
| 59 |
+
.warmup-demo .memory-area {
|
| 60 |
+
height: 400px;
|
| 61 |
+
border: 2px dashed #ccc;
|
| 62 |
+
border-radius: 6px;
|
| 63 |
+
padding: 10px;
|
| 64 |
+
margin: 20px 0;
|
| 65 |
+
background: #fff;
|
| 66 |
+
position: relative;
|
| 67 |
+
overflow: hidden;
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
.warmup-demo .layer-box {
|
| 71 |
+
width: 80px;
|
| 72 |
+
height: 30px;
|
| 73 |
+
border: 2px solid #666;
|
| 74 |
+
border-radius: 4px;
|
| 75 |
+
margin: 3px;
|
| 76 |
+
display: inline-block;
|
| 77 |
+
position: relative;
|
| 78 |
+
background: #fff;
|
| 79 |
+
transition: all 0.3s ease;
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
.warmup-demo .layer-box.allocating {
|
| 83 |
+
background: #e9ecef;
|
| 84 |
+
border-color: #adb5bd;
|
| 85 |
+
}
|
| 86 |
+
|
| 87 |
+
.warmup-demo .layer-box.allocating::after {
|
| 88 |
+
content: "malloc";
|
| 89 |
+
position: absolute;
|
| 90 |
+
top: 50%;
|
| 91 |
+
left: 50%;
|
| 92 |
+
transform: translate(-50%, -50%);
|
| 93 |
+
font-size: 10px;
|
| 94 |
+
color: #666;
|
| 95 |
+
font-weight: bold;
|
| 96 |
+
}
|
| 97 |
+
|
| 98 |
+
.warmup-demo .layer-box.loaded {
|
| 99 |
+
background: #d1e7dd;
|
| 100 |
+
border-color: #198754;
|
| 101 |
+
}
|
| 102 |
+
|
| 103 |
+
.warmup-demo .layer-box.loaded::after {
|
| 104 |
+
content: "data";
|
| 105 |
+
position: absolute;
|
| 106 |
+
top: 50%;
|
| 107 |
+
left: 50%;
|
| 108 |
+
transform: translate(-50%, -50%);
|
| 109 |
+
font-size: 10px;
|
| 110 |
+
color: #198754;
|
| 111 |
+
font-weight: bold;
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
.warmup-demo .warmup-container {
|
| 115 |
+
width: 100%;
|
| 116 |
+
height: 60px;
|
| 117 |
+
border: 3px solid #666;
|
| 118 |
+
border-radius: 6px;
|
| 119 |
+
margin-bottom: 20px;
|
| 120 |
+
background: #fff;
|
| 121 |
+
position: relative;
|
| 122 |
+
overflow: hidden;
|
| 123 |
+
}
|
| 124 |
+
|
| 125 |
+
.warmup-demo .warmup-container.allocated {
|
| 126 |
+
border-color: #0d6efd;
|
| 127 |
+
background: #e7f1ff;
|
| 128 |
+
}
|
| 129 |
+
|
| 130 |
+
.warmup-demo .warmup-container::before {
|
| 131 |
+
content: "Pre-allocated Memory Pool";
|
| 132 |
+
position: absolute;
|
| 133 |
+
top: 50%;
|
| 134 |
+
left: 50%;
|
| 135 |
+
transform: translate(-50%, -50%);
|
| 136 |
+
font-size: 14px;
|
| 137 |
+
color: #666;
|
| 138 |
+
font-weight: bold;
|
| 139 |
+
z-index: 1;
|
| 140 |
+
}
|
| 141 |
+
|
| 142 |
+
.warmup-demo .warmup-container.allocated::before {
|
| 143 |
+
color: #0d6efd;
|
| 144 |
+
}
|
| 145 |
+
|
| 146 |
+
.warmup-demo .warmup-fill {
|
| 147 |
+
height: 100%;
|
| 148 |
+
background: linear-gradient(90deg, #198754, #20c997);
|
| 149 |
+
width: 0%;
|
| 150 |
+
transition: width 0.5s ease;
|
| 151 |
+
border-radius: 3px;
|
| 152 |
+
position: relative;
|
| 153 |
+
z-index: 2;
|
| 154 |
+
}
|
| 155 |
+
|
| 156 |
+
.warmup-demo .warmup-fill::after {
|
| 157 |
+
content: "Layer Data Loading";
|
| 158 |
+
position: absolute;
|
| 159 |
+
top: 50%;
|
| 160 |
+
left: 50%;
|
| 161 |
+
transform: translate(-50%, -50%);
|
| 162 |
+
font-size: 12px;
|
| 163 |
+
color: white;
|
| 164 |
+
font-weight: bold;
|
| 165 |
+
white-space: nowrap;
|
| 166 |
+
}
|
| 167 |
+
|
| 168 |
+
.warmup-demo .timing {
|
| 169 |
+
text-align: center;
|
| 170 |
+
font-size: 24px;
|
| 171 |
+
font-weight: bold;
|
| 172 |
+
margin: 15px 0;
|
| 173 |
+
min-height: 30px;
|
| 174 |
+
}
|
| 175 |
+
|
| 176 |
+
.warmup-demo .no-warmup .timing {
|
| 177 |
+
color: #d63384;
|
| 178 |
+
}
|
| 179 |
+
|
| 180 |
+
.warmup-demo .with-warmup .timing {
|
| 181 |
+
color: #198754;
|
| 182 |
+
}
|
| 183 |
+
|
| 184 |
+
.warmup-demo .controls {
|
| 185 |
+
text-align: center;
|
| 186 |
+
margin: 30px 0;
|
| 187 |
+
}
|
| 188 |
+
|
| 189 |
+
.warmup-demo .btn {
|
| 190 |
+
background: #0d6efd;
|
| 191 |
+
color: white;
|
| 192 |
+
border: none;
|
| 193 |
+
padding: 12px 24px;
|
| 194 |
+
border-radius: 6px;
|
| 195 |
+
font-size: 16px;
|
| 196 |
+
cursor: pointer;
|
| 197 |
+
margin: 0 10px;
|
| 198 |
+
transition: background 0.3s ease;
|
| 199 |
+
}
|
| 200 |
+
|
| 201 |
+
.warmup-demo .btn:hover {
|
| 202 |
+
background: #0b5ed7;
|
| 203 |
+
}
|
| 204 |
+
|
| 205 |
+
.warmup-demo .btn:disabled {
|
| 206 |
+
background: #6c757d;
|
| 207 |
+
cursor: not-allowed;
|
| 208 |
+
}
|
| 209 |
+
|
| 210 |
+
.warmup-demo .description {
|
| 211 |
+
background: #f8f9fa;
|
| 212 |
+
padding: 15px;
|
| 213 |
+
border-radius: 6px;
|
| 214 |
+
margin-top: 15px;
|
| 215 |
+
font-size: 14px;
|
| 216 |
+
line-height: 1.5;
|
| 217 |
+
}
|
| 218 |
+
|
| 219 |
+
.warmup-demo .phase-indicator {
|
| 220 |
+
font-size: 14px;
|
| 221 |
+
color: #666;
|
| 222 |
+
text-align: center;
|
| 223 |
+
margin-top: 10px;
|
| 224 |
+
min-height: 20px;
|
| 225 |
+
}
|
| 226 |
+
|
| 227 |
+
.warmup-demo .layer-counter {
|
| 228 |
+
text-align: center;
|
| 229 |
+
font-size: 16px;
|
| 230 |
+
color: #495057;
|
| 231 |
+
margin: 10px 0;
|
| 232 |
+
}
|
| 233 |
+
</style>
|
| 234 |
+
|
| 235 |
+
<div class="warmup-demo">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 236 |
<div class="container">
|
| 237 |
+
<p class="subtitle">Mem allocation patterns during model loading</p>
|
|
|
|
| 238 |
|
| 239 |
<div class="controls">
|
| 240 |
<button class="btn" id="startBtn" onclick="startDemo()">Start Animation</button>
|
|
|
|
| 278 |
</div>
|
| 279 |
</div>
|
| 280 |
</div>
|
| 281 |
+
</div>
|
| 282 |
+
|
| 283 |
+
<script>
|
| 284 |
+
let animationSpeed = 1 / 2.4;
|
| 285 |
+
let isRunning = false;
|
| 286 |
+
const totalLayers = 10;
|
| 287 |
+
|
| 288 |
+
function startDemo() {
|
| 289 |
+
if (isRunning) return;
|
| 290 |
+
isRunning = true;
|
| 291 |
+
|
| 292 |
+
document.getElementById('startBtn').disabled = true;
|
| 293 |
+
document.getElementById('resetBtn').disabled = true;
|
| 294 |
+
|
| 295 |
+
Promise.all([
|
| 296 |
+
animateNoWarmup(),
|
| 297 |
+
animateWithWarmup()
|
| 298 |
+
]).then(() => {
|
| 299 |
+
isRunning = false;
|
| 300 |
+
document.getElementById('startBtn').disabled = false;
|
| 301 |
+
document.getElementById('resetBtn').disabled = false;
|
| 302 |
+
});
|
| 303 |
+
}
|
| 304 |
+
|
| 305 |
+
function resetDemo() {
|
| 306 |
+
if (isRunning) return;
|
| 307 |
+
|
| 308 |
+
document.getElementById('noWarmupArea').innerHTML = '';
|
| 309 |
+
document.getElementById('warmupLayers').innerHTML = '';
|
| 310 |
+
document.getElementById('warmupFill').style.width = '0%';
|
| 311 |
+
document.getElementById('warmupContainer').classList.remove('allocated');
|
| 312 |
+
|
| 313 |
+
document.getElementById('noWarmupTime').textContent = '0.00s';
|
| 314 |
+
document.getElementById('warmupTime').textContent = '0.00s';
|
| 315 |
+
|
| 316 |
+
document.getElementById('noWarmupCounter').textContent = 'Layers loaded: 0/10';
|
| 317 |
+
document.getElementById('warmupCounter').textContent = 'Layers loaded: 0/10';
|
| 318 |
+
|
| 319 |
+
document.getElementById('noWarmupPhase').textContent = '';
|
| 320 |
+
document.getElementById('warmupPhase').textContent = '';
|
| 321 |
+
}
|
| 322 |
+
|
| 323 |
+
async function animateNoWarmup() {
|
| 324 |
+
const container = document.getElementById('noWarmupArea');
|
| 325 |
+
const timeEl = document.getElementById('noWarmupTime');
|
| 326 |
+
const counterEl = document.getElementById('noWarmupCounter');
|
| 327 |
+
const phaseEl = document.getElementById('noWarmupPhase');
|
| 328 |
+
|
| 329 |
+
let currentTime = 0;
|
| 330 |
+
const baseDelay = 200 / animationSpeed;
|
| 331 |
+
|
| 332 |
+
phaseEl.textContent = 'Loading model layers...';
|
| 333 |
+
|
| 334 |
+
for (let i = 0; i < totalLayers; i++) {
|
| 335 |
+
const layerBox = document.createElement('div');
|
| 336 |
+
layerBox.className = 'layer-box';
|
| 337 |
+
container.appendChild(layerBox);
|
| 338 |
+
|
| 339 |
+
await sleep(baseDelay * 0.3);
|
| 340 |
+
layerBox.classList.add('allocating');
|
| 341 |
+
currentTime += 0.08;
|
| 342 |
+
timeEl.textContent = currentTime.toFixed(2) + 's';
|
| 343 |
|
| 344 |
+
await sleep(baseDelay * 0.7);
|
| 345 |
+
layerBox.classList.remove('allocating');
|
| 346 |
+
layerBox.classList.add('loaded');
|
| 347 |
+
currentTime += 0.12;
|
| 348 |
+
timeEl.textContent = currentTime.toFixed(2) + 's';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 349 |
|
| 350 |
+
counterEl.textContent = `Layers loaded: ${i + 1}/${totalLayers}`;
|
|
|
|
|
|
|
| 351 |
}
|
| 352 |
|
| 353 |
+
phaseEl.textContent = 'Complete!';
|
| 354 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 355 |
|
| 356 |
+
async function animateWithWarmup() {
|
| 357 |
+
const container = document.getElementById('warmupLayers');
|
| 358 |
+
const timeEl = document.getElementById('warmupTime');
|
| 359 |
+
const counterEl = document.getElementById('warmupCounter');
|
| 360 |
+
const phaseEl = document.getElementById('warmupPhase');
|
| 361 |
+
const warmupContainer = document.getElementById('warmupContainer');
|
| 362 |
+
const warmupFill = document.getElementById('warmupFill');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 363 |
|
| 364 |
+
let currentTime = 0;
|
| 365 |
+
const baseDelay = 200 / animationSpeed;
|
| 366 |
|
| 367 |
+
phaseEl.textContent = 'Warming up allocator...';
|
| 368 |
+
await sleep(baseDelay * 2);
|
| 369 |
+
warmupContainer.classList.add('allocated');
|
| 370 |
+
currentTime += 0.3;
|
| 371 |
+
timeEl.textContent = currentTime.toFixed(2) + 's';
|
|
|
|
|
|
|
|
|
|
| 372 |
|
| 373 |
+
phaseEl.textContent = 'Loading model layers...';
|
|
|
|
|
|
|
| 374 |
|
| 375 |
+
for (let i = 0; i < totalLayers; i++) {
|
| 376 |
+
const layerBox = document.createElement('div');
|
| 377 |
+
layerBox.className = 'layer-box loaded';
|
| 378 |
+
layerBox.style.width = '40px';
|
| 379 |
+
layerBox.style.height = '20px';
|
| 380 |
+
container.appendChild(layerBox);
|
| 381 |
|
| 382 |
+
const progress = ((i + 1) / totalLayers) * 100;
|
| 383 |
+
warmupFill.style.width = progress + '%';
|
|
|
|
| 384 |
|
| 385 |
+
await sleep(baseDelay * 0.5);
|
| 386 |
+
currentTime += 0.08;
|
| 387 |
+
timeEl.textContent = currentTime.toFixed(2) + 's';
|
| 388 |
|
| 389 |
+
counterEl.textContent = `Layers loaded: ${i + 1}/${totalLayers}`;
|
|
|
|
| 390 |
}
|
| 391 |
+
|
| 392 |
+
phaseEl.textContent = 'Complete!';
|
| 393 |
+
}
|
| 394 |
+
|
| 395 |
+
function sleep(ms) {
|
| 396 |
+
return new Promise(resolve => setTimeout(resolve, ms));
|
| 397 |
+
}
|
| 398 |
+
</script>
|
webpack.config.js
CHANGED
|
@@ -31,11 +31,19 @@ const loadFragmentsMap = (() => {
|
|
| 31 |
const dottedPath = 'fragment-' + nameWithoutExt.replace(/\\/g, '-').replace(/\//g, '-').replace(/\./g, '-');
|
| 32 |
const content = fs.readFileSync(filePath, "utf8");
|
| 33 |
// Minify the HTML content using swcMinifyFragment
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 37 |
}
|
| 38 |
-
const minifiedContent = minifiedRes.code;
|
| 39 |
cachedFragments[dottedPath] = minifiedContent;
|
| 40 |
}
|
| 41 |
}));
|
|
@@ -325,10 +333,6 @@ module.exports = {
|
|
| 325 |
}
|
| 326 |
]
|
| 327 |
}),
|
| 328 |
-
new HtmlMinimizerPlugin({
|
| 329 |
-
test: /fragments\/.*\.html$/i,
|
| 330 |
-
minify: HtmlMinimizerPlugin.swcMinifyFragment,
|
| 331 |
-
})
|
| 332 |
]
|
| 333 |
},
|
| 334 |
};
|
|
|
|
| 31 |
const dottedPath = 'fragment-' + nameWithoutExt.replace(/\\/g, '-').replace(/\//g, '-').replace(/\./g, '-');
|
| 32 |
const content = fs.readFileSync(filePath, "utf8");
|
| 33 |
// Minify the HTML content using swcMinifyFragment
|
| 34 |
+
let minifiedContent;
|
| 35 |
+
try {
|
| 36 |
+
const minifiedRes = await HtmlMinimizerPlugin.swcMinifyFragment({"tmp.html": content})
|
| 37 |
+
if (minifiedRes.errors) {
|
| 38 |
+
console.warn("HTML minification warnings:", minifiedRes.errors);
|
| 39 |
+
minifiedContent = content; // Use original content if errors
|
| 40 |
+
} else {
|
| 41 |
+
minifiedContent = minifiedRes.code;
|
| 42 |
+
}
|
| 43 |
+
} catch (error) {
|
| 44 |
+
console.warn(`Failed to minify fragment ${filePath}, using original content:`, error.message);
|
| 45 |
+
minifiedContent = content; // Fallback to original content
|
| 46 |
}
|
|
|
|
| 47 |
cachedFragments[dottedPath] = minifiedContent;
|
| 48 |
}
|
| 49 |
}));
|
|
|
|
| 333 |
}
|
| 334 |
]
|
| 335 |
}),
|
|
|
|
|
|
|
|
|
|
|
|
|
| 336 |
]
|
| 337 |
},
|
| 338 |
};
|