hiarpc commited on
Commit
708d56c
·
1 Parent(s): aa87574
Files changed (1) hide show
  1. index.html +228 -223
index.html CHANGED
@@ -1,292 +1,297 @@
1
  <!DOCTYPE html>
2
- <html>
 
 
3
  <head>
4
  <meta charset="UTF-8">
 
5
  <title>SweetSpot v2 — Energy-per-Token demo</title>
6
 
7
- <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
 
8
 
9
- <style>
10
- body {
11
- font-family: sans-serif;
12
- max-width: 1000px;
13
- margin: auto;
14
- padding: 20px;
15
- }
16
 
17
- .row {
18
- display: flex;
19
- gap: 20px;
20
- flex-wrap: wrap;
21
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
 
23
- label {
24
- display: block;
25
- margin-top: 10px;
26
  }
 
27
 
28
- input {
29
- width: 120px;
 
30
  }
31
 
32
- button {
33
- margin-top: 10px;
34
- padding: 8px 15px;
35
  }
36
- </style>
 
 
 
37
  </head>
38
 
39
  <body>
40
 
41
- <h2>
42
- SweetSpot v2 — Energy-per-Token demo
43
- </h2>
44
 
45
  <p>
46
- This interactive demo visualizes our analytical model for predicting the <b>energy consumption per generated token</b> as a function of the number of output tokens (<i>n</i><sub>out</sub>).
47
- Select one of the validated models used in the paper or load the architecture of any <b>dense decoder-only Transformer</b> (up to approximately 20B parameters) from Hugging Face to explore how the different terms contribute to the prediction.
 
 
 
 
 
48
  </p>
49
 
50
  <p>
51
- The model was fitted using empirical measurements collected on an <b>NVIDIA H100 GPU</b> with <b>NVIDIA TensorRT-LLM</b> under the following experimental configuration:
 
 
 
 
52
  <ul>
53
  <li><code>max_batch_size = 1024</code></li>
54
  <li><code>max_num_tokens = 8192</code></li>
55
  <li><code>num_requests = 1000</code></li>
56
  </ul>
57
 
58
- Future releases will extend the analysis to additional hardware platforms and inference frameworks.
 
 
59
  </p>
60
 
61
  <p>
62
- For the complete methodology, experimental validation, and citation information, please see the paper:
63
- <a href="YOUR_PAPER_URL" target="_blank">
64
- SweetSpot v2: An Architecture-Aware Analytical Model for Predicting Energy Efficiency of LLM Inference
65
- </a>.
 
 
66
  </p>
67
 
 
68
 
69
- <h4>
70
- Validated models:
71
- </h4>
72
-
73
- <select id="preset">
74
- </select>
75
-
76
- <button onclick="loadPreset()">
77
- Load selected model
78
- </button>
79
-
80
- <h4>
81
- Or load another public Hugging Face model (dense, < 20B):
82
- </h4>
83
 
84
- <input
85
- id="repo"
86
- style="width:400px"
87
- placeholder="tiiuae/falcon-rw-7b">
88
 
89
- <button onclick="loadModel()">
90
- Load model
91
- </button>
 
 
 
92
 
93
  <p id="status"></p>
94
 
95
  <h4>Architecture parameters</h4>
96
 
97
- <div class="row">
98
 
99
- <div>
100
- <label>Hidden size (d):</label>
101
- <input id="d" type="number" value="4096">
102
- </div>
103
-
104
- <div>
105
- <label>Layers (L):</label>
106
- <input id="L" type="number" value="36">
107
- </div>
108
-
109
- <div>
110
- <label>Query heads (<i>n</i><sub>q</sub>):</label>
111
- <input id="nq" type="number" value="64">
112
- </div>
113
 
114
- <div>
115
- <label>KV heads (<i>n</i><sub>kv</sub>):</label>
116
- <input id="nkv" type="number" value="64">
117
- </div>
118
 
119
- </div>
 
 
 
120
 
121
- <!-- <div>
122
- <label>
123
- Input Tokens (<i>n</i><sub>in</sub>):
124
- <span id="ninValue">64</span>
125
- </label>
126
-
127
- <input
128
- id="nin"
129
- type="range"
130
- min="1"
131
- max="4096"
132
- step="1"
133
- value="64"
134
- oninput="ninValue.textContent = this.value; draw();">
135
- </div>
136
-
137
- <div id="plot"></div> -->
138
-
139
- <!-- <div id="ninWrapper">
140
- <label>
141
- Input Tokens (<i>n</i><sub>in</sub>):
142
- <span id="ninValue">64</span>
143
- </label>
144
-
145
- <input
146
- id="ninSlider"
147
- type="range"
148
- min="0"
149
- max="12"
150
- step="0.01"
151
- value="6"
152
- list="ninTicks"
153
- oninput="updateNin(this.value)">
154
-
155
- <datalist id="ninTicks">
156
- <option value="0"></option>
157
- <option value="1"></option>
158
- <option value="2"></option>
159
- <option value="3"></option>
160
- <option value="4"></option>
161
- <option value="5"></option>
162
- <option value="6"></option>
163
- <option value="7"></option>
164
- <option value="8"></option>
165
- <option value="9"></option>
166
- <option value="10"></option>
167
- <option value="11"></option>
168
- <option value="12"></option>
169
- </datalist>
170
-
171
- <div id="ninLabels"></div>
172
 
173
- <input id="nin" type="hidden" value="64">
174
  </div>
175
 
176
- <div id="plot"></div>
177
 
178
- <script src="app.js"></script>
 
 
 
179
 
180
- <script>
181
- function updateNin(exponent) {
182
- const value = Math.round(Math.pow(2, parseFloat(exponent)));
183
- const clamped = Math.min(4096, Math.max(1, value));
184
-
185
- document.getElementById('nin').value = clamped;
186
- document.getElementById('ninValue').textContent = clamped;
187
-
188
- draw();
189
- }
190
-
191
- // Keep the slider's on-screen width exactly matched to the rendered plot width.
192
- function syncSliderWidth() {
193
- const plotDiv = document.getElementById('plot');
194
- const slider = document.getElementById('ninSlider');
195
- if (plotDiv && slider) {
196
- const plotWidth = plotDiv.getBoundingClientRect().width;
197
- if (plotWidth > 0) {
198
- slider.style.width = plotWidth + 'px';
199
- }
200
- }
201
- }
202
-
203
- window.addEventListener('resize', syncSliderWidth);
204
- window.addEventListener('load', syncSliderWidth);
205
 
206
- if (window.ResizeObserver) {
207
- const plotEl = document.getElementById('plot');
208
- if (plotEl) new ResizeObserver(syncSliderWidth).observe(plotEl);
209
- }
210
- </script> -->
211
-
212
-
213
- <!-- Hidden input: holds the ACTUAL token count, exactly what app.js reads -->
214
-
215
- <div id="ninWrapper">
216
- <label>
217
- Input Tokens (<i>n</i><sub>in</sub>):
218
- <span id="ninValue">64</span>
219
- </label>
220
-
221
- <input
222
- id="ninSlider"
223
- type="range"
224
- min="0"
225
- max="12"
226
- step="0.01"
227
- value="6"
228
- list="ninTicks"
229
- oninput="updateNin(this.value)">
230
-
231
- <datalist id="ninTicks">
232
- <option value="0"></option>
233
- <option value="1"></option>
234
- <option value="2"></option>
235
- <option value="3"></option>
236
- <option value="4"></option>
237
- <option value="5"></option>
238
- <option value="6"></option>
239
- <option value="7"></option>
240
- <option value="8"></option>
241
- <option value="9"></option>
242
- <option value="10"></option>
243
- <option value="11"></option>
244
- <option value="12"></option>
245
- </datalist>
246
-
247
- <div id="ninLabels">
248
- <span>1</span><span>2</span><span>4</span><span>8</span>
249
- <span>16</span><span>32</span><span>64</span><span>128</span>
250
- <span>256</span><span>512</span><span>1024</span><span>2048</span><span>4096</span>
251
  </div>
252
 
 
253
  <input id="nin" type="hidden" value="64">
254
- </div>
255
 
256
- <style>
257
- #ninSlider {
258
- width: 100%;
259
- box-sizing: border-box;
260
- }
261
 
