Web Neural Network API

Editor’s Draft,

More details about this document
This version:
https://webmachinelearning.github.io/webnn/
Latest published version:
https://www.w3.org/TR/webnn/
Implementation Report:
https://wpt.fyi/results/webnn?label=master&label=experimental&aligned&q=webnn
Test Suite:
https://github.com/web-platform-tests/wpt/tree/master/webnn
Feedback:
GitHub
Inline In Spec
Editors:
Ningxin Hu (Intel Corporation)
Dwayne Robinson (Microsoft Corporation)
Former Editor:
Chai Chaoweeraprasit (Microsoft Corporation)
Other:
Implementation Status, Explainer, Samples

Abstract

This document describes a dedicated low-level API for neural network inference hardware acceleration.

Status of this document

This section describes the status of this document at the time of its publication. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.

This document was published by the Web Machine Learning Working Group as an Editors' Draft. This document is intended to become a W3C Recommendation. Feedback and comments on this specification are welcome. Please use Github issues. Discussions may also be found in the public-webmachinelearning@w3.org archives.

Publication as an Editors' Draft does not imply endorsement by W3C and its Members. This is a draft document and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to cite this document as other than a work in progress.

This document was produced by a group operating under the W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent that the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

This document is governed by the 18 August 2025 W3C Process Document.

Between Candidate Recommendation Snapshot 11 April 2024 and 22 January 2026, the WebNN specification has undergone substantial evolution with over 100 significant changes. The most notable additions include a third wave of operators for enhanced transformers support, the MLTensor API for buffer sharing, and a new abstract device selection mechanism. The API surface has been modernized and interoperability improvements have been made informed by wider implementation experience and developer feedback. This specification version strengthens security and privacy considerations including fingerprinting mitigations, and adds new accessibility considerations. These changes reflect the specification’s maturation toward product readiness with improved developer ergonomics, wider backend compatibility, and standards compliance. For more details, see § 14 Changes.

This document is maintained and updated at any time. Some parts of this document are work in progress and further improvements are expected to be reflected in revised Candidate Recommendation Drafts and Snapshots.

Before requesting transition to Proposed Recommendation, the Working Group will seek to demonstrate that:

1. Introduction

The Web Neural Network API defines a web-friendly hardware-agnostic abstraction layer that makes use of Machine Learning capabilities of operating systems and underlying hardware platforms without being tied to platform-specific capabilities. The abstraction layer addresses the requirements of key Machine Learning JavaScript frameworks and also allows web developers familiar with the ML domain to write custom code without the help of libraries.

For an illustrated introduction, please see the explainer.

2. Use cases

2.1. Application Use Cases

This section illustrates application-level use cases for neural network inference hardware acceleration. All applications in those use cases can be built on top of pre-trained deep neural network (DNN) [models].

Note: Please be aware that some of the use cases described here, are by their very nature, privacy-invasive. Developers who are planning to use the API for such use cases should ensure that the API is being used to benefit users, for purposes that users understand, and approve. They should apply the Ethical Principles for Web Machine Learning [webmachinelearning-ethics] and implement appropriate privacy risk mitigations such as transparency, data minimisation, and users controls.

Note: § 3 Accessibility Considerations provides guidance on how to improve accessibility of these use cases.

2.1.1. Person Detection

A user opens a web-based video conferencing application, but she temporarily leaves from her room. The application is watching whether she is in front of her PC by using object detection (for example, using object detection approaches such as [SSD] or [YOLO] that use a single DNN) to detect regions in a camera input frame that include persons.

When she comes back, the application automatically detects her and notifies other online users that she is active now.

2.1.2. Semantic Segmentation

A user joins a teleconference via a web-based video conferencing application at her desk since no meeting room in her office is available. During the teleconference, she does not wish that her room and people in the background are visible. To protect the privacy of the other people and the surroundings, the application runs a machine learning model such as [DeepLabv3+], [MaskR-CNN] or [SegAny] to semantically split an image into segments and replaces segments that represent other people and background with another picture.

2.1.3. Skeleton Detection

A web-based video conferencing application tracks a pose of user’s skeleton by running a machine learning model, which allows for real-time human pose estimation, such as [PoseNet] to recognize her gesture and body language. When she raises her hand, her microphone is automatically unmuted and she can start speaking on the teleconference.

2.1.4. Face Recognition

There are multiple people in the conference room and they join an online meeting using a web-based video conferencing application. The application detects faces of participants by using object detection (for example, using object detection approaches such as [SSD]) and checks whether each face was present at the previous meeting or not by running a machine learning model such as [FaceNet], which verifies whether two faces would be identical or not.

2.1.5. Facial Landmark Detection

