Hugging Face 发布 @huggingface/kernels,提供 207 个 WebGPU 内核用于浏览器本地 AI 推理

Hugging Face:Blog(RSS)·2026-09-01 08:00·15小时前
AI 导读

Hugging Face WebAI 团队发布 @huggingface/kernels 库及 207 个以独立仓库形式托管在 Hub 上的 WebGPU 内核(Apache-2.0),每个内核带 manifest、正确性测试、基准用例和 WGSL 着色器模板。

Hugging Face:Blog(RSS)
精选
62AI 编辑部评分,满分 100

Hugging Face 发布 @huggingface/kernels,提供 207 个 WebGPU 内核用于浏览器本地 AI 推理

2026-09-01 08:00· 15小时前
AI 导读

Hugging Face WebAI 团队发布 @huggingface/kernels 库及 207 个以独立仓库形式托管在 Hub 上的 WebGPU 内核(Apache-2.0),每个内核带 manifest、正确性测试、基准用例和 WGSL 着色器模板。

推荐理由

原文给出与 ORT WebGPU 的对比数据和开源加载方式,读者可据此评估浏览器本地推理的可行路径。

正文 · AI 翻译

在 Hugging Face 的 WebAI 团队,我们最大的目标之一就是让浏览器端推理尽可能快速且用户友好。要实现这一目标,需要多层努力:模型需要适合浏览器的表示形式,运行时需要构建高效的执行计划,而技术栈底层的各个 GPU 操作则需要充分利用各种不同的设备和浏览器实现。今天,我们发布了这一努力的第一层成果:@huggingface/kernels,这是一个用于从 Hugging Face Hub 加载和运行优化 WebGPU 内核的精简库,同时还在 huggingface.co/webgpu-kernels 发布了首批 207 个内核。

该集合涵盖了各种机器学习架构和工作负载中广泛使用的操作。更重要的是,每个内核都以完整、带版本号的软件包形式发布:其接口、着色器模板、正确性测试用例、基准测试用例和使用说明都一起存放在 Hub 上。

我们还推出了 Fleet,这是一套浏览器内的 GPU 基准测试和测试套件,可在你的硬件上运行内核并为其评分。除了你本机的测试结果外,Fleet 还为社区提供了一种方式,可以从我们传统测试实验室无法覆盖的设备上贡献性能和正确性证据。在你同意的情况下,每次运行都会添加私有证据,这可以帮助我们发现故障(错误结果、病态慢速案例等)、改进内核变体,并在真实硬件上做出更好的优化决策。

摘要

  • 207 个 WebGPU 内核,以独立仓库的形式发布在 webgpu-kernels 组织中。采用 Apache-2.0 许可证。
  • 一个 JavaScript 加载器 @huggingface/kernels,可直接从 Hub 下载、准备并运行内核。
  • 每个内核都有明确的契约和可复现的证据,包括清单、正确性测试、基准测试用例和 WGSL 着色器模板。
  • Fleet,一个基于浏览器的基准测试工具,通过众包方式收集真实 GPU 上的正确性和性能证据,帮助我们改进内核及其变体。

为什么从内核开始?

在浏览器中运行的模型最终会变成一系列 GPU 操作:矩阵乘法、归一化、卷积、注意力原语、量化操作、数据布局变换等等。WebGPU 通过可移植的 API 让这些操作在现代浏览器中得以使用,而 WGSL 则为执行这些操作的着色器提供了一种通用语言。

然而,可移植性并不自动意味着性能。两个着色器可以实现相同的操作并产生相同的输出,但在不同加速器上的表现却可能截然不同。工作组大小、内存访问模式、向量化、数据类型和融合策略都会影响性能。最佳选择也会随输入形状、设备、浏览器和可用的 WebGPU 功能而变化。

这就是为什么内核构成了快速浏览器推理的基础层。更高级别的运行时,其效率只能取决于它们所调度的操作。通过让这些操作可以被单独发现、测试、基准测试和版本管理,我们可以在保持上层稳定契约的同时,独立地改进这一基础。

一个内核仓库,而不仅仅是着色器

该集合中的每个内核都有自己的仓库和内核卡片。卡片记录了操作的语义、输入、输出、属性、支持的数据类型、源文件,以及一个可直接运行的 @huggingface/kernels 示例。

