ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

ONNX Runtime Web WebNN EP 算子支持指南:覆盖清单、版本区间与底层实现解析

ONNX Runtime Web WebNN EP 算子支持指南:覆盖清单、版本区间与底层实现解析 ONNX Runtime Web WebNN EP 算子支持指南覆盖清单、版本区间与底层实现解析【免费下载链接】onnxruntimeONNX Runtime: cross-platform, high performance ML inferencing and training accelerator项目地址: https://gitcode.com/GitHub_Trending/on/onnxruntime本指南基于 js/web/docs/webnn-operators.md 展开系统梳理 ONNX Runtime Web 中WebNN EPExecution Provider对 ONNX 算子及 opset 版本的支持范围、每条支持项背后的 WebNN API 映射以及各算子的实际约束条件。读完本文你将掌握如何按表判断一个 ONNX 模型能否在 WebNN EP 上运行、每条支持记录中版本区间/WebNN API/注释三列的确切含义以及 WebNN EP 在 onnxruntime/core/providers/webnn 源码中如何完成从算子注册、能力检查到模型编译的完整流程。一、WebNN EP 与支持表的使用前提1.1 什么是 WebNN EPWebNN EP 是 ONNX Runtime Web 通过 WebNNWeb Neural Network APIW3C 标准见 webmachinelearning/webnn将模型推理卸载到浏览器底层硬件加速器CPU/GPU/NPU的执行提供程序。它的 C 侧实现位于 onnxruntime/core/providers/webnn而 JS 侧入口在 js/web/lib/wasm/jsep/backend-webnn.ts 与 js/web/lib/wasm/session-options.ts。WebNN API 目前在 Windows、Linux、macOS、Android 与 ChromeOS 上的最新版 Chrome 和 Edge 中可用需在浏览器实验特性中开启Enables WebNN API标志。由于不同平台对 WebNN 各算子的实现进度不一同一算子在不同平台上的支持状态可能有差异具体实现细节应参考 WebNN status。这也意味着下面的支持表描述的是 WebNN EP 代码层面允许的算子集合最终能否在某个平台上成功运行还取决于该平台浏览器对 WebNN 对应 API 的实现程度。1.2 支持表三列的含义支持表每行包含三列含义如下列含义OperatorONNX 算子名来自ai.onnx域或 Microsoft 扩展域com.microsoftOpset该算子可用的 opset 版本区间7-12, 13表示当前支持 opset 7 到 12以及 13 及以上版本WebNN API实现该算子所调用的一个或多个 WebNN 底层原语如abs、conv2d、matmul关于 opset 需要特别说明ONNX Runtime 官方只保证对ai.onnx域中 opset 7 及以上版本标注的模型提供支持原文档中的 Note。因此低于 opset 7 的模型即使算子出现在表中也不能视为受支持。1.3 从源码看能力检查流程WebNN EP 的算子支持检查并非运行时逐个硬编码而是由执行提供程序的GetCapability流程驱动。在 webnn_execution_provider.cc 中可以看到完整链条构造MLGraphBuilderemscripten::val::global(MLGraphBuilder).new_(wnn_context_)调用 helper.cc 中的GetSupportedNodes/IsNodeSupported按节点类型在算子构建器注册表中查找对查到的节点调用IsOpSupported做细粒度检查含opSupportLimits()返回的 rank 范围校验见 helper.cc最终通过CreateSupportedPartitions把支持的节点划分成子图并生成 metadef命名形如WEBNN_hash_id。其中算子构建器注册表定义在 op_builder_factory.cc一个 ONNX 算子由对应的*_op_builder.cc实现如conv_op_builder.cc、gemm_op_builder.cc、gqa_op_builder.cc。表中有不少算子如DynamicQuantizeLinear、Einsum、LRN、SimplifiedLayerNormalization的 WebNN API 列包含多个原语正是因为它们在 builders/impl 下被分解为若干基础 WebNN 操作的组合。另外值得注意在 JS 侧启用 WebNN EP 时session-options.ts 会自动设置session.disable_quant_qdq与session.disable_qdq_constant_folding两项会话配置以保证 DQ/Q 节点以独立算子形式保留给 WebNN EP 处理——这正是表中ConvInteger、DequantizeLinear、QuantizeLinear、MatMulInteger、MatMulNBits等量化算子能被识别的前提。二、完整算子支持表原文档全量继承下表为 WebNN EP 当前支持的 ONNX 算子全集按算子名排序含 opset 支持区间、映射的 WebNN API 与关键约束注释。OperatorOpsetWebNN APICommentsAbsai.onnx(7-12, 13)absAddai.onnx(7-12, 13, 14)addAndai.onnx(7)logicalAndArgMaxai.onnx(7-10, 11, 12, 13)argMaxArgMinai.onnx(7-10, 11, 12, 13)argMinAveragePoolai.onnx(7-9, 10, 11, 12-18, 19)averagePool2dOnly supports 4-D input, 2-D kernel_shapeBatchNormalizationai.onnx(7-8, 9-13, 14, 15)batchNormalizationOnly supports training_mode value is 0, one outputCastai.onnx(7-8, 9-12, 13-18, 19-20, 21)castCeilai.onnx(7-12, 13)ceilClipai.onnx(7-10, 11, 12, 13)clampConcatai.onnx(7-10, 11-12, 13)concatConvai.onnx(7-10, 11)conv2dOnly supports 3-D or 4-D input and W (weight)ConvIntegerai.onnx(10)cast, conv2d, dequantizeLinearOnly supports 3-D or 4-D input and W (weight)ConvTransposeai.onnx(7-10, 11)convTranspose2dOnly supports 3-D or 4-D input and W (weight)Cosai.onnx(7)cosCumSumai.onnx(11-13, 14)cumulativeSumaxis input should be a constantDivai.onnx(7-12, 13, 14)divDepthToSpaceai.onnx(7-10, 11-12, 13)reshape, transposeDequantizeLinearai.onnx(10-12, 13-18, 19-20, 21-22, 23)dequantizeLinear, reshapeDropoutai.onnx(7-9, 10-11, 12, 13-21, 22)identityOnly supports test modeDynamicQuantizeLinearai.onnx(11)cast, clamp, div, div, max, min, quantizeLinear, reduceMax, reduceMin, reshape, roundEven, subEinsumai.onnx(12)reshape, transpose, matmul, reduceSum, mul, triangularEluai.onnx(7)eluEqualai.onnx(7-10, 11-12, 13-18, 19)equalErfai.onnx(7-9, 10-12, 13)erfExpai.onnx(7-12, 13)expExpandai.onnx(8-12, 13)expandshape input should be a constantFlattenai.onnx(7-8, 9-10, 11-12, 13-20, 21)reshapeFloorai.onnx(7-12, 13)floorGatherai.onnx(7-10, 11-12, 13)gatherGatherBlockQuantizedcom.microsoft(1)dequantizeLinear, gatheruint8-packed 4-bit data (bits4) is reinterpreted as uint4, which requires quantize_axis to be the last axis and data (and zero_points, if present) to be constant initializersGatherElementsai.onnx(11-12, 13)gatherElementsGatherNDai.onnx(11, 12, 13)gatherNDOnly supports batch_dims 0Geluai.onnx(20)geluGemmai.onnx(7-8, 9-10, 11-12, 13)gemmGlobalAveragePoolai.onnx(7)averagePool2dOnly supports 4-D inputGlobalMaxPoolai.onnx(7)maxPool2dOnly supports 4-D inputGlobalLpPoolai.onnx(7)l2Pool2dOnly supports 4-D input, p value is 2Greaterai.onnx(7-8, 9-12, 13)greaterGreaterOrEqualai.onnx(12-15, 16)greaterOrEqualGroupQueryAttentioncom.microsoft(1)add, cast, concat, constant, cumulativeSum, div, expand, lesser, matmul, reshape, scatterND, softmax, transpose, whereOnly supports input total_sequence_length is constant and past_sequence_length of past kv equals to present_sequence_length of present kv.GRUai.onnx(7-13, 14-21, 22)gruOnly supports layout 0. clip is not supported. The activation functions in activations must be one of Relu, Tanh, Sigmoid. Forward and backward activations must be the same if bidirectional. sequence_lens if present should be constant with values equal to the first dimension length of input XHardSigmoidai.onnx(7)hardSigmoidHardSwishai.onnx(14)hardSwishIdentityai.onnx(7-13, 14-15, 16-18, 19-20, 21)identityInstanceNormalizationai.onnx(7)instanceNormalizationIsNaNai.onnx(9-12, 13-19, 20)isNaNIsInfai.onnx(10-19, 20)isInfinite, equal, greaterLayerNormalizationai.onnx(7-16, 17)layerNormalizationLeakyReluai.onnx(7-15, 16)leakyReluLessai.onnx(7-12, 13)lesserLessOrEqualai.onnx(12-15, 16)lesserOrEqualLogai.onnx(7-12, 13)logLpNormalizationai.onnx(7-21, 22)div, max, reduceL1, reduceL2LpPoolai.onnx(7-10, 11-17, 18)l2Pool2dOnly supports 4-D input, 2-D kernel_shape, p value is 2LRNai.onnx(7-12, 13)pad, averagePool2d, transpose, add, mul, pow, divLSTMai.onnx(7-13, 14-21, 22)lstmOnly supports layout 0, input_forget 0. clip is not supported. The activation functions in activations must be one of Relu, Tanh, Sigmoid. Forward and backward activations must be the same if bidirectional. sequence_lens if present should be constant with values equal to the first dimension length of input XMatMulai.onnx(7-8, 9-12, 13)matmulMatMulIntegerai.onnx(10)cast, dequantizeLinear, matmulMatMulNBitscom.microsoft(1)add, dequantizeLinear, matmul, reshape, transposeInputs B and zero_points (if present) should be constants, input g_idx is not supported, only bits4 and bits8 are supportedMaxai.onnx(7, 8-11, 12, 13)maxMaxPoolai.onnx(7, 8-9, 10, 11, 12)maxPool2dOnly supports 4-D input, 2-D kernel_shape, storage_order ! 1, one outputMinai.onnx(7, 8-11, 12, 13)minMulai.onnx(7-12, 13, 14)mulMultiHeadAttentioncom.microsoft(1)add, cast, concat, constant, div, matmul, reshape, softmax, transposeDoes not support inputs bias, key_padding_mask, past_sequence_length, or cache_indirection. Does not support output qkNegai.onnx(7-12, 13)negNotai.onnx(7)logicalNotOrai.onnx(7)logicalOrPadai.onnx(7-10, 11-12, 13-17, 18, 19-20, 21)padmodes wrap is not supportedPowai.onnx(7-11, 12, 13-14, 15)powPReluai.onnx(7-8, 9-15, 16)preluQuantizeLinearai.onnx(10-12, 13-18, 19-20, 21-22, 23)quantizeLinear, reshapeReciprocalai.onnx(7-12, 13)reciprocalRoundai.onnx(11-21, 22)roundEvenReduceL1ai.onnx(7-10, 11-12, 13-17, 18)reduceL1Input axes if present should be a constantReduceL2ai.onnx(7-10, 11-12, 13-17, 18)reduceL2Input axes if present should be a constantReduceLogSumai.onnx(7-10, 11-12, 13-17, 18)reduceLogSumInput axes if present should be a constantReduceLogSumExpai.onnx(7-10, 11-12, 13-17, 18)reduceLogSumExpInput axes if present should be a constantReduceMaxai.onnx(7-10, 11, 12, 13-17, 18-19, 20)reduceMaxInput axes if present should be a constantReduceMeanai.onnx(7-10, 11-12, 13-17, 18)reduceMeanInput axes if present should be a constantReduceMinai.onnx(7-10, 11, 12, 13-17, 18-19, 20)reduceMinInput axes if present should be a constantReduceProdai.onnx(7-10, 11-12, 13-17, 18)reduceProductInput axes if present should be a constantReduceSumai.onnx(7-10, 11-12, 13)reduceSumInput axes if present should be a constantReduceSumSquareai.onnx(7-10, 11-12, 13-17, 18)reduceSumSquareInput axes if present should be a constantReluai.onnx(7-12, 13, 14)reluReshapeai.onnx(7-12, 13, 14-18, 19-20, 21)reshapeInput shape should be a constant, 0 dimension value in shape is not supportedResizeai.onnx(11-12, 13-17, 18, 19)resample2dOnly supports 4-D input, antialias 0, exclude_outside 0, keep_aspect_ratio_policy stretch, linear and nearest modes, input scales and sizes if present must be a constantRotaryEmbeddingai.onnx(23), com.microsoft(1)add, concat, gather, mul, reshape, slice, splitScatterElementsai.onnx(11-12, 13-15, 16-17, 18)scatterElementsOnly supports reduction noneScatterNDai.onnx(11-12, 13-15, 16-17, 18)scatterNDOnly supports reduction noneShapeai.onnx(7-12, 13-14, 15-18, 19-20, 21)sliceSimplifiedLayerNormalizationai.onnx(1)pow, reduceMean, add, sqrt, div, mulSigmoidai.onnx(7-12, 13)sigmoidSignai.onnx(9-12, 13)signSkipLayerNormalizationcom.microsoft(1)add, layerNormalizationSkipSimplifiedLayerNormalizationcom.microsoft(1)pow, reduceMean, add, sqrt, div, mulSoftplusai.onnx(7)softplusSoftsignai.onnx(7)softsignSinai.onnx(7)sinSliceai.onnx(7-9, 10, 11-12, 13)slice, reverseInput starts, ends, axes, and steps if present must be a constantSoftmaxai.onnx(7-10, 11-12, 13)softmaxSplitai.onnx(7-10, 11-12, 13-17, 18)splitInput split if present should be a constantSqrtai.onnx(7-12, 13)sqrtSqueezeai.onnx(7-10, 11-12, 13-20, 21)reshapeInput axes if present should be a constantSubai.onnx(7-12, 13, 14)subTanai.onnx(7)tanTanhai.onnx(7-12, 13)tanhTileai.onnx(7-12, 13)tileInput repeats should be a constantTransposeai.onnx(7-12, 13-20, 21)transposeTriluai.onnx(14)triangularInput k (option diagonal for WebNN) if present should be a constantUnsqueezeai.onnx(7-10, 11-12, 13-20, 21)reshapeWhereai.onnx(7-8, 9-15, 16)whereXorai.onnx(7)logicalXor三、约束条件的规律性解读表中 Comments 列并非随意罗列而是体现了 WebNN EP 在算子映射上的几条系统性规律1. 常量输入约束Constant Input Requirement多个算子要求某个输入必须是常量constant initializer原因在于 WebNN 构建图时需要把 shape、axes、split、starts/ends 等元数据在编译期确定下来。典型包括CumSum的axis、Expand的shape、Split的split、Tile的repeats、Trilu的k全部Reduce*系列算子的axes如存在Reshape的shape且 shape 中不允许出现 0 维、Resize的scales/sizes、Slice的starts/ends/axes/steps、Squeeze的axes。这与 helper.cc 中的形状检查逻辑呼应——WebNN 不支持动态形状动态维度需要用户通过sessionOptions.FreeDimensionOverrides预先固定。2. 秩Rank与 kernel 维度限制AveragePool、MaxPool、LpPool仅支持 4-D 输入和 2-Dkernel_shape且MaxPool要求storage_order ! 1、只输出一个张量Conv/ConvInteger/ConvTranspose仅支持 3-D 或 4-D 输入与权重GlobalAveragePool/GlobalMaxPool/GlobalLpPool仅支持 4-D 输入GlobalLpPool与LpPool的p值必须为 2。这是因为底层 WebNN API 提供的是 2D 变体averagePool2d、maxPool2d、conv2d、convTranspose2dWebNN EP 会把 ONNX 的 N-D 语义收缩到 WebNN 的 2D 语义上超出范围的秩无法映射。3. 循环网络RNN相关约束GRU与LSTM的限制高度一致layout必须为 0不支持clip激活函数只能是Relu/Tanh/Sigmoid双向时必须前后向激活一致sequence_lens若存在须为常量且等于输入X第一维长度。此外LSTM还要求input_forget 0。这些约束在 gru_op_builder.cc 与 lstm_op_builder.cc 中有对应的属性校验实现。4. 量化与注意力扩展算子量化系列ConvInteger、MatMulInteger通过castdequantizeLinearconv2d/matmul组合实现DequantizeLinear/QuantizeLinear在量化轴axis不是最后一维时需配合reshapeMatMulNBits仅支持 bits4 与 bits8权重B与zero_points必须为常量且不支持g_idx输入GatherBlockQuantized要求 uint8 打包的 4-bit 数据按 uint4 重新解释因此quantize_axis必须是最后一维、data与zero_points必须为常量初始化器。注意力系列MultiHeadAttention不支持bias、key_padding_mask、past_sequence_length、cache_indirection输入及qk输出GroupQueryAttention要求输入total_sequence_length为常量且 past kv 的past_sequence_length必须等于 present kv 的present_sequence_length。RotaryEmbedding同时支持ai.onnx(23)与com.microsoft(1)两个域。这些算子的构建器分别位于 mha_op_builder.cc、gqa_op_builder.cc 与 rotaryEmbedding_op_builder.cc。5. 仅支持推理路径的算子Dropout仅支持测试模式test modeBatchNormalization仅支持training_mode 0且只输出一个结果。这与 ONNX Runtime 推理引擎的定位一致训练相关路径不会被 WebNN EP 接管。四、算子映射的复合实现从 ONNX 到 WebNN 原语支持表的 WebNN API 列值得再展开一层当某一格出现多个 API 时说明该 ONNX 算子并非一对一映射而是在 onnxruntime/core/providers/webnn/builders/impl 中由多个 WebNN 原语拼装而成。从源码结构看可以归纳出以下模式一对一直接映射Abs → abs、Add → add、Relu → relu、MatMul → matmul、Concat → concat等是最常见的形态构建器直接在 WebNN builder 上调用同名方法。同构替代Clip → clamp、Round → roundEven、Reshape/Flatten/Squeeze/Unsqueeze → reshape、Shape → slice、Dropout(测试模式) → identityONNX 语义与 WebNN 原语语义一致或 WebNN 侧可用更基础的原语表达。分解组合LRN需要pad averagePool2d transpose add mul pow div七个原语SimplifiedLayerNormalization由pow reduceMean add sqrt div mul组成DynamicQuantizeLinear用cast/clamp/div/max/min/quantizeLinear/reduceMax/reduceMin/reshape/roundEven/sub展开。这类算子的实现可以在 lrn_op_builder.cc、normalization_op_builder.cc 与 dynamicQuantizeLinear_op_builder.cc 中逐行验证。这一设计使 WebNN EP 能用有限的标准 WebNN 原语覆盖远超其原生算子集的 ONNX 算子面代价是部分复合算子在精度、速度与内存占用上不如原生实现这也是为何支持表中会为复合算子标注出若干不支持的属性组合。五、在 ONNX Runtime Web 中启用 WebNN EP 的配置方式支持表是能不能跑的判据而怎么让它跑涉及执行提供程序的注册参数。在 webnn_provider_factory.cc 中WebNNProviderFactoryCreator::Create从 ProviderOptions 中读取deviceType在 helper.cc 中DeviceTypeFromString支持gpu、cpu、npu三种取值非法值会抛出Unknown WebNN deviceType.。在 JS 侧如 js/web/lib/wasm/session-options.ts 所示通过executionProviders传入webnn并可选指定deviceTypeimport * as ort from onnxruntime-web; const session await ort.InferenceSession.create(./model.onnx, { executionProviders: [{ name: webnn, deviceType: gpu, // 可选gpu | cpu | npu }], });要点选择webnnEP 时ORT 会自动追加session.disable_quant_qdq1与session.disable_qdq_constant_folding1以保留 DQ/Q 节点供 WebNN EP 处理见 session-options.ts。deviceType会以会话配置的形式传递到 C 层最终由WebNNExecutionProvider解析在 webnn_execution_provider.cc 中provider 还会调用 WebNN 的opSupportLimits()获取当前实现对各算子的支持上限用于更精确的能力判定。如果模型含有动态维度需要预先通过sessionOptions.freeDimensionOverrides固定形状否则对应节点可能无法被 WebNN EP 接受参考 helper.cc 中的日志提示。六、使用支持表的实操建议先对照 opset再对照算子模型导出的 opset 版本决定了检查哪一行。例如 opset 13 的模型Reshape使用ai.onnx(13, 14-18, 19-20, 21)段opset 12 及以下则需检查对应旧段。低于 7 的 opset 不在官方保证范围内。逐条核对 Comments 列即使算子名与 opset 命中仍需检查属性与输入形态是否满足注释中的约束如Conv的 3-D/4-D 输入、GatherND的batch_dims 0、Pad不支持wrap模式、ScatterElements/ScatterND仅支持reduction none。结合平台差异评估表内支持不等于当前浏览器可运行。Chrome/Edge 各平台对 WebNN 的实现进度不同最终以浏览器实际行为为准排查失败时留意 WebNN 侧的opSupportLimits()返回值WebNN EP 已在代码中用它做 rank 范围预检。关注com.microsoft扩展域GatherBlockQuantized、GroupQueryAttention、MatMulNBits、MultiHeadAttention、RotaryEmbedding、SkipLayerNormalization、SkipSimplifiedLayerNormalization来自 Microsoft 扩展域com.microsoft(1)只有包含这些扩展算子的模型多为 LLM/Transformer 结构才会用到普通 CNN 模型通常不涉及。七、小结WebNN EP 的算子支持表本质上回答了三个问题哪些 ONNX 算子能被 WebNN 接管Operator、哪些 opset 版本区间可用Opset、底层用什么 WebNN API 实现WebNN API。配合 op_builder_factory.cc 的注册表、helper.cc 的能力检查逻辑以及 builders/impl 下的逐算子实现开发者可以在模型落地前准确预判兼容性并在遇到节点下沉失败时快速定位是哪一类约束常量输入、秩、属性、平台实现导致的拒绝。需要继续深入算子级细节时建议以 js/web/docs/webnn-operators.md 为总览配合 WebNN status 与各*_op_builder.cc源文件交叉验证。【免费下载链接】onnxruntimeONNX Runtime: cross-platform, high performance ML inferencing and training accelerator项目地址: https://gitcode.com/GitHub_Trending/on/onnxruntime创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表