A user wants to find new glasses that beautifully fits her on an online glasses store. The online store offers web-based try-on simulator that runs a machine learning model such as Face Alignment Network [FAN] to detect facial landmarks like eyes, nose, mouth, etc. When she chooses a pair of glasses, the simulator properly renders the selected glasses on the detected position of eyes on her facial image.

2.1.6. Style Transfer

A user is looking for cosmetics on an online store and wondering which color may fit her face. The online store shows sample facial makeup images of cosmetics, and offers makeup simulator that runs a machine learning model like [ContextualLoss] or [PairedCycleGAN] to transfer the makeup style of the sample makeup image to her facial image. She can check how the selected makeup looks like on her face by the simulator.

2.1.7. Super Resolution

A web-based video conferencing is receiving a video stream from its peer, but the resolution of the video becomes lower due to network congestion. To prevent degradation of the perceived video quality, the application runs a machine learning model for super-resolution such as [SRGAN] to generate higher-resolution video frames.

2.1.8. Image Captioning

For better accessibility, a web-based presentation application provides automatic image captioning by running a machine learning model such as [im2txt] which predicts explanatory words of the presentation slides.

2.1.9. Text-to-image

Images are a core part of modern web experiences. An ability to generate images based on text input in a privacy-preserving manner enables visual personalization and adaptation of web applications and content. For example, a web application can use as an input a natural language description on the web page or a description provided by the user within a text prompt to produce an image matching the text description. This text-to-image use case enabled by latent diffusion model architecture [LDM] forms the basis for additional text-to-image use cases. For example, inpainting where a portion of an existing image on the web page is selectively modified using the newly generated content, or the converse, outpainting, where an original image is extended beyond its original dimensions filling the empty space with generated content.

2.1.10. Machine Translation

Multiple people from various countries are talking via a web-based real-time text chat application. The application translates their conversation by using a machine learning model such as [GNMT] or [OpenNMT], which translates every text into different language.

2.1.11. Emotion Analysis

A user is talking to her friend via a web-based real-time text chat application, and she is wondering how the friend feels because she cannot see the friend’s face. The application analyses the friend’s emotion by using a machine learning model such as [DeepMoji], which infers emotion from input texts, and displays an emoji that represents the estimated emotion.

2.1.12. Video Summarization

A web-based video conferencing application records received video streams, and it needs to reduce recorded video data to be stored. The application generates the short version of the recorded video by using a machine learning model for video summarization such as [Video-Summarization-with-LSTM].

2.1.13. Noise Suppression

A web-based video conferencing application records received audio streams, but usually the background noise is everywhere. The application leverages real-time noise suppression using Recurrent Neural Network such as [RNNoise] for suppressing background dynamic noise like baby cry or dog barking to improve audio experiences in video conferences.

2.1.14. Speech Recognition

Speech recognition, also known as speech to text, enables recognition and translation of spoken language into text. Example applications of speech recognition include transcription, automatic translation, multimodal interaction, real-time captioning and virtual assistants. Speech recognition improves accessibility of auditory content and makes it possible to interact with such content in a privacy-preserving manner in a textual form. Examples of common use cases include watching videos or participating in online meetings using real-time captioning. Models such as [Whisper] approach humans in their accuracy and robustness and are well positioned to improve accessibility of such use cases.

2.1.15. Text Generation

Various text generation use cases are enabled by large language models (LLM) that are able to perform tasks where a general ability to predict the next item in a text sequence is required. This class of models can translate texts, answer questions based on a text input, summarize a larger body of text, or generate text output based on a textual input. LLMs enable better performance compared to older models based on RNN, CNN, or LSTM architectures and further improve the performance of many other use cases discussed in this section. Examples of LLMs include [t5-small], [m2m100_418M], [gpt2], and [llama-2-7b].

2.1.16. Detecting fake video

A user is exposed to realistic fake videos generated by ‘deepfake’ on the web. The fake video can swap the speaker’s face into the president’s face to incite a user politically or to manipulate user’s opinion. The deepfake detection applications such as [FaceForensics++] analyze the videos and protect a user against the fake videos or images. When she watches a fake video on the web, the detection application alerts her of the fraud video in real-time.

2.2. Framework Use Cases

This section collects framework-level use cases for a dedicated low-level API for neural network inference hardware acceleration. It is expected that Machine Learning frameworks will be key consumers of the Web Neural Network API (WebNN API) and the low-level details exposed through the WebNN API are abstracted out from typical web developers. However, it is also expected that web developers with specific interest and competence in Machine Learning will want to interface with the WebNN API directly instead of a higher-level ML framework.

2.2.1. Custom Layer

