HackerTrans
TopNewTrendsCommentsPastAskShowJobs

Py2wasm – A Python to WASM Compiler(wasmer.io)

193 points·by fock·2 lata temu·49 comments
wasmer.io
Py2wasm – A Python to WASM Compiler

https://wasmer.io/posts/py2wasm-a-python-to-wasm-compiler

174 comments

wdroz·2 lata temu
> py2wasm converts your Python programs to WebAssembly, running them at 3x faster speeds

This is clearly written in the article, but I hope that the impatient readers will understand that this is 3 times faster than the CPython wasm, not the native CPython.
5-·2 lata temu
even more specifically, 3 times faster than wasmer's build of cpython (whatever that is), running on their runtime.

i'd be curious to see this benchmark extended, as in my own experience toying with python-like interpreters, you get ~2x slowdown (like their end result) from just compiling to wasm/wasi with clang and running in any 'fast' runtime (e.g. node or wasmtime).
syrusakbary·2 lata temu
Hey, I'd love to reproduce the ~2x slowdown you commented from running the workload in Native CPython compared to Wasm CPython (in any runtime, browser or outside).

Any tip would be helpful so we can debug it. If your claims are accurate, we can easily get py2wasm even running faster than native CPython!

Note: we benchmarked in a M3 Max laptop, so maybe there's some difference there?
kelp·2 lata temu
Here is a trivial example, also on a M3 Max:

  cat hello.py
  print("Hello, Wasm!")

  time python3 ./hello.py
  Hello, Wasm!

  ________________________________________________________
  Executed in   26.86 millis    fish           external
     usr time   16.37 millis    0.13 millis   16.24 millis
     sys time    7.25 millis    1.14 millis    6.11 millis

  time wasmer hello.wasm
  Hello, Wasm!

  ________________________________________________________
  Executed in   84.77 millis    fish           external
     usr time   50.26 millis    0.14 millis   50.12 millis
     sys time   28.97 millis    1.21 millis   27.76 millis

  time wasmtime hello.wasm
  Hello, Wasm!

  ________________________________________________________
  Executed in  141.72 millis    fish           external
     usr time  120.86 millis    0.13 millis  120.72 millis
     sys time   16.65 millis    1.20 millis   15.45 millis
[deleted]·2 lata temu
5-·2 lata temu
note that i'm not claiming 2x slowdown for cpython.

but here's one test i've run just now:

using your test file, i've run this one-liner on my x86_64 linux laptop in https://pyodide.org/en/stable/console.html in chromium (v8) and natively (pyodide's urllib doesn't handle https for some reason):

   import requests;exec(requests.get('https://gist.githubusercontent.com/syrusakbary/b318c97aaa8de6e8040fdd5d3995cb7c/raw/1c6cc96cf98bd7bd41c81ba9d10dc4d19b1c3e53/pystone.py').text)
native: ~470k

pyodide: ~200k

i.e. ~2.4x slowdown
syrusakbary·2 lata temu
Thanks!

That should help us a lot to investigate further the difference in timing. I remember trying the py2wasm strategy about 4 years ago, and I got it running faster than native CPython, so there must be something we are missing!
[deleted]·2 lata temu
IshKebab·2 lata temu
Yeah more honest would have been "2x slower"!
williamstein·2 lata temu
Even more honest would be “on one particular microbenchmark that everybody optimizes for”.

That said, this seems like a really cool project that could have some real value! It still fully depends on having the full CPython runtime environment, but that means it could work correctly with most existing code and libraries (including numpy and script).
wasiwin·2 lata temu
From what I could tell, Nuitka dynamically loads extension modules so this wouldn't work with Webassembly modules which are statically linked. If I could be enhanced to automatically build wheels of packages like numpy and statically link them, then that could bring extensions to Wasm and be very cool. IIRC, Google does this with their Python apps so the concept does exist but don't think I've seen any OSS tooling trying that.
boomskats·2 lata temu
So I had a look at the repo/branches at https://github.com/wasmerio/py2wasm. This might be a nit, but in the spirit of OSS: if I'd done this work, I'd have contributed it to upstream Nuitka. I definitely would not have forked a whole new GitHub repo and given it a completely different name.

What's the rationale for creating a new project and calling it py2wasm? Am I missing something?
syrusakbary·2 lata temu
Thanks for the feedback! I'm Syrus, main author of the work on py2wasm.

We already opened a PR into Nuitka to bring the relevant changes upstream: https://github.com/Nuitka/Nuitka/pull/2814

We envision py2wasm being a thin layer on top of Nuitka, as also commented in the article (not a fork as it is right now, although forking got us into the proof of concept a bit faster!).

From what we gathered, we believe that there's usefulness on having py2wasm as a separate package, as py2wasm would also need to ship the precompiled Python distribution (3.11) for WASI (which will not be needed for the other Nuitka use cases), apart of also shipping other tools that are not directly relevant for Nuitka
theanonymousone·2 lata temu
On a different note, will there some technical documents on how exactly to use it, e.g. exporting functions etc...?

By the way is it an alpha release, usable for testing, or something in between?
spencerflem·2 lata temu
Reading the blog post- they are contributing it upstream
boomskats·2 lata temu
Well, reading the blog post, they're announcing a whole new compiler. I'd encourage you to have a look at the PR their post links to.
Ennea·2 lata temu
My first thought upon reading Nuitka's name in the article was along the lines of "I hope they've contributed some of this to Nuitka". Not a very nice trend.
__s·2 lata temu
What trend?

Forking happens all the time. It's one of the benefits of open source. I've often made PRs on github to projects while shifting projects I work on to my fork since upstreaming can take months or often never happen

Granted, Nuitka is an active project, but wasmer.io is going to have a much more focused desire with their changes that they can deploy, meanwhile getting it upstream will have to go through rounds of review & adjustments

https://github.com/rustwasm/wasm-pack/pull/937 this small change took over 2 years to merge. Open source takes time
ubj·2 lata temu
Nice--it's great to see more options for interoperability between Python and WASM. I was aware of Pyodide [1], but Py2wasm seems to be a tool for compiling specific scripts into WASM rather than having an entire Python distribution in the browser. Please correct me if I'm misunderstanding the difference between the two however.

[1]: https://pyodide.org/en/stable/
theanonymousone·2 lata temu
That's my understanding as well. And Pyodide being a great piece of engineering, is still lagging behind compiled Wasm languages in terms of footprint at least and performance sometimes, unfortunately.
umvi·2 lata temu
What's up with the botspam in this thread? Looks like hundreds of sex bot accounts are being created. Pages seem really slow to load currently... someone should notify dang.
ptx·2 lata temu
How come the CPython interpreter is so slow when compiled to WebAssembly? According to the figures in the article, it runs at 23% the speed of the native version.

Wasmer, which they're using in the benchmarks, should run code "at near-native speeds" according to the docs[0]. Apparently it has multiple compiler backends, so maybe the choice of backend affects the result?

[0] https://docs.wasmer.io/runtime
spankalee·2 lata temu
With WasmGC finalized, I hope we see more compilers that target it instead of including their own GC.

It's could be a new interpreter, or maybe a version of CPython that uses WasmGC structs for all Python objects, or a compiler similar to this but that targets WasmGC directly.
Jasper_·2 lata temu
WasmGC is not really what you think it is. Think of it as a full-on replacement for the linear memory model, not as a way to add GC to it.

It's exceptionally difficult to port a language runtime over to WasmGC -- it doesn't even offer finalizers, so __del__ can't implemented correctly (even ignoring the issues with existing __del__ semantics in Python leading to compatibility issues). It doesn't support interior pointers, so you can't have a pointer into the middle of an array.

There's no easy way to port Python to WasmGC.
kevingadd·2 lata temu
Current WasmGC is missing a lot of critical features for production grade GC, like finalization and interior pointers. It's really promising though, so I think once the gaps get filled in you'll see a bunch of runtimes start moving over - maybe .NET, etc.
grondilu·2 lata temu
Nice. Maybe a pie in the sky but considering how prevalent python is in machine learning, how likely is it that at some point most ML frameworks written in python become executable on a web browser through WASM?
ilyaraz90·2 lata temu
You can already run inference of many modern ML models in-browser via, e.g., https://huggingface.co/docs/transformers.js/en/index .
lmeyerov·2 lata temu
Last we checked for one of our use cases around sandboxing, key pydata libraries were slowly moving there, but it takes a village.

