WCNegentropy commited on
Commit
ee16adb
·
verified ·
1 Parent(s): b528828

Remove nested directory: BitTransformerLM/bit_transformer/templates/dashboard.html

Browse files
BitTransformerLM/bit_transformer/templates/dashboard.html DELETED
@@ -1,454 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <title>Bit Transformer Dashboard</title>
6
- <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
7
- <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
8
- </head>
9
- <body>
10
- <h1>Bit Transformer Dashboard</h1>
11
- <div class="container">
12
- <section>
13
- <h2>Initialize Model</h2>
14
- <form id="initForm">
15
- d_model: <input type="number" name="d_model" value="{{ defaults.d_model }}" title="Model width (default {{ defaults.d_model }})"><br>
16
- nhead: <input type="number" name="nhead" value="{{ defaults.nhead }}" title="Attention heads (default {{ defaults.nhead }})"><br>
17
- num_layers: <input type="number" name="num_layers" value="{{ defaults.num_layers }}" title="Transformer layers (default {{ defaults.num_layers }})"><br>
18
- dim_feedforward: <input type="number" name="dim_feedforward" value="{{ defaults.dim_feedforward }}" title="Feedforward dim (default {{ defaults.dim_feedforward }})"><br>
19
- max_seq_len: <input type="number" name="max_seq_len" value="{{ defaults.max_seq_len }}" title="Max sequence length (default {{ defaults.max_seq_len }})"><br>
20
- chunk_size: <input type="number" name="chunk_size" title="Chunked attention size"><br>
21
- overlap: <input type="number" name="overlap" value="{{ defaults.overlap }}" title="Sliding window overlap"><br>
22
- Reversible: <input type="checkbox" name="reversible" id="reversible_box" title="Use reversible layers (default {{ defaults.reversible }})"><br>
23
- Gradient Checkpointing: <input type="checkbox" name="use_checkpoint" id="checkpoint_box" checked title="Enable gradient checkpointing (default {{ defaults.use_checkpoint }})"><br>
24
- act_threshold: <input type="number" step="0.01" name="act_threshold" value="{{ defaults.act_threshold }}" title="ACT halt threshold (default {{ defaults.act_threshold }})"><br>
25
- c_floor: <input type="number" step="0.01" name="c_floor" value="{{ c_floor }}" title="Complexity floor"><br>
26
- s_floor: <input type="number" step="0.01" name="s_floor" value="{{ s_floor }}" title="Symbiosis floor"><br>
27
- <button type="submit">Init</button>
28
- </form>
29
- </section>
30
- <section>
31
- <h2>Train Step</h2>
32
- <form id="trainForm">
33
- Bits (e.g. 0 1 0 1): <input type="text" name="bits" value="0 1 0 1"><br>
34
- Upload file: <input type="file" id="train_file"><br>
35
- <button type="submit">Train</button>
36
- </form>
37
- <label>Load sample dataset:
38
- <select id="datasetSelect">
39
- <option value="">--Select--</option>
40
- <option value="wikitext2_train">Wikitext-2 (train)</option>
41
- <option value="wikitext2_validation">Wikitext-2 (validation)</option>
42
- </select>
43
- </label>
44
- <p id="trainOut"></p>
45
- </section>
46
- <section>
47
- <h2>Scale Up</h2>
48
- Width Mult: <input type="number" step="0.1" id="width_mult" value="1.0"><br>
49
- <button id="scaleBtn">Scale Model</button>
50
- </section>
51
- <section>
52
- <h2>Collapse Submodel</h2>
53
- <form id="collapseForm">
54
- Cluster Bits (JSON array of arrays):<br>
55
- <textarea name="clusters" rows="3" cols="40">[[0,1,0,1],[1,1,0,0]]</textarea><br>
56
- Target Params (JSON):<br>
57
- <textarea name="params" rows="3" cols="40">{"d_model":32,"nhead":4,"num_layers":1,"dim_feedforward":64,"max_seq_len":16}</textarea><br>
58
- Width Scale: <input type="number" step="0.1" id="width_scale" value="1.0"><br>
59
- <button type="submit">Collapse</button>
60
- </form>
61
- </section>
62
- <section>
63
- <h2>Inference</h2>
64
- <form id="inferForm">
65
- Bits: <input type="text" name="bits" value="0 1 0 1"><br>
66
- Upload file: <input type="file" id="infer_file"><br>
67
- <button type="submit">Infer</button>
68
- </form>
69
- <pre id="inferOut"></pre>
70
- </section>
71
- <section>
72
- <h2>Long Inference</h2>
73
- <form id="inferLongForm">
74
- Bits: <input type="text" name="bits" value="0 1 0 1"><br>
75
- ctx_bits: <input type="number" name="ctx_bits" value="4096"><br>
76
- overlap: <input type="number" name="overlap" value="256"><br>
77
- <button type="submit">Infer Long</button>
78
- </form>
79
- <pre id="inferLongOut"></pre>
80
- </section>
81
- <section>
82
- <h2>Text Inference</h2>
83
- <form id="textInferForm">
84
- Text: <input type="text" name="text" value="hello"><br>
85
- <button type="submit">Infer Text</button>
86
- </form>
87
- <pre id="textInferOut"></pre>
88
- </section>
89
- <section>
90
- <h2>&lambda; Weights</h2>
91
- <form id="lambdaForm">
92
- &lambda;<sub>K</sub>: <input type="range" min="0" max="2" step="0.1" id="lambda_K" oninput="lambda_K_val.innerText=value"><span id="lambda_K_val"></span><br>
93
- &lambda;<sub>C</sub>: <input type="range" min="0" max="2" step="0.1" id="lambda_C" oninput="lambda_C_val.innerText=value"><span id="lambda_C_val"></span><br>
94
- &lambda;<sub>S</sub>: <input type="range" min="0" max="2" step="0.1" id="lambda_S" oninput="lambda_S_val.innerText=value"><span id="lambda_S_val"></span><br>
95
- <button type="submit">Update</button>
96
- </form>
97
- </section>
98
- <section>
99
- <h2>Diffusion LM</h2>
100
- <label><input type="checkbox" id="diffusion_box"> Enable Diffusion Mode</label>
101
- </section>
102
- <section>
103
- <h2>GPU Acceleration</h2>
104
- <label><input type="checkbox" id="gpu_box"> Enable FSDP &amp; CUDA</label>
105
- </section>
106
- <section>
107
- <h2>Enable Compression</h2>
108
- <label><input type="checkbox" id="compression_box"> Compress I/O</label>
109
- <p>Ratio: <span id="comp_ratio">1.0</span></p>
110
- </section>
111
- <section>
112
- <h2>Quantization Aware Training</h2>
113
- <label><input type="checkbox" id="qat_box"> Enable 4-bit QAT</label>
114
- </section>
115
- <section>
116
- <h2>Model Status</h2>
117
- <pre id="statusOut"></pre>
118
- </section>
119
- <section>
120
- <h2>Telemetry</h2>
121
- <canvas id="metricChart" width="600" height="300"></canvas>
122
- </section>
123
- <section>
124
- <h2>Hugging Face Checkpoints</h2>
125
- Repo ID: <input type="text" id="hf_repo"><br>
126
- Token: <input type="password" id="hf_token" placeholder="optional"><br>
127
- <button id="uploadBtn">Upload weights</button>
128
- <button id="downloadBtn">Download weights</button>
129
- <p id="hfStatus"></p>
130
- </section>
131
-
132
- <script>
133
- async function postJSON(url, data){
134
- const resp = await fetch(url, {method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify(data)});
135
- return resp.json();
136
- }
137
-
138
- async function pollJob(id){
139
- while(true){
140
- const job = await fetch(`/job/${id}`).then(r=>r.json());
141
- if(job.status === 'completed') return job.result;
142
- if(job.status === 'error') throw job.error || 'Job failed';
143
- await new Promise(r=>setTimeout(r, 1000));
144
- }
145
- }
146
-
147
- function loadInitParams(){
148
- const saved = JSON.parse(localStorage.getItem('init_params')||'{}');
149
- const form = document.getElementById('initForm');
150
- for(const [k,v] of Object.entries(saved)){
151
- const el = form.elements[k];
152
- if(!el) continue;
153
- if(el.type === 'checkbox') el.checked = v; else el.value = v;
154
- }
155
- }
156
- loadInitParams();
157
-
158
- function byteArrayToBits(arr){
159
- const bits=[];
160
- for(const b of arr){
161
- for(let i=7;i>=0;i--) bits.push((b>>i)&1);
162
- }
163
- return bits;
164
- }
165
-
166
- let trainFileBits=null, inferFileBits=null, datasetBits=null;
167
-
168
- async function fileToBits(file){
169
- if(file.type.startsWith('text')){
170
- const text = await file.text();
171
- const res = await postJSON('/text_to_bits', {text});
172
- return res.bits;
173
- }
174
- const buf = await file.arrayBuffer();
175
- return byteArrayToBits(new Uint8Array(buf));
176
- }
177
-
178
- let metricChart;
179
- async function initChart(){
180
- const data = await fetch('/metrics').then(r=>r.json());
181
- const labels = data.negentropy.map((_,i)=>i);
182
- const ctx = document.getElementById('metricChart').getContext('2d');
183
- metricChart = new Chart(ctx, {
184
- type:'line',
185
- data:{
186
- labels:labels,
187
- datasets:[
188
- {label:'Negentropy', data:data.negentropy, borderColor:'blue', fill:false},
189
- {label:'LZ Complexity', data:data.lz_complexity, borderColor:'orange', fill:false},
190
- {label:'Symbiosis', data:data.symbiosis, borderColor:'green', fill:false}
191
- ]
192
- },
193
- options:{responsive:false, interaction:{mode:'index', intersect:false}}
194
- });
195
- }
196
-
197
- async function updateChart(){
198
- const data = await fetch('/metrics').then(r=>r.json());
199
- const labels = data.negentropy.map((_,i)=>i);
200
- metricChart.data.labels = labels;
201
- metricChart.data.datasets[0].data = data.negentropy;
202
- metricChart.data.datasets[1].data = data.lz_complexity;
203
- metricChart.data.datasets[2].data = data.symbiosis;
204
- metricChart.update();
205
- }
206
-
207
- initChart();
208
- setInterval(updateChart, 2000);
209
-
210
- async function refreshStatus(){
211
- const [s, c] = await Promise.all([fetch('/status'), fetch('/model_config')]);
212
- const status = await s.json();
213
- const config = await c.json();
214
- document.getElementById('statusOut').innerText = JSON.stringify({...status, ...config}, null, 2);
215
- }
216
-
217
- document.getElementById('initForm').addEventListener('submit', async (e)=>{
218
- e.preventDefault();
219
- const fd = new FormData(e.target);
220
- const obj = Object.fromEntries(fd.entries());
221
- const ints = ['d_model','nhead','num_layers','dim_feedforward','max_seq_len','chunk_size','overlap'];
222
- ints.forEach(k=>{ if(obj[k]===''){ delete obj[k]; } else obj[k]=parseInt(obj[k]); });
223
- obj.reversible = document.getElementById('reversible_box').checked;
224
- obj.use_checkpoint = document.getElementById('checkpoint_box').checked;
225
- obj.act_threshold = parseFloat(obj.act_threshold);
226
- const floors = {c_floor: parseFloat(obj.c_floor), s_floor: parseFloat(obj.s_floor)};
227
- delete obj.c_floor; delete obj.s_floor;
228
- await postJSON('/init', obj);
229
- await postJSON('/config/telemetry', floors);
230
- localStorage.setItem('init_params', JSON.stringify({...obj, ...floors}));
231
- refreshStatus();
232
- updateChart();
233
- });
234
-
235
- document.getElementById('trainForm').addEventListener('submit', async (e)=>{
236
- e.preventDefault();
237
- const form = e.target;
238
- let payload;
239
- if(trainFileBits){
240
- payload = trainFileBits;
241
- } else if(datasetBits){
242
- payload = datasetBits;
243
- } else {
244
- payload = [form.bits.value.trim().split(/\s+/).map(Number)];
245
- }
246
- for(const el of form.elements) el.disabled = true;
247
- const out = document.getElementById('trainOut');
248
- out.innerText = '⏳';
249
- try{
250
- const job = await postJSON('/train', {bits: payload});
251
- const res = await pollJob(job.job_id);
252
- out.innerText = 'Loss: '+res.loss.toFixed(4);
253
- if(res.ratio !== undefined){
254
- document.getElementById('comp_ratio').innerText = res.ratio.toFixed(2);
255
- }
256
- } catch(err){
257
- out.innerText = 'Error';
258
- alert(err);
259
- } finally {
260
- for(const el of form.elements) el.disabled = false;
261
- refreshStatus();
262
- updateChart();
263
- }
264
- });
265
-
266
- document.getElementById('train_file').addEventListener('change', async (e)=>{
267
- const f = e.target.files[0];
268
- if(!f) return;
269
- const bits = await fileToBits(f);
270
- trainFileBits = [bits];
271
- datasetBits = null;
272
- document.querySelector('#trainForm input[name="bits"]').value = bits.slice(0,64).join(' ');
273
- });
274
-
275
- document.querySelector('#trainForm input[name="bits"]').addEventListener('input', ()=>{
276
- trainFileBits = null;
277
- datasetBits = null;
278
- });
279
-
280
- document.getElementById('scaleBtn').addEventListener('click', async ()=>{
281
- const btn = document.getElementById('scaleBtn');
282
- const input = document.getElementById('width_mult');
283
- const mult = parseFloat(input.value);
284
- btn.disabled = true; input.disabled = true;
285
- const original = btn.innerText; btn.innerText = '⏳';
286
- try{
287
- const job = await postJSON('/scale_up', {width_mult: mult});
288
- await pollJob(job.job_id);
289
- } catch(err){
290
- alert(err);
291
- } finally {
292
- btn.innerText = original;
293
- btn.disabled = false; input.disabled = false;
294
- refreshStatus();
295
- updateChart();
296
- }
297
- });
298
-
299
- document.getElementById('collapseForm').addEventListener('submit', async (e)=>{
300
- e.preventDefault();
301
- const form = e.target;
302
- const btn = form.querySelector('button');
303
- for(const el of form.elements) el.disabled = true;
304
- const clusters = JSON.parse(form.clusters.value);
305
- const params = JSON.parse(form.params.value);
306
- const w = parseFloat(document.getElementById('width_scale').value);
307
- const original = btn.innerText; btn.innerText = '⏳';
308
- try{
309
- const job = await postJSON('/collapse', {clusters: clusters, params: params, width_scale: w});
310
- await pollJob(job.job_id);
311
- } catch(err){
312
- alert(err);
313
- } finally {
314
- btn.innerText = original;
315
- for(const el of form.elements) el.disabled = false;
316
- refreshStatus();
317
- updateChart();
318
- }
319
- });
320
-
321
- document.getElementById('inferForm').addEventListener('submit', async (e)=>{
322
- e.preventDefault();
323
- let bits;
324
- if(inferFileBits){
325
- bits = inferFileBits;
326
- } else if(datasetBits){
327
- bits = [datasetBits[0]];
328
- } else {
329
- bits = [e.target.bits.value.trim().split(/\s+/).map(Number)];
330
- }
331
- const res = await postJSON('/infer', {bits});
332
- if(res.error){
333
- alert(res.error + '\n' + (res.suggestion||''));
334
- } else {
335
- document.getElementById('inferOut').innerText = JSON.stringify(res, null, 2);
336
- if(res.ratio !== undefined){
337
- document.getElementById('comp_ratio').innerText = res.ratio.toFixed(2);
338
- }
339
- }
340
- refreshStatus();
341
- updateChart();
342
- });
343
-
344
- document.getElementById('infer_file').addEventListener('change', async (e)=>{
345
- const f = e.target.files[0];
346
- if(!f) return;
347
- const bits = await fileToBits(f);
348
- inferFileBits = [bits];
349
- datasetBits = null;
350
- document.querySelector('#inferForm input[name="bits"]').value = bits.slice(0,64).join(' ');
351
- });
352
-
353
- document.querySelector('#inferForm input[name="bits"]').addEventListener('input', ()=>{
354
- inferFileBits = null;
355
- datasetBits = null;
356
- });
357
-
358
- document.getElementById('datasetSelect').addEventListener('change', async (e)=>{
359
- const val = e.target.value;
360
- trainFileBits = null;
361
- inferFileBits = null;
362
- if(!val){ datasetBits = null; return; }
363
- const [name, split] = val.split('_');
364
- const resp = await fetch(`/dataset?name=${name}&split=${split}&size=4&seq_len=64`);
365
- const data = await resp.json();
366
- datasetBits = data.bits;
367
- const preview = data.bits[0].slice(0,64).join(' ');
368
- document.querySelector('#trainForm input[name="bits"]').value = preview;
369
- document.querySelector('#inferForm input[name="bits"]').value = preview;
370
- });
371
-
372
- document.getElementById('inferLongForm').addEventListener('submit', async (e)=>{
373
- e.preventDefault();
374
- const bits = e.target.bits.value.trim().split(/\s+/).map(Number);
375
- const ctx = parseInt(e.target.ctx_bits.value);
376
- const ov = parseInt(e.target.overlap.value);
377
- const res = await postJSON('/infer_long', {bits: bits, ctx_bits: ctx, overlap: ov});
378
- document.getElementById('inferLongOut').innerText = JSON.stringify(res, null, 2);
379
- refreshStatus();
380
- updateChart();
381
- });
382
-
383
- document.getElementById('textInferForm').addEventListener('submit', async (e)=>{
384
- e.preventDefault();
385
- const text = e.target.text.value;
386
- const res = await postJSON('/infer_text', {text:text});
387
- document.getElementById('textInferOut').innerText = JSON.stringify(res, null, 2);
388
- refreshStatus();
389
- updateChart();
390
- });
391
-
392
- async function loadLambdas(){
393
- const resp = await fetch('/lambdas');
394
- const vals = await resp.json();
395
- for(const k of ['lambda_K','lambda_C','lambda_S']){
396
- document.getElementById(k).value = vals[k];
397
- document.getElementById(k+"_val").innerText = vals[k];
398
- }
399
- }
400
-
401
- document.getElementById('lambdaForm').addEventListener('submit', async (e)=>{
402
- e.preventDefault();
403
- const data = {
404
- lambda_K: parseFloat(document.getElementById('lambda_K').value),
405
- lambda_C: parseFloat(document.getElementById('lambda_C').value),
406
- lambda_S: parseFloat(document.getElementById('lambda_S').value),
407
- };
408
- await postJSON('/lambdas', data);
409
- for(const k in data){
410
- document.getElementById(k+"_val").innerText = data[k];
411
- }
412
- refreshStatus();
413
- });
414
-
415
- loadLambdas();
416
-
417
- function restoreToggle(id,key,endpoint,field){
418
- const box = document.getElementById(id);
419
- const saved = localStorage.getItem(key);
420
- if(saved !== null){ box.checked = saved === 'true'; postJSON(endpoint,{[field]: box.checked}); }
421
- box.addEventListener('change', async (e)=>{
422
- await postJSON(endpoint, {[field]: e.target.checked});
423
- localStorage.setItem(key, e.target.checked);
424
- refreshStatus();
425
- });
426
- }
427
-
428
- restoreToggle('diffusion_box','diffusion','/diffusion','diffusion');
429
- restoreToggle('gpu_box','use_gpu','/gpu','use_gpu');
430
- restoreToggle('compression_box','compression','/compression','compression');
431
- restoreToggle('qat_box','qat','/qat','qat');
432
-
433
- document.getElementById('uploadBtn').addEventListener('click', async ()=>{
434
- const repo = document.getElementById('hf_repo').value;
435
- const token = document.getElementById('hf_token').value;
436
- const res = await postJSON('/save_checkpoint', {repo_id: repo, token: token||undefined});
437
- document.getElementById('hfStatus').innerText = res.status || res.error;
438
- });
439
-
440
- document.getElementById('downloadBtn').addEventListener('click', async ()=>{
441
- const repo = document.getElementById('hf_repo').value;
442
- const token = document.getElementById('hf_token').value;
443
- const res = await postJSON('/download_checkpoint', {repo_id: repo, token: token||undefined});
444
- document.getElementById('hfStatus').innerText = res.status || res.error;
445
- refreshStatus();
446
- updateChart();
447
- });
448
-
449
- refreshStatus();
450
- </script>
451
- </div>
452
- </body>
453
- </html>
454
-