A web application developer wants to run a DNN model on the WebNN API. However, she has found that some of activation functions like [LeakyReLU], [ELU], etc. are not included in the WebNN API. To address this issue, she constructs custom layers of the additional activation functions on top of the WebNN API. Note that the scope of custom layers may include convolution, normalization, etc. as well as activation.

2.2.2. Network Concatenation

A web application uses a DNN model, and its model data of upper convolutional layers and lower fully-connected layers are stored in separate files, since model data of the fully-connected layers are periodically updated due to fine tuning at the server side.

Therefore, the application downloads both partial model files at first and concatenates them into a single model. When the model is updated, the application downloads fine-tuned part of the model and replace only the fully-connected layers with it.

2.2.3. Performance Adaptation

A web application developer has a concern about performance of her DNN model on mobile devices. She has confirmed that it may run too slow on mobile devices which do not have GPU acceleration. To address this issue, her web application refers to the WebNN API to confirm whether acceleration is available or not, so that the application can display the warning for devices without acceleration.

After several weeks, she has developed a tiny DNN model that can even run on CPU. In order to accommodate CPU execution, she modifies the application so that the application loads the tiny model in the case of CPU-only devices.

2.2.4. Operation Level Execution

A JavaScript ML framework is responsible for loading, interpreting and executing a ML model. During the model execution phase, the framework iterates through the operations of the model and executes each operation on the hardware device, like CPU, GPU or ML accelerator. To avoid the unnecessary data copying across devices, the framework selects the same device to execute the operations. For a compute intensive operation, such as convolution 2D or matrix multiplication, the framework uses WebNN API to execute it with the ML-specific acceleration available on that selected device.

2.2.5. Integration with real-time video processing

The user experience of WebRTC-based video conferencing is enhanced using real-time video processing. For example, background blur implemented using a § 2.1.2 Semantic Segmentation model blurs the background in the user’s live camera feed. To satisfy the performance requirements of this use case, the WebNN API integrates with primitives from other Web APIs that make up the media pipeline to allow WebNN API-based transformation of real-time video streams.

3. Accessibility Considerations

This section provides guidance to web authors on how to improve accessibility of § 2.1 Application Use Cases enabled by neural network inference hardware acceleration. This guidance generalizes beyond the specific use cases outlined in this specification, and web authors are encouraged to consult [wcag] for further accessibility guidance and § 6 Ethical Considerations for digital accessibility in context of ethical principles.

§ 2.1.8 Image Captioning can be improved by ensuring the captions are surfaced to screen-reader and other Assistive Technology (AT) users. Web authors are encouraged to ensure the generated image captions are semantically linked to their respective images, either via the standard alt attribute, or other means which may depend on whether the descriptions are updated on initial page load, or later, as the result of user action.

§ 2.1.11 Emotion Analysis can mis-label and thus mis-classify users, leading to discriminatory experiences. Web authors are encouraged to expose confidence scores and give users an option to turn the feature off.

§ 2.1.13 Noise Suppression with aggressive filters can wipe out the speech of users with dysarthria, making captions and recognition fail. Web authors are encouraged to expose a bypass or sensitivity control, and not hard-wire noise suppression when live captions are active.

§ 2.2.5 Integration with real-time video processing with background-blur powered segmentation helps remove distractions, but can add too much delay that breaks lip-reading and live captions. Web authors are encouraged to provide an ability for user-facing keyboard- and screen-reader-operable “Background blur on/off” control, surfaced next to other accessibility/media settings.

§ 7.2 Device Selection allows web authors to indicate preferences for execution speed and power consumption. Implementers are encouraged to allow users to override the web author hint in browser UI to ensure that people on low-end or battery-sensitive devices can keep captions and other critical accessibility features responsive, especially on portable AAC or eye-gaze setups.

4. Security Considerations

This specification defines a low-level API for neural network inference hardware acceleration. This API is considered a powerful feature [POWERFUL-FEATURES] because it grants low-level access to a user’s computer. To meet the authentication and confidentiality expectations of a powerful feature and to prevent man-in-the-middle attacks, all interfaces defined by this specification are only available in a secure context.

This API is disabled by default in all cross-origin frames using the § 7.5 Permissions Policy Integration. This prevents third-party content from using this API unless the embedding page explicitly sets a policy that grants permission.

This API allows creation of an MLContext from a GPUDevice defined by WebGPU specification. See WebGPU Security Considerations for more information regarding security characteristics of this context.

This API provides an abstraction across GPU, CPU, and dedicated ML accelerator hardware. When using a GPU, denial of service considerations similar to WebGPU apply. When using a CPU or a dedicated ML accelerator, the types of potential resource contention are different and mitigations will be implementation and configuration dependent. Implementations should use whatever mechanisms are available from the platform to prevent sites from using an unfair amount of system resources. These compute units are shared resources, and the use of any compute API will affect overall performance on a fully-loaded system.

