Mamba WebGPU -- First Browser-Native SSM Inference Engine
Falcon-Mamba 7B running in a browser tab. Pure WebGPU compute shaders. No MLC, no TVM, no WASM, no compilation step. 12 hand-written WGSL shaders. First ever browser-native Mamba/SSM inference.
What This Is
A complete inference runtime for Falcon-Mamba-7B-Instruct that runs entirely in the browser using WebGPU compute shaders. No server-side inference -- the model loads into GPU memory via the browser's WebGPU API and generates text using hand-written WGSL compute shaders.
This is NOT a transformer runtime. This is an SSM (State Space Model) runtime -- the Mamba architecture, which uses persistent recurrent state instead of KV cache. The state is fixed-size (38MB) regardless of context length.
Why This Matters
WebLLM ships transformer models to the browser. This ships SSM models.
MLC/TVM don't support Mamba architecture (confirmed)
The SSM state IS persistent memory -- save it, restore it, the entity remembers
Fixed 38MB state vs unbounded KV cache growth
No server needed for inference
Quick Start
bash
1# Clone this repo2git clone https://huggingface.co/LJTSG/mamba-webgpu
34# Start the dev server (serves weights from HF cache via byte-range requests)5node serve_mamba.js
67# Open http://localhost:81408# Click: Initialize -> Load Weights -> Generate
Requirements:
Falcon-Mamba-7B-Instruct weights in your HuggingFace cache (~/.cache/huggingface/hub/models--tiiuae--falcon-mamba-7b-instruct/)
Node.js (for the dev server)
Python + transformers (for tokenization)
Chrome/Edge with WebGPU support
GPU with >= 16GB accessible via WebGPU (tested on AMD Strix Halo iGPU with 64GB unified memory)
~60s weight loading (14GB F32 via byte-range fetch)
38MB persistent SSM state (64 layers x 608KB)
~960 shader dispatches per token (15 ops x 64 layers)
The Build Story
Built over 36 hours across two sessions. Six bugs stood between "all zeros" and coherent output:
Buffer alignment -- WebGPU requires storage buffer binding offsets to be 256-byte aligned. An unaligned offset silently invalidated entire command encoders.
A_log transform -- Falcon-Mamba stores A_log; the SSU needs A = -exp(A_log) for proper state decay.
Storage buffer limit -- The SSU shader uses 9 storage buffers; default WebGPU limit is 8.
Illegal buffer flags -- MAP_READ cannot be combined with STORAGE usage.
Diagnostic overhead -- Per-token GPU readbacks for debugging were causing device timeouts.
Missing RMSNorm on B, C, dt_pre -- Falcon-Mamba applies weightless RMSNorm to B, C, and dt_pre before the SSU. Standard Mamba does not. This was the final bug -- every shader was correct, but we were implementing the wrong model.
The debugging involved systematic golden-value comparison against PyTorch, checking each intermediate buffer across all 8192 elements. Every single shader operation matched to 6 decimal places. The divergence was in the model architecture, not the compute.