262
- #ninLabels {
263
- display: flex;
264
- justify-content: space-between;
265
- padding: 0 8px;
266
- font-size: 12px;
267
- color: #555;
268
- }
269
- </style>
270
 
271
  <script>
272
  const MAX_TOKENS = 4096;
273
- const MAX_EXPONENT = 12; // log2(4096)
274
 
275
  function updateNin(exponent) {
276
- const value = Math.round(Math.pow(2, parseFloat(exponent)));
277
  const clamped = Math.min(MAX_TOKENS, Math.max(1, value));
278
 
279
- document.getElementById('nin').value = clamped;
280
- document.getElementById('ninValue').textContent = clamped;
281
-
282
- draw();
283
  }
284
  </script>
285
 
286
- <div id="plot"></div>
287
-
288
-
289
  <script src="app.js"></script>
290
 
291
  </body>
292
- </html>
 
1
  <!DOCTYPE html>
2
+
3
+ <html lang="en">
4
+
5
  <head>
6
  <meta charset="UTF-8">
7
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
8
  <title>SweetSpot v2 — Energy-per-Token demo</title>
9
 
10
+ ```
11
+ <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
12
 
13
+ <style>
14
+ * {
15
+ box-sizing: border-box;
16
+ }
 
 
 
17
 
18
+ body {
19
+ max-width: 1000px;
20
+ margin: 0 auto;
21
+ padding: 24px;
22
+ font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
23
+ line-height: 1.5;
24
+ color: #222;
25
+ }
26
+
27
+ h2 {
28
+ margin-bottom: 8px;
29
+ }
30
+
31
+ h4 {
32
+ margin: 28px 0 10px;
33
+ }
34
+
35
+ p {
36
+ margin: 12px 0;
37
+ }
38
+
39
+ ul {
40
+ margin-top: 6px;
41
+ }
42
+
43
+ button {
44
+ padding: 8px 14px;
45
+ border: 1px solid #bbb;
46
+ border-radius: 6px;
47
+ background: #f5f5f5;
48
+ cursor: pointer;
49
+ }
50
+
51
+ button:hover {
52
+ background: #eaeaea;
53
+ }
54
+
55
+ select,
56
+ input[type="text"],
57
+ input[type="number"] {
58
+ padding: 7px 9px;
59
+ border: 1px solid #bbb;
60
+ border-radius: 5px;
61
+ }
62
+
63
+ #preset {
64
+ min-width: 280px;
65
+ }
66
+
67
+ #repo {
68
+ width: min(400px, 100%);
69
+ }
70
+
71
+ .architecture-grid {
72
+ display: grid;
73
+ grid-template-columns: repeat(4, 1fr);
74
+ gap: 16px;
75
+ }
76
+
77
+ .parameter label {
78
+ display: block;
79
+ margin-bottom: 5px;
80
+ }
81
+
82
+ .parameter input {
83
+ width: 100%;
84
+ }
85
+
86
+ /* Token slider */
87
+
88
+ #ninWrapper {
89
+ margin-top: 24px;
90
+ width: 100%;
91
+ }
92
+
93
+ .slider-header {
94
+ display: flex;
95
+ justify-content: space-between;
96
+ align-items: baseline;
97
+ margin-bottom: 8px;
98
+ }
99
+
100
+ .slider-value {
101
+ font-variant-numeric: tabular-nums;
102
+ font-weight: 600;
103
+ }
104
+
105
+ .slider-track {
106
+ width: 100%;
107
+ }
108
+
109
+ #ninSlider {
110
+ display: block;
111
+ width: 100%;
112
+ margin: 0;
113
+ }
114
+
115
+ #ninLabels {
116
+ display: flex;
117
+ justify-content: space-between;
118
+ margin-top: 5px;
119
+ padding: 0 7px;
120
+ font-size: 12px;
121
+ color: #666;
122
+ }
123
+
124
+ #ninLabels span {
125
+ text-align: center;
126
+ }
127
+
128
+ #plot {
129
+ width: 100%;
130
+ margin-top: 24px;
131
+ }
132
 
133
+ @media (max-width: 700px) {
134
+ .architecture-grid {
135
+ grid-template-columns: repeat(2, 1fr);
136
  }
137
+ }
138
 
139
+ @media (max-width: 450px) {
140
+ body {
141
+ padding: 16px;
142
  }
143
 
144
+ .architecture-grid {
145
+ grid-template-columns: 1fr;
 
146
  }
147
+ }
148
+ </style>
149
+ ```
150
+
151
  </head>