例如,ai.onnx.Add 实现了带有多向广播的逐元素加法。它是神经网络中最简单的操作之一,从残差连接到添加偏置,无处不在。它的卡片记录了两个输入、广播后的输出形状、支持的数据类型,以及针对不同形状和设备可用的变体。

Image 6: Files in the ai.onnx.Add WebGPU kernel repository

ai.onnx.Add 仓库将其清单、正确性和基准测试用例,以及 WGSL 着色器模板打包在一起。

在卡片背后,仓库包含了理解和评估实现所需的工件:

  • 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] 的输出。加载器根据清单契约和输入推导出该输出形状和逻辑数据类型,然后自动分配 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 内核 ORT WebGPU 加速倍数
Add 5 0.064 毫秒 0.227 毫秒 3.52 倍
MatMul 29 0.115 毫秒 0.131 毫秒 1.14 倍
Softmax 12 0.114 毫秒 0.240 毫秒 2.11 倍
LayerNormalization 6 0.061 毫秒 0.135 毫秒 2.22 倍

一些个别的胜出案例差距要大得多。一个特别困难的双线性 Einsum 用例(i,ij,j,大小为 4096)在我们的内核上运行耗时 0.136 毫秒,而 ORT WebGPU 则需要 1,396 毫秒:快了超过 10,000 倍。对 [256, 4096] 进行逐行 CumSum 运算快了 301 倍,耗时 0.016 毫秒对比 4.784 毫秒。这些是特殊情况,而非你在各处都应期待的加速幅度,但它们展示了当通用实现陷入慢速路径时,专用内核能带来多大的帮助。

我们对 GPU 本身执行的工作进行了计时,排除了加载内核、创建会话、上传输入、编译着色器以及读回输出等准备工作。非常短的工作负载自然更难测量,而且小规模用例可能受益于 GPU 缓存,因此这些数字最好被理解为一种有用的对比参考,而非对每个应用的性能承诺。

这些也是单个运算的结果,而非完整模型的结果。具体性能会因 GPU 和浏览器而异,这正是 Fleet 对于构建更全面图景如此重要的原因。

我们还在与 ONNX Runtime 团队合作,将这些改进上游化,以便让更广泛的 ONNX Runtime Web 生态系统受益。

从单台设备到设备集群

WebGPU 性能因 GPU、浏览器和驱动程序而异,因此单台机器的结果只能说明部分情况。Fleet 让任何人都能在浏览器中运行正确性和性能检查,并查看内核在其硬件上的表现。

在获得同意后,每次运行都会私下贡献证据,帮助我们识别特定设备的故障、比较不同变体并改进选择规则。目标很简单:利用广泛而真实的覆盖范围,让内核为所有人变得更快、更可靠。

为 WebAI 构建共享基础

最初的 207 个内核是一个起点,而非最终状态。在 Hub 上独立发布内核,为我们提供了一个共同的地方来检查契约、比较实现、复现正确性检查并改进性能,而无需将每个着色器直接嵌入到每个运行时中。

该集合也是 Hub 更广泛内核生态系统的一部分:在内核页面上,WebGPU 内核与 CUDA、ROCm、Metal 及其他平台的内核并列展示,并且可以像 Hub 上的任何其他工件一样进行筛选、排序和探索。

Image 7: The Hub Kernels page filtered to the WebGPU platform, listing the 207 published kernels

Hub 内核页面上全部 207 个 WebGPU 内核,已按平台筛选。

这些组成部分相互强化:

  1. 内核仓库定义了透明、带版本管理的运算契约。
  2. @huggingface/kernels 让这些运算能够从 JavaScript 中轻松加载和运行。
  3. Fleet 通过众包方式,在远比传统基准测试实验室所能覆盖的更广泛设备范围内收集真实世界的证据。
  4. 每一次贡献的运行结果都能揭示失败案例、指导调优、改进变体选择,并帮助验证未来的内核版本。

这是我们浏览器推理栈后续步骤的低层基础。我们很高兴能将这些内核连接到更高级别的模型工具,继续扩大算子覆盖范围,并让 WebAI 生态系统中更易用上快速的本地推理。

探索 WebGPU 内核集合,试用 @huggingface/kernels,并加入 Fleet,从你的设备贡献数据,帮助我们让这些内核惠及所有人。

来源:Hugging Face:Blog(RSS)· huggingface.co