目前在 Chrome 和 Edge Canary 中可用 (runtime flag)
WebNN Spec |
Web Platform Tests |
XNNPack/CPU backend | External Delegate | Execution Provider |
---|---|---|---|---|
Lite for TensorFlow.js | ||||
clamp
|
📈
🧪
|
✅ clamp |
✅ ReluN1To1
|
✅ Clip
|
✅ Relu6 | ||||
concat |
📈
🧪
|
✅ concatenate2 |
✅ Concatenation |
✅ Concat |
✅ concatenate3 | ||||
✅ concatenate4 | ||||
conv2d
|
📈
🧪
|
✅ convolution_2d
|
✅ Conv2d |
✅ Conv
|
✅ DepthwiseConv2d | ||||
convTranspose2d
|
📈
🧪
|
✅ deconvolution_2d
|
✅ TransposeConv |
✅ ConvTranspose
|
✅ Convolution2DTransposeBias | ||||
add element-wise binary | 📈 🧪 | ✅ add2 | ✅ Add | ✅ Add |
sub element-wise binary | 📈 🧪 | ✅ subtract | ✅ Sub | ✅ Sub |
mul element-wise binary | 📈 🧪 | ✅ multiply2 | ✅ Mul | ✅ Mul |
div element-wise binary | 📈 🧪 | ✅ divide | ✅ Div | ✅ Div |
max element-wise binary | 📈 🧪 | ✅ maximum2 | ✅ Maximum | ✅ Max |
min element-wise binary | 📈 🧪 | ✅ minimum2 | ✅ Minimum | ✅ Min |
abs element-wise unary | 📈 🧪 | ✅ abs | ✅ Abs | ✅ Abs |
ceil element-wise unary | 📈 🧪 | ✅ ceiling | ✅ Ceil | ✅ Ceil |
floor element-wise unary | 📈 🧪 | ✅ floor | ✅ Floor | ✅ Floor |
neg element-wise unary | 📈 🧪 | ✅ negate | ✅ Neg | ✅ Neg |
elu | 📈 🧪 | ✅ elu | ✅ Elu | ✅ Elu |
gemm | 📈 🧪 | ✅ fully_connected | ✅ FullyConnected | ✅ Gemm |
WebNN Spec |
Web Platform Tests |
XNNPack/CPU backend | External Delegate | Execution Provider |
---|---|---|---|---|
Lite for TensorFlow.js
|
||||
hardSwish | 📈 🧪 | ✅ hardswish | ✅ HardSwish | ✅ HardSwish |
leakyRelu | 📈 🧪 | ✅ leaky_relu | ✅ LeakyRelu | ✅ LeakyRelu |
pad | 📈 🧪 | ✅ static_constant_pad | ✅ Pad | ✅ Pad |
averagePool2d
pooling
|
📈
🧪
|
✅ average_pooling_2d
|
✅ AveragePool2d | ✅ GlobalAveragePool |
✅ Mean | ✅ AveragePool | |||
maxPool2d
pooling
|
📈
🧪
|
✅ max_pooling_2d
|
✅ MaxPool2d
|
✅ GlobalMaxPool |
✅ MaxPool | ||||
prelu | 📈 🧪 | ✅ prelu | ✅ Prelu | ✅ Prelu |
relu | 📈 🧪 | ✅ clamp | ✅ Relu | ✅ Relu |
resample2d | 🚀🚀 | ✅ static_resize_bilinear_2d | ✅ ResizeBilinear | ✅ Resize |
reshape | 📈 🧪 | ✅ static_reshape | ✅ Reshape | ✅ Reshape |
sigmoid | 📈 🧪 | ✅ sigmoid | ✅ Logistic | ✅ Sigmoid |
split |
📈
🧪
|
✅ even_split2 |
✅ Split |
✅ Split |
✅ even_split3 | ||||
✅ even_split4 | ||||
✅ static_slice (uneven split) | ||||
slice | 📈 🧪 | ✅ static_slice | ✅ Slice | ✅ Slice |
✅ StridedSlice | ||||
softmax | 📈 🧪 | ✅ softmax | ✅ Softmax | ✅ Softmax |
transpose | 📈 🧪 | ✅ static_transpose | ✅ Transpose | ✅ Transpose |
78 | 29 | 35 | 34 | 68 |
const context = await navigator.ml.createContext({powerPreference: 'low-power'});
// The following code builds a graph as:
// constant1 ---+
// +--- Add ---> intermediateOutput1 ---+
// input1 ---+ |
// +--- Mul---> output
// constant2 ---+ |
// +--- Add ---> intermediateOutput2 ---+
// input2 ---+
// Use tensors in 4 dimensions.
const TENSOR_DIMS = [1, 2, 2, 2];
const TENSOR_SIZE = 8;
const builder = new MLGraphBuilder(context);
// Create MLOperandDescriptor object.
const desc = {dataType: 'float32', dimensions: TENSOR_DIMS};
// constant1 is a constant MLOperand with the value 0.5.
const constantBuffer1 = new Float32Array(TENSOR_SIZE).fill(0.5);
const constant1 = builder.constant(desc, constantBuffer1);
// input1 is one of the input MLOperands. Its value will be set before execution.
const input1 = builder.input('input1', desc);
// constant2 is another constant MLOperand with the value 0.5.
const constantBuffer2 = new Float32Array(TENSOR_SIZE).fill(0.5);
const constant2 = builder.constant(desc, constantBuffer2);
// input2 is another input MLOperand. Its value will be set before execution.
const input2 = builder.input('input2', desc);
// intermediateOutput1 is the output of the first Add operation.
const intermediateOutput1 = builder.add(constant1, input1);
// intermediateOutput2 is the output of the second Add operation.
const intermediateOutput2 = builder.add(constant2, input2);
// output is the output MLOperand of the Mul operation.
const output = builder.mul(intermediateOutput1, intermediateOutput2);
// Compile the constructed graph.
const graph = await builder.build({'output': output});
// Setup the input buffers with value 1.
const inputBuffer1 = new Float32Array(TENSOR_SIZE).fill(1);
const inputBuffer2 = new Float32Array(TENSOR_SIZE).fill(1);
const outputBuffer = new Float32Array(TENSOR_SIZE);
// Execute the compiled graph with the specified inputs.
const inputs = {
'input1': inputBuffer1,
'input2': inputBuffer2,
};
const outputs = {'output': outputBuffer};
const results = await context.compute(graph, inputs, outputs);
console.log('Output value: ' + results.outputs.output);
// Output value: 2.25,2.25,2.25,2.25,2.25,2.25,2.25,2.25
import { InferenceSession } from "onnxruntime-web";
// ...
// Initialize the ONNX model
const initModel = async () => {
ort.env.wasm.numThreads = 1; // 4
ort.env.wasm.simd = true;
ort.env.wasm.proxy = true;
const options: InferenceSession.SessionOptions = {
// provider name: wasm, webnn
// deviceType: cpu, gpu
// powerPreference: default, high-performance
executionProviders:
[{ name: "wasm"}], // WebAssembly CPU
};
// ...
};
const results = await model.run(feeds);
const output = results[model.outputNames[0]];
WebAssembly 后端
import { InferenceSession } from "onnxruntime-web";
// ...
// Initialize the ONNX model
const initModel = async () => {
env.wasm.numThreads = 1; // 4
env.wasm.simd = true;
env.wasm.proxy = true;
const options: InferenceSession.SessionOptions = {
// provider name: wasm, webnn
// deviceType: cpu, gpu
// powerPreference: default, high-performance
executionProviders:
[{ name: "webnn", deviceType: "gpu", powerPreference: 'default' }],
};
// ...
};
const results = await model.run(feeds);
const output = results[model.outputNames[0]];
WebNN 后端