LoginSignup
7
6

Pyodideは今どれくらいできるのか

Last updated at Posted at 2024-01-24

Pyodide

Pyodideは、CPythonをWebAssembly/Emscriptenに移植したものです。ブラウザ向けのPythonランタイムとも言えます。

2019年にMozillaが発表し、2021年に独立したプロジェクトになりました

発音

以上を参考にカタカナにすると「パイアダイド」?

Pyodideを使う目的

RustやGoなどソースコードをコンパイルしてWebAssemblyバイナリを生成するものは高いパフォーマンスが期待できます。
一方でPyodideはコンパイルをせず実行環境をWebAssemblyに持ってきている方式なので、パフォーマンス面の恩恵は大きくないと思われます。PythonのコードやライブラリをWebフロントエンドに持ってきて、モバイルなど様々な環境でもサーバを使わずに動かせるという点が長所になると思います。

特にPythonはデータサイエンスや科学技術計算まわりでよく使われますが、そういった資産をそのままWebフロントエンドに持ってくるのがPyodideの主な目的のひとつになると思います。

Pyodideの試す

Web上にコンソールがあり、いきなり試せます。

image.png

Pyodideでコードを実装する

とりあえず動かす

公式サイトのサンプルをもとに、こんなHTMLを書きます。

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>

    <script src="https://cdn.jsdelivr.net/pyodide/v0.24.1/full/pyodide.js"></script>
  </head>

  <body>
    <script>
      async function main() {
        let pyodide = await loadPyodide();
        const code = `
from datetime import datetime
now = datetime.now()
now.strftime("ただいま%Y年%m月%d日 %H時%M分%S秒です")
        `;
        window.alert(pyodide.runPython(code));
      };

      main();
    </script>
  </body>
</html>

code変数のテンプレートリテラルに文字列でPythonソースコードが入っています。

ポイントは下記2点です。

  • <script src="https://cdn.jsdelivr.net/pyodide/v0.24.1/full/pyodide.js"></script>でPyodideを読み込む
  • pyodide.runPython()にPythonコードを文字列で与えて実行

HTMLファイルが用意できたら、適当な方法でHTTPサーバを立ち上げます。
PythonやNode.jsがあれば$ python -m http.server 3000$ npx serveとか。Dockerがあれば$ docker run -it --rm -v $(pwd):/app --workdir /app -p 3000:3000 python:3.10-slim python -m http.server 3000とか$ docker run -it --rm -v $(pwd):/app --workdir /app -p 3000:3000 node:alpine npx serveなど、お好みの方法を使えばいいです。

これで、localhostをブラウザで開けばPythonが実行できます。

image.png

パッケージの追加

Pythonの強みのひとつは機械学習などの豊富なパッケージです。Pyodideを使えば、それらをそのままWebフロントエンドで利用できます。

下記のような、scikit-learnで単純な線形回帰をするPythonプログラムを実行したいとします。

Python
import pandas
import numpy
from sklearn import linear_model

df = pandas.DataFrame([
    {"身長": 160, "体重": 57},
    {"身長": 169, "体重": 61},
    {"身長": 180, "体重": 70},
])

reg = linear_model.LinearRegression()
reg.fit(df[["身長"]].values, df["体重"].values)

reg.predict([[175]])[0] #=> 66.16611295681065

pandas,numpy,scikit-learnのパッケージはmicropip.install()で追加できます。

