Hugging Face 在 9 月 1 日放出 @huggingface/kernels,一个 JavaScript 加载器库,用来从 Hub 上下载、准备并运行优化过的 WebGPU 内核。随之上线的还有 207 个已经调好的 GPU 算子,覆盖矩阵乘法、归一化、卷积、注意力原语、量化运算和数据布局转换,横跨多种机器学习架构。协议是 Apache-2.0。
组织方式是这套东西最不寻常的地方:每个内核作为一个独立仓库发布,各自带着接口定义、着色器模板、正确性测试和基准数据。放到 Hub 上之后,一个算子和一个模型在版本管理、下载和引用上走同一套机制。
809 组对照
性能这块给的是和 ORT WebGPU 1.30.0-dev 的横向比较,样本是 809 个测试用例:几何平均加速 2.57 倍,中位数加速 1.90 倍,胜负记录 629 胜 176 负 4 平。拆到单个算子,Add 快 3.52 倍,Softmax 快 2.11 倍,LayerNormalization 快 2.22 倍。
粗算一下胜率是 78%。几何平均 2.57 倍明显高于中位数 1.90 倍,说明加速幅度的分布往右偏——少数算子快得特别多,把平均值拉了上去。真实负载能感受到的提速,大概率更接近中位数那一档,而不是宣传里最亮眼的那个数。这不影响结论的方向,只是把预期摆回原位。
配套还有一个叫 Fleet 的浏览器内基准工具,思路是众包:谁的机器跑过,性能和正确性的证据就回流一份。WebGPU 的硬件碎片化程度比服务端 CUDA 高出一大截,集成显卡、独立显卡、移动 GPU、不同浏览器实现之间的表现差异很大,靠实验室里那几台机器测不出全貌。把测试摊给用户是务实的办法。
为什么卡在算子这层
浏览器端跑模型的吸引力一直很明确:计算发生在用户设备上,服务端不出算力钱,数据也不用离开本地。落地卡住的原因通常不在模型格式,也不在推理框架,而在下面那层算子——同一个 Softmax,写得好和写得一般,差出来的是能不能实时的区别。
以往这层只能跟着推理运行时整体升级。想换一个更快的注意力实现,通常要等框架发新版本。拆成独立仓库之后,算子变成可以单独替换、单独回滚、单独提交改进的单元。给某个模型换一个针对特定 GPU 优化过的矩阵乘法内核,理论上不用动其余任何代码。
调用方式也压得很短,拿到内核对象直接当函数用:
const add = await getKernel("webgpu-kernels/ai.onnx.Add", { version: 1 });
运行前提是浏览器支持 WebGPU,检测方法就一句 "gpu" in navigator。
对端侧工具的账
这轮更新的受益方很具体:做纯浏览器图片处理、本地转写、离线翻译、隐私敏感型工具的团队。这类产品的商业模型建立在服务器只发静态文件、不承担计算成本上,能塞进浏览器的模型规模,直接由算子性能决定。算子整体快一倍,可用模型的参数量上限就往上挪一档,原本要等三秒的操作能压进一秒。
保守的部分也要讲清楚。基准比较的对象是 ORT WebGPU 的一个 dev 版本,对手也在迭代;207 个算子听着多,但覆盖的是常见操作,遇到冷门结构仍然要自己写。WebGPU 在各浏览器上的支持度虽然已经铺开,移动端的实现质量参差不齐,跨设备表现需要自己拿 Fleet 之类的工具摸一遍。
把算子做成可寻址、可版本化、可众包验证的资源,比单纯快一倍这件事影响更长远。模型权重早就是这么流转的,基础设施代码跟上来,只是时间问题。
参考来源:Hugging Face 官方博客、CocoLoop、Hugging Face Hub 仓库;207 个内核数量、809 个测试用例、几何平均 2.57 倍与中位数 1.90 倍、629 胜 176 负 4 平的胜负记录及单算子倍数,均按官方公告核对,胜率与分布偏斜部分为编辑粗算。