At that time, I think our blockers were Apache Arrow, Parquet readers, and startup time. There were active issues on all three. The GPU & multicore thing is a different story.as that is more about Google & Apple than WASM wrt browsers, and I'd be curious about the CUDA story serverside. We didn't research the equivalent of volume mounts and shmem for fast read-only data imports.

For Louie.AI, we ended up continuing with serverside & container-based sandboxing (containers w libseccomp, nsjail, disabled networking, ...).

Hard to motivate wasm in the server for general pydata sandboxing in 2024 given startup times, slowdowns, devices, etc: most of our users who want the extra protection would also rather just self-host, decreasing the threat model. Maybe look again in 2025? It's still a good direction, just not there yet.

As a browser option, or using with some more limited cloud FaaS use cases, still potentially interesting for us, and we will keep tracking.
miohtama·2 lata temu
Pyarrow is giving a headache trying to get it compiled with Emscripten
lmeyerov·2 lata temu
An irony here is that we donated the pure JS/TS implementation of arrow to apache
Beretta_Vexee·2 lata temu
Python in ML acts as a glue language for loading the data, the interface, api, et. The hard work is done by C libraries running in parallel on GPUs.

Python is quite slow, and handles parallelization very badly. This is not very important for data loading and conditioning tasks, which would benefit little from parallelization, but it is critical for inference.
miohtama·2 lata temu
Depending on the underling machine learning activity (GPU/no-GPU) it should be already possible today. Any low level machine learning loops are raw native code or GPU already and Python’s execution speed is irrelevant here.

The question is do the web browsers and WebAssembly have enough RAM to do any meaningful machine learning work.
westurner·2 lata temu
WebGL, WebGPU, WebNN

Which have better process isolation; containers or Chrome's app sandbox at pwn2own how do I know what is running in a WASM browser tab?

JupyterLite, datasette-lite, and the Pyodide plugin for vscode.dev ship with Pyodide's WASM compilation of CPython and SciPy Stack / PyData tools.

`%pip install -q mendeley` in a notebook opened with the Pyodide Jupyter kernel works by calling `await micropip.install(["mendeley"])` IIRC.

picomamba installs conda packages from emscripten-forge, which is like conda-forge: https://news.ycombinator.com/item?id=33892076#33916270 :

> FWIU Service Workers and Task Workers and Web Locks are the browser APIs available for concurrency in browsers

sqlite-wasm, sqlite-wasm-http, duckdb-wasm, (edit) postgresql WASM / pglite ; WhatTheDuck, pretzelai ; lancedb/lance is faster than pandas with dtype_backend="arrow" and has a vector index

"SQLite Wasm in the browser backed by the Origin Private File System" (2023) https://news.ycombinator.com/item?id=34352935#34366429

"WebGPU is now available on Android" (2024) https://news.ycombinator.com/item?id=39046787

"WebNN: Web Neural Network API" https://www.w3.org/TR/webnn/ : https://news.ycombinator.com/item?id=36159049

"The best WebAssembly runtime may be no runtime" (2024) https://news.ycombinator.com/item?id=38609105

(Edit) emscripten-forge packages are built for the wasm32-unknown-emscripten build target, but wasm32-wasi is what is now supported by cpython (and pypi?) https://www.google.com/search?q=wasm32-wasi+conda-forge
movpasd·2 lata temu
The actual underlying models run in a lower-level language (not Python).

But with the right tool chain, you already can do this. You can use Pyodide to embed a Python interpreter in WASM, and if you set things up correctly you should be able to make the underlying C/FORTRAN/whatever extensions target WASM also and link them up.

TFA is compiling a subset of actual raw Python to WASM (no extension). To be honest, I think applications for this are pretty niche. I don't think Python is a super ergonomic language once you remove all the dynamicity to allow it to compile down. But maybe someone can prove me wrong.
calebkaiser·2 lata temu
We implemented an in-browser Python editor/interpreter built on Pyodide over at Comet. Our users are data scientists who need to build custom visualizations quite often, and the most familiar language for most of them is Python.

