CoolFace
Modelpublic

LJTSG/mamba-webgpu

sourceHugging Faceapache-2.0updated 4mo agoView on Hugging Face
0likes
index.html137 linesDownload Raw Back to root
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>7body { font-family: monospace; background: #0d1117; color: #c9d1d9; padding: 24px; max-width: 900px; margin: 0 auto; }8h1 { 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; }14button { background: #238636; color: white; border: none; border-radius: 6px; padding: 8px 16px; cursor: pointer; font-weight: bold; margin: 4px; }15button:disabled { opacity: 0.5; cursor: wait; }16input { 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">50import { MambaRuntime } from './mamba_runtime.js';51 52let mamba = null;53const log = document.getElementById('log');54const status = document.getElementById('status');55 56function 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 load63(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 81window.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 12 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 96window.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 113window.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>137