Once the graph is fully constructed and compiled, the input shapes into each of the operations in the graph are inferred and finalized. The bounds checking occurs when the compute method is invoked that executes the graph against the actual data. No actual data is bound to the compiled graph before this stage. It is the implementation’s responsibility to make sure proper bounds checking occurs against the shapes of the data already inferred by that time.

Document operations susceptible to out-of-bounds access as a guidance to implementers.

Implementations must defend against control-flow attacks based on changes to data considered to be constant. For example, optimizations in the underlying platform may assume that a weight remains unchanged throughout a computation. If the API allowed the contents of buffers holding weights to change during a computation then those optimization assumptions would be invalidated, causing undefined behavior in the underlying platform. The API mitigates this category of attacks from script by always copying or transferring buffers, but implementations should consider additional defenses such as process isolation of data assumed to be constant.

As a future-proofing measure, the API design allows certain operations that can be generically emulated to be deprecated for security, performance, or other reasons without breaking compatibility. This is made possible by high-level functions that are defined in terms of smaller primitive operations defined in this specifications. This enables a native implementation of a high-level function to be replaced with a polyfill implementation.

Investigate side channel attack feasibility considering the current state where CPU is shared between processes running renderers.

In order to not allow an attacker to target a specific implementation that may contain a flaw, the § 7.2 Device Selection mechanism is a hint only, and the concrete device selection is left to the implementation - a user agent could for instance choose never to run a model on a device with known vulnerabilities. As a further mitigation, no device enumeration mechanism is defined.

Hinting partially mitigates the concern. Investigate additional mitigations.

The API design minimizes the attack surface for the compiled computational graph. The MLGraphBuilder interface that hosts the various operations is a data definition API and as such doesn’t execute anything, only constructs data. What follows, is that the potential for an attack is limited to when binding the data to the graph before executing it by invoking the MLContext.dispatch() method. This enables implementers to focus on hardening the MLContext.dispatch() method. For example, by making sure it honors the boundary of data and fails appropriately when the bounds are not respected.

Purpose-built Web APIs for measuring high-resolution time mitigate against timing attacks using techniques such as resolution reduction, adding jitter, detection of abuse and API call throttling [hr-time-3]. The practical deployment of WebNN implementations are likely to bring enough jitter to make timing attacks impractical (e.g. because they would use IPC) but implementers are advised to consider and test their implementations against timing attacks.

Note: Security risks related to Unicode sequences are discussed in context of the label USVString definition.

4.1. Guidelines for new operations

This section is non-normative.

To ensure operations defined in this specification are shaped in a way they can be implemented securely, this section includes guidelines on how operations are expected to be defined to reduce potential for implementation problems. These guidelines are expected to evolve over time to align with industry best practices:

In general, always consider the security and privacy implications as documented in [security-privacy-questionnaire] by the Technical Architecture Group and the Privacy Interest Group when adding new features.

5. Privacy Considerations

This API provides a privacy improvement over cloud-based inference alternatives by keeping sensitive user data within the browser’s sandbox. Input data such as images, audio, video streams, and other personal information never leave the user’s device, eliminating risks associated with data transmission to remote servers and third-party data processing.

However, as a powerful local compute API that interacts closely with hardware acceleration capabilities, the WebNN API has to balance performance optimization with privacy protection. The API includes multiple privacy-preserving measures to mitigate against fingerprinting while still enabling effective machine learning inference capabilities.

5.1. Fingerprinting

By design, this API aims to expose the minimum amount of information necessary to address the identified § 2 Use cases with the best performance and reliability of results. First, the API mitigates against fingerprinting through standardization: by defining consistent behavior across diverse platform APIs and by minimizing information leakage about the underlying hardware variation across conformant implementations. This is achieved through:

The overall design ensures that implementations maintain a consistent interface across different platforms while providing the necessary functionality. By abstracting platform-specific details, the API can provide privacy-preserving predictable behavior regardless of whether the underlying acceleration is provided by CPU, GPU, or dedicated ML hardware.

Note: MLContextOptions is under active development, and the design is expected to change, informed by further implementation experience and new use cases from the wider web community.

