forked from webmachinelearning/webnn
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.bs
2693 lines (2341 loc) · 123 KB
/
index.bs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<pre class='metadata'>
Title: Web Neural Network API
Shortname: webnn
Level: None
Status: w3c/ED
Group: webmlwg
TR: https://www.w3.org/TR/webnn/
URL: https://webmachinelearning.github.io/webnn/
Editor: Ningxin Hu 68202, Intel Corporation https://intel.com
Editor: Chai Chaoweeraprasit 120203, Microsoft Corporation https://microsoft.com
Abstract: This document describes a dedicated low-level API for neural network inference hardware acceleration.
Repository: https://github.com/webmachinelearning/webnn
Test Suite: https://github.com/web-platform-tests/wpt/tree/master/webnn
!Explainer: <a href="https://github.com/webmachinelearning/webnn/blob/master/explainer.md">explainer.md</a>
!Polyfill: <a href="https://github.com/webmachinelearning/webnn-polyfill">webnn-polyfill</a> / <a href="https://github.com/webmachinelearning/webnn-samples">webnn-samples</a>
Markup Shorthands: markdown yes
Markup Shorthands: dfn yes
Markup Shorthands: idl yes
Markup Shorthands: css no
Logo: https://webmachinelearning.github.io/webmachinelearning-logo.png
</pre>
<pre class="anchors">
urlPrefix: https://www.khronos.org/registry/webgl/specs/latest/1.0/; spec: WEBGL-1
type: interface
text: WebGLRenderingContext; url: 5.14
text: WebGLBuffer; url: 5.4
text: WebGLTexture; url: 5.9
urlPrefix: https://gpuweb.github.io/gpuweb/; spec: WEBGPU
type: interface
text: GPUDevice; url: gpu-device
text: GPUBuffer; url: buffer-interface
text: GPUTexture; url: texture-interface
</pre>
<pre class="biblio">
{
"WEBGPU": {
"authors": [
"Dzmitry Malyshau",
"Kai Ninomiya"
],
"href": "https://gpuweb.github.io/gpuweb/",
"title": "WebGPU",
"status": "ED",
"publisher": "W3C",
"deliveredBy": [
"https://www.w3.org/2020/gpu/"
]
}
}
</pre>
<pre class="link-defaults">
spec:html;
type:interface; text:Navigator
spec:webidl;
type:dfn; text:record
type:dfn; text:resolve
</pre>
<style>
/* Make <dl> blocks more distinct from their surroundings. */
main dl:not(.switch) {
border-left: thin solid #f3e48c;
padding-left: .5em;
}
/* <p> by default has these margins. Update ul/ol/dl to match,
* since they are also put in places where paragraphs go. */
p, ul, ol, dl {
margin: 1em 0;
}
/* Box for Valid Usage requirements. */
div.validusage {
padding: .5em;
border: thin solid #88e !important;
border-radius: .5em;
}
/*
* Stylistic labels, for clarity of presentation of these blocks.
*
* NOTE: This text is non-accessible and non-selectable; surrounding
* text must also explain the context.
*/
.validusage {
position: relative;
}
.validusage::before {
font-weight: bold;
font-style: italic;
font-size: 130%;
color: rgba(0, 0, 0, 0.15);
color: var(--watermark-text);
position: absolute;
right: .3em;
top: -.1em;
}
.validusage::before {
content: "Valid Usage";
}
/*
* Ensure that argumentdef blocks don't overflow algorithm section borders. This is made far harder
* than it needs to be because the top-level W3C stylesheet has several @media + min-width variants
* that mark themselves as !important and then proceed to do the wrong thing.
*/
@media screen and (min-width: 78em) {
body:not(.toc-inline) .algorithm .overlarge {
margin-right: auto !important;
}
}
@media screen and (min-width: 90em) {
body:not(.toc-inline) .algorithm .overlarge {
margin-right: auto !important;
}
}
.algorithm .overlarge {
margin-right: auto !important;
}
/*
* The default algorithm style has a caption that doesn't suit this spec's
* formatting particularly well. Hide it.
*/
.algorithm .argumentdef {
margin-top: 0;
}
.algorithm .argumentdef>caption {
display: none;
}
/*
* Add vertical lines to demarcate multi-column cells.
*/
table.data td[colspan] {
border-left-style: dotted;
border-right-style: dotted;
}
table.data.no-colspan-center td[colspan],
table.data.no-colspan-center th[colspan] {
text-align: unset;
}
table.data tr.row-continuation td,
table.data tr.row-continuation th {
border-top: none;
}
/*
* Sticky table headers.
*/
.overlarge {
/* position: sticky doesn't work inside scrollable elements. */
overflow-x: unset;
}
thead.stickyheader th, th.stickyheader {
position: sticky;
top: 0;
background: #f8f8f8;
background: var(--stickyheader-background);
}
/*
* Generic table format.
*/
th {
text-align: left;
}
th, td {
border-bottom: 1px solid black;
border-collapse: collapse;
padding-left: 5px;
padding-right: 5px;
}
/*
* Darkmode colors
*/
:root {
--watermark-text: rgba(0, 0, 0, 15%);
--stickyheader-background: #f8f8f8;
--tint-red: rgba(255, 0, 0, 6%);
--tint-green: rgba(0, 255, 0, 10%);
--tint-blue: rgba(0, 0, 255, 5%);
--tint-purple: rgba(255, 0, 255, 5%);
}
@media (prefers-color-scheme:dark) {
:root {
--watermark-text: rgba(255, 255, 255, 25%);
--stickyheader-background: #181818;
--tint-red: rgba(255, 0, 0, 20%);
--tint-green: rgba(0, 255, 0, 18%);
--tint-blue: rgba(0, 130, 255, 24%);
--tint-purple: rgba(255, 0, 255, 22%);
}
}
</style>
Introduction {#intro}
=====================
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. A complementary <a href="https://webmachinelearning.github.io/model-loader/">Model Loader API</a> defines a higher-level abstraction targeting primarily web developers.
For an illustrated introduction, please see the <a href="https://github.com/webmachinelearning/webnn/blob/master/explainer.md">explainer</a>.
Use cases {#usecases}
=====================
## Application Use Cases ## {#usecases-application}
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]].
### Person Detection ### {#usecase-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.
### Semantic Segmentation ### {#usecase-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+]] or
[[MaskR-CNN]] to semantically split an image into segments and replaces
segments that represent other people and background with another picture.
### Skeleton Detection ### {#usecase-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.
### Face Recognition ### {#usecase-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.
### Facial Landmark Detection ### {#usecase-facial-landmarks}
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.
### Style Transfer ### {#usecase-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.
### Super Resolution ### {#usecase-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.
### Image Captioning ### {#usecase-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.
### Machine Translation ### {#usecase-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.
### Emotion Analysis ### {#usecase-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.
### Video Summarization ### {#usecase-video-summalization}
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]].
### Noise Suppression ### {#usecase-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.
### Detecting fake video ### {#usecase-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.
## Framework Use Cases ## {#usecases-framework}
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.
### Custom Layer ### {#usecase-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.
### Network Concatenation ### {#usecase-network-concat}
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.
### Performance Adaptation ### {#usecase-perf-adapt}
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.
### Operation Level Execution ### {#usecase-op-level-exec}
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.
### Integration with real-time video processing ### {#usecase-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 [[#usecase-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.
Security Considerations {#security}
===================================
This API is disabled by default in all cross-origin frames using the [[#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}} or {{WebGLRenderingContext}} defined by WebGPU and WebGL specifications respectively. See <a href="https://gpuweb.github.io/gpuweb/#security">WebGPU Security Considerations</a> and <a href="https://www.khronos.org/registry/webgl/specs/latest/1.0/#4">WebGL Security Consideration</a> for more information regarding security characteristics of these contexts.
Privacy Considerations {#privacy}
===================================
This API enhances privacy compared to cloud-based inference, since input data such as locally sourced images or video streams stay within the browser's sandbox.
This API exposes the minimum amount of information necessary to address the identified [[#usecases]] for the best performance and reliability of results.
No information from the underlying platform is exposed directly. An execution time analysis may reveal indirectly the performance of the underlying platform's neural network hardware acceleration capabilities relative to another underlying platform.
Note: The group is <a href="https://github.com/webmachinelearning/webnn/issues/85">soliciting further input</a> on the proposed execution time analysis fingerprinting vector and will augment this section with more information and mitigations to inform the implementers of this API.
Implementers of this API are expected to be familiar with the <a href="https://gpuweb.github.io/gpuweb/#security-privacy">WebGPU Privacy Considerations</a>.
Ethical Considerations {#ethics}
===================================
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. This work currently happens in a dedicated <a href="https://github.com/webmachinelearning/ethical-webmachinelearning">GitHub repository</a>.
# Programming Model # {#programming-model}
## Overview ## {#programming-model-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, a model) and exposes
a compute method to perform inference.
The {{MLGraphBuilder}} interface serves as a builder (factory) to create a {{MLGraph}}.
An {{MLOperand}} is a representation of data that flows within the computational graph,
which include 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.
At inference time, every {{MLOperand}} will be bound to a tensor (the actual data).
The {{MLGraphBuilder}} interface enables the creation of {{MLOperand}}s.
A key part of the {{MLGraphBuilder}} interface are the operations (such as
{{MLGraphBuilder/gemm()}} and {{MLGraphBuilder/softmax()}}). The operations have a functional
semantics, with no side effects.
Each operation invocation conceptually returns a distinct new value, without
changing the value of any other {{MLOperand}}.
The {{MLGraphBuilder/build()}} method of the {{MLGraphBuilder}} interface is used to compile and optimize
the computation graph used to compute one or more specified outputs. The key
purpose of the compilation step is to enable optimizations that span two or
more operations, such as operation or loop fusion.
The {{MLGraph/compute()}} method of the {{MLGraph}} interface is used to execute the
compiled computation graph (to perform inference). The caller supplies the input
values using {{MLNamedInputs}}, binding the input {{MLOperand}}s to their values.
The caller supplies pre-allocated buffers for output {{MLOperand}}s using {{MLNamedOutputs}}.
The runtime values (of {{MLOperand}}s) are tensors, 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).
As mentioned above, the operations have a 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, or squeeze may return a view of its input tensor
that shares the same buffer as the input tensor. (In the case of reshape or squeeze,
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.
## Device Selection ## {#programming-model-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. An {{MLContext}} could be created from a specific GPU device such as {{GPUDevice}} or {{WebGLRenderingContext}} that is already in use by the application, in which case the corresponding {{GPUBuffer}} or {{WebGLBuffer}} resources used as graph constants, as well as the {{GPUTexture}} and {{WebGLTexture}} as graph inputs must also be created from the same device. In a multi-adapter configuration, the device used for {{MLContext}} must be created from the same adapter as the device used to allocate the resources referenced in the graph.
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 the application's preference specified in the {{MLPowerPreference}} and the {{MLDevicePreference}} options:
- The *"gpu"* device provides the broadest range of achievable performance across graphics hardware platforms from consumer devices to professional workstations.
- The *"cpu"* device provides the broadest reach of software compute availability, but with limited scalability of execution performance on the more complex neural networks.
- When the device preference is not specified (*"default"*), the user agent selects the most suitable device to use.
The following table summarizes the types of resource supported by the device selected.
<div class="note">
<table>
<tr><th>Device Type<th>ArrayBufferView<th>GPUBuffer<th>GPUTexture<th>WebGLBuffer<th>WebGLTexture
<tr><td>GPUDevice<td>Yes<td>Yes<td>Yes<td>No<td>No
<tr><td>WebGLRenderingContext<td>Yes<td>No<td>No<td>Yes<td>Yes
<tr><td>default<td>Yes<td>No<td>No<td>No<td>No
<tr><td>gpu<td>Yes<td>No<td>No<td>No<td>No
<tr><td>cpu<td>Yes<td>No<td>No<td>No<td>No
</table>
</div>
API {#api}
=====================
## navigator.ml ## {#api-navigator-ml}
A {{ML}} object is available in the {{Window}} and {{DedicatedWorkerGlobalScope}} contexts through the {{Navigator}}
and {{WorkerNavigator}} interfaces respectively and is exposed via `navigator.ml`:
<script type=idl>
interface mixin NavigatorML {
[SecureContext, SameObject] readonly attribute ML ml;
};
Navigator includes NavigatorML;
WorkerNavigator includes NavigatorML;
</script>
## ML ## {#api-ml}
<script type=idl>
enum MLDevicePreference {
"default",
"gpu",
"cpu"
};
enum MLPowerPreference {
// Let the user agent select the most suitable behavior.
"default",
// Prioritizes execution speed over power consumption.
"high-performance",
// Prioritizes power consumption over other considerations such as execution speed.
"low-power"
};
dictionary MLContextOptions {
// Preferred kind of device used
MLDevicePreference devicePreference = "default";
// Preference as related to power consumption
MLPowerPreference powerPreference = "default";
};
[SecureContext, Exposed=(Window, DedicatedWorker)]
interface ML {
// Create a context with options
MLContext createContext(optional MLContextOptions options = {});
// Create a context from WebGL rendering context
MLContext createContext(WebGLRenderingContext glContext);
// Create a context from WebGPU device
MLContext createContext(GPUDevice gpuDevice);
};
</script>
The {{ML/createContext()}} method steps are:
1. If the [=responsible document=] is not [=allowed to use=] the [=webnn-feature|webnn=] feature, then throw a "{{SecurityError!!exception}}" {{DOMException}} and abort these steps.
1. Let |context| be a new {{MLContext}} object.
1. Switch on the method's first argument:
<dl class=switch>
<dt>{{MLContextOptions}}
<dd>Set |context|'s [=context type=] to [=default-context|default=].
<dt>{{WebGLRenderingContext}}
<dd>Set |context|'s [=context type=] to [=webgl-context|webgl=].
<dt>{{GPUDevice}}
<dd>Set |context|'s [=context type=] to [=webgpu-context|webgpu=].
<dt>Otherwise
<dd>Set |context|'s [=context type=] to [=default-context|default=].
</dl>
1. Return |context|.
### Permissions Policy Integration ### {#permissions-policy-integration}
This specification defines a <a>policy-controlled feature</a> identified by the
string "<code><dfn data-lt="webnn-feature">webnn</dfn></code>".
Its <a>default allowlist</a> is <code>'self'</code>.
## MLContext ## {#api-mlcontext}
The {{MLContext}} interface represents a global state of neural network compute workload and execution processes.
<script type=idl>
[SecureContext, Exposed=(Window, DedicatedWorker)]
interface MLContext {};
</script>
The <dfn>context type</dfn> for an {{MLContext}} is either "<code><dfn data-lt="default-context">default</dfn></code>", "<code><dfn data-lt="webgl-context">webgl</dfn></code>" or "<code><dfn data-lt="webgpu-context">webgpu</dfn></code>".
## MLOperandDescriptor ## {#api-mloperanddescriptor}
<script type=idl>
enum MLInputOperandLayout {
"nchw",
"nhwc"
};
enum MLOperandType {
"float32",
"float16",
"int32",
"uint32",
"int8",
"uint8"
};
dictionary MLOperandDescriptor {
// The operand type.
required MLOperandType type;
// The dimensions field is only required for tensor operands.
// The negative value means an unknown dimension.
sequence<long> dimensions;
};
</script>
## MLOperand ## {#api-mloperand}
An {{MLOperand}} represents an intermediary graph being constructed as a result of compositing parts of an operation into a fully composed operation.
For instance, an {{MLOperand}} may represent a constant feeding to an operation or the result from combining multiple constants together into an operation. See also [[#programming-model]].
<script type=idl>
[SecureContext, Exposed=(Window, DedicatedWorker)]
interface MLOperand {};
</script>
## MLOperator ## {#api-mloperator}
Objects implementing the {{MLOperator}} interface represent activation function types. As a generic construct, this interface may be reused for other types in a future version of this specification.
<script type=idl>
[SecureContext, Exposed=(Window, DedicatedWorker)]
interface MLOperator {};
</script>
<div class="note">
These activations function types are used to create other operations. One such use of this interface is for when an activation function is fused into another operation such as [[#api-mlgraphbuilder-conv2d]] or [[#api-mlgraphbuilder-batchnorm]] during a graph construction session.
</div>
<div class="note">
The implementation of the {{MLOperator}} interface can simply be a struct that holds a string type of the activation function along with other properties needed. The actual creation of the activation function e.g. a [[#api-mlgraphbuilder-sigmoid]] or [[#api-mlgraphbuilder-relu]] can then be deferred until when the rest of the graph is ready to connect with it such as during the construction of [[#api-mlgraphbuilder-conv2d]] for example.
</div>
## MLGraphBuilder ## {#api-mlgraphbuilder}
The {{MLGraphBuilder}} interface defines a set of operations as identified by the [[#usecases]] that can be composed into a computational graph. It also represents the intermediate state of a graph building session.
<script type=idl>
typedef record<DOMString, MLOperand> MLNamedOperands;
dictionary MLBufferResourceView {
required (WebGLBuffer or GPUBuffer) resource;
unsigned long long offset = 0;
unsigned long long size;
};
typedef (ArrayBufferView or MLBufferResourceView) MLBufferView;
[SecureContext, Exposed=(Window, DedicatedWorker)]
interface MLGraphBuilder {
// Construct the graph builder from the context.
constructor(MLContext context);
// Create an operand for a graph input.
MLOperand input(DOMString name, MLOperandDescriptor desc);
// Create an operand for a graph constant.
MLOperand constant(MLOperandDescriptor desc, MLBufferView bufferView);
// Create a single-value operand from the specified number of the specified type.
MLOperand constant(double value, optional MLOperandType type = "float32");
// Compile the graph up to the specified output operands
MLGraph build(MLNamedOperands outputs);
};
</script>
### batchNormalization ### {#api-mlgraphbuilder-batchnorm}
Normalize the tensor values of input features across the batch dimension using [[Batch-Normalization]]. For each input feature, the mean and variance values of that feature supplied in this calculation as parameters are previously computed across the batch dimension of the input during the model training phase of this operation.
<script type=idl>
dictionary MLBatchNormalizationOptions {
MLOperand scale;
MLOperand bias;
long axis = 1;
float epsilon = 1e-5;
MLOperator activation;
};
partial interface MLGraphBuilder {
MLOperand batchNormalization(MLOperand input, MLOperand mean, MLOperand variance,
optional MLBatchNormalizationOptions options = {});
};
</script>
<div algorithm=batchnorm>
**Arguments:**
- *input*: an {{MLOperand}}. The input N-D tensor.
- *mean*: an {{MLOperand}}. The 1-D tensor of the mean values of the input features across the batch whose length is equal to the size of the input dimension denoted by *options.axis*.
- *variance*: an {{MLOperand}}. The 1-D tensor of the variance values of the input features across the batch whose length is equal to the size of the input dimension denoted by *options.axis*.
- *options*: an optional {{MLBatchNormalizationOptions}}. The optional parameters of the operation.
- *scale*: an {{MLOperand}}. The 1-D tensor of the scaling values whose length is equal to the size of the input dimension denoted by *options.axis*.
- *bias*: an {{MLOperand}}. The 1-D tensor of the bias values whose length is equal to the size of the input dimension denoted by *options.axis*.
- *axis*: a {{long}} scalar. The index to the feature count dimension of the input shape for which the mean and variance values are. When it's not specified, the default value is 1.
- *epsilon*: a {{float}} scalar. A small value to prevent computational error due to divide-by-zero. The default value is 0.00001 when not specified.
- *activation*: an {{MLOperator}}. The optional activation function that immediately follows the normalization operation.
**Returns:** an {{MLOperand}}. The batch-normalized N-D tensor of the same shape as the input tensor.
When *input* is a 4-D tensor of the *"nchw"* or *"nhwc"* layout, *options.axis* should be set to 1 or 3 respectively. The axis value designates the feature or channel count dimension of the input tensor.
<div class="note">
The behavior of this operation when the input tensor is 4-D of the *"nchw"* layout and the activation is of operator type *relu* can be generically emulated from the usage of other operations as follow. However, user agents typically have a more efficient implementation for it, therefore its usage is encouraged from the performance standpoint.
<pre highlight="js">
const shape = [1,-1,1,1];
return builder.relu(
builder.add(
builder.mul(
builder.reshape(options.scale, shape),
builder.div(
builder.sub(input, builder.reshape(mean, shape)),
builder.pow(
builder.add(builder.reshape(variance, shape), builder.constant(options.epsilon)),
builder.constant(0.5))
)),
builder.reshape(options.bias, shape)));
</pre>
</div>
</div>
### clamp ### {#api-mlgraphbuilder-clamp}
Clamp the input tensor element-wise within a range specified by the minimum and maximum values.
<script type=idl>
dictionary MLClampOptions {
float minValue;
float maxValue;
};
partial interface MLGraphBuilder {
MLOperand clamp(MLOperand x, optional MLClampOptions options = {});
MLOperator clamp(optional MLClampOptions options = {});
};
</script>
<div algorithm=clamp>
**Arguments:**
- *x*: an {{MLOperand}}. The input tensor.
- *options*: an optional {{MLClampOptions}}. The optional parameters of the operation.
- *minValue*: a {{float}} scalar. Specifies the minimum value of the range. When it is not specified, the clamping is not performed on the lower limit of the range.
- *maxValue*: a {{float}} scalar. Specifies the maximum value of the range. When it is not specified, the clamping is not performed on the upper limit of the range.
**Returns:**
- an {{MLOperand}}. The output tensor of the same shape as *x*.
- an {{MLOperator}}. The operator representing the clamp operation.
<div class="note">
The behavior of this operation can be generically emulated from the usage of
other operations as follow. However, user agents typically have a more
efficient implementation for it, therefore its usage is encouraged from the
performance standpoint.
<pre highlight="js">
if (options.minValue === undefined) {
if (options.maxValue === undefined) {
return x;
} else {
return builder.min(x, builder.constant(options.maxValue));
}
} else {
if (options.maxValue === undefined) {
return builder.max(x, builder.constant(options.minValue));
} else {
return builder.min(
builder.max(x, builder.constant(options.minValue)),
builder.constant(options.maxValue));
}
}
</pre>
</div>
</div>
### concat ### {#api-mlgraphbuilder-concat}
Concatenates the input tensors along a given axis.
<script type=idl>
partial interface MLGraphBuilder {
MLOperand concat(sequence<MLOperand> inputs, long axis);
};
</script>
<div algorithm=concat>
**Arguments:**
- *inputs*: a sequence of {{MLOperand}}. All input tensors must have the
same shape, except for the size of the dimension to concatenate on.
- *axis*: a {{long}} scalar. The axis that the inputs concatenate along, with
the value in the interval [0, N) where N is the rank of all the
inputs.
**Returns:** an {{MLOperand}}. The concatenated tensor of all the inputs along
the *axis*. The output tensor has the same shape except on the dimension
that all the inputs concatenated along. The size of that dimension is
computed as the sum of all the input sizes of the same dimension.
</div>
### conv2d ### {#api-mlgraphbuilder-conv2d}
Compute a 2-D convolution given 4-D input and filter tensors
<script type=idl>
enum MLConv2dFilterOperandLayout {
"oihw",
"hwio",
"ohwi",
"ihwo"
};
enum MLAutoPad {
"explicit",
"same-upper",
"same-lower"
};
dictionary MLConv2dOptions {
sequence<long> padding;
sequence<long> strides;
sequence<long> dilations;
MLAutoPad autoPad = "explicit";
long groups = 1;
MLInputOperandLayout inputLayout = "nchw";
MLConv2dFilterOperandLayout filterLayout = "oihw";
MLOperand bias;
MLOperator activation;
};
partial interface MLGraphBuilder {
MLOperand conv2d(MLOperand input, MLOperand filter, optional MLConv2dOptions options = {});
};
</script>
<div algorithm=conv2d>
**Arguments:**
- *input*: an {{MLOperand}}. The input 4-D tensor. The logical shape
is interpreted according to the value of *options.inputLayout*.
- *filter*: an {{MLOperand}}. The filter 4-D tensor. The logical shape is
interpreted according to the value of *options.filterLayout* and *options.groups*.
- *options*: an optional {{MLConv2dOptions}}. The optional parameters of the operation.
- *padding*: a sequence of {{long}} of length 4. The additional rows and columns added to the beginning and ending of each spatial dimension of *input*, [beginning_height, ending_height, beginning_width, ending_width]. If not present, the values are assumed to be [0,0,0,0].
- *strides*: a sequence of {{long}} of length 2. The stride of the sliding window for each spatial dimension of *input*, [stride_height, stride_width]. If not present, the values are assumed to be [1,1].
- *dilations*: a sequence of {{long}} of length 2. The dilation factor for each spatial dimension of *input*, [dilation_height, dilation_width]. If not present, the values are assumed to be [1,1].
- *autoPad*: an {{MLAutoPad}}. The automatic input padding options. By default, this argument is set to *"explicit"*, which means that the values in the *options.padding* array should be used for input padding. When the option is set other than *"explicit"*, the values in the *options.padding* array are ignored. With the *"same-upper"* option, the padding values are automatically computed such that the additional ending padding of the spatial input dimensions would allow all of the input values in the corresponding dimension to be filtered. The *"same-lower"* option is similar but padding is applied to the beginning padding of the spatial input dimensions instead of the ending one.
- *groups*: a {{long}} scalar. The number of groups that input channels and output channels are divided into, default to 1.
- *inputLayout*: an {{MLInputOperandLayout}}. The default value is *"nchw"*. This option specifies the layout format of the input and output tensor as follow:
"nchw":
- input tensor: [batches, input_channels, height, width]
- output tensor: [batches, output_channels, height, width]
"nhwc":
- input tensor: [batches, height, width, input_channels]
- output tensor: [batches, height, width, output_channels]
- *filterLayout*: an {{MLConv2dFilterOperandLayout}}. The default value is *"oihw"*. This option specifies the layout format of the filter tensor as follow:
"oihw":
- [output_channels, input_channels/groups, height, width]
"hwio":
- [height, width, input_channels/groups, output_channels]
"ohwi":
- [output_channels, height, width, input_channels/groups]
"ihwo":
- [input_channels/groups, height, width, output_channels]
- *bias*: an {{MLOperand}}. The additional 1-D tensor with the shape of [output_channels] whose values are to be added to the convolution result.
- *activation*: an {{MLOperator}}. The optional activation function that immediately follows the convolution operation.
**Returns:** an {{MLOperand}}. The output 4-D tensor that contains the convolution result. The output shape is interpreted according to the *options.inputLayout* value. More specifically, the spatial dimensions or the sizes of the last two dimensions of the output tensor for the *nchw* input layout can be calculated as follow:
*output size = 1 + (input size - filter size - (filter size - 1) ** *(dilation - 1) + beginning padding + ending padding) / stride*
<div class="note">
A *depthwise* conv2d operation is a variant of grouped convolution, used in models like the MobileNet, where the *options.groups* = input_channels = output_channels and the shape of filter tensor is [options.groups, 1, height, width]
for *"oihw"* layout, [height, width, 1, options.groups] for *"hwio"* layout, [options.groups, height, width, 1] for *"ohwi"* layout and [1, height, width, options.groups] for *"ihwo"* layout.
</div>
</div>
### convTranspose2d ### {#api-mlgraphbuilder-convtranspose2d}
Compute a 2-D transposed convolution given 4-D input and filter tensors
<script type=idl>
enum MLConvTranspose2dFilterOperandLayout {
"iohw",
"hwoi",
"ohwi"
};
dictionary MLConvTranspose2dOptions {
sequence<long> padding;
sequence<long> strides;
sequence<long> dilations;
sequence<long> outputPadding;
sequence<long> outputSizes;
MLAutoPad autoPad = "explicit";
long groups = 1;
MLInputOperandLayout inputLayout = "nchw";
MLConvTranspose2dFilterOperandLayout filterLayout = "iohw";
MLOperand bias;
MLOperator activation;
};
partial interface MLGraphBuilder {
MLOperand convTranspose2d(MLOperand input, MLOperand filter,
optional MLConvTranspose2dOptions options = {});
};
</script>
<div algorithm=convtranspose2d>
**Arguments:**
- *input*: an {{MLOperand}}. The input 4-D tensor. The logical shape
is interpreted according to the value of *options.inputLayout*.
- *filter*: an {{MLOperand}}. The filter 4-D tensor. The logical shape is
interpreted according to the value of *options.filterLayout* and *options.groups*.
- *options*: an optional {{MLConvTranspose2dOptions}}. The optional parameters of the operation.
- *padding*: a sequence of {{long}} of length 4. The additional rows and columns added to the beginning and ending of each spatial dimension of *input*, [beginning_height, ending_height, beginning_width, ending_width]. If not present, the values are assumed to be [0,0,0,0].
- *strides*: a sequence of {{long}} of length 2. The stride of the sliding window for each spatial dimension of *input*, [stride_height, stride_width]. If not present, the values are assumed to be [1,1].
- *dilations*: a sequence of {{long}} of length 2. The dilation factor for each spatial dimension of *input*, [dilation_height, dilation_width]. If not present, the values are assumed to be [1,1].
- *outputPadding*: a sequence of {{long}} of length 2. The padding values applied to each spatial dimension of the output tensor. This explicit padding values are needed to disambiguate the output tensor shape for transposed convolution when the value of the *options.strides* is greater than 1. Note that these values are only used to disambiguate output shape when needed; it does not necessarily cause any padding value to be written to the output tensor. If not specified, the values are assumed to be [0,0].
- *outputSizes*: a sequence of {{long}} of length 2. The sizes of the last two dimensions of the output tensor. When the output sizes are explicitly specified, the output padding values in *options.outputPadding* are ignored. If not specified, the output sizes are automatically computed.
- *autoPad*: an {{MLAutoPad}}. The automatic input padding options. By default, this argument is set to *"explicit"*, which means that the values in the *options.padding* array should be used for input padding. When the option is set other than *"explicit"*, the values in the *options.padding* array are ignored. With the *"same-upper"* option, the padding values are automatically computed such that the additional ending padding of the spatial input dimensions would allow all of the input values in the corresponding dimension to be filtered. The *"same-lower"* option is similar but padding is applied to the beginning padding of the spatial input dimensions instead of the ending one.
- *groups*: a {{long}} scalar. The number of groups that input channels and output channels are divided into, default to 1.
- *inputLayout*: an {{MLInputOperandLayout}}. The default value is *"nchw"*. This option specifies the layout format of the input and output tensor as follow:
"nchw":
- input tensor: [batches, input_channels, height, width]
- output tensor: [batches, output_channels, height, width]
"nhwc":
- input tensor: [batches, height, width, input_channels]
- output tensor: [batches, height, width, output_channels]
- *filterLayout*: an {{MLConvTranspose2dFilterOperandLayout}}. The default value is *"iohw"*. This option specifies the layout format of the filter tensor as follow:
"iohw":
- [input_channels, output_channels/groups, height, width]
"hwoi":
- [height, width, output_channels/groups, input_channels]
"ohwi":
- [output_channels/groups, height, width, input_channels]
- *bias*: an {{MLOperand}}. The additional 1-D tensor with the shape of [output_channels] whose values are to be added to the transposed convolution result.
- *activation*: an {{MLOperator}}. The optional activation function that immediately follows the transposed convolution operation.
**Returns:** an {{MLOperand}}. The output 4-D tensor that contains the transposed convolution result. The output shape is interpreted according to the *options.inputLayout* value. More specifically, unless the *options.outputSizes* values are explicitly specified, the *options.outputPadding* may be needed to compute the spatial dimension values of the output tensor as follow:
*output size = (input size - 1) ** *stride + filter size + (filter size - 1) ** *(dilation - 1) - beginning padding - ending padding + output padding*
</div>
### element-wise binary operations ### {#api-mlgraphbuilder-binary}
Compute the element-wise binary addition, subtraction, multiplication, division,
maximum and minimum of the two input tensors.
<script type=idl>
partial interface MLGraphBuilder {
MLOperand add(MLOperand a, MLOperand b);
MLOperand sub(MLOperand a, MLOperand b);
MLOperand mul(MLOperand a, MLOperand b);
MLOperand div(MLOperand a, MLOperand b);
MLOperand max(MLOperand a, MLOperand b);
MLOperand min(MLOperand a, MLOperand b);
MLOperand pow(MLOperand a, MLOperand b);
};
</script>
<div algorithm=binary>
**Arguments:**
- *a*: an {{MLOperand}}. The first input tensor.
- *b*: an {{MLOperand}}. The second input tensor.
**Returns:** an {{MLOperand}}. The output tensor that contains the result of
element-wise binary operation of the two input tensors.
The element-wise binary operation will be broadcasted according to
[[!numpy-broadcasting-rule]]. The rank of the output tensor is the maximum
rank of the input tensors. For each dimension of the output tensor, its size
is the maximum size along that dimension of the input tensors.
**Operation types:**
- *add*: Add the values of the two input tensors, element-wise.
- *sub*: Subtract the values of the second input tensor from the values of the first input tensor, element-wise.
- *mul*: Multiply the values of the two input tensors, element-wise.
- *div*: Divide the values of the first input tensor with the values of the second tensor, element-wise.
- *max*: Select the greater values of the two input tensors, element-wise.
- *min*: Select the lesser values of the two input tensors, element-wise.
- *pow*: Compute the values of the values of the first input tensor to the power of the values of the second input tensor, element-wise.
</div>
### element-wise unary operations ### {#api-mlgraphbuilder-unary}
Compute the element-wise unary operation for input tensor.
<script type=idl>
partial interface MLGraphBuilder {
MLOperand abs(MLOperand x);
MLOperand ceil(MLOperand x);
MLOperand cos(MLOperand x);
MLOperand exp(MLOperand x);
MLOperand floor(MLOperand x);
MLOperand log(MLOperand x);
MLOperand neg(MLOperand x);
MLOperand sin(MLOperand x);
MLOperand tan(MLOperand x);
};
</script>
<div algorithm=unary>
**Arguments:**
- *x*: an {{MLOperand}}. The input tensor.
**Returns:** an {{MLOperand}}. The output tensor that contains the result of
element-wise unary operation of the input tensor. The shape of the output
tensor is the same as the shape of input tensor.
**Operation types:**
- *abs*: Compute the absolute value of the input tensor, element-wise.
- *ceil*: Compute the ceiling of the input tensor, element-wise.
- *cos*: Compute the cosine of the input tensor, element-wise.
- *exp*: Compute the exponential of the input tensor, element-wise.
- *floor*: Compute the floor of the input tensor, element-wise.
- *log*: Compute the natural logarithm of the input tensor, element-wise.
- *neg*: Compute the numerical negative value of the input tensor, element-wise.
- *sin*: Compute the sine of the input tensor, element-wise.
- *tan*: Compute the tangent of the input tensor, element-wise.
</div>
### elu ### {#api-mlgraphbuilder-elu}