- 人工智能
- 机器学习
- 深度学习
- 前端
- 后端
【免费下载链接】tfjs
A WebGL accelerated JavaScript library for training and deploying ML models.
本指南以 tfjs-backend-webgpu/README.md 为主体,系统介绍 TensorFlow.js 的 WebGPU 加速后端:如何在浏览器中通过 NPM 或<script>标签接入、后端初始化时底层做了哪些工作、当前支持哪些模型与算子、以及开发与测试的具体方法。读完本文,你将掌握在 Chrome 113+ 上启用 WebGPU 后端运行 TensorFlow.js 模型推理的完整流程,并理解其内部注册机制与性能相关的环境标志。
一、背景:WebGPU 与 TensorFlow.js
WebGPU 是 W3C 制定的下一代 GPU API 规范,相比 WebGL 提供了更接近现代图形与计算硬件的访问能力,支持通用 GPU 计算(Compute Shader)、更大的缓冲区与更精细的资源控制。TensorFlow.js 通过tfjs-backend-webgpu包将这一能力接入其多后端架构,为模型推理提供 GPU 加速。
Chrome 自 2023 年 5 月 2 日起在 M113 版本中默认启用 WebGPU,这意味着无需开启任何实验性开关即可使用该后端。项目描述将自身定位为 "A WebGL accelerated JavaScript library",而 WebGPU 后端正是这一加速路线的下一代演进方向。
当前支持运行的模型
根据 README,该后端目前可以运行以下模型:
- BlazeFace(人脸检测)
- BodyPix(人体分割)
- Face landmarks detection(人脸关键点检测)
- HandPose(手部姿态估计)
- MobileNet(图像分类)
- PoseDetection(姿态检测)
- Universal sentence encoder(通用句向量编码)
- AutoML Image classification(AutoML 图像分类)
- AutoML Object detection(AutoML 目标检测)
- Speech commands(语音命令识别)
二、快速开始:导入 WebGPU 后端
方式一:通过 NPM 导入
首先安装依赖(需要同时安装核心库与 WebGPU 后端):
npm install @tensorflow/tfjs @tensorflow/tfjs-backend-webgpu然后在代码中引入并切换后端:
// 导入 @tensorflow/tfjs 或 @tensorflow/tfjs-core import * as tf from '@tensorflow/tfjs'; // 将 WebGPU 后端注册到全局后端注册表中(副作用导入) import '@tensorflow/tfjs-backend-webgpu'; // 将后端设置为 webgpu,并等待模块就绪 tf.setBackend('webgpu').then(() => main());关键点说明:
import '@tensorflow/tfjs-backend-webgpu'是副作用导入,其入口 src/index.ts 会执行import './register_all_kernels',将全部 WebGPU 算子注册进 tfjs-core 的 kernel 注册表;tf.setBackend('webgpu')返回一个 Promise,必须在then回调(或await之后)再执行模型加载与推理,因为 GPU 设备初始化是异步的;- 若页面环境不支持 WebGPU(例如
navigator.gpu不存在),注册不会发生,调用setBackend('webgpu')会失败,此时应回退到其他后端(如 WebGL 或 CPU)。
方式二:通过<script>标签导入
<!-- 导入 @tensorflow/tfjs 或 @tensorflow/tfjs-core --> <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs/dist/tf.min.js"> </script> <!-- 将 WebGPU 后端注册到全局后端注册表中 --> <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-webgpu/dist/tf-backend-webgpu.js"></script> <script> // 将后端设置为 webgpu,并等待模块就绪 tf.setBackend('webgpu').then(() => main()); </script>与 NPM 方式一致,setBackend('webgpu')需要以异步方式等待就绪。
三、后端初始化背后的源码细节
setBackend('webgpu')触发的是 src/base.ts 中的注册逻辑。从源码可以看出初始化流程的完整链路:
if (isWebGPUSupported()) { registerBackend('webgpu', async () => { const gpuDescriptor: GPURequestAdapterOptions = { powerPreference: env().get('WEBGPU_USE_LOW_POWER_GPU') ? 'low-power' : 'high-performance' }; const adapter = await navigator.gpu.requestAdapter(gpuDescriptor); ... }, 3 /*priority*/); }具体流程如下:
- 能力检测:
isWebGPUSupported()(定义于 src/webgpu_util.ts)检查globalThis.navigator.gpu是否存在,不存在则不注册后端; - 获取 Adapter:调用
navigator.gpu.requestAdapter(),默认请求high-performanceGPU,可通过WEBGPU_USE_LOW_POWER_GPU标志切换为low-power(更省电); - 特性协商:检测 adapter 是否支持
timestamp-query(用于 kernel 计时)与bgra8unorm-storage(用于存储纹理),仅当支持时才加入requiredFeatures; - 请求 Device:通过
adapter.requestDevice()获取 GPU 设备,并显式请求若干关键 limits(如maxComputeWorkgroupStorageSize、maxComputeWorkgroupsPerDimension、maxStorageBufferBindingSize、maxBufferSize等),以保证后续 shader 编译与调度不会超出设备上限; - 实例化后端:以
3的优先级将WebGPUBackend注册到 tfjs-core,WebGPUBackend类定义于 src/backend_webgpu.ts,内部持有device、queue、bufferManager、textureManager、tensorMap等核心状态。
值得注意的是,后端还包含一个"小张量交给 CPU"的调度策略:源码中CPU_HANDOFF_SIZE_THRESHOLD默认取环境标志WEBGPU_CPU_HANDOFF_SIZE_THRESHOLD的值,当输入张量过小且位于 CPU 上时,会直接委托 CPU 后端执行,避免 GPU 启动开销。
四、性能调优环境标志(Flags)
后端通过 tfjs-core 的env().registerFlag()暴露了一系列可调参数,全部定义于 src/flags_webgpu.ts,可在运行时通过tf.env().set('FLAG_NAME', value)调整:
| 标志名 | 默认值 | 说明 |
|---|---|---|
WEBGPU_DEFERRED_SUBMIT_BATCH_SIZE | 15 | 设备队列中的批量提交调度大小,控制 GPU 命令的合并粒度 |
WEBGPU_CPU_FORWARD | true | 当张量较小且位于 CPU 上时,是否将执行转发给 CPU 后端 |
WEBGPU_CPU_HANDOFF_SIZE_THRESHOLD | 1000 | 决定是否把计算委托给 CPU 的输入张量大小阈值 |
WEBGPU_MATMUL_PROGRAM_TYPE | -1 | 选择 matmul 的实现程序类型(-1 表示未设置,走默认策略),可选值见MatMulProgramType枚举 |
WEBGPU_USE_NAIVE_CONV2D_TRANSPOSE | true | 转置卷积是否直接实现朴素逻辑,而非用 matmul 模拟 |
WEBGPU_USE_LOW_POWER_GPU | false | 是否请求低功耗 GPU,否则请求高性能 GPU |
WEBGPU_USE_PROFILE_TOOL | false | 是否创建 dummy canvas 以配合 PIX 等图形性能分析工具 |
WEBGPU_IMPORT_EXTERNAL_TEXTURE | true | 是否使用外部纹理导入 API |
WEBGPU_USE_NAIVE_CONV2D_DEBUG | false | 调试用:是否使用朴素 conv2d 实现 |
WEBGPU_THRESHOLD_TO_INCREASE_WORKGROUPS_FOR_MATMUL | -1 | matmul 增加分派 workgroup 的阈值,-1 表示未由用户设置,采用默认策略;用于解决低占用率问题 |
WEBGPU_CONV_SEPARATE_IM2COL_SHADER | false | 卷积是否将 im2col 作为独立 shader 运行 |
WEBGPU_PRINT_SHADER | '' | 按 shader key 匹配并打印生成的 WGSL 源码,支持逗号分隔多个 key,'all'打印全部,例如'unary,conv2d' |
WEBGPU_ENGINE_COMPILE_ONLY | false | 实验性标志:是否进入仅编译阶段 |
这些标志对应了 README 中提到的性能演进方向:FP16、DP4A(INT8 点积指令)等特性将陆续引入,而 matmul/conv 的多种程序变体与 workgroup 调优正是为这些指令集与硬件特性预留的扩展点。
五、算子支持情况:如何确认一个 op 是否可用
README 指出,实时更新的支持算子列表位于register_all_kernels.ts(本文仓库中对应 src/register_all_kernels.ts)。该文件是理解算子覆盖面的第一手材料。
从源码看,它采用统一的 kernel 注册模式:每个算子对应一个KernelConfig,包含kernelName、backendName: 'webgpu'与kernelFunc,最后统一放入kernelConfigs数组并通过registerKernel注册。例如卷积算子的配置定义于 src/kernels/Conv2D.ts:
export const conv2DConfig: KernelConfig = { kernelName: Conv2D, backendName: 'webgpu', kernelFunc: conv2d as unknown as KernelFunc };当前注册的算子覆盖了(以文件名为准)以下主要类别:
- 张量操作:
Reshape、Transpose、Concat、SplitV、Slice、StridedSlice、Tile、GatherV2、GatherNd、ScatterNd、PadV2、MirrorPad、Pack/Unpack、ExpandDims、Reverse、Fill、ZerosLike、OnesLike、Identity、Range、LinSpace等; - 数学运算:
Add/AddN/Sub/Multiply/RealDiv/FloorDiv/Mod/Pow/Maximum/Minimum/SquaredDifference、Abs/Neg/Sqrt/Rsqrt/Exp/Log/Log1p/Expm1、全套三角函数与双曲函数(Sin/Cos/Tan/Asin/Acos/Atan/Atan2/Sinh/Cosh/Tanh及各自反函数)、Erf、Sign/Step/ClipByValue、LeakyRelu/Relu/Relu6/Elu/Selu/Softplus/Softmax/Prelu等激活函数; - 规约与统计:
Sum/Mean/Min/Max/Prod/All/Any、ArgMax/ArgMin、TopK、Cumsum/Cumprod、LogSumExp相关、BroadcastArgs等; - 卷积与池化:
Conv2D/Conv3D、FusedConv2D、DepthwiseConv2dNative、Conv2DBackpropInput/Conv2DBackpropFilter等梯度算子、MaxPool/AvgPool及其 3D 与梯度版本、MaxPoolWithArgmax、Dilation2D及梯度、LRN/LRNGrad、CropAndResize、ResizeBilinear/ResizeNearestNeighbor及梯度、RotateWithOffset、Transform等; - 矩阵运算:
BatchMatMul、_FusedMatMul(含 bias/激活融合)、Einsum; - 其他:
NonMaxSuppressionV3/V5(目标检测 NMS)、FFT/IFFT、OneHot、Multinomial、SearchSorted、StringNGrams、UnsortedSegmentSum/SparseSegmentSum/SparseSegmentMean/SparseToDense、DenseBincount/Bincount、Draw、FromPixels等。
每个算子的完整实现都位于 src/kernels/ 目录下,共 172 个 kernel 文件,可通过find_files按需查阅具体实现。README 同时鼓励社区贡献缺失的算子,贡献入口见仓库根目录的 CONTRIBUTING.md。
六、FAQ:常见问题
何时应该使用 WebGPU 后端?
WebGPU 后端的使命是在所有方案中取得最佳性能。不过这一目标无法一蹴而就,官方承诺通过快速、持续的优化推进。许多激动人心的特性(如 FP16、DP4A)即将引入——前者指半精度浮点运算,后者指 GPU 的 8-bit 整数点积指令,两者都是现代 GPU 加速推理的关键技术。
你们实现了多少个算子?
实时更新的算子清单见上文提到的 src/register_all_kernels.ts(从源码统计,当前注册了约 170 个 kernel 配置)。仓库欢迎贡献,具体流程参见 CONTRIBUTING.md 中的 "Adding functionality" 章节。
支持训练吗?
"可能"。WebGPU 后端目前还缺少一批梯度计算所需的算子,现阶段团队专注于把推理做到最快。从 src/kernels/ 目录可以看到,虽然已经实现了相当数量的梯度算子(如Conv2DBackpropFilter、AvgPoolGrad、MaxPoolGrad、ResizeBilinearGrad等),但完整训练链路所需的算子仍未全部覆盖。
可以在 Node.js 中运行吗?
可以。如果遇到问题,可以反馈给官方。仓库根目录的 tsconfig 与各包的 package.json 均针对 Node 场景做了相应配置。
如何反馈问题?
在官方 GitHub 仓库的 Issues 页面提交 issue 即可(tfjs 主仓库的 issues 入口)。注意:本文所基于的仓库为只读镜像,反馈请前往上游 tfjs 项目。
七、开发:构建与测试
构建
在tfjs-backend-webgpu/目录下执行:
yarn build该命令实际调用的是仓库根目录的 Bazel 构建(见 package.json 中的build脚本:bazel build tfjs-backend-webgpu:tfjs-backend-webgpu_pkg),产物包含dist/tf-backend-webgpu.node.js、dist/index.js、dist/tf-backend-webgpu.min.js等入口,分别面向 Node、ES Module 与浏览器 script 标签场景。
测试
WebGPU 后端目前使用 Chrome Canary 渠道进行测试:
yarn test # --test_env=CHROME_CANARY_BIN=/path/to/chrome测试通过 Karma 在浏览器中运行(karma.conf.js配置于 tfjs-backend-webgpu/karma.conf.js),这是因为 WebGPU 需要真实 GPU 驱动环境;指定CHROME_CANARY_BIN可让测试框架使用 Chrome Canary 可执行文件。由于 WebGPU 仍处于快速演进阶段,测试对浏览器版本有较高要求,这是后端开发中需要特别留意的一点。
八、从源码看 WebGPU 后端的调度与优化设计
除 README 之外,仓库还提供了丰富的实现细节,帮助理解该后端的性能设计:
- 计算调度模型:每个算子对应一个实现 WebGPUProgram 接口的 WGSL 程序,通过
dispatchLayout将张量维度映射到dispatch三维线程组,workgroupSize与workPerThread决定每个线程组内线程数量与每线程处理的输出元素数; - workgroup 自适应:src/webgpu_util.ts 中的
computeWorkgroupSizeForConv2d、computeWorkPerThreadForConv2d、computeWorkgroupInfoForMatMul会依据输出形状动态选择 workgroup 尺寸(如卷积默认[16,16,1],小尺寸维度降为[4,16,1]或[16,4,1]),以平衡 EU(执行单元)占用率与共享内存限制; - matmul 多实现:
MatMulProgramType枚举列出了MatMulReduceProgram、MatMulSplitKProgram、MatMulSmallOutputSizeProgram、MatMulPackedProgram四种实现,配合WEBGPU_MATMUL_PROGRAM_TYPE标志可切换验证,体现了针对不同矩阵形状的算法分派思路; - Fused 算子:实现了
FusedConv2D、FusedDepthwiseConv2D、_FusedMatMul等融合算子,将卷积/矩阵乘与其后的激活、批归一化合并为一次 GPU 内核执行,减少中间张量读写。
九、小结
tfjs-backend-webgpu为 TensorFlow.js 提供了基于 WebGPU 的下一代 GPU 加速路径。本文完整覆盖了官方 README 的接入方式(NPM 与 script 标签)、FAQ、构建与测试流程,并进一步结合仓库源码(src/base.ts、src/flags_webgpu.ts、src/register_all_kernels.ts 等)剖析了后端注册机制、环境标志、算子覆盖与性能设计。随着 FP16、DP4A 等特性的引入,该后端有望在浏览器端模型推理性能上持续逼近原生水平——使用时请留意 Chrome 113+ 的版本前提,并善用WEBGPU_*系列标志按实际硬件进行调优。
- 人工智能
- 机器学习
- 深度学习
- 前端
- 后端
【免费下载链接】tfjs
A WebGL accelerated JavaScript library for training and deploying ML models.
相关推荐
Aria2App vs 传统下载工具:为什么它是移动设备的最佳选择
Aria2App vs 传统下载工具:为什么它是移动设备的最佳选择 Aria2App是一款基于aria2的高级下载管理器,不仅支持本地下载,还能轻松管理远程服务
Emscripten WebGPU 支持指南:使用 Emdawnwebgpu Port 编写浏览器 WebGPU 应用
Emscripten WebGPU 支持指南:使用 Emdawnwebgpu Port 编写浏览器 WebGPU 应用 Emscripten 通过名为 Emda
编译器WebAssembly开发工具构建工具TensorFlow.js WebGL 后端(@tensorflow/tfjs-backend-webgl)引入指南与源码机制解析
TensorFlow.js WebGL 后端(@tensorflow/tfjs backend webgl)引入指南与源码机制解析 本篇技术指南聚焦 Tenso
人工智能机器学习深度学习前端后端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考