Web Stable Diffusion 是由 mlc-ai 在 GitHub 上开源的项目,目的是把 Stable Diffusion 模型带到网页浏览器中。根据项目说明,所有计算都在浏览器内部完成,无需服务器支持;项目方称其为“全球首个完全在浏览器中运行的 Stable Diffusion”。该项目关注的是将部分或全部计算放到客户端一侧,以带来降低服务提供方成本、增强个性化与隐私保护等潜在好处。项目还提到,如果对把基于 LLM 的聊天机器人部署到浏览器感兴趣,可以参考 Web LLM。
项目采用机器学习编译(MLC)技术。整体方案构建在开源生态之上,包括 PyTorch、Hugging Face diffusers 与 tokenizers、Rust、WASM 和 WebGPU;主要流程基于 Apache TVM Unity。项目使用 Runway 的 stable diffusion v1-5 模型(来自 Hugging Face diffuser 库),并用 TorchDynamo 与 Torch FX 将关键模型组件捕获为 TVM 中的 IRModule。TVM IRModule 中的每个函数都可以进一步转换并生成可运行代码,从而在支持最小 TVM 运行时的任意环境(包括 JavaScript)中通用部署。项目使用 TensorIR 和 MetaSchedule 构建自动生成优化程序的方案,这些变换在特定设备上通过原生 GPU 运行时进行调优,然后用于生成优化的 GPU 着色器;项目还提供一个记录这些变换的数据库,使新的构建无需重新调优。项目还构建了静态内存规划优化,以便跨多个层复用内存;使用 Emscripten 和 TypeScript 构建可部署生成模块的 TVM Web 运行时,并利用 Hugging Face 的 rust tokenizers 库的 wasm 移植版。除了最后用于连接各组件的约 400 行 JavaScript 应用外,该工作流的所有部分都在 Python 中完成。
项目提供 Jupyter notebook,逐步走完全部阶段,包括:阐述 Web ML 模型部署的关键点以及项目如何满足这些关键点、导入 stable diffusion 模型、优化模型、构建模型、使用原生 GPU 运行时在本地部署模型,以及使用 WebGPU 运行时在网页上部署模型。
如果要在命令行中执行这些步骤,需要先安装 TVM Unity:可以使用 pip3 install mlc-ai-nightly -f https://mlc.ai/wheels 安装 TVM Unity wheel,或按照 TVM 文档从源码构建;从源码构建时在 git clone 之后使用 git checkout origin/unity 切换到 TVM Unity。导入、优化并构建 stable diffusion 模型时运行 python3 build.py;默认 build.py 以 apple/m2-gpu 作为构建目标,也可以通过 python3 build.py --target cuda 指定 CUDA 目标。使用原生 GPU 运行时在本地部署模型时运行 python3 deploy.py --prompt " A photo of an astronaut riding a horse on mars. ",可以把提示词替换为自己的内容,并可通过 --negative-prompt "Your negative prompt" 指定负向提示词。
使用 WebGPU 运行时在网页上部署模型时,walkthrough notebook 的最后一节“Deploy on web”列出了完整说明。项目也提供了一份纯文本说明:首先安装所有前置依赖。emscripten 是基于 LLVM 的编译器,可将 C/C++ 源码编译为 WebAssembly;按照安装说明安装最新 emsdk,并通过 source path/to/emsdk_env.sh 加载 emsdk_env.sh,使 emcc 可从 PATH 访问且命令 emcc 可用。Rust;wasm-pack,它帮助构建 Rust 生成的 WebAssembly,在本项目中用于 tokenizer;按照官方指南安装 jekyll,这是项目用于网站的工具;通过命令 gem install jekyll-remote-theme 安装 jekyll-remote-theme;安装 Chrome Canary,这是支持使用 WebGPU 的 Chrome 开发者版本。可以分别在终端中试用 emcc、jekyll 和 wasm-pack 来验证安装成功。然后准备 Web 构建所需的所有依赖:./scripts/prep_deps.sh。接着可以通过运行 python3 build.py --target webgpu 将模型构建到 WebGPU 后端,并以 WebAssembly 文件格式把可执行文件导出到磁盘。最后使用 ./scripts/local_deploy_site.sh 搭建站点。站点搭好后,可以在 Chrome Canary 中访问 localhost:8888/ 在本机体验演示。项目特别提示,启动 Chrome Canary 时需要使用 /Applications/Google \ Chrome \ Canary.app/Contents/MacOS/Google \ Chrome \ Canary --enable-dawn-features=disable_robustness 来关闭 Chrome 的 robustness 检查。
项目还提供了与原生 GPU 运行时的对比、限制与机会说明。除了 WebGPU 运行时,项目也提供使用本地 GPU 运行时的原生部署选项;这些选项既可作为在原生环境部署的工具,也可作为比较原生 GPU 驱动性能与 WebGPU 的参照点。WebGPU 通过将 WGSL(WebGPU Shading Language)着色器翻译为原生着色器来工作,因此理论上 WebGPU 运行时与原生环境之间可以达到零差距。但项目指出,如果直接用 Chrome 在 Apple silicon 上查看当前演示,会发现性能下降约 3 倍,这是因为 Chrome 的 WebGPU 实现为所有数组索引访问插入了边界裁剪,使 a[i] 变成 a[min(i, a.size)]。理想情况下,下游着色器编译器应能优化掉边界裁剪,但目前并非如此。一旦 WebGPU 实现更加成熟、能够检查索引访问范围并去掉此类裁剪,这一差距就可以修复。项目提到可以通过使用特殊标志启动 Chrome 来绕过这一问题,退出 Chrome 后,在命令行输入相应命令,就会发现在执行速度与原生 GPU 环境一样快,并预计该问题会随着 WebGPU 成熟而解决。
项目认为 WebGPU 仍在演进,仅通过 Chrome Canary 提供,且可能不稳定;它还存在限制,例如仅支持 FP32(FP16 着色器扩展已在规范中但尚未实现)。此处的 stable diffusion 需要具有足够内存(8GB)的 GPU。项目截至目前只在 Apple silicon 上测试过其方案。项目还提到有机会支持 FlashAttention 和量化等高级优化,以进一步提升系统性能。项目认为这些机会可以在不久的将来被解决,解决方案中的单个组件仍可能有用,例如可以只部署模型的文本编码器部分;同样的 Python 优先开发、通用部署工作流也可用于将 ML 模型带到其他环境,如新硬件或移动场景;同样的机器学习编译栈也与服务器类用例共享,可用于优化服务器工作负载。