What's really exciting is that it's not just a small subset of Python, but everything. You can even import packages like
Matplotlib. The way this works is via Pyodide, a port of the CPython runtime implemented in WebAssembly.
Naturally, I was curious if it was possible to run PyMC through PyScript. On first thought this might seem impossible because PyMC compiles the model evaluation code to C or JAX (through
Aesara also has a Python mode which, while being much slower, is fully functional.
Before, you could have a PyMC model run on the server and then send the results back to the client (i.e. the browser). However, this has a few short-comings:
If we can just run PyMC in the browser directly, all these problems go away. There is no interplay between client and server because everything runs on the client. There are no scaling issues because users use their own CPUs to fit their models. And finally, no data ever gets transmitted to the server, so it's completely safe and privacy preserving.
PyScript it's possible to install any packages that are on
micropip. However, currently only
wheel packages are supported. So the first step was to create and upload wheels for
arviz depends on
netCDF4 which is currently not available in
PyScript. So I created a fork
microarviz which does not rely on
netCDF4. I then created
micropymc which instead requires
microarviz. And... that was it! I could then install
micropymc and import it into
PyScript. Of course, if you want to use this yourself you don't have to repeat my steps, you can just directly install
micropymc. Because we also want interactive plots, we also install
<py-env> - bokeh - micropymc </py-env>
micropymc in your browser and we can
import pymc as pm. Easy-peasy.
Next, we can just embed our Python code in
<py-script> import json from js import Bokeh, JSON from bokeh.embed import json_item from bokeh.plotting import figure import arviz as az # Make arviz use bokeh for interactive plotting az.rcParams["plot.backend"] = "bokeh" import pymc as pm def run_model(n=10, k=5): # Define model with pm.Model() as model: p = pm.Beta("p", alpha=1, beta=1) obs = pm.Binomial("obs", p=p, n=n, observed=k) idata = pm.sample() # Generate plot p = figure(plot_width=500, plot_height=400, toolbar_location="below") az.plot_posterior(idata, var_names=["p"], show=False, ax=p) p_json = json.dumps(json_item(p, "myplot")) Bokeh.embed.embed_item(JSON.parse(p_json)) </py-script>
Note that because
PyMC uses for plotting), has support for
bokeh, a Python-to-JS plotting library, we can also get interactive plots.
There is no 3, you just open the website in your browser, it will install the packages and that's it!
I was surprised by how simple it was to get this going, it took me a couple of hours to put everything together. These are really interesting times we're living in.
So what could we do with this? Well, the possibilities are endless. The main applications will resolve around two possibilities:
Some example applications could be:
This universality is now coming to Python, giving web programmers access to its rich ecosystem, including the PyData stack. And with this blog post, you can also run complex Bayesian models in PyMC.
I cannot wait to see what amazing things the community will produce around this!