One of the issues you'll run into is that Pyodide only works by default with packages that have pure Python wheels available. The team has developed support for some libraries with C dependencies (like scikit-learn, I believe), but frameworks like PyTorch are particularly thorny (see this issue: https://github.com/pyodide/pyodide/issues/1625 )

We ended up rolling out a new version of our Python visualizations that runs off-browser, in order to support enough libraries/get the performance we need: https://www.comet.com/docs/v2/guides/comet-ui/experiment-man...
thangngoc89·2 lata temu
For popular ML/DL models, you could already export model to ONNX format for interference. However, glue codes are still python and you may need to replace that part with the host’s language
theanonymousone·2 lata temu
It may be a stupid question, but is there already some DOM access or a dedicated package that allows writing web applications in this compiled python?
miohtama·2 lata temu
Yes. Here is an example how to integrate Python to React front end

https://blog.pyodide.org/posts/react-in-python-with-pyodide/

Similar examples for raw DOM manipulation should be available for Pyodide as well. It has bindings to all JS code, so it can do everything that JS can do.
theanonymousone·2 lata temu
Thanks. I know about the one for Pyodide. Is it confirmed that it works for this new py2wasm compiler?
vimota·2 lata temu
> We worked on py2wasm to fulfill our own needs first, as we want to accelerate Python execution to the maximum, so we can move our Python Django backend from Google Cloud into Wasmer Edge.

I was under the impression that Django was stateful and not meant to be run in a serverless/edge cloud. Is that not the case or are you planning to do a special setup to support that?
weinzierl·2 lata temu
I want the opposite. The Python VM is everywhere. Can't I just run my WASM on Python? (The WASM runtime must be pure Python, installing C/C++ extensions is against the spirit of this.)
hathawsh·2 lata temu
Hmm, what I want is to run WASM using a CPython extension. CPython extensions are vital to Python. I'm curious why you say an extension is against the spirit of it.
Rucadi·2 lata temu
I mean, the performance would be abysmal.
[deleted]·2 lata temu
lenerdenator·2 lata temu
Would it be too late to call it PyToWasm?

I know Python 2 has been EOL for over four years now but you still see it (much to the chagrin of decent engineers everywhere) in the wild; could generate confusion.
lagt_t·2 lata temu
What's the hello world wasm file size?
kelp·2 lata temu


  ls -lh hello.wasm
  -rw-r--r--@ 1 tcole  staff    24M Apr 22 14:18 hello.wasm
This is on macOS. That is hello.py compiled to wasm with Py2wasm.
syrusakbary·2 lata temu
Indeed, this can be way further optimized. For example, you can probably do a wasm-strip and wasm-opt passes that would leave the wasm file being ~5-10Mb. Still very big, but a bit more reasonable.

