-
-
Notifications
You must be signed in to change notification settings - Fork 110
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add: WASM Emscripten example #347
base: main
Are you sure you want to change the base?
Conversation
This comment was marked as off-topic.
This comment was marked as off-topic.
I imagine an even more minimal example / test setup than YoloV8 that is first compiled and then run in the CI within a headless Chromium. We could check the developer console output to determine whether the model was correctly inferred. What do you think? Which model would be suited? Any good example how to use headless Chromium in GitHub workflows? Would this become its own workflow or rather a job in an existing workflow? PS: I guess we could use puppeteer to execute JavaScript code without any |
YOLOv8 is already a pretty good example model - not too simple like the MNIST model, but not too large like GPT-2. I don't know off the top of my head if either supports WASM threads but we should give Node.js or ideally Deno a shot before jumping straight to headless Chromium for CI. Btw, great work here! Until now I didn't think it was even possible to get |
Sure, I can use Deno to test the
|
cbf5276
to
4337eca
Compare
I have observed that you have added mechanisms to provide a precompiled static libonnxruntime for the Emscripten environment. However, when I try to use the |
Like I said in #349 I couldn't get binaries for 1.20.2 but they should be available for 1.21. Keep the current binary mechanism, and don't worry about CI, I'll handle those when 1.21 rolls around 👍 |
Hello 👋,
I noticed that support for the WASM (WASI?) target in this crate has been officially dropped. However, I recently encountered a use case that requires me running
onnxruntime
on the Web. This led me to investigate whetherort
could work within an Emscripten environment.I discovered that this crate can be used as-is with the
wasm32-unknown-emscripten
Rust compilation target! While the setup can get a bit complex—especially when enabling multi-threading inonnxruntime
—it works well. I would love to see this example merged into the official repository, but I also understand if it is considered too experimental to be officially endorsed.Here’s a
.gif
for motivation, showcasing my example using the YoloV8 model to classify objects in pictures on Chromium:The Less Crazy Part
Microsoft does not provide precompiled static libraries for WASM, so I created a GitHub Actions workflow to handle this. The generated
libonnxruntime.a
can be linked withort
as usual—even when targetingwasm32-unknown-emscripten
.To expose Rust functions to JavaScript, the Rust main file must provide a C interface, which Emscripten can export. I use
rust-embed
to bundle the.onnx
model into the.wasm
. Anindex.html
file then incorporates the.js
and.wasm
outputs, which include the compiled Rust code,onnxruntime
, and the model.Additionally, the Emscripten SDK version used by the Rust compiler must match the exact version used by
onnxruntime
for successful linking.The Crazy Part
Things get trickier when enabling multi-threading in
onnxruntime
. Since v1.19.0, Microsoft recommends enabling multi-threading using the--enable_wasm_threads
build flag. This linkslibonnxruntime.a
topthread
, meaning all linked objects—including Rust’s standard library—must also be compiled withpthread
support.However, Rust’s standard library is not compiled this way by default, so you must switch to Rust nightly and compile the Rust standard library with
+atomics,+bulk-memory,+mutable-globals
.Additionally, the server must set specific CORS flags, as multi-threaded Emscripten uses
SharedArrayBuffer
in the Web browser, which requires these settings.Verdict
I am already opening the pull request as a draft to get early feedback. However, at least following ToDos are pending before a pull request could happen:
ort
's precompiled staticlibonnxruntime
mechanism.In the future, I would love to see Web-exclusive execution providers to be available in
ort
: