精选Hugging Face Blog新闻
Hugging Face 发布 200 多个 WebGPU 内核,加速本地 AI 推理
Hugging Face 推出了 @huggingface/kernels 库,包含 200 多个 WebGPU 内核,旨在提升浏览器端 AI 推理性能。该库为开发者提供了优化的计算内核,可加速本地模型运行,减少延迟,推动端侧 AI 应用发展。
今天,我们发布了这项工作的第一层:@huggingface/kernels,一个用于从 Hugging Face Hub 加载并运行优化后的 WebGPU 内核的精简库,同时附带一个包含 207 个内核的初始集合,位于 huggingface.co/webgpu-kernels。
该集合涵盖了广泛机器学习架构和工作负载中使用的各类运算。更重要的是,每个内核都以完整、带版本号的包形式发布:其接口、着色器模板、正确性测试用例、基准测试用例和使用说明全部集中存放在 Hub 上。
我们还推出了 Fleet,一套浏览器内的 GPU 基准测试与测试套件,可在你的硬件上运行并评分这些内核。除了为你自己的机器提供结果之外,Fleet 还为社区提供了一种途径,让我们能够从传统测试实验室无法覆盖的设备上贡献性能和正确性证据。在你同意的前提下,每次运行都会添加私有证据,帮助我们发现问题(错误结果、病态慢速案例等)、改进内核变体,并在真实硬件上做出更优的优化决策。
TL;DR
- 207 个 WebGPU 内核,以独立仓库形式发布在 webgpu-kernels 组织中,采用 Apache-2.0 许可证。
- 一个 JavaScript 加载器 @huggingface/kernels,可直接从 Hub 下载、准备并运行内核。
- 每个内核都有明确的契约和可复现的证据,包括清单、正确性测试、基准测试用例和 WGSL 着色器模板。
- Fleet,一套基于浏览器的基准测试工具,通过众包方式收集真实 GPU 上的正确性和性能证据,帮助我们改进内核及其变体。
为什么从内核开始?
在浏览器中运行的模型最终会变成一系列 GPU 运算:矩阵乘法、归一化、卷积、注意力原语、量化运算、数据布局变换等等。WebGPU 通过可移植的 API 让这些运算在现代浏览器中可用,而 WGSL 则为执行这些运算的着色器提供了通用语言。
然而,可移植性并不自动意味着高性能。两个着色器可以实现相同的运算并产生相同的输出,但在不同加速器上的表现可能完全不同。工作组大小、内存访问模式、向量化、数据类型和融合策略都会影响性能。最佳选择还可能随输入形状、设备、浏览器和可用的 WebGPU 特性而变化。
这就是为什么内核构成了快速浏览器推理的基础层。更高级别的运行时只能与其分发的运算一样高效。通过让这些运算可单独发现、可测试、可基准测试并带版本管理,我们可以在保持上层稳定契约的同时,独立地改进这一基础层。
一个内核仓库,而不仅仅是一个着色器
集合中的每个内核都有自己的仓库和内核卡片。卡片记录了运算的语义、输入、输出、属性、支持的数据类型、源文件,以及一个可直接运行的 @huggingface/kernels 示例。
例如,ai.onnx.Add 实现了带多方向广播的逐元素加法。它是神经网络中最简单的运算之一,从残差连接到添加偏置都随处可见。其卡片记录了两个输入、广播后的输出形状、支持的数据类型,以及针对不同形状和设备可用的变体。

