Mamba meets Jupyterliteの日本語訳

Hiromasa Ohashi
PyData.Osaka
Published in
16 min readDec 12, 2022

この記事はMamba meets Jupyterliteの日本語翻訳記事です。
typoや翻訳ミスを見つけましたらこちらのリポジトリのissueから報告いただくか、当該記事に対応したmdファイルに対してプルリクエストを発行していただければと思います。

Mamba meets JupyterLite

mambaをベースにしたWebAssembly用パッケージの配布と、Jupyterliteを用いたスケーラブルな計算環境のデプロイ方法について紹介する。

Jupyterliteはサーバーを用いることなくウェブブラウザ内で完全に動作するJupyterのディストリビューションです。
この動作を実現するためには、(Jupyterの)言語カーネルもブラウザ内で動作させなければなりません。

ブラウザ内で静的サイトとして動作するJupyterLite

このアプローチの大きな利点はデプロイが容易となることです。
Jupyterliteがあれば、ライブコンピューティング環境を提供するために必要となるのは静的なアセット群のみとなります。

これにより、予めサーバーアーキテクチャのデプロイを行わずとも、コンソールやノートブックのUIを任意の静的ページやブログへと埋め込むことが可能となります。
このアプローチの拡張性によって、私たちのエコシステム(NumPy, SymPy, Pandas, PyMC, 等々)の内のいくつかのメジャーなプロジェクトはウェブサイト上にインタラクティブに動作する実例を埋め込めるようになり、そこには毎月何百万人ものユーザーが訪れています。

Jupyterliteはインタラクティブなコンソールやノートブックを
サーバーコンポーネントなしでウェブページに埋め込むための
最も簡単でスケーラブルな方法です。

最も有名なJupyterLiteのカーネルはPyolite Pythonカーネルであり、WebAssembly向けのPyodideディストリビューションを元に構築されています。

Pyodideは単にCPythonインタプリタであるだけでなく、NumPy, Pandas, Matplotlibのような多くの科学技術計算パッケージを含んでいます。

Pyodideはまたforeign function interface(FFI)を提供しており、FFIによってJavaScriptからPythonを呼ぶことやその逆を行うことが可能となります。

Pyodide、そしてその先へ

Pyodideは多くの科学技術計算パッケージを提供する一方で、
そのモノリシックな配布モデルでは、Pyodide上にインストールされるPythonのみで書かれたパッケージのバージョンを設定することはできますが、そうではないパッケージのバージョンを指定することはできません。

我々のゴールはパッケージマネージャによる計算環境の構成を可能とし
大規模なソフトウェアパッケージ配布のクラウドソーシングのためにconda-forgeのモデルを採用することです。

計算環境に特定のバージョンのパッケージを固定できることはソフトウェアにおける再現性のために強く要求されます。
実際に、固定されたWebAseembly環境は再現性のタイムカプセルとして捉えることができます。

WebAssemblyはWeb標準化されたものとして認識されており、ネイティブバイナリパッケージよりもはるかに長く実行できるはずです。
つまり、これらはアーキテクチャとプラットフォームの組み合わせに縛られるため、最終的にはエミュレータが必要となるでしょう。

これが我々がEmscriptenを用いて構築されたWebAssemblyパッケージのmambaベースによる配布方法を開発した理由となります。

Emscripten-forge

Mamba/Condaパッケージマネージャを選ぶことは自然です。
その主な強みはコミュニティによってメンテナンスされているパッケージ配布元のconda-forgeであり、
科学技術計算パッケージのデファクトスタンダートな取得元となっています。

conda-forgeの主な強みは、パッケージ配布における強固な技術的基盤と
マルチプラットフォームな特性を持つことに加え、そのソーシャルモデルにあります。
パッケージに関する問題をクラウドソーシングのアプローチによって解決し、
メンテナチーム間での関心の分離と全面的な自動化のバランスを保つことで、
驚くべきメンテナコミュニティを実現しています。

我々はすべてのレシピが同じ空間上に存在するように、この成果をconda-forgeプロジェクトへとコントリビュートすることを予定しています。

Mamba/CondaパッケージマネージャはLinux, OS X(x86とarm64の両方)、Windowsのような多くのプラットフォームとアーキテクチャをサポートしています。
しかしながら、WebAssemblyに属するプラットフォームはまだサポートされていません。

mamba & condaへのWebAseemblyサポートの追加