index.html
       async function main() {
         let pyodide = await loadPyodide();
+        await pyodide.loadPackage("micropip");
+        const micropip = pyodide.pyimport("micropip");
+        await micropip.install('numpy');
+        await micropip.install('pandas');
+        await micropip.install('scikit-learn');

これで上記のPythonコードが動くようになります。

ただし、当然100%なんでも動かせるわけではありません。

Micropip can only load pure Python wheels or wasm32/emscripten wheels built by Pyodide.

Pyodideでビルドされたwheelか、pure Pythonで書かれたwheelしか読み込めません。

たとえばtransformersは記事執筆現在ValueError: Can't find a pure Python 3 wheel for 'safetensors>=0.3.1'.というエラーで失敗します。Pyodideで使うにはなんとかしてwasm用ビルドを用意する必要があります。
TransformersにはJavaScriptに移植されたTransformers.jsがありますが、そちらをPyodideで動くようにラップしたTransformers.js.pyというのはあります。

Pyodideを使った色々なアプリケーション

PyScript

PyScriptはPyodideを利用して1HTML内にPythonを埋め込んで実行するためのパッケージです。Anaconda Inc.が開発しています。

Web開発に慣れているなら、サンプルコードを見たほうが話が早いと思います。

<!doctype html>
<html>
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="stylesheet" href="https://pyscript.net/releases/2024.1.1/core.css">
    <script type="module" src="https://pyscript.net/releases/2024.1.1/core.js"></script>
    <title>PyScript Hello World</title>
  </head>

  <body>
    <section>
      Hello world!
      <script type="py">
        from pyscript import display
        from datetime import datetime
        now = datetime.now()
        display(now.strftime("ただいま%Y年%m月%d日 %H時%M分%S秒です"))
      </script>
    </section>
  </body>
</html>

先ほどPyodideを使った例ではJavaScript側にメインの処理があって、文字列としてPythonコードを渡したりしていましたが、PyScriptでは<script type="py">タグの中にPythonコードを記述しています。
パッケージの追加も簡単になります。

<py-config>
{
  "packages": ["pandas", "numpy", "scikit-learn"]
}
</py-config>
<script type="py">
from pyscript import display
import pandas
import numpy
from sklearn import linear_model

df = pandas.DataFrame([
    {"身長": 160, "体重": 57},
    {"身長": 169, "体重": 61},
    {"身長": 180, "体重": 70},
])

reg = linear_model.LinearRegression()
reg.fit(df[["身長"]].values, df["体重"].values)

display(reg.predict([[175]])[0]) #=> 66.16611295681065
</script>

スクラッチでPyodideを利用したWebアプリを開発するなら、PyScriptを使うほうが便利だと思います。

Jupyter Lite

Jupyter Liteは、ブラウザだけで動作するJupyterLabです。デモサイトで試せます。

image.png

JupyterLabを使ったことがあれば、特に何も違和感は無いと思います。見た目はふつうのJupyterLabなので違いが分かりにくいですが、クライアントサイドで動いています。ネットワークがオフラインになっても使えます。

GradioのPyodide版「Gradio-Lite」

Gradioは、Pythonで機械学習アプリケーションをWebに実装して共有するための便利なフレームワークです。Gradio自体はサーバサイドで動くWebアプリケーションですが、そのGradioをPyodideを利用してブラウザに移植したのがGradio-Liteです。

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>

    <script type="module" crossorigin src="https://cdn.jsdelivr.net/npm/@gradio/lite/dist/lite.js"></script>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@gradio/lite/dist/lite.css" />
  </head>
  <body>
    <gradio-lite>
import gradio as gr

def greet(name):
  return f"こんにちは、{name}さん"

gr.Interface(greet, "textbox", "textbox").launch()
    </gradio-lite>
  </body>
</html>

image.png

他にもStreamlitのPyodide版「stlite」もあります。

まとめ

Pyodideを使ってPythonのソースコードをブラウザ上などで動かせるようになります。いくつかの主要なPythonアプリケーションがPyodideに対応しているのもあって、Pythonで開発したアプリケーションをデプロイ・配布する手段のひとつとして選択肢に入ることはあると思います。
一方でPyTorchのサポートが難しいGPUが使えないなどで、本格的な機械学習アプリケーションの開発をすべてPyodideで行うのは今は難しいと思いました。

参考

  1. 厳密にはMicroPythonもサポートしている

7
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
6