The good thing is that thanks to Nuitka you could actually do some tree shaking and only include the imported files and not everything in between (although this might break other behavior such as eval and so).
theanonymousone·2 lata temu
You got it to work? For me it complains about some header files missing and breaks the nuitka installed on the system.
somesun·2 lata temu
I wonder what's the meaning of doing this , if hello world program need 20M to download before run ?
theanonymousone·2 lata temu
Wow! 24M makes it even less practical than interpreted pyodide.
spxneo·2 lata temu
so does this mean we can run FastAPI inside a browser?
SEXMCNIGGA7245·2 lata temu
SEXMCNIGGA873·2 lata temu
SEXMCNIGGA20011·2 lata temu
SEXMCNIGGA45429·2 lata temu
SEXMCNIGGA44908·2 lata temu
SEXMCNIGGA43492·2 lata temu
SEXMCNIGGA14809·2 lata temu
SEXMCNIGGA28008·2 lata temu
SEXMCNIGGA34706·2 lata temu
SEXMCNIGGA33367·2 lata temu
SEXMCNIGGA38282·2 lata temu
SEXMCNIGGA18460·2 lata temu
2genders25554·2 lata temu
SEXMCNIGGA30273·2 lata temu
SEXMCNIGGA8979·2 lata temu
SEXMCNIGGA27931·2 lata temu
SEXMCNIGGA37114·2 lata temu
SEXMCNIGGA34137·2 lata temu
SEXMCNIGGA20534·2 lata temu
2genders47876·2 lata temu
SEXMCNIGGA504·2 lata temu
SEXMCNIGGA7379·2 lata temu
SEXMCNIGGA40191·2 lata temu
SEXMCNIGGA25974·2 lata temu
SEXMCNIGGA10750·2 lata temu
SEXMCNIGGA43331·2 lata temu
2genders22750·2 lata temu
SEXMCNIGGA18150·2 lata temu
SEXMCNIGGA2949·2 lata temu
SEXMCNIGGA22606·2 lata temu
SEXMCNIGGA44847·2 lata temu
SEXMCNIGGA44676·2 lata temu
SEXMCNIGGA32196·2 lata temu
SEXMCNIGGA23941·2 lata temu
SEXMCNIGGA15779·2 lata temu
2genders28600·2 lata temu
2genders716·2 lata temu
2genders13908·2 lata temu
2genders13469·2 lata temu
2genders37544·2 lata temu
2genders46966·2 lata temu
2genders12752·2 lata temu
SEXMCNIGGA19328·2 lata temu
SEXMCNIGGA26559·2 lata temu
SEXMCNIGGA29758·2 lata temu
barfard·2 lata temu
indianmilf44940·2 lata temu
indianmilf7653·2 lata temu
indianmilf32545·2 lata temu
indianmilf28572·2 lata temu
indianmilf36765·2 lata temu
2genders6254·2 lata temu
2genders20124·2 lata temu
SEXMCNIGGA15477·2 lata temu
2genders19703·2 lata temu
indianmilf34967·2 lata temu
indianmilf7542·2 lata temu
sexmc19673·2 lata temu
sexmc10662·2 lata temu
indianmilf41566·2 lata temu
sexmc26257·2 lata temu
sexmc6561·2 lata temu
2genders15635·2 lata temu
2genders37480·2 lata temu
2genders29067·2 lata temu
2genders5140·2 lata temu
2genders20299·2 lata temu
sexmc39654·2 lata temu
2genders31778·2 lata temu
SEXMCNIGGA7771·2 lata temu
sexmc21258·2 lata temu
sexmc22673·2 lata temu
sexmc41709·2 lata temu
sexmc20177·2 lata temu
sexmc32904·2 lata temu
sexmc21609·2 lata temu
sexmc28768·2 lata temu
2genders25672·2 lata temu
2genders10659·2 lata temu
2genders46577·2 lata temu
2genders20059·2 lata temu
2genders37005·2 lata temu
2genders7267·2 lata temu
2genders34842·2 lata temu
2genders10037·2 lata temu
2genders46677·2 lata temu
2genders3617·2 lata temu
SEXMCNIGGA12823·2 lata temu
SEXMCNIGGA22197·2 lata temu
SEXMCNIGGA32276·2 lata temu
SEXMCNIGGA43288·2 lata temu
SEXMCNIGGA26313·2 lata temu
SEXMCNIGGA5794·2 lata temu
SEXMCNIGGA26666·2 lata temu
SEXMCNIGGA20545·2 lata temu
SEXMCNIGGA22793·2 lata temu
SEXMCNIGGA40029·2 lata temu
SEXMCNIGGA27725·2 lata temu
SEXMCNIGGA26553·2 lata temu
SEXMCNIGGA9292·2 lata temu
SEXMCNIGGA2036·2 lata temu
SEXMCNIGGA45669·2 lata temu
SEXMCNIGGA237·2 lata temu
2genders20975·2 lata temu
SEXMCNIGGA31119·2 lata temu
SEXMCNIGGA6180·2 lata temu
SEXMCNIGGA41234·2 lata temu
SEXMCNIGGA19401·2 lata temu
2genders12521·2 lata temu
2genders39997·2 lata temu
SEXMCNIGGA19236·2 lata temu
2genders17397·2 lata temu
SEXMCNIGGA47748·2 lata temu
2genders35549·2 lata temu
2genders48337·2 lata temu
2genders24085·2 lata temu
SEXMCNIGGA30430·2 lata temu
SEXMCNIGGA15705·2 lata temu
SEXMCNIGGA38268·2 lata temu
SEXMCNIGGA14282·2 lata temu
2genders45784·2 lata temu
SEXMCNIGGA30292·2 lata temu