浏览器内 WebGPU 推理:在网页中运行本地 AI 模型
什么是浏览器内 WebGPU 推理
浏览器内 WebGPU 推理是指在网页中直接利用用户的 GPU 硬件运行 AI 模型。过去,浏览器中的机器学习主要依赖 CPU(速度慢)或 WebGL(兼容性广但限制多)。WebGPU 作为新一代图形与计算 API,提供了接近原生 Vulkan/Metal/DirectX 12 的计算能力,让复杂的神经网络在网页端运行成为可能。你将不再需要服务器端推理,所有计算都在本地完成,数据无需离开设备。
为什么选择 WebGPU 进行 AI 推理
WebGPU vs WebGL
- 计算着色器原生支持:WebGPU 从设计之初就包含通用计算管线,支持共享内存、原子操作等高级特性,而 WebGL 需要通过片段着色器间接模拟计算,效率低且代码复杂。
- 更低的开销:WebGPU 减少了驱动层的命令验证和状态切换开销,在相同硬件上,WebGPU 推理延迟通常比 WebGL 低 2~5 倍。
- 更现代的 GPU 特性:WebGPU 可以映射 Vulkan 等底层 API 的特性,比如工作组屏障、统一缓冲区管理,适合 Transformer 等需要大量并行计算的结构。
性能优势
- 速度:以 Stable Diffusion(图像生成)为例,WebGPU 在主流笔记本上生成 512×512 图像仅需数秒,WebGL 需要数十秒,而纯 CPU 可能超过一分钟。
- 功耗与散热:GPU 执行推理比 CPU 更节能,在移动设备上电池消耗更低。
- 隐私与低延迟:模型、输入数据始终留在浏览器中,无需上传到远程服务器,适合医疗、金融等敏感场景,也能在离线或弱网环境下使用。
浏览器兼容性
- 桌面端:Chrome 113+、Edge 113+、Opera 99+ 已经默认开启 WebGPU;Firefox 正在 Nightly 中实验性支持;Safari 17+ 已初步支持。
- 移动端:Chrome 121+(Android)已开启;iOS Safari 需要进一步测试。
- 检测方法:在 JavaScript 中检查
navigator.gpu是否存在即可。 - 兜底策略:建议同时提供 WebGL 或 WASM(CPU)回退方案,以覆盖更广的用户设备。
快速入门:搭建 WebGPU 推理环境
检查 WebGPU 支持
if (!navigator.gpu) {
throw new Error('当前浏览器不支持 WebGPU,请使用最新版 Chrome/Edge/Opera 并确认硬件加速已开启。');
}
获取 GPU 适配器与设备
const adapter = await navigator.gpu.requestAdapter();
if (!adapter) {
throw new Error('无法获取 GPU 适配器,可能未安装合适的显卡驱动。');
}
const device = await adapter.requestDevice();
至此,device 对象就是后续推理框架所需的底层 WebGPU 设备,不需要再手动编写复杂的着色器和管理缓冲区。
选择推理框架
- Transformers.js:专为浏览器设计的 Hugging Face Transformers 移植,支持 WebGPU 后端,几行代码即可运行文本、图像、语音模型。
- ONNX Runtime Web:微软提供的 ONNX 模型运行时,包含 WebGPU 执行提供程序,适合已经转换成 ONNX 的自定义模型。
- TensorFlow.js(实验性):提供 WebGPU 后端,但成熟度略低。
推荐初学者从 Transformers.js 开始,简单易用且模型库丰富。
使用 Transformers.js 实现 WebGPU 推理
安装与导入
通过 CDN 或 npm 安装。CDN 方式:
<script type="module">
import { pipeline, env } from 'https://cdn.jsdelivr.net/npm/@huggingface/transformers@3.0.2';
</script>
npm 方式:npm install @huggingface/transformers。
加载模型并指定 WebGPU 后端
在创建 pipeline 前,设置 env.backends.onnx.preferredBackend = 'webgpu' 来优先使用 WebGPU,并关闭本地模型缓存(开发环境可选):
env.backends.onnx.preferredBackend = 'webgpu';
// 如果没有 WebGPU,自动降级到 wasm/webgl
env.allowLocalModels = false; // 强制从 Hugging Face Hub 下载
然后加载一个情感分析模型:
const classifier = await pipeline('sentiment-analysis', 'Xenova/bert-base-multilingual-uncased-sentiment');
运行推理
const result = await classifier('I love WebGPU!');
console.log(result);
// 输出: [{ label: '5 stars', score: 0.9... }]
首次加载需要下载模型文件(约 100~300 MB),之后会缓存在 IndexedDB 中,再次加载几乎瞬间完成。实际推理时,计算会被提交到 GPU 上并行执行,不阻塞主页面 UI。
提示:
env.backends.onnx.wasm.numThreads可控制 CPU 回退时的线程数,但对 WebGPU 无影响。
使用 ONNX Runtime Web 进行 WebGPU 推理
适合已经拥有 ONNX 模型的开发者。
引入 ONNX Runtime Web
<script src="https://cdn.jsdelivr.net/npm/onnxruntime-web/dist/ort.min.js"></script>
或 npm install onnxruntime-web。
加载 ONNX 模型
确保模型文件(例如 model.onnx)可通过 URL 访问。创建推理会话时指定 executionProviders: ['webgpu']:
const session = await ort.InferenceSession.create('./model.onnx', {
executionProviders: ['webgpu'],
graphOptimizationLevel: 'all'
});
创建推理会话并执行
// 准备输入张量(例如 1×3×224×224 图像数据)
const input = new ort.Tensor('float32', new Float32Array(224*224*3), [1, 3, 224, 224]);
const feeds = { input: input };
const results = await session.run(feeds);
console.log(results.output.data);
- 张量数据类型必须匹配模型要求,常见
float32、float16等。 - WebGPU 执行提供程序会在底层自动将数据传输至 GPU 并完成计算,无需手动管理。
- 对于较大模型,ONNX Runtime Web 会利用 WebGPU 的
MAP_READ/MAP_WRITE特性优化内存传输。
性能优化建议
减少数据传输
浏览器与 GPU 之间的数据交换是主要瓶颈。尽量复用已经在 GPU 上的张量,避免在每次推理时创建新的输入数组。利用 ort.Tensor 的 dispose() 及时释放资源。
批处理
一次推理处理多条数据(比如多句文本合并成一个批次)可让 GPU 的计算单元更饱和。Transformers.js 的 pipeline 默认不支持批处理,需自己构造 tokenizer 的输出并手动调用模型 forward。
使用合适的张量类型
- float16:若模型支持,可将权重和输入转为 float16,内存占用减半,在移动 GPU 上加速明显。
onnxruntime-web需要设置preferredOutputLocation等高级选项。 - 量化模型:优选使用已经进行 INT8 或 QInt8 量化的 ONNX 模型,减少带宽和计算量。
模型分片与缓存
大型模型(如 LLaMA-7B)无法一次加载,可使用 WebGPU 的缓冲区分段上传,配合 Service Worker 实现流式下载与缓存,避免阻塞主线程。
实战:构建一个图像分类 Web 应用
我们将使用 Transformers.js 和 WebGPU 实现上传照片并识别物体类别。
步骤1:准备 HTML 页面,包含文件选择器和结果显示区。
<input type="file" id="upload" accept="image/*">
<img id="preview" style="max-width: 300px; display: none;">
<pre id="result"></pre>
步骤2:JavaScript 初始化 pipeline 为 image-classification 模型,明确设置 device: 'webgpu'(最新版 Transformers.js 支持此参数)。
const classifier = await pipeline('image-classification', 'Xenova/vit-base-patch16-224', {
device: 'webgpu'
});
步骤3:监听文件变化,读取图片为 Blob URL 并显示,然后进行推理。
document.getElementById('upload').addEventListener('change', async (e) => {
const file = e.target.files[0];
const img = document.getElementById('preview');
img.src = URL.createObjectURL(file);
img.style.display = 'block';
img.onload = async () => {
const results = await classifier(img.src);
document.getElementById('result').textContent = JSON.stringify(results, null, 2);
};
});
用户选择图片后,几毫秒内即可得到 Top-5 分类结果,所有计算在本地 GPU 完成。
常见问题与故障排除
navigator.gpu为 undefined:检查浏览器版本,确保硬件加速已开启(如 Chrome 设置 → 系统 → 使用图形加速)。Linux 需要开启 Vulkan 支持。- 推理结果全为 NaN 或随机:可能模型格式不兼容,或使用
float16时硬件不支持,尝试改用float32。 - 性能不达预期:使用浏览器的
chrome://gpu页面查看 WebGPU 状态;确认没有切换至集成显卡(混用显卡可能导致回退)。 - 加载模型失败(CORS):模型文件需托管在允许跨域访问的服务器上,或使用 CDN;开发时可用
--disable-web-security启动 Chrome(仅限测试)。 - 内存溢出:大型模型可能超出 GPU 内存限制,尝试使用更小的蒸馏版本或开启模型分块加载。
总结与展望
WebGPU 将桌面级 GPU 计算能力带入浏览器,使本地 AI 推理成为现实。随着 Chrome、Edge、Safari 等主流浏览器的全面支持,未来我们将看到更多无需安装的智能应用:实时视频背景替换、文本补全、文档问答、甚至完全本地运行的代码助手。快在你的开发环境中尝试一下,体验在浏览器中驱动 GPU 解锁 AI 的能力。