MLGraph.devices API extension has been proposed to expose the actual devices selected for execution after the graph is fully constructed and compiled. Privacy implications of this API extension are under investigation. [Issue #836]

5.2. Execution Time Analysis

The timing characteristics of operations can provide some indirect information about the underlying hardware performance, a feature inherent to any compute API. In certain circumstances an execution time analysis can reveal indirectly the performance of the underlying platform’s neural network hardware acceleration capabilities relative to another underlying platform. See also § 4 Security Considerations for further discussion on timing attacks.

Note: The group welcomes further input on the proposed execution time analysis fingerprinting vector and mitigations.

5.3. WebGPU Comparison

Unlike WebGPU, this API does not intrinsically support custom shader authoring; and as a result is not prone to timing attacks that rely on shader caches, or other persistent data. The API builds upon pre-existing shaders and lower level primitives of the browser or the underlying OS. Web developers who interface with GPUDevice are expected to be aware of WebGPU compilation cache considerations.

The WebGPU API identifies machine-specific artifacts as a privacy consideration. Similarly, the WebNN API’s compute unit scheduling may under certain circumstances introduce a fingerprint. However, similarly to WebGPU, such fingerprints are identical across most or all of the devices of each vendor, mitigating the concern. Furthermore, software implementations can be used to further eliminate such artifacts.

In general, implementers of this API are expected to apply WebGPU Privacy Considerations to their implementations where applicable.

6. Ethical Considerations

The Working Group has started documenting ethical issues associated with using Machine Learning on the Web, to help identify what mitigations its normative specifications should take into account. The Working Group publishes and maintains an Ethical Principles for Web Machine Learning document [webmachinelearning-ethics] open to contributions from the wider community via a dedicated GitHub repository.

7. Programming Model

7.1. Overview

At the heart of neural networks is a computational graph of mathematical operations. These operations are the building blocks of modern machine learning technologies in computer vision, natural language processing, and robotics. The WebNN API is a specification for constructing, compiling, and executing computational graphs of neural networks.

The MLGraph interface represents a compiled computational graph that is immutable (that is, a model).

The MLGraphBuilder interface serves as a builder (factory) to construct a computational graph (its graph) that is then compiled to create an MLGraph.

In WebNN, a computational graph is composed of operators which act on data, and are the nodes of the graph. MLOperands are a representation of data that flows within the computational graph, and are the edges of the graph. MLOperands include a computational graph’s input values for inference, constants (including trained weights) used for inference, intermediate values (often referred to as activations) computed during inference, as well as the output values of inference. An operator’s input is one or more MLOperands. An operator’s output is one or more MLOperands. Operators have operator-specific parameters that control their behavior, which can include zero or more activation functions.

A key part of the MLGraphBuilder interface are methods such as gemm() and relu() which create an operator which represents the actual operation to perform on the input data when the computation is run, and return a new MLOperand holding the operator. Methods that create an MLOperand connect any inputs and activations to the operator. Each method invocation returns a distinct new value, without changing the value of any other MLOperand.

An operator has a label, a string which may be included in diagnostics such as exception messages. When an operator is created its label is initialized in an implementation-defined manner and may include the passed label.

Consider adding a mechanism for reporting errors during dispatch(). [Issue #778]

At inference time, every MLOperand will be bound to a tensor (the actual data), which are essentially multidimensional arrays. The representation of the tensors is implementation dependent, but it typically includes the array data stored in some buffer (memory) and some metadata describing the array data (such as its shape).

Operations within the computational graph have functional semantics. This allows the implementation to potentially share the array data between multiple tensors. For example, the implementation of operations such as reshape, or slice may return a view of its input tensor that shares the same buffer as the input tensor. (In the case of reshape, the entire data is shared, while in the case of slice, a part of the input data is shared.) The implementation may use views, as above, for intermediate values.

Before the execution, the computation graph that is used to compute one or more specified outputs needs to be converted, compiled, and optimized. The key purpose of the compilation step is to enable optimizations that span two or more operations, such as operation or loop fusion. The user agent may also perform these optimizations during graph conversion.

The MLGraphBuilder.build() method compiles the graph in the background without blocking the calling thread, and returns a Promise that resolves to an MLGraph. Each MLGraphBuilder can build at most one MLGraph.

The MLGraph underlying implementation will be composed of platform-specific representations of operators and operands which correspond to the MLGraphBuilder’s operators and MLOperands, but which are not script-visible and may be compositions or decompositions of the graph as constructed by script.

Once the MLGraph is constructed, the MLContext.dispatch() method performs the execution of the graph asynchronously either on a parallel timeline in a separate worker thread for the CPU execution or on a GPU timeline in a GPU command queue. This method returns immediately without blocking the calling thread while the actual execution is offloaded to a different timeline. The caller supplies the input values using MLNamedTensors, binding the input MLOperands to their values. The caller also supplies MLNamedTensors for output MLOperands which will contain the result of graph execution, if successful, which may be read back to script using the MLContext.readTensor(tensor) method. This type of execution supports CPU, GPU, and NPU devices.

7.2. Device Selection

An MLContext interface represents a global state of neural network execution. One of the important context states is the underlying execution device that manages the resources and facilitates the compilation and the eventual execution of the neural network graph. In addition to the default method of creation with MLContextOptions, an MLContext could also be created from a specific GPUDevice that is already in use by the application.

In a situation when a GPU context executes a graph with a constant or an input in the system memory as an ArrayBufferView, the input content is automatically uploaded from the system memory to the GPU memory, and downloaded back to the system memory of an ArrayBufferView output buffer at the end of the graph execution. This data upload and download cycles will only occur whenever the execution device requires the data to be copied out of and back into the system memory, such as in the case of the GPU. It doesn’t occur when the device is a CPU device. Additionally, the result of the graph execution is in a known layout format. While the execution may be optimized for a native memory access pattern in an intermediate result within the graph, the output of the last operation of the graph must convert the content back to a known layout format at the end of the graph in order to maintain the expected behavior from the caller’s perspective.

When an MLContext is created with MLContextOptions, the user agent selects and creates the underlying execution device by taking into account these options.

Depending on the underlying platform, the user agent may select different combinations of CPU, NPU and GPU devices.

For a history and rationale of this design, please see the device selection explainer.

7.3. Operators

This section is non-normative.

The WebNN API defines a set of operators required by well-known CNN and RNN, transformer and generative models that address key § 2.1 Application Use Cases. The details of each operator are defined in the normative sections of this specification, in alphabetical order by the operator name. These operators are grouped into categories based on their functionality in the following non-normative table to give a functional overview of the API surface.

Note: Some operators belong to multiple categories. For example, clamp() is both a math function and also used as an activation.

Operators by category
Category Operators​
Tensor creation input(), constant()
Tensor manipulation concat(), expand(), gather(), gatherElements(), scatterElements(), gatherND(), scatterND(), where(), pad(), reshape(), slice(), split(), transpose(), resample2d(), reverse(), tile(), triangular()
Tensor quantization quantizeLinear(), dequantizeLinear()
Tensor casting cast()
Mathematics add(), sub(), mul(), div(), max(), min(), clamp(), pow(), abs(), ceil(), cos(), erf(), exp(), floor(), identity(), log(), neg(), reciprocal(), roundEven(), sin(), sqrt(), tan(), tanh(), sign(), clamp()
Logical equal(), notEqual(), greater(), greaterOrEqual(), lesser(), lesserOrEqual(), logicalNot(), logicalAnd(), logicalOr(), logicalXor(), isNaN(), isInfinite()
Matrix multiplication matmul(), gemm()
Convolution conv2d(), convTranspose2d()
Pooling averagePool2d(), l2Pool2d(), maxPool2d()
Activation clamp(), elu(), gelu(), hardSigmoid(), hardSwish(), leakyRelu(), linear(), prelu(), relu(), sigmoid(), softmax(), softplus(), softsign(), tanh()
Normalization batchNormalization(), instanceNormalization(), layerNormalization()
Reduction argMin(), argMax(), reduceL1(), reduceL2(), reduceLogSum(), reduceLogSumExp(), reduceMax(), reduceMean(), reduceMin(), reduceProduct(), reduceSum(), reduceSumSquare(), cumulativeSum()
Recurrent Neural Networks gruCell(), gru(), lstmCell(), lstm()

7.4. Task Source

The ML task source is a task source to be used for all tasks related to asynchronous compilation and execution of MLGraphs and creation of MLContexts.

To queue an ML task given a global object global and a series of steps steps, queue a global task on the ML task source with global and steps.

7.5. Permissions Policy Integration

This specification defines a policy-controlled feature identified by the string "webnn". Its default allowlist is 'self'.

8. API

8.1. The navigator.ml interface

An ML object is available in the Window and WorkerGlobalScope contexts through the Navigator and WorkerNavigator interfaces respectively and is exposed via navigator.ml.

interface mixin NavigatorML {
  [SecureContext, SameObject] readonly attribute ML ml;
};
Navigator includes NavigatorML;
WorkerNavigator includes NavigatorML;

8.2. ML interface

enum MLPowerPreference {
  "default",
  "high-performance",
  "low-power"
};

dictionary MLContextOptions {
  MLPowerPreference powerPreference = "default";
  boolean accelerated = true;
};

[SecureContext, Exposed=(Window, Worker)]
interface ML {
  Promise<MLContext> createContext(optional MLContextOptions options = {});
  Promise<MLContext> createContext(GPUDevice gpuDevice);
};

8.2.1. MLContextOptions

Note: MLContextOptions is under active development, and the design is expected to change, informed by further implementation experience and new use cases from the wider web community. The Working Group is considering additional API controls to allow the definition of a fallback device, multiple devices in a preferred order, or an exclusion of a specific device. Other considerations under discussion include error handling, ultimate fallback, and quantized operators. Feedback is welcome on any of these design considerations from web developers, library authors, OS and hardware vendors, and other stakeholders via GitHub. See § 5 Privacy Considerations for additional discussion of fingerprinting considerations.

The powerPreference option is an MLPowerPreference and indicates the application’s preference as related to power consumption. It is one of the following:

"default"
Let the user agent select the most suitable behavior.
"high-performance"
Prioritizes execution speed over power consumption.
"low-power"
Prioritizes power consumption over other considerations such as execution speed.

The accelerated option indicates the application’s preference as related to massively parallel acceleration. This option has less priority than powerPreference. When set to true (by default), the underlying platform will attempt to use the available massively parallel accelerators, such as a GPU or NPU, also depending on the powerPreference. When set to false, the application indicates it prefers CPU inference. If there is contradictory input, for instance when powerPreference is "high-performance" and accelerated is false, then the implementation will choose the best available match in the underlying platform (for instance a high performance CPU mode, or will ignore accelerated as it has less priority than powerPreference).

8.2.2. createContext()

Arguments: Returns: an MLContext.
To create a context given realm realm and options (a GPUDevice or MLContextOptions), run these steps:
  1. Let context be a new MLContext in realm.

  2. If options is a GPUDevice object, then:

    1. Set context.[[contextType]] to "webgpu".

    2. Set context.[[powerPreference]] to "default".

    3. Set context.[[accelerated]] to true.

  3. Otherwise:

    1. Set context.[[contextType]] to "default".

    2. Set context.[[lost]] to a new promise in realm.

    3. If options["powerPreference"] exists, then set context.[[powerPreference]] to options["powerPreference"].

    4. Otherwise, set context.[[powerPreference]] to "default".

    5. If options["accelerated"] exists, then set context.[[accelerated]] to options["accelerated"].

    6. Otherwise, set context.[[accelerated]] to true.

  4. If the user agent cannot support context.[[contextType]], then return failure.

  5. Return context.

The createContext(options) steps are:
  1. Let global be this’s relevant global object.

  2. Let realm be this’s relevant realm.

  3. If global’s associated Document is not allowed to use the webnn feature, then return a new promise in realm rejected with a "SecurityError" DOMException.

  4. Let promise be a new promise in realm.

  5. Run the following steps in parallel.

    1. Let context be the result of creating a context given realm and options. If that returns failure, then queue an ML task with global to reject promise with a "NotSupportedError" DOMException and abort these steps.

    2. Queue an ML task with global to resolve promise with context.

  6. Return promise.

The createContext(gpuDevice) method steps are:
  1. Let global be this’s relevant global object.

  2. Let realm be this’s relevant realm.

  3. If global’s associated Document is not allowed to use the webnn feature, then return a new promise in realm rejected with a "SecurityError" DOMException.

  4. Let promise be a new promise in realm.

  5. Run the following steps in parallel.

    1. Let context be the result of creating a context given realm and gpuDevice. If that returns failure, then queue an ML task with global to reject promise with a "NotSupportedError" DOMException and abort these steps.

    2. Queue an ML task with global to resolve promise with context.

  6. Return promise.

8.3. MLContext interface

The MLContext interface represents a global state of neural network compute workload and execution processes. Each MLContext object has associated context type and MLPowerPreference.
typedef record<USVString, MLTensor> MLNamedTensors;

dictionary MLContextLostInfo {
  DOMString message;
};

[SecureContext, Exposed=(Window, Worker)]
interface MLContext {
  undefined dispatch(MLGraph graph, MLNamedTensors inputs, MLNamedTensors outputs);

  Promise<MLTensor> createTensor(MLTensorDescriptor descriptor);
  Promise<MLTensor> createExportableTensor(
    MLTensorDescriptor descriptor, GPUDevice gpuDevice);
  Promise<MLTensor> createConstantTensor(
    MLOperandDescriptor descriptor, AllowSharedBufferSource inputData);

  Promise<ArrayBuffer> readTensor(MLTensor tensor);
  Promise<undefined> readTensor(MLTensor tensor, AllowSharedBufferSource outputData);

  undefined writeTensor(MLTensor tensor, AllowSharedBufferSource inputData);

  GPUBuffer exportToGPU(MLTensor tensor);

  MLOpSupportLimits opSupportLimits();

  undefined destroy();

  readonly attribute boolean accelerated;
  readonly attribute Promise<MLContextLostInfo> lost;
};
MLContext has the following internal slots:
[[contextType]] of type context type.

The MLContext’s context type.

[[powerPreference]] of type MLPowerPreference.

The MLContext’s MLPowerPreference.

[[accelerated]] of type boolean.

The MLContext’s processing type (CPU or massively parallel processing).

[[lost]] of type Promise<MLContextLostInfo>.

A Promise that is resolved when the MLContext’s underlying execution device is no longer available.

[[timeline]]

A timeline associated with the execution of operations on the compute units of the MLContext. These operations include inferencing on computational graphs and modifying the [[data]] of MLTensors.

More rigorously define this timeline. [Issue #529]

The context type is the type of the execution context that manages the resources and facilitates the compilation and execution of the neural network graph:

"default"
Context created per user preference options.
"webgpu"
Context created from WebGPU device.
The accelerated getter steps are to return this.[[accelerated]].
To validate buffer with descriptor given AllowSharedBufferSource bufferSource and MLOperandDescriptor descriptor, run the following steps:
  1. If bufferSource’s byte length is not equal to descriptor’s byte length, then return false.

  2. Switch on the type of bufferSource:

    ArrayBuffer

    Return true.

    SharedArrayBuffer

    Return true.

    ArrayBufferView
    1. If bufferSource is a Uint8Array object, then return true.

    2. If bufferSource matches descriptor’s dataType according to this table, then return true.

    3. Return false.

Note: Using Uint8Array regardless of the descriptor’s dataType is supported as a generic way of representing a slice of an ArrayBuffer, for example part of a WebAssembly.Memory instance. Developers are encouraged to use more specific view types when authoring WebNN code for readability and maintainability.

To validate tensors with descriptors given an MLNamedTensors namedTensors with record<USVString, MLOperandDescriptor> namedDescriptors:
  1. If namedTensors’s size is not equal to namedDescriptors’s size, then return false.

  2. For each nametensor of namedTensors:

    1. If tensor.[[isConstant]] is true, then return false.

    2. If namedDescriptors[name] does not exist, then return false.

    3. If tensor.[[descriptor]] is not equal to namedDescriptors[name], then return false.

  3. Return true.

8.3.1. dispatch()

Schedules the computational workload of a compiled MLGraph on the MLContext’s [[timeline]].

Arguments:

Returns: undefined.

Note: dispatch() itself provides no signal that graph execution has completed. Rather, callers can await the results of reading back the output tensors. See § 8.3.1.1 Examples below.

The dispatch(graph, inputs, outputs) method steps are:
  1. If graph.[[context]] is not this, then throw a TypeError.

  2. If graph.[[isDestroyed]] is true, then throw an "InvalidStateError" DOMException.

  3. Let allTensors be a list of MLTensors consisting of inputs’s values extended by outputs’s values.

  4. If allTensors contains any duplicate items, then throw a TypeError.

  5. For each tensor of allTensors:

    1. If tensor.[[context]] is not this, then throw a TypeError.

    2. If tensor.[[isDestroyed]] is true, then throw a TypeError.

    3. If tensor is exported, then throw a TypeError.

  6. If validating tensors with descriptors given inputs and graph.[[inputDescriptors]] returns false, then throw a TypeError.

  7. If validating tensors with descriptors given outputs and graph.[[outputDescriptors]] returns false, then throw a TypeError.

  8. Enqueue the following steps to graph.[[context]].[[timeline]]:

    1. Run these steps, but abort when this is lost:

      1. Issue a compute request to graph.[[implementation]] given inputs and outputs.

        Add a mechanism for reporting errors during graph execution. [Issue #778]

When a constant operand is created using a tensor, it is legal for that tensor to be destroyed after build completes. Implementations are expected to ensure that the compiled graph remains valid and unaffected by such destruction.

8.3.1.1. Examples
The following code showcases executing an MLGraph using MLTensors.
const descriptor = {
  dataType: 'float32',
  shape: [2, 2]
};
const context = await navigator.ml.createContext();
const builder = new MLGraphBuilder(context);

// 1. Create a computational graph 'C = 0.2 * A + B'.
const constant = builder.constant(descriptor, new Float32Array(4).fill(0.2));
const A = builder.input('A', descriptor);
const B = builder.input('B', descriptor);
const C = builder.add(builder.mul(A, constant), B);

// 2. Compile the graph.
const graph = await builder.build({'C': C});

// 3. Create reusable input and output tensors.
const [inputTensorA, inputTensorB, outputTensorC] = await Promise.all([
  context.createTensor({dataType: A.dataType, shape: A.shape, writable: true}),
  context.createTensor({dataType: B.dataType, shape: B.shape, writable: true}),
  context.createTensor({dataType: C.dataType, shape: C.shape, readable: true})
]);

// 4. Initialize the inputs.
context.writeTensor(inputTensorA, new Float32Array(4).fill(1.0));
context.writeTensor(inputTensorB, new Float32Array(4).fill(0.8));

// 5. Execute the graph.
const inputs = {
  'A'