WebAssemblyプラットフォーム用のcondaパッケージを作成するために、我々はEmscriptenツールチェインに頼りました。

  • 我々はcondaとboaに対して、emscripten-32を省略した名称であるwasm32-unknown-emscriptenと呼ばれる新しいターゲットプラットフォームを定義しました。
    そして、我々はEmscriptenコンパイラを関連付けました。それはこの新しいターゲット用の C/C++ コンパイラとしてcondaパッケージに同封されています。
    これはbzip2zlibなどのような単純なライブラリだけでなく、Pythonのようなより複雑なパッケージを含む多くのパッケージをビルドすることを既に可能としています。
  • Python拡張モジュールに対しては、我々はクロスコンパイルのための仮想環境を作成可能なcrossenvを用い、crossenvをcondaへと統合するためのcross-pythonを用いました。
    クロスコンパイルのための全てのコードとレシピはemscripten-forgeのGitHubリポジトリにホストされています。
  • そして、GitHub actionsを用いてEmscriptenでパッケージをビルドし、それらをパッケージサーバーへとアップロードします。
  • パッケージはQuetzオープンソースサーバのデプロイメント上にホストされます。

これがあれば、ユーザーはemscripten-32ターゲット用の環境を(下記のように)簡単に構築することができるようになります:

micromamba create -n my-env --platform=emscripten-32 \ 
-c https://repo.mamba.pm/emscripten-forge \
-c https://repo.mamba.pm/conda-forge \
python ipython numpy jedi

我々はchannelとしてemscripten-forgeを追加しただけでなく、conda-forgeも追加したことに注意してください。これは全てのnoarchパッケージが使用可能となることを意味します。

新しいパッケージのemscripten-forgeチャンネルへの追加

新しいパッケージを追加するのは簡単な手続きです:

  • リポジトリをforkする https://github.com/emscripten-forge/recipes
  • パッケージに対するフォルダを recipes/recipes_emscripten/<my_package> に作成する
  • パッケージに対してrecipe.yamlrecipes/recipes_emscripten/<your_package>の中に追加する
  • レシピを含むプルリクエストを作成する。プルリクエストがマージされると、パッケージは自動的にemscripten-forgeチャンネルにアップロードされる

JupyterLiteとの統合

Emscriptenパッケージをcondaベースで配布することは一般的な目的に向けたものですが、
当初から特定のアプリケーション:Jupyterliteについても気に留めていました。
既存のPyoliteカーネルはPyodideディストリビューションと非常に密接に結合しているため、我々はxeus-pythonを用いることに決定しました。

(ipykernelではなく)xeus-pythonを選ぶ主な理由はxeusベースのカーネルがあれば、カーネルのコミュニケーション層をオーバーライドすることが可能となるからです(例えばZMQからHTTP/2への切り替え)。
Jupyterliteの場合においては、実装は単純に直接的なJavaScriptの関数呼び出しに依存します。

Jupyterliteのxeusベースのカーネルについての詳細は過去のブログ記事をチェックしてみてください。

完全なPythonでの開発体験の提供

WebAssemblyプラットフォームに残っている制限としてエンドユーザーに完全な体験を提供するための応急措置が必要となることがあります。
例えば、socket は WebAssembly では作ることができず、デフォルトの asyncio イベントループ実装を使用できません。
幸いなことに、Pyodideの作者達はWebLoopと呼ばれるカスタム版のasyncioのイベントループを開発しました、これはPyodideによって提供されるPython-JavaScriptのforeign function interface(FFI)を用いてブラウザのイベントループをラップしたものです。

Pyjsとは

PyodideのFFIを抽出し他のプロジェクトで用いることは簡単ではないため、我々はモダンなPython-JavaScript FFIをスクラッチから実装しました。
これは次のトリックによって実現されています。

  • C++からPythonを呼び出すため、またはその逆を行うためにPybind11が用いられます
  • C++からJavaScriptを呼び出すため、またはその逆を行うためにEmbindが用いられます

Pybind11Embindを同時に用いる場合は、C++を中間に挟むことによって、我々はJavaScriptからPythonを呼び出すことやその逆が可能となります。
これはシンプルなFFIを比較的少ないコードでスクラッチから書くことを可能とするだけでなく、低レベルなCPython APIの呼び出しを避けることができ、その代わりにpybind11::objectemscripten::valのような高レベルな構成要素を用いることを可能とします。
このコードはpyjsリポジトリで使用可能です。
APIはPyodideのものと非常に似通っており、そのためコード中でPyodideのWebLoop実装と同じように代替として用いることが可能です。

デプロイ方法:

xeus-python-kernelはcondaパッケージをPythonランタイム内にプリインストールすることを可能とします。
これはXuesPythonEnv.packagesのCLIオプションをjupyter lite buildに渡すことによって行えるようになります。
次のコマンドはNumPy, Matplotlib, ipyleafletをインストールします。

jupyter lite build --XeusPythonEnv.packages=\
numpy,\
matplotlib,\
ipyleaflet
xeus-pythonカーネルを用いてipyleafletウィジェットが可視化されている例。

xeus-python-kernelのGitHubリポジトリに更なる詳細が載っています。

その将来はどうなるのか?

