README.md 21.7 KB
Newer Older
gaoqiong's avatar
gaoqiong committed
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
# ONNX Runtime JavaScript API

This directory contains multiple NPM projects:

- [onnxruntime-common](#onnxruntime-common)
- [onnxruntime-node](#onnxruntime-node)
- [onnxruntime-web](#onnxruntime-web)
- [onnxruntime-react-native](#onnxruntime-react-native)

## Development

This folder contains a `.vscode` folder for Visual Studio Code workspace configs. Using VSCode to open this folder
will allow code-formatting and linting features on typescript and C/C++ source code inside this folder. Following files
are used for code-formatting and linting features for developers:

- .vscode/\*\*
- package.json
- packages-lock.json
- .eslintrc.js
- .clang-format

Please follow the steps described below to setup development environment.

### Prerequisites

- Node.js (16.0+): https://nodejs.org/ - (Optional) Use nvm ([Windows](https://github.com/coreybutler/nvm-windows) / [Mac/Linux](https://github.com/creationix/nvm)) to install Node.js

- Python (2.7 or 3.6+): https://www.python.org/downloads/

  - python should be added to the PATH environment variable

- Visual Studio Code: https://code.visualstudio.com/

  - **required** extension: [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint)
  - **required** extension: [Clang-Format](https://marketplace.visualstudio.com/items?itemName=xaver.clang-format)
  - **required** extension: [Debugger for Chrome](https://marketplace.visualstudio.com/items?itemName=msjsdiag.debugger-for-chrome)

- Chrome or Edge Browser

### Setup TypeScript development environment

In `<ORT_ROOT>/js`, run:

```
npm ci
```

This will install Clang-format and ESLint for code-formatting and linting features. This is a one-time setup unless a `git clean` is performed or folder `<ORT_ROOT>/js/node_modules` is removed manually.

### Using VSCode:

Use VSCode to open folder `<ORT_ROOT>/js`.

Make sure to open the correct folder to allow VSCode to load workspace configuration. Otherwise typescript and code formatter may not work as expected.

To populate typescript type declarations, in each project folder, run `npm ci`.

### Run code formatter and linter manually

In `<ORT_ROOT>/js`, use `npm run lint` to run ESLint , and use `npm run format` to run clang-format.

## onnxruntime-common

> language: typescript

> dependency:

> folder: <ORT_ROOT>/js/common

This project is designed to include all "common" code, which are pure javascript that can run in both Node.js and browsers.

### Requirements

Node.js v12+ (recommended v14+)

### Build

Use following command in folder `<ORT_ROOT>/js/common` to install NPM packages, build typescript files and generate bundles:

```
npm ci
```

### Distribution

It should be able to consumed by both from projects that uses NPM packages (through a Node.js folder structure of `node_modules` folder that generated by `npm install onnxruntime-common`) and from a CDN service that serves a `.min.js` bundle file.

### Features

Following features are included in `onnxruntime-common`:

- `InferenceSession` interfaces
- `Tensor`/`OnnxValue` interfaces, implementation and a set of utility functions
- `Backend` interfaces and a set of functions for backend registration

### Generate API reference document

Use following command in folder `<ORT_ROOT>/js/common` to generate API reference document:

```
npx typedoc
```

Document will be generated in folder `<ORT_ROOT>/js/common/docs`.

## onnxruntime-node

> language: typescript/C++

> dependency: onnxruntime-common, ONNXRuntime.dll

> folder: <ORT_ROOT>/js/node

This project is designed to be used as a NPM package to enable Node.js users to consume ONNX Runtime via Node.js binding, in Node.js or any Node.js compatible environment.

### Requirements

Node.js v12+ (recommended v14+)

### Build

#### Build ONNX Runtime and Node.js binding

Follow [instructions](https://www.onnxruntime.ai/docs/how-to/build.html#apis-and-language-bindings) for building ONNX Runtime Node.js binding

#### Build Node.js binding only

Use following command in folder `<ORT_ROOT>/js/node` to install NPM packages and build typescript files:

```
npm ci
```

This will download the latest pre-built ONNX Runtime binaries for the current platform.

### Distribution

It should be able to consumed by from projects that uses NPM packages (through a Node.js folder structure of `node_modules` folder that generated by `npm install onnxruntime-node`).

## onnxruntime-web

> language: typescript

> dependency: onnxruntime-common, ONNXRuntime WebAssembly

> folder: <ORT_ROOT>/js/web

This project is a library for running ONNX models on browsers. It is the successor of [ONNX.js](https://github.com/Microsoft/onnxjs).

### Build

1. Install NPM packages

   1. in `<ORT_ROOT>/js/`, run `npm ci`.
   2. in `<ORT_ROOT>/js/common/`, run `npm ci`.
   3. in `<ORT_ROOT>/js/web/`, run `npm ci`.

2. Prepare ONNX Runtime WebAssembly artifacts.

   You can either use the prebuilt artifacts or build it by yourself.

   - Setup by script.

     In `<ORT_ROOT>/js/web/`, run `npm run pull:wasm` to pull WebAssembly artifacts for latest main branch from CI pipeline.

   - Download artifacts from pipeline manually.

     you can download prebuilt WebAssembly artifacts from [Windows WebAssembly CI Pipeline](https://dev.azure.com/onnxruntime/onnxruntime/_build?definitionId=161&_a=summary). Select a build, download artifacts "Release_ort-wasm" and "Release_ort-wasm-threaded" and unzip. See instructions below to put files into destination folders.

   - Build WebAssembly artifacts.

     1. Build ONNX Runtime WebAssembly

        ~~Follow [instructions](https://www.onnxruntime.ai/docs/how-to/build.html#apis-and-language-bindings) for building ONNX Runtime WebAssembly. (TODO: document is not ready. we are working on it. Please see steps described as below.)~~

        in `<ORT_ROOT>/`, run one of the following commands to build WebAssembly:

        ```sh
        # In windows, use 'build' to replace './build.sh'

        # The following command build debug.
        ./build.sh --build_wasm

        # The following command build debug with debug info.
        ./build.sh --build_wasm --skip_tests --enable_wasm_debug_info

        # The following command build release.
        ./build.sh --config Release --build_wasm --skip_tests --disable_wasm_exception_catching --disable_rtti
        ```

        To build with multi-thread support, append flag `--enable_wasm_threads` to the command. To build with SIMD support, append flag `--enable_wasm_simd` to the command. Make sure to build both single-thread and multi-thread with and without SIMD before next step.

     2. Copy following files from build output folder to `<ORT_ROOT>/js/web/dist/`:

        - ort-wasm.wasm
        - ort-wasm-threaded.wasm (build with flag '--enable_wasm_threads')
        - ort-wasm-simd.wasm (build with flag '--enable_wasm_simd')
        - ort-wasm-simd-threaded.wasm (build with flags '--enable_wasm_threads --enable_wasm_simd')

     3. Copy following files from build output folder to `<ORT_ROOT>/js/web/lib/wasm/binding/`:

        - ort-wasm.js
        - ort-wasm-threaded.js (build with flag '--enable_wasm_threads')
        - ort-wasm-threaded.worker.js (build with flag '--enable_wasm_threads')

3. Use following command in folder `<ORT_ROOT>/js/web` to build:
   ```
   npm run build
   ```

### Test

We use command `npm test` (test runner) and `npm run test:e2e` (E2E test) for tests in ONNXRuntime Web.

#### test runner

In folder `<ORT_ROOT>/js/web`,

- Run `npm test -- --help` for a full CLI instruction.
- Run `npm test -- <your-args> --debug` to run one or more test cases.

There are multiple levels of tests for ONNXRuntime Web:

- unit test: tests for individual components written in TypeScript. Launch unit test by:
  ```
  npm test -- unittest
  ```
- model test: run a single model. The model folder should contains one .onnx model file and one or more folders for test cases, each folder contains several input*\*.pb and output*\*.pb as test data. Launch model test by:
  ```
  npm test -- model <model_folder>
  ```
- op test: test a single operator. An op test is described in a `.jsonc` file which specify the operator type, its attributes and one or more test case(s), each includes a list of expected input tensor(s) and output tensor(s). The `.jsonc` file is located at `<ORT_ROOT>/js/web/test/data/ops`. Launch op test by:

  ```
  npm test -- op <file_name>
  ```

- suite test: suite test includes unit test, a list of model tests and op tests. Launch suite test by:
  ```
  npm test
  ```

#### E2E test

E2E test is for testing end-to-end package consuming. In this test, NPM packages for `onnxruntime-common` and `onnxruntime-web` are generated and a clean folder is used for installing packages. Then a simple mocha test is performed to make sure package can be consumed correctly.

To launch E2E test:

```
npm run test:e2e
```

### Debugging

#### Debugging TypeScript on Desktop/Chrome

To debug the code from test-runner on Chrome:

- Launch `npm test -- <your_args> --debug`. It opens an instance of Chrome browser.
- In the open Chrome browser, click the `DEBUG` button on the top-right of the page.
- In VSCode, click [side bar]->Run and Debug->select [Attach to Chrome]->click [Start Debugging] to attach.
- put breakpoints in source code, and Refresh the page to reload.

#### Debugging TypeScript on iOS/Safari

To debug on an Apple iOS device, please refer to the following steps:

- install [
  RemoteDebug iOS WebKit Adapter](https://github.com/RemoteDebug/remotedebug-ios-webkit-adapter) by following its instructions.
- launch the adapter in commandline: `remotedebug_ios_webkit_adapter --port=9000`.
- in VSCode, select debug configuration `Remote Browser via Webkit Adaptor`.
- follow the steps above to debug.

#### Debugging TypeScript on Android/Chrome

To debug on an Android device, please refer to the following steps:

- Install [Android SDK Platform Tools](https://developer.android.com/studio/releases/platform-tools) and make sure `adb` is ready to use.
- Follow instructions in [Remote Debugging on Android](https://developer.chrome.com/devtools/docs/remote-debugging-legacy) to launch `adb`. Make sure to use port 9000 so that the existing debug configuration works.
- in VSCode, select debug configuration `Remote Browser via Webkit Adaptor`.
- follow the steps above to debug.

#### Debugging C/C++ for ONNX Runtime WebAssembly

To debug C/C++ code for ONNX Runtime WebAssembly, you need to build ONNX Runtime with debug info (see [Build](#Build-2)).

Currently debugging C/C++ code in WebAssembly is not supported in VSCode yet. Please follow [this instruction](https://developer.chrome.com/blog/wasm-debugging-2020/) to debug in browser devtool using extension [C/C++ DevTools Support (DWARF)](https://chrome.google.com/webstore/detail/cc%20%20-devtools-support-dwa/pdcpmagijalfljmkmjngeonclgbbannb).

### Generating Document

This section describes how to generate the latest document for ONNX Runtime Web.

The document contains information about operators WebGL backend supports. It should align with the operator resolve rules in code and spec definition from ONNX.

In folder `<ORT_ROOT>/js/web`, use command `npm run build:doc` to generate the latest documents.

### Distribution

It should be able to consumed by both from projects that uses NPM packages (through a Node.js folder structure of `node_modules` folder that generated by `npm install onnxruntime-web`) and from a CDN service that serves a `ort.min.js` file and one or multiple `.wasm` file(s).

#### Reduced WebAssembly artifacts

By default, the WebAssembly artifacts from onnxruntime-web package allows use of both standard ONNX models (.onnx) and ORT format models (.ort). There is an option to use a minimal build of ONNX Runtime to reduce the binary size, which only supports ORT format models. See also [ORT format model](https://onnxruntime.ai/docs/tutorials/mobile/overview.html) for more information.

#### Reduced JavaScript bundle file fize

By default, the main bundle file `ort.min.js` of ONNX Runtime Web contains all features. However, its size is over 500kB and for some scenarios we want a smaller sized bundle file, if we don't use all the features. The following table lists all available bundles with their support status of features.

|bundle file name|file size|file size (gzipped)|WebGL|WASM-core|WASM-proxy|WASM-threads|ES5 backward compatibility|
|-|-|-|-|------|-----|---|-|
|ort.es5.min.js|594.15KB|134.25KB|O|O|O|O|O|
|ort.min.js|526.02KB|125.07KB|O|O|O|O|X|
|ort.webgl.min.js|385.25KB|83.83KB|O|X|X|X|X|
|ort.wasm.min.js|148.56|44KB|X|O|O|O|X|
|ort.wasm-core.min.js|40.56KB|12.74KB|X|O|X|X|X|

#### Build ONNX Runtime as a WebAssembly static library

When `--build_wasm_static_lib` is given instead of `--build_wasm`, it builds a WebAssembly static library of ONNX Runtime and creates a `libonnxruntime_webassembly.a` file at a build output directory. Developers who have their own C/C++ project and build it as WebAssembly with ONNX Runtime, this build option would be useful. This static library is not published by a pipeline, so a manual build is required if necessary.

## onnxruntime-react-native

> language: typescript, java, objective-c

> dependency: onnxruntime-common

> folder: <ORT_ROOT>/js/react_native

This project provides an ONNX Runtime React Native JavaScript library to run ONNX models on React Native Android and iOS app.

### Requirements

- Yarn
- Android SDK and NDK, which can be installed via Android Studio or sdkmanager command line tool
- A Mac computer with the latest macOS
- [Xcode](https://developer.apple.com/xcode/)
- [CMake](https://cmake.org/download/)
- [Python 3](https://www.python.org/downloads/mac-osx/)

### Models with ORT format

Prior to ORT v1.13, the ONNX Runtime React Native package utilized the ONNX Runtime Mobile package, which required an ONNX model to be converted to ORT format.
Follow these [instructions](https://onnxruntime.ai/docs/reference/ort-format-models.html#convert-onnx-models-to-ort-format) to convert ONNX model to ORT format.
Note that the ONNX Runtime Mobile package includes a reduced set of operators and types, so not all models are supported. See [here](https://onnxruntime.ai/docs/reference/operators/MobileOps.html) for the list of supported operators and types.

From ORT v1.13 onwards the 'full' ONNX Runtime package is used. It supports both ONNX and ORT format models, and all operators and types.

### Build

1. Install NPM packages for ONNX Runtime common JavaScript library and required React Native JavaScript libraries

   - in `<ORT_ROOT>/js/`, run `npm ci`.
   - in `<ORT_ROOT>/js/common/`, run `npm ci`.
   - in `<ORT_ROOT>/js/react_native/`, run `yarn`.

2. Acquire or build the Android ONNX Runtime package

   1. To use a published Android ONNX Runtime Mobile package from Maven, go to step 5.

   2. Set up an Android build environment using these [instructions](https://onnxruntime.ai/docs/build/android.html). Note that the dependencies are quite convoluted, so using the specified JDK and Gradle versions is important.

   3. In `<ORT_ROOT>`, run the below python script to build the ONNX Runtime Android archive file. On a Windows machine, this requires an admin account to build.

   You can build a 'full' package that supports all operators and types, or a reduced size 'mobile' package that supports a limited set of operators and types based on your model/s to miminize the binary size. 
   See [here](https://onnxruntime.ai/docs/build/custom.html) for information about how the reduced build works, including creating the configuration file using your model/s.


      Full build:
      ```sh
      python tools/ci_build/github/android/build_aar_package.py tools/ci_build/github/android/default_full_aar_build_settings.json --config Release --android_sdk_path <ANDROID_SDK_PATH> --android_ndk_path <ANDROID_NDK_PATH> --build_dir <BUILD_DIRECTORY>
      ```

      Reduced size build with configuration file generated from your model/s. Note that either Release or MinSizeRel could be used as the config, depending on your priorities:
      ```sh
      python tools/ci_build/github/android/build_aar_package.py tools/ci_build/github/android/default_mobile_aar_build_settings.json --config MinSizeRel --android_sdk_path <ANDROID_SDK_PATH> --android_ndk_path <ANDROID_NDK_PATH> --build_dir <BUILD_DIRECTORY> --include_ops_by_config <required_ops_and_types_for_your_models.config> --enable_reduced_operator_type_support
      ```

   4. Move the generated ONNX Runtime Android archive file to `<ORT_ROOT>/js/react_native/android/libs/`.

      Full build:
      Copy `<BUILD_DIRECTORY>/aar_out/Release/com/microsoft/onnxruntime/onnxruntime-android/<version>/onnxruntime-android-<version>.aar` into `<ORT_ROOT>/js/react_native/android/libs` directory.

      Reduced size build:
      Copy `<BUILD_DIRECTORY>/aar_out/MinSizeRel/com/microsoft/onnxruntime/onnxruntime-mobile/<version>/onnxruntime-mobile-<version>.aar` into `<ORT_ROOT>/js/react_native/android/libs` directory and update to dependencies in [js/react_native/android/build.gradle](https://github.com/microsoft/onnxruntime/blob/365a01397dbd1293e0c2773380c57fd271432b72/js/react_native/android/build.gradle#L136-L137) to use onnxruntime-mobile instead of onnxruntime-android.


   5. To verify, open the Android Emulator and run this command from `<ORT_ROOT>/js/react_native/android`

      ```sh
      ./gradlew connectedDebugAndroidTest
      ```

3. Build iOS ONNX Runtime package

   1. To use the published C/C++ ONNX Runtime package from CocoaPods, skip all steps below.

   2. Set up iOS build environment using these [instructions](https://onnxruntime.ai/docs/build/ios.html).

   3. Build a fat ONNX Runtime Mobile Framework for iOS and iOS simulator from `<ORT_ROOT>` using this command:

      Full build:
      ```sh
      python tools/ci_build/github/apple/build_ios_framework.py tools/ci_build/github/apple/default_full_ios_framework_build_settings.json --config Release
      ```

      Reduced size build:
      ```sh
      python tools/ci_build/github/apple/build_ios_framework.py tools/ci_build/github/apple/default_mobile_ios_framework_build_settings.json --config MinSizeRel --include_ops_by_config <required_ops_and_types_for_your_models.config> --enable_reduced_operator_type_support
      ```

      The build creates `Headers`, `LICENSE`, and `onnxruntime.xcframework` in `build/iOS_framework/framework_out` directory. From `framework_out` directory, create an archive file named `onnxruntime-c.zip` for a full build or  `onnxruntime-mobile-c.zip` for a reduced size build and copy to `<ORT_ROOT>/js/react_native/local_pods` directory.

      Full build:
      ```sh
      zip -r onnxruntime-c.zip .
      ```

      Reduced size build:
      ```sh
      zip -r onnxruntime-mobile-c.zip .
      ```

   4. To verify, open the iOS Simulator and run the below command from `<ORT_ROOT>/js/react_native/ios`. Change the destination argument as needed to specify a running iOS Simulator.

      If using the reduced size build it is necessary to first update some configuration to use the mobile ORT package:
        - replace `onnxruntime/onnxruntime.framework` with `onnxruntime-mobile/onnxruntime.framework` in /js/react_native/ios/OnnxruntimeModule.xcodeproj/project.pbxproj
        - replace `onnxruntime-c` with `onnxruntime-mobile-c` in /js/react_native/ios/Podfile
        - For reference, [this PR](https://github.com/microsoft/onnxruntime/pull/13037) shows the changes made to switch from using the 'mobile' ORT package to the 'full' package.

      ```sh
      pod install
      xcodebuild test -workspace OnnxruntimeModule.xcworkspace -scheme OnnxruntimeModuleTest -destination 'platform=iOS Simulator,OS=latest,name=iPhone 13'
      ```

4. Test Android and iOS apps. In Windows, open Android Emulator first.

   `debug.keystore` must be generated ahead for Android example.

   ```sh
   keytool -genkey -v -keystore <ORT_ROOT>/js/react_native/e2e/android/debug.keystore -alias androiddebugkey -storepass android -keypass android -keyalg RSA -keysize 2048 -validity 999999 -dname "CN=Android Debug,O=Android,C=US"
   ```

   From `<ORT_ROOT>/js/react_native,

   ```sh
   yarn bootstrap
   ```

   When testing with a custom built ONNX Runtime Android package, copy `<BUILD_DIRECTORY>/aar_out/MinSizeRel/com/microsoft/onnxruntime/onnxruntime-{android|mobile}/<version>/onnxruntime-{android|mobile}-<version>.aar` into the `<ORT_ROOT>/js/react_native/e2e/android/app/libs` directory.

   When testing with a custom built ONNX Runtime iOS package, copy `onnxruntime-[mobile-]c.zip` into the `<ORT_ROOT>/js/react_native/local_pods` directory.

   If using the reduced size build it is necessary to update some configuration to use the mobile ORT package:
     - replace `com.microsoft.onnxruntime:onnxruntime-android` with `com.microsoft.onnxruntime:onnxruntime-mobile` in /js/react_native/e2e/android/app/build.gradle
     - replace `onnxruntime-c` with `onnxruntime-mobile-c` in /js/react_native/e2e/ios/Podfile

   From `<ORT_ROOT>/js/react_native/e2e/android`, run e2e Android tests as follows,

   ```sh
   ./gradlew :app:connectedDebugAndroidTest
   ```

   From `<ORT_ROOT>/js/react_native/e2e/ios`, run e2e iOS tests as follows,

   ```sh
   xcrun xcodebuild test -workspace OnnxruntimeModuleExample.xcworkspace -scheme OnnxruntimeModuleExample -destination 'platform=iOS Simulator,OS=latest,name=iPhone 13'
   ```

   ***`yarn bootstrap` changes `packages.json` and `yarn.lock` files. Once testing is done, restore changes to avoid unwanted commit.***

5. Run Android and iOS apps.

   ```sh
   yarn e2e android
   yarn e2e ios
   ```

### NPM Packaging

1. Update a version using `npm version <version>` from `<ORT_ROOT>/js/react_native` folder. If it's for a dev, use `npm version <version>-dev.<subversion>`

2. Run `npm pack` and verify NPM package contents

3. Run `npm publish <tgz> --dry-run` to see how it's going to be published

4. Run `npm publish <tgz>` to publish to npmjs. If it's for a dev, add flag `--tag dev`.

### Distribution

It should be able to consumed by React Native projects that uses Yarn packages through `yarn add onnxruntime-react-native`.