卡片背后,仓库包含了理解和评估实现所需的工件:
manifest.json 是操作契约的权威来源。它定义了输入、输出、属性、类型约束和形状推导规则。 - metadata.json 记录内核标识符、摘要和来源信息。 - test.json 包含正确性测试用例,因此可以根据预期行为检查实现是否正确。 - bench.json 包含基准测试和调优用例,代表用于评估内核的工作负载。 - *.wgsl.jinja 文件包含参数化的 WGSL 实现,用于为特定请求和设备生成着色器。
这种结构将着色器转变为可复用的软件工件。接口无需阅读 WGSL 即可检查,正确性和性能测试用例随实现一起分发,已发布的版本可以显式加载,而不依赖于无版本的 URL。我们的内核还可以作为参考实现,供开发人员构建自定义 WebGPU 内核或将这些操作集成到他们自己的运行时中。
从 Hub 加载内核
从 npm 安装该包:
npm install @huggingface/kernels@preview运行这些内核需要支持 WebGPU 的浏览器。WebGPU 的可用性取决于浏览器、操作系统、GPU 和驱动程序。你可以通过 JavaScript 中的 "gpu" in navigator 来检查。
@huggingface/kernels 提供了内核仓库与你的应用程序之间的桥梁。使用 Hub 仓库 ID 和契约版本调用 getKernel,然后使用类型化的输入数据和张量形状调用返回的函数。以下是一个简单的偏置加法示例:
import { getKernel } from "@huggingface/kernels";
const add = await getKernel("webgpu-kernels/ai.onnx.Add", { version: 1 });
const { c } = await add({
a: {
data: new Float32Array([1, 2, 3, 4, 5, 6]),
shape: [2, 3],
},
b: {
data: new Float32Array([10, 20, 30]),
shape: [3],
},
});第二个输入沿第一个维度进行广播,生成形状为 [2, 3] 的输出。加载器根据 manifest 契约和输入推导出输出形状和逻辑数据类型,然后自动分配 c。
对六个浮点数进行加法是刻意设计的最小演示。在这个规模下,GPU 往返的开销远大于计算本身。关键在于调用模式:对于优化内核真正发挥价值的重型操作(如矩阵乘法 ai.onnx.MatMul),调用方式完全相同。只有仓库 ID 和输入发生变化。
即使是这个基础操作也说明了内核为何需要变体。等形状加法可以使用直接的向量化路径,而广播输入则需要不同的索引逻辑。已发布的 Add 内核包含等形状、向量化广播、标量处理和通用广播等变体。运行时可以在不改变面向应用程序的 API 的情况下,选择适合当前调用和设备的实现。
version: 1 选项选择已发布内核契约的第 1 版。它与 ONNX opset、算子的 since_version 或模型修订版本是分开的。将这些概念分开,可以让应用程序依赖于稳定的 JavaScript 面向契约,而内核实现在其后不断演进。
内核有多快?
那么,优化内核到底能带来多大的差异?我们将我们的内核集合与 ORT WebGPU 在 Apple M4 GPU 上进行了对比测试,使用的是 ONNX Runtime Web 1.30.0-dev.20260826-b1f76d586a。我们从全部 207 个操作中的 1,756 个测试用例开始,保留了双方输出匹配且计时可靠的 809 个用例。
在这些对比中,我们的内核在几何均值上快 2.57 倍,中位数上快 1.90 倍,其中 629 次胜出,176 次落后,4 次平局。以下是四个常见操作的详细对比:
| 运算 | 对比用例数 | 我们的 WebGPU Kernel | ORT WebGPU | 加速比 |
|---|---|---|---|---|
| Add | 5 | 0.064 ms | 0.227 ms | 3.52x |
| MatMul | 29 | 0.115 ms | 0.131 ms | 1.14x |
| Softmax | 12 | 0.114 ms | 0.240 ms | 2.11x |
| LayerNormalization | 6 | 0.061 ms | 0.135 ms | 2.22x |
个别场景的收益要大得多。一个特别困难的双线性 Einsum 用例(i,ij,j,规模 4096),我们的 kernel 运行耗时 0.136 ms,而 ORT WebGPU 耗时 1,396 ms:加速超过 10,000 倍。对 [256, 4096] 的行方向 CumSum 运算,我们的耗时 0.016 ms,对比 ORT WebGPU 的 4.784 ms,加速 301 倍。这些属于特殊情况,并非你在所有场景中都能预期的加速幅度,但它们充分说明,当通用实现落入慢路径时,专用 kernel 能带来多大的帮助。
我们只统计 GPU 本身的计算耗时,不包含加载 kernel、创建会话、上传输入、编译着色器以及回读输出等准备工作。极短的工作负载天然难以精确测量,小规模用例也可能受益于 GPU 缓存,因此这些数字更适合作为有参考价值的对比,而非对每个应用的性能承诺。
此外,这些结果针对的是单个运算,而非完整模型。实际性能会因 GPU 和浏览器而异,这正是 Fleet 在构建更全面图景时如此重要的原因。
我们也在与 ONNX Runtime 团队合作,将这些改进上游化,让更广泛的 ONNX Runtime Web 生态也能受益。
从单台设备到设备集群
WebGPU 性能在不同 GPU、浏览器和驱动之间差异很大,因此单台机器的结果只能反映部分情况。Fleet 让任何人都能在浏览器中运行正确性和性能检查,观察 kernel 在其硬件上的表现。
在用户同意的前提下,每次运行都会匿名贡献证据,帮助我们识别特定设备的故障、比较不同实现变体,并改进选择规则。目标很简单:借助广泛而真实的覆盖,让 kernel 对所有人都更快、更可靠。
为 WebAI 构建共享基础
最初的 207 个 kernel 只是起点,而非终点。将 kernel 独立发布到 Hub 上,为我们提供了一个统一的场所来检查契约、比较实现、复现正确性检查并改进性能,而无需将每个着色器直接嵌入到每个运行时中。
该集合也是 Hub 更广泛 kernel 生态的一部分:在 Kernels 页面上,WebGPU kernels 与 CUDA、ROCm、Metal 及其他平台的 kernels 并列展示,可以像 Hub 上的任何其他工件一样进行筛选、排序和探索。

这些组件相互支撑:
- Kernel 仓库定义了透明、带版本管理的运算契约。
- @huggingface/kernels 让这些运算可以从 JavaScript 中直接加载和运行。
- Fleet 在远超传统基准测试实验室所能覆盖的设备范围内,众包真实世界的证据。
- 每一次贡献的运行都可能揭示故障、指导调优、改进变体选择,并帮助验证未来的 kernel 版本。
这是我们浏览器推理栈下一步发展的底层基础。我们期待将这些 kernel 与更高级的模型工具连接起来,持续扩展运算覆盖范围,让快速本地推理在整个 WebAI 生态中更易用。
欢迎探索 WebGPU kernel 集合,试用 @huggingface/kernels,并加入 Fleet,从你的设备贡献证据,帮助我们让这些 kernel 对所有人都更好。
译文已达到本站中文翻译的字数上限,剩余内容请查看原文。