JupyterLiteとMambaの連携は更に何百万人ものユーザーにJupyterを使用してもらう潜在的な可能性を秘めています。
そのスケーラビリティと、デプロイの容易さ、再現性、そしてアクセシビリティがあれば、
JupyterLiteはあらゆる場所で活用されるでしょう。
つまり、独立したクラウドインフラストラクチャへのアクセスができない国、組織、学校は、
生徒のデータを危険に晒したり、生徒がコントロールしないリソースに依存し過ぎることなく、
実際に所有するサーバー上にJupyterベースの教育プラットフォームを展開することが可能となるでしょう。

「次のステップ」として取り組んでいる項目の要約

  • Mambalite: ランタイム上でのパッケージインストールのサポート。Pyodideのpip-liteと同様に、ランタイム上でパッケージをダウンロードすることを可能とします。
  • Fortran: Emscriptenを用いてFortranのコードをコンパイルすることは現在サポートされていませんが、SciPyのようなキーとなるパッケージで必要不可欠です。PyodideはFortranをCへと変換するコンバータのf2cに依存しており、FortranのコードをEmscriptenでコンパイルするためのパッチの集合を用いています。我々はより直接的な、SciPyをLFortranを用いてコンパイルするアプローチを試しています。
  • Binderlite: Binderはnotebookを含むリポジトリをJupyterLab環境上で実行できるように変換し、コードを即座に誰にでも、どこででも再現可能とするためのものです。普通の JupyterLab インスタンスの代わりに JupyterLite インスタンスに依存するバージョンの Binder となる BinderLite を構築するためピースがEmscripten-forgeには欠けています。
  • Rust/PyO3サポート: 我々はPyodideチームのRust/PyO3サポートに関する成果をemscripten-forgeへ統合することを進めています。これはcryptograpyのようなRustの拡張モジュールをビルドする上で重要となるでしょう。

功績に対する称賛

このプロジェクトは多くの方々の成果の上に成り立っています!

Pyodideチーム

PyodideプロジェクトはMozilla foundationでMichael Droettboomによって始められ、今はHood Chatham, Roman Yurchak, Gyeongjae Choiらによってメンテナンスされています。

Pyodideプロジェクトが実現したブラウザ内でPythonを使用可能にするという基盤となる成果に基づいて、
Jupyterliteから今回の成果に至るまでの全ての成果が生み出されました。

Emscriptenチーム

Pyodideとemscripten-forgeの両方がEmscriptenツールチェイン上に構築され、WebAssemblyのプログラムをWebブラウザ上で意図通りに実行できるようにするための基盤となるコンポーネントを提供しています。

JupyterLiteチーム

JupyterLiteプロジェクトはJeremy Tuloupによって始められ、Nick BollwegMarting Renouらから重要な貢献を受けたプロジェクトです。

Mamba Orgチーム

mambaのエコシステムはこれらの開発を可能にするための手段となりつつあります。
我々はQuestzオープンソースサーバをパッケージのホスティングに利用し、Boaというツールをそれらのパッケージをビルドするために用いています。mamba開発チームにおいて、我々はWolf Vollprecht, Johan Mabille, Joel Lamotte, Andreas Trawögeの成果を強調したいと思います。

Xeusチーム

XeusプロジェクトはJohan MabilleSylvainCorlayによって始められました。
XeusプロジェクトはJupyterLiteへの統合の基礎となり、全てのピース(Xeus, Mamba, Jupyter)をまとめ上げる役割を果たしました。
この JupyterLite との統合における Martin RenouThorsten Beierの功績は特筆すべきです。

謝辞

QuantStackでの Thorsten Beier, Johan Mabille, Martin Renou, Sylvain Corlay, Wolf Vollprecht, Joel Lamotte, Andreas Trawoger らの仕事はBloombergによる資金援助を受けました。

著者達について

Thorsten Beier

Thorsten BeierQuantStackで働く科学ソフトウェアエンジニアです。
QuantStackにジョインする前は、Heidelberg大学でコンピュータサイエンスの学位を取得しEMBLで働きました。
オープンソース開発者として、ThorstenはC++ではxeusxtensor、Pythonではinferno, kipoi, ilastik, napari-splineitなど、さまざまなプロジェクトに貢献しました。

Martin Renou

Martin RenouQuantStackで働く科学ソフトウェアエンジニアです。
QuantStackにジョインする前は、彼は仏・航空宇宙工学学校SUPAEROで学んでいました。
彼はまたパリのLogilabで働き、ケンブリッジのEnthoughtで働きました。
QuantStackにおけるオープンソース開発者として、MartinはC++ではxsimd, xtensor, xframe、PythonとJavaScriptではipyleafletipywebrtcなど、さまざまなプロジェクトに貢献しました。

David Brochart, Sylvain Corlay, Wolf Vollprecht, Jeremy Tuloupに感謝します。

--

--