LJTSG commited on
Commit
ed8ac31
·
verified ·
1 Parent(s): 48d826b

Upload index.html with huggingface_hub

Browse files
Files changed (1) hide show
  1. index.html +136 -0
index.html ADDED
@@ -0,0 +1,136 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>Mamba WebGPU — First Browser-Native SSM Inference</title>
6
+ <style>
7
+ body { font-family: monospace; background: #0d1117; color: #c9d1d9; padding: 24px; max-width: 900px; margin: 0 auto; }
8
+ h1 { color: #58a6ff; font-size: 20px; }
9
+ .card { background: #161b22; border: 1px solid #30363d; border-radius: 8px; padding: 16px; margin: 12px 0; }
10
+ .label { color: #8b949e; font-size: 12px; text-transform: uppercase; letter-spacing: 1px; }
11
+ .value { color: #c9d1d9; font-size: 14px; margin-top: 4px; }
12
+ .green { color: #3fb950; } .red { color: #f85149; } .amber { color: #d29922; }
13
+ #log { font-size: 12px; background: #010409; border: 1px solid #30363d; border-radius: 6px; padding: 10px; max-height: 400px; overflow-y: auto; white-space: pre-wrap; }
14
+ button { background: #238636; color: white; border: none; border-radius: 6px; padding: 8px 16px; cursor: pointer; font-weight: bold; margin: 4px; }
15
+ button:disabled { opacity: 0.5; cursor: wait; }
16
+ input { background: #161b22; border: 1px solid #30363d; color: #c9d1d9; border-radius: 6px; padding: 8px 12px; width: 60%; }
17
+ </style>
18
+ </head>
19
+ <body>
20
+ <h1>🐍 Mamba WebGPU — Falcon-Mamba 7B in Browser</h1>
21
+ <p>First browser-native Mamba/SSM inference engine. Pure WebGPU compute shaders — no MLC, no TVM.</p>
22
+
23
+ <div class="card">
24
+ <div class="label">Status</div>
25
+ <div class="value" id="status"><span class="amber">⬤</span> not initialized</div>
26
+ </div>
27
+
28
+ <div class="card">
29
+ <div class="label">WebGPU Info</div>
30
+ <div class="value" id="gpu-info">checking...</div>
31
+ </div>
32
+
33
+ <div class="card">
34
+ <button id="btn-init" onclick="doInit()">1. Initialize WebGPU + Compile Shaders</button>
35
+ <button id="btn-load" onclick="doLoad()" disabled>2. Load Weights</button>
36
+ <button id="btn-gen" onclick="doGenerate()" disabled>3. Generate</button>
37
+ </div>
38
+
39
+ <div class="card">
40
+ <div class="label">Prompt</div>
41
+ <input id="prompt" value="Hello, I am Grandma Goodwin and" />
42
+ </div>
43
+
44
+ <div class="card">
45
+ <div class="label">Log</div>
46
+ <div id="log"></div>
47
+ </div>
48
+
49
+ <script type="module">
50
+ import { MambaRuntime } from './mamba_runtime.js';
51
+
52
+ let mamba = null;
53
+ const log = document.getElementById('log');
54
+ const status = document.getElementById('status');
55
+
56
+ function l(msg) {
57
+ const ts = new Date().toISOString().slice(11, 19);
58
+ log.textContent += `[${ts}] ${msg}\n`;
59
+ log.scrollTop = log.scrollHeight;
60
+ }
61
+
62
+ // Check WebGPU on load
63
+ (async () => {
64
+ const info = document.getElementById('gpu-info');
65
+ if (!navigator.gpu) {
66
+ info.innerHTML = '<span class="red">WebGPU not supported</span>';
67
+ return;
68
+ }
69
+ const adapter = await navigator.gpu.requestAdapter();
70
+ if (!adapter) {
71
+ info.innerHTML = '<span class="red">No adapter found</span>';
72
+ return;
73
+ }
74
+ const ai = adapter.info || {};
75
+ const lim = adapter.limits;
76
+ info.innerHTML = `<span class="green">✓</span> ${ai.vendor || '?'} ${ai.architecture || '?'} | ` +
77
+ `maxBufferSize: ${(lim.maxBufferSize/1024/1024/1024).toFixed(2)} GB | ` +
78
+ `maxStorageBuffer: ${(lim.maxStorageBufferBindingSize/1024/1024).toFixed(0)} MB`;
79
+ })();
80
+
81
+ window.doInit = async function() {
82
+ try {
83
+ document.getElementById('btn-init').disabled = true;
84
+ l('Initializing WebGPU device...');
85
+ mamba = new MambaRuntime();
86
+ await mamba.init();
87
+ l('✓ Device ready, all 9 shaders compiled');
88
+ status.innerHTML = '<span class="green">⬤</span> shaders compiled — ready to load weights';
89
+ document.getElementById('btn-load').disabled = false;
90
+ } catch (e) {
91
+ l('✗ Init failed: ' + e.message);
92
+ status.innerHTML = '<span class="red">⬤</span> ' + e.message;
93
+ }
94
+ };
95
+
96
+ window.doLoad = async function() {
97
+ try {
98
+ document.getElementById('btn-load').disabled = true;
99
+ l('Loading Falcon-Mamba 7B weights...');
100
+ l('(Point ./weights/ to your safetensors directory)');
101
+ status.innerHTML = '<span class="amber">⬤</span> loading weights...';
102
+ await mamba.loadWeights('./weights');
103
+ l('✓ Weights loaded, SSM state allocated');
104
+ status.innerHTML = '<span class="green">⬤</span> model loaded — ready to generate';
105
+ document.getElementById('btn-gen').disabled = false;
106
+ } catch (e) {
107
+ l('✗ Load failed: ' + e.message);
108
+ status.innerHTML = '<span class="red">⬤</span> ' + e.message;
109
+ document.getElementById('btn-load').disabled = false;
110
+ }
111
+ };
112
+
113
+ window.doGenerate = async function() {
114
+ const btn = document.getElementById('btn-gen');
115
+ if (btn.disabled) return;
116
+ btn.disabled = true;
117
+ const prompt = document.getElementById('prompt').value;
118
+ l('Generating: "' + prompt + '"');
119
+ status.innerHTML = '<span class="amber">⬤</span> encoding prompt...';
120
+ const t0 = performance.now();
121
+ try {
122
+ const result = await mamba.generate(prompt, 100, 0.75, (token, step) => {
123
+ if (step === 0) status.innerHTML = '<span class="amber">⬤</span> generating tokens...';
124
+ });
125
+ const elapsed = ((performance.now() - t0) / 1000).toFixed(1);
126
+ l(`[${elapsed}s] ${prompt}${result}`);
127
+ status.innerHTML = '<span class="green">⬤</span> done';
128
+ } catch(e) {
129
+ l('ERROR: ' + e.message);
130
+ status.innerHTML = '<span class="red">⬤</span> error';
131
+ }
132
+ btn.disabled = false;
133
+ };
134
+ </script>
135
+ </body>
136
+ </html>