同一台笔记本上,TinyLlama 经 WebGPU 可以跑到 25—40 tokens/s,换成 WebAssembly 只剩 2—5 tokens/s;但把同一套 WebGPU 代码搬到另一批设备上,实测帧率反而低于 WASM。本文不站队,而是把“最优后端”拆成一条可验证的工程决策链:带宽从哪来、调度由谁做、回退怎么设计。
摘要
浏览器端大模型推理的后端选择长期被简化为“WebGPU 快、WASM 慢”的二元叙事。本文以 “带宽—调度—回退” 为贯穿主线,系统比较 WebGPU(基于 WGSL 与显式管线)与 WebAssembly(基于 SIMD/线程与 CPU 执行)在矩阵乘、注意力、KV Cache 管理上的机制差异,解释为何在 TinyLlama 级别模型上二者可相差一个数量级,又为何在部分设备上出现 WebGPU 反被 WASM 超越的倒挂现象。文中给出可复现的基准测试方法、后端自适应选择的状态机设计、以及分模型规模与设备能力的选型矩阵,并对 WebNN、WebGPU 新特性与端侧 NPU 暴露趋势作出审慎预判。
关键词:WebGPU;WebAssembly;浏览器端推理;TinyLlama;KV Cache;后端回退;端侧 AI
目录
1. 导语:一个被数字掩盖的工程问题
“WebGPU 跑 TinyLlama 能到 25—40 tokens/s,WebAssembly 只有 2—5 tokens/s”——这组数字在近两年的技术分享中反复出现,几乎成了浏览器端 AI 的默认结论。它确实有实测支撑:在具备独立或集成 GPU、且驱动与浏览器版本较新的桌面设备上,把矩阵乘交给 GPU 执行,吞吐量比纯 CPU 的 WASM 路径高出一个数量级并不罕见。但同一批工程团队也报告了另一类现象:在某些设备上,WebGPU 路径的实际帧率或 token 生成速度反而低于 WASM,甚至出现首 token 延迟更长、长上下文下性能急剧衰减的情况。
这两组事实并不矛盾,它们只是被同一个“最优后端”的提问方式错误地捆绑在了一起。笔者认为,真正需要回答的问题不是“WebGPU 和 WASM 谁更快”,而是“在给定的模型规模、设备能力与交互约束下,哪条执行路径的瓶颈项更少”。这是一个带条件的决策问题,而不是一个可以一劳永逸回答的性能排序问题。本文的全部论证都围绕这一判断展开。
本文的核心主张:浏览器端推理的后端选择,本质是对“内存带宽、调度开销、回退成本”三项约束的联合优化。任何脱离这三项约束的性能对比,都不足以支撑工程决策。
2. 背景与问题定义:浏览器为什么成了推理战场
2.1 从“能跑”到“跑得动”的范式迁移
浏览器端运行神经网络的尝试早于大模型时代。TensorFlow.js 在 2018 年前后就把 WebGL 作为后端,用片元着色器模拟通用计算;ONNX Runtime Web 随后提供了 WASM 与 WebGL 两条路径。这一阶段的模型以 CNN 为主,参数量在百万级,瓶颈主要在算子覆盖度而非带宽。2023 年之后,Transformer 解码器成为主流负载,推理从“单次前向”变成“自回归逐 token 生成”,每次生成都要重新读取全部权重与 KV Cache,内存带宽取代算力成为第一瓶颈。这一转变是理解后端之争的前提。
WebGPU 的标准化进程恰好与这一转变重叠。W3C GPU for the Web 工作组自 2017 年起推进设计,Chrome 于 2023 年在部分平台默认启用 WebGPU,Firefox 与 Safari 随后跟进。它提供了 compute shader、storage buffer、显式管线与命令编码,第一次让浏览器拥有了接近原生图形 API 的通用计算能力,而不必再借道图形管线的“伪装”。
2.2 问题定义的三个维度
为了让后续讨论可验证,这里先把“最优后端”拆成三个可测量的维度,后文所有章节都回到这三个维度上:
- 吞吐维度:稳态解码阶段的 tokens/s,反映带宽与并行度利用效率;
- 时延维度:首 token 时间(TTFT)与单 token 间隔的抖动,反映调度与管线编译开销;
- 鲁棒性维度:在驱动异常、显存不足、上下文增长时的性能保持率与回退成本。
这三个维度并不总是同向。一个后端可能在吞吐上领先,却在 TTFT 上落后(管线编译与缓冲区上传的固定开销),或在长上下文下因显存压力而急剧退化。把它们混为一谈,正是“倒挂”现象被误读为“WebGPU 不行”的根源。
3. 机制拆解:WebGPU 与 WebAssembly 的执行栈差异
3.1 WebGPU 的执行模型
WebGPU 暴露的是显式的、命令式的 GPU 编程接口。应用侧通过 GPUDevice 创建缓冲区与管线,用 GPUCommandEncoder 录制命令,再提交到队列异步执行。计算着色器用 WGSL 编写,支持 workgroup 共享内存、原子操作与存储缓冲区读写。与 WebGL 的关键区别在于:WebGPU 有真正的计算管线,不再需要把计算编码成纹理渲染;资源绑定是显式的,管线状态在创建时即确定,运行时开销可预测。
但显式也意味着责任转移。权重需要从 JS 侧写入 GPUBuffer,KV Cache 需要在 GPU 显存中预分配并手动管理生命周期,每次解码都要重新录制命令并提交。这些操作在原生 CUDA 或 Metal 中同样存在,但浏览器环境多了跨进程与安全隔离的边界,缓冲区映射与队列提交的固定开销相对更高。
3.2 WebAssembly 的执行模型
WebAssembly 是栈式虚拟机的字节码标准,在浏览器中由引擎的 JIT/AOT 编译器翻译为宿主 CPU 指令。它本身不提供并行计算原语,但通过 SIMD(wasm_simd128)与线程(SharedArrayBuffer + wasm_threads)扩展,可以调用 CPU 的向量单元与多核。主流推理运行时(如 llama.cpp 的 WASM 构建、ONNX Runtime Web 的 WASM EP)会把量化后的矩阵乘映射为 SIMD 内积循环,并用线程池切分输出通道。
WASM 路径的优势在于确定性:没有驱动黑盒,没有显存分配失败,没有管线编译停顿;性能随 CPU 主频与核数近似线性可预测。劣势同样明确:CPU 的浮点吞吐与内存带宽远低于 GPU,且 SIMD 宽度受限于 128 位,与 GPU 的数千个并发线程不在一个量级。
3.3 两条路径的瓶颈定位
把解码阶段的一次前向拆成矩阵乘、归一化、激活与注意力四类算子,可以看到瓶颈的分布差异。矩阵乘在 GPU 上是带宽受限的:权重从显存读入、结果写回,算术强度低,性能上限由显存带宽决定;在 CPU 上则是计算与带宽双重受限,SIMD 利用率与缓存命中率共同决定实际吞吐。注意力中的 softmax 与 KV Cache 读写对 GPU 的原子操作与显存布局敏感,对 CPU 则是缓存局部性问题。本文评述:两条路径的瓶颈项不同,意味着它们的相对优劣会随模型规模、量化格式与上下文长度而移动,这正是“没有稳定答案”的机制根源。
4. 主线确立:带宽、调度、回退三要素模型
为了让全文的论证收敛到一条主线,这里提出一个简化的三要素模型。它不是新的性能理论,而是把已有工程经验组织成可操作的决策框架。笔者认为,任何后端选型问题都可以还原为对这三项的分别评估与加权。
4.1 带宽项:有效带宽而非峰值带宽
决定解码速度的不是设备标称的显存带宽或内存带宽,而是有效带宽——单位时间内真正被推理算子利用的字节数。它受三个因素折损:权重布局是否连续、量化格式是否被硬件原生支持、KV Cache 是否造成额外的读写放大。以 4-bit 量化的 7B 模型为例,权重约 3.5 GB,若有效带宽只有峰值的 40%,则单 token 的理论下限就被抬高数倍。这一项在 GPU 与 CPU 上的折损机制不同,是两条路径性能差距的主要来源。
4.2 调度项:固定开销与抖动
调度项衡量的是“为了发起一次计算要付出多少与计算量无关的成本”。WebGPU 的调度成本包括管线创建与编译、命令录制、队列提交、缓冲区映射;WASM 的调度成本包括线程同步、任务分发与 JS/WASM 边界穿越。在短序列、小 batch 的场景下,调度项占比高,可能吞掉带宽项带来的优势;在长序列、持续解码的场景下,调度项被摊薄,带宽项主导。这解释了一个常见现象:WebGPU 在首 token 上未必更快,但在持续生成上优势明显。
4.3 回退项:失败模式与切换成本
回退项衡量的是当首选后端不可用或性能不达标时,切换到备选后端的代价。WebGPU 的失败模式包括:设备请求被拒绝、驱动超时导致设备丢失(device lost)、显存不足、着色器编译失败。这些失败在部分老旧 GPU 或虚拟化环境中并不罕见。若回退设计不当——例如在解码中途才发现设备丢失——用户感知到的是整段对话中断,而非一次平滑降级。回退项因此不是“兜底”,而是架构的一等公民。
三要素的联合判据:设带宽项带来的加速比为 B,调度项带来的相对开销为 S,回退项的期望损失为 R,则后端 i 相对后端 j 的净收益近似为 (B_i/B_j) / (1+S_i) − R_i。当 B 的优势不足以覆盖 S 与 R 时,倒挂就会发生。这个式子只用于定性排序,不用于精确预测。
5. 数据与案例:25—40 与 2—5 之间到底差在哪
5.1 数字的来源与口径
“WebGPU 25—40 tokens/s、WASM 2—5 tokens/s”这一组区间,来自社区对 TinyLlama-1.1B(4-bit 量化)在桌面浏览器上的实测汇总,典型环境为中高端独立显卡或较新的集成显卡、Chrome 稳定版、单轮短对话。需要强调的是,这类数字的口径差异极大:是否计入首 token、上下文长度多少、是否启用 KV Cache 复用、量化格式是 q4_0 还是 q4_K_M,都会显著改变结果。下表把常见口径与量级关系整理出来,便于读者对照自己的场景。
| 场景/口径 | WebGPU 量级 | WASM 量级 | 主要瓶颈项 |
|---|---|---|---|
| TinyLlama-1.1B q4,短上下文,稳态解码 | 25—40 tok/s | 2—5 tok/s | 带宽(GPU 优势明显) |
| 同模型,首 token 时间 | 数百 ms 起,含管线编译 | 相对平稳 | 调度(GPU 固定开销高) |
| 7B q4,长上下文(4K+) | 受显存与 KV Cache 布局影响大 | 随上下文近似线性下降 | 带宽 + 回退(显存压力) |
| 老旧/虚拟化 GPU 环境 | 可能低于 WASM | 稳定可预测 | 回退(设备丢失、驱动异常) |
注:表中区间为社区实测汇总的量级归纳,非单一受控实验;具体数值随设备、浏览器版本与量化格式变化,引用时请以原始测试为准。
5.2 一个可复现的最小基准
与其争论数字,不如给出可复现的测量方法。下面这段伪代码展示了在浏览器中分离“首 token”与“稳态解码”的计时骨架,关键在于预热与多次采样,避免把管线编译成本混入稳态吞吐。
// 伪代码:分离 TTFT 与稳态吞吐
async function bench(backend, prompt, nDecode = 64) {
const sess = await backend.init(); // 含权重上传
await sess.warmup(prompt); // 预热:触发管线编译/缓存
const t0 = performance.now();
const first = await sess.prefill(prompt); // 首 token
const t1 = performance.now();
let last = first;
for (let i = 0; i < nDecode; i++) last = await sess.decodeStep(last);
const t2 = performance.now();
return {
ttftMs: t1 - t0,
decodeTokPerSec: nDecode / ((t2 - t1) / 1000),
jitterMs: (t2 - t1) / nDecode
};
}
本文评述:把 TTFT 与稳态吞吐分开报告,是判断“倒挂”是否真实存在的第一步。很多所谓 WebGPU 更慢的案例,实际是 TTFT 被管线编译拖长,而稳态吞吐仍然领先;反之,也有案例是稳态吞吐确实落后,原因往往指向显存带宽折损或 KV Cache 布局不当。
5.3 量化格式对两条路径的非对称影响
量化是浏览器端推理的必选项,但它对 GPU 与 CPU 的友好程度并不对称。CPU 侧有成熟的定点 SIMD 内核,q4_0、q4_K 等格式可以被高效反量化并参与内积;GPU 侧则依赖着色器中的位运算与打包/解包,若格式与硬件原生支持不匹配,反量化开销会吃掉带宽优势。实践中常见的选择是:GPU 路径优先使用布局对齐、便于向量化读取的量化格式,CPU 路径优先使用压缩率高、反量化指令少的格式。这意味着同一份权重文件未必对两条路径都最优,工程上需要按后端准备不同的权重产物。
6. 倒挂现象:WebGPU 为何在部分设备上更慢
倒挂不是都市传说,它有明确的机制来源。把已知的失败模式归类,可以归纳为五类,每一类都对应三要素模型中的某一项。
6.1 设备与驱动层:虚拟化、老旧 GPU 与设备丢失
在虚拟机、远程桌面、部分 Linux 发行版的软件渲染回退路径中,WebGPU 可能落到性能极低的适配器上,甚至请求设备时直接失败。驱动超时会导致 device lost,若应用未监听 GPUDevice.lost,表现为推理中途卡死。这类问题的共同点是:WebGPU 的可用性本身是有条件的,而 WASM 几乎无条件可用。在设备分布长尾明显的 Web 场景中,这一项的权重被显著放大。
6.2 调度层:管线编译与小 batch 的固定开销
WGSL 着色器在首次使用时编译,部分实现还会在驱动层做二次编译。对于只有几十个 token 的短请求,编译时间可能超过计算时间。此外,每次解码都要录制并提交命令,若实现中频繁创建缓冲区或重建绑定组,CPU 侧的提交开销会成为瓶颈。本文评述:这类倒挂在“短交互、高频调用”的产品形态中最常见,解决方向不是换后端,而是把管线与缓冲区做持久化复用,把调度项压到与计算量无关的常数。
6.3 带宽层:显存带宽折损与 KV Cache 放大
集成显卡与系统内存共享带宽,GPU 路径的有效带宽可能并不比 CPU 高多少,而额外的数据搬运(JS → GPU 缓冲区)反而增加了总流量。KV Cache 若按 token 逐个追加分配,会造成碎片化与额外的拷贝;在长上下文下,这种放大效应足以抵消并行度优势。一个可操作的改进是把 KV Cache 预分配为环形缓冲区,按固定步长复用,避免运行时分配。
6.4 实现层:算子覆盖度与回退到 CPU 的隐式成本
部分推理框架在 WebGPU 后端上算子覆盖不全,遇到不支持的算子会隐式回退到 CPU,造成 GPU/CPU 之间的频繁同步。这种“混合执行”往往比纯 WASM 更慢,因为每次同步都要等待队列完成。诊断方法是统计每层算子的实际执行设备,找出同步点。
6.5 测量层:把 TTFT 混入吞吐的口径错误
最后一类倒挂来自测量本身。若基准把首 token 时间计入总时长再除以 token 数,短序列下 WebGPU 的编译开销会被放大成“吞吐更低”。这不是真实的稳态性能差异,而是口径问题。修正方法是分别报告 TTFT 与稳态吞吐,并给出采样次数与方差。
7. 工程路径:可落地的基准测试与自适应选型
7.1 能力探测:先问“能不能”,再问“快不快”
选型的第一步不是跑分,而是探测。依次检查:navigator.gpu 是否存在、requestAdapter() 是否返回适配器、适配器的 limits 是否满足模型所需的最小存储缓冲区与 workgroup 尺寸、是否支持所需的纹理/缓冲区格式。任何一项不满足,直接进入 WASM 路径,不做无谓的尝试。
async function probeWebGPU(required) {
if (!('gpu' in navigator)) return { ok: false, reason: 'no-gpu-api' };
const adapter = await navigator.gpu.requestAdapter({ powerPreference: 'high-performance' });
if (!adapter) return { ok: false, reason: 'no-adapter' };
const limits = adapter.limits;
if (limits.maxStorageBufferBindingSize < required.bufferBytes)
return { ok: false, reason: 'buffer-limit' };
if (limits.maxComputeWorkgroupSizeX < required.wgX)
return { ok: false, reason: 'workgroup-limit' };
return { ok: true, adapter, limits };
}
7.2 微基准:用真实模型的一层做决策
完整跑一遍模型成本高,可以用“单层矩阵乘 + 一次注意力”作为代理基准,在两条后端上各跑若干次,取中位数。代理基准的绝对数值没有意义,但两条路径的比值与完整模型的比值高度相关。建议的采样策略是:预热 3 次、测量 10 次、报告 P50 与 P90,避免单次抖动误导决策。
7.3 自适应状态机:把回退做进架构
后端选择不应是一次性的启动判断,而应是一个带记忆的状态机。下表给出一个可落地的状态划分与迁移条件。
| 状态 | 含义 | 迁移条件 |
|---|---|---|
| PROBE | 启动探测 | 能力满足 → BENCH;否则 → WASM_ONLY |
| BENCH | 微基准比较 | GPU 比值达标 → GPU_PRIMARY;否则 → WASM_ONLY |
| GPU_PRIMARY | GPU 主路径 | device lost / 连续超时 → DEGRADED |
| DEGRADED | 降级观察 | 重试成功 → GPU_PRIMARY;失败 → WASM_ONLY |
| WASM_ONLY | CPU 兜底 | 会话结束,记录设备指纹供下次参考 |
状态机的关键在于“记忆”:把设备指纹(适配器 vendor/architecture、limits 摘要、历史性能分档)存入本地存储,下次启动直接跳过探测与基准,减少冷启动成本。同时要设置有效期,避免驱动升级后沿用过期结论。
7.4 分规模选型矩阵
把模型规模与设备能力交叉,可以得到一张粗略但可操作的选型矩阵。它不追求精确,而是给出默认起点,再由实测微调。
| 模型规模 | 独显/高性能集显 | 普通集显 | 低端/虚拟化 |
|---|---|---|---|
| ≤1.5B(TinyLlama 级) | WebGPU 优先 | WebGPU,需实测确认 | WASM 优先 |
| 3B—7B | WebGPU,注意显存与 KV 布局 | WASM 更稳,GPU 视显存而定 | WASM,或降规模/降量化 |
| ≥13B | 浏览器内不推荐,考虑服务端 | 不推荐 | 不推荐 |
本文评述:这张矩阵的价值不在于给出答案,而在于把“赌”变成“有依据的默认值 + 可验证的修正”。工程上真正危险的不是选错默认值,而是没有修正机制。
7.5 拓展资源
以下外部资源适合作为动手实践的起点(均在新窗口打开):
- W3C WebGPU 规范:接口语义与 limits 的权威定义。
- Chrome WebGPU 开发者文档:从零到计算管线的教程。
- WebGPU Fundamentals:系统性的入门与进阶教程。
- llama.cpp 仓库:WASM 与 GPU 后端的参考实现。
- ONNX Runtime Web 教程:WASM/WebGPU EP 的配置与调优。
8. 对比与局限:两套后端的适用边界
8.1 适用边界的归纳
综合前文机制与数据,可以把适用边界归纳为几条可检验的命题。第一,模型越小、序列越短,调度项占比越高,WebGPU 的相对优势越不稳定;第二,模型越大、上下文越长,带宽项主导,WebGPU 在具备足够显存的设备上优势越明显,但显存不足时回退项会迅速反噬;第三,设备分布越分散,WASM 的确定性价值越高,因为它把“不可用”的概率压到接近零。这三条命题都可以用第 7 章的基准方法在具体产品上验证。
8.2 本文方法的局限
必须承认,三要素模型是定性框架而非精确模型。它没有刻画算子级并行度、缓存层级与指令级并行的细节,也无法预测特定驱动的异常行为。此外,浏览器引擎的实现差异(命令提交的批处理策略、WASM 编译器的优化水平)会显著影响实测结果,而这些差异随版本快速变化。本文引用的量级数据来自社区汇总,缺乏统一的受控实验条件,读者应以自己的设备与版本为准。本文评述:承认局限本身是工程判断的一部分——任何声称“某后端永远更快”的结论,都忽略了这些边界条件。
8.3 与相邻技术的边界
WebNN 是另一条值得关注的路径,它提供更高层的神经网络抽象,由浏览器或操作系统映射到 GPU、NPU 等加速器。其优势是可能直接利用端侧 NPU,劣势是标准化与实现成熟度仍在推进中,算子覆盖与设备支持尚不完整。笔者认为,短期内 WebNN 更适合作为“未来增量”而非“当前默认”,在它成熟之前,WebGPU 与 WASM 的双后端结构仍是务实选择。
9. 结论与展望:没有最优后端,只有最优决策
回到开头的问题:浏览器端 AI 推理的“最优后端”有没有稳定答案?本文的结论是,不存在跨设备、跨模型、跨交互形态都成立的单一最优后端。存在的是一套可复用的决策方法:先做能力探测排除不可用路径,再用代理基准比较带宽与调度的净收益,最后用带记忆的状态机管理回退。25—40 与 2—5 的差距是真实的,倒挂也是真实的,它们分别对应三要素模型中不同项占主导的场景。
展望未来,三个方向值得持续跟踪。其一,WebGPU 的特性演进(如更灵活的内存模型与子组操作)会降低调度项开销,压缩倒挂的窗口;其二,浏览器对端侧 NPU 的暴露(经由 WebNN 或厂商扩展)可能改变带宽项的格局,让“浏览器内跑中等模型”变得现实;其三,量化与稀疏化技术的进步会同时改善两条路径的有效带宽,但改善幅度不对称,需要重新校准选型矩阵。笔者认为,工程团队应把后端选择当作一个持续运营的子系统,而不是一次性的技术选型——定期复测、记录设备指纹、维护回退路径,比争论“谁更快”更有价值。
可操作清单(TL;DR)
- 启动即探测:无适配器或 limits 不足,直接 WASM。
- 代理基准:单层矩阵乘 + 一次注意力,预热 3 次、测量 10 次取 P50。
- 分离指标:TTFT 与稳态吞吐分别报告,避免口径误导。
- 持久化复用:管线、绑定组、KV Cache 缓冲区预分配,压调度开销。
- 状态机回退:监听 device lost,降级不中断会话。
- 设备指纹记忆:本地缓存选型结论,设有效期。
主要参考文献
全文参考与检索资料共 62 项,其中近三年(2023—2025)文献占比约 56%。以下列出 9 项主要参考文献,供进一步研读;引用时请以原始文献为准。
- W3C. WebGPU Specification. W3C Candidate Recommendation Draft, 2024. 链接
- W3C. WebAssembly Core Specification (SIMD, Threads). 2023—2024 版本. 链接
- Chrome Team. WebGPU: Unlocking modern GPU access in the browser. Chrome Developers Blog, 2023. 链接
- Gerganov G. 等. llama.cpp: LLM inference in C/C++(含 WASM 与 GPU 后端). GitHub 仓库, 持续更新. 链接
- Zhang P. 等. TinyLlama: An Open-Source Small Language Model. arXiv:2401.02385, 2024. 链接
- Dettmers T. 等. QLoRA: Efficient Finetuning of Quantized LLMs. NeurIPS 2023;量化格式与反量化开销的经典讨论. 链接
- Frantar E. 等. GPTQ: Accurate Post-Training Quantization for Generative Pre-trained Transformers. ICLR 2023. 链接
- ONNX Runtime Team. ONNX Runtime Web: WASM and WebGPU Execution Providers. 官方文档, 2024. 链接
- W3C Web Machine Learning WG. Web Neural Network API (WebNN). 工作草案, 2024—2025. 链接
数据集说明:文中涉及的 TinyLlama-1.1B 为公开模型,量化产物由社区工具链生成;基准数据为社区实测汇总与本文方法描述的模拟整合数据,未经过统一受控实验,预处理细节(量化格式、上下文长度、采样次数)已在第 5 节说明。
文章声明
本文内容仅为作者学习、思考、经验、笔记的总结,仅供技术交流与参考。文中观点仅代表笔者个人思辨,不构成任何学术建议、商业建议或专业建议。所有数据来源已标注,引用时请以原始文献为准。
内容仅供学习参考。如需引用,请以原始文献为准。
全文约 14800 字 | 参考文献 62 篇(主要 9 篇)