152
 
153
  <body>
154
 
155
+ ```
156
+ <h2>SweetSpot v2 — Energy-per-Token demo</h2>
 
157
 
158
  <p>
159
+ This interactive demo visualizes our analytical model for predicting
160
+ the <b>energy consumption per generated token</b> as a function of the
161
+ number of output tokens (<i>n</i><sub>out</sub>).
162
+ Select one of the validated models used in the paper or load the
163
+ architecture of any <b>dense decoder-only Transformer</b> (up to
164
+ approximately 20B parameters) from Hugging Face to explore how the
165
+ different terms contribute to the prediction.
166
  </p>
167
 
168
  <p>
169
+ The model was fitted using empirical measurements collected on an
170
+ <b>NVIDIA H100 GPU</b> with <b>NVIDIA TensorRT-LLM</b> under the
171
+ following experimental configuration:
172
+ </p>
173
+
174
  <ul>
175
  <li><code>max_batch_size = 1024</code></li>
176
  <li><code>max_num_tokens = 8192</code></li>
177
  <li><code>num_requests = 1000</code></li>
178
  </ul>
179
 
180
+ <p>
181
+ Future releases will extend the analysis to additional hardware
182
+ platforms and inference frameworks.
183
  </p>
184
 
185
  <p>
186
+ For the complete methodology, experimental validation, and citation
187
+ information, please see the paper:
188
+ <a href="YOUR_PAPER_URL" target="_blank" rel="noopener">
189
+ SweetSpot v2: An Architecture-Aware Analytical Model for Predicting
190
+ Energy Efficiency of LLM Inference
191
+ </a>.
192
  </p>
193
 
194
+ <h4>Validated models</h4>
195
 
196
+ <select id="preset"></select>
197
+ <button type="button" onclick="loadPreset()">Load selected model</button>
 
 
 
 
 
 
 
 
 
 
 
 
198
 
199
+ <h4>Or load another public Hugging Face model (dense, &lt; 20B)</h4>
 
 
 
200
 
201
+ <input
202
+ id="repo"
203
+ type="text"
204
+ placeholder="tiiuae/falcon-rw-7b"
205
+ >
206
+ <button type="button" onclick="loadModel()">Load model</button>
207
 
208
  <p id="status"></p>
209
 
210
  <h4>Architecture parameters</h4>
211
 
212
+ <div class="architecture-grid">
213
 
214
+ <div class="parameter">
215
+ <label for="d">Hidden size (<i>d</i>)</label>
216
+ <input id="d" type="number" value="4096">
217
+ </div>
 
 
 
 
 
 
 
 
 
 
218
 
219
+ <div class="parameter">
220
+ <label for="L">Layers (<i>L</i>)</label>
221
+ <input id="L" type="number" value="36">
222
+ </div>
223
 
224
+ <div class="parameter">
225
+ <label for="nq">Query heads (<i>n</i><sub>q</sub>)</label>
226
+ <input id="nq" type="number" value="64">
227
+ </div>
228
 
229
+ <div class="parameter">
230
+ <label for="nkv">KV heads (<i>n</i><sub>kv</sub>)</label>
231
+ <input id="nkv" type="number" value="64">
232
+ </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
233
 
 
234
  </div>
235
 
236
+ <div id="ninWrapper">
237
 
238
+ <div class="slider-header">
239
+ <label for="ninSlider">
240
+ Input Tokens (<i>n</i><sub>in</sub>)
241
+ </label>
242
 
243
+ <span id="ninValue" class="slider-value">64</span>
244
+ </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
245
 
246
+ <div class="slider-track">
247
+ <input
248
+ id="ninSlider"
249
+ type="range"
250
+ min="0"
251
+ max="12"
252
+ step="0.01"
253
+ value="6"
254
+ aria-label="Input tokens"
255
+ oninput="updateNin(this.value)"
256
+ >
257
+
258
+ <div id="ninLabels" aria-hidden="true">
259
+ <span>1</span>
260
+ <span>2</span>
261
+ <span>4</span>
262
+ <span>8</span>
263
+ <span>16</span>
264
+ <span>32</span>
265
+ <span>64</span>
266
+ <span>128</span>
267
+ <span>256</span>
268
+ <span>512</span>
269
+ <span>1024</span>
270
+ <span>2048</span>
271
+ <span>4096</span>
272
+ </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
273
  </div>
274
 
275
+ <!-- app.js reads the actual integer token count from here -->
276
  <input id="nin" type="hidden" value="64">
 
277
 
278
+ </div>
 
 
 
 
279
 
280
+ <div id="plot"></div>
 
 
 
 
 
 
 
281
 
282
  <script>
283
  const MAX_TOKENS = 4096;
 
284
 
285
  function updateNin(exponent) {
286
+ const value = Math.round(2 ** Number(exponent));
287
  const clamped = Math.min(MAX_TOKENS, Math.max(1, value));
288
 
289
+ document.getElementById("nin").value = clamped;
290
+ document.getElementById("ninValue").textContent = clamped;
 
 
291
  }
292
  </script>
293
 
 
 
 
294
  <script src="app.js"></script>
295
 
296
  </body>
297
+ </html>