wasm-compatibility について
marimo NotebookのWebAssembly環境での実行可否を調べる開発者向けのチェック用スキルです。marimoのlintルールと手動確認を組み合わせ、問題点と対処案を報告します。
主な機能
- 01WASM lintルールの実行
- 02依存関係と実行時パターンの確認
- 03並行処理の制約評価
- 04互換性の所見と対処案の作成
活用シーン
- 01Notebookのブラウザー互換性確認
- 02非対応のインポートとシステム呼び出しの特定
- 03パッケージと並行処理のリスク評価
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ marimo-team/ skills --skill wasm-compatibilityインストール後、Claude Code で/wasm-compatibilityを入力して読み込まれたか確認します。
同梱ファイルreferences/pyodide-packages.md
詳細
marimo ノートブックの WASM 互換性チェッカー
marimo ノートブックを WebAssembly(WASM)環境(marimo プレイグラウンド、コミュニティクラウド、またはエクスポートされた WASM HTML)で実行できるか確認します。
手順
1. ノートブックを読む
対象のノートブックファイルを読みます。ユーザーが指定していない場合は、確認するノートブックを尋ねてください。
2. marimo の WASM lint ルールを実行する
marimo には、WASM との互換性の問題のほとんどを自動で検出する lint ルールが 3 つあります。まずこれらを実行し、手作業で再確認するのではなく、その出力に基づいてレポートを作成してください。
marimo check <notebook> --select MW --format json
- MW001
incompatible-import— Pyodide で不足している、または機能しない標準ライブラリモジュール(subprocess、pdb、dbm、resource、fcntl、termios、readline、curses、tkinter、pydecimal、test)に加え、ネイティブの同期機構、共有メモリ、パイプ、またはプロセスのフォークが必要な multiprocessing のエクスポートとサブモジュール(Lock、Condition、Semaphore、Barrier、Manager、Pipe、RLock、shared_memory、ForkContext/ForkProcess、ThreadPoolなど)を検出します。Process、Queue、SimpleQueue、Pool、ProcessPoolExecutorは引き続き許可されます。WASM 互換の協調型アダプター上で実行されます(手順 3 を参照)。 - MW002
unsafe-system-call—os.system()、os.fork()、signal.signal()、breakpoint()など、インポート自体は成功しても Pyodide では失敗する呼び出しを検出します。 - MW003
incompatible-package— ノートブックの PEP 723 依存関係ツリーを解決し(sys_platform != 'emscripten'マーカーによって除外されるものはスキップ)、PyPI で WASM 互換の wheel があるか確認します。たとえば、jax経由で推移的に取り込まれるjaxlibのようなケースを検出します。
注意点: MW001 が検出するのはインポート文(from multiprocessing import Lock、import multiprocessing.synchronize)であり、その後の属性アクセスではありません。import multiprocessing だけを行い、コードの後のほうで multiprocessing.Lock() を呼び出すと、見逃される場合があります。並行処理のコードを含むノートブックでは、手作業でも確認してください。
注意点: MW003 の結果に問題がなくても、それだけでパッケージをブラウザーで安全に使用できるとは限りません。ノートブックでパッケージに sys_platform != 'emscripten' を指定している場合、MW003 はそのパッケージを完全にスキップします。これは、パッケージが WASM にインストールされないことだけを示しており、ノートブックで使用されていないことを示すものではありません。ノートブックに cache_cells = true も設定されていて、--execute を指定してエクスポートされているか確認してください(手順 4 を参照)。そうであれば、除外されたパッケージもキャッシュを通じて使用できます。そうでない場合、除外されたパッケージをインポートまたは参照するコードパスはブラウザーで失敗しますが、MW003 は警告しません。
3. リンターがカバーしない項目を確認する
以下は、エージェント主導で手動確認する項目です。
- PEP 723 メタデータ。 ノートブックに
# /// scriptブロックがない場合、またはdependenciesに記載されていないパッケージをインポートしている場合は、WARN とします。このメタデータがないと、WASM でノートブックを起動したときにパッケージが自動インストールされません。バージョンの固定や下限の指定は問題ありません。marimo は WASM で実行する際にバージョン制約を取り除きます。 - 実行時にのみ発生するパターン。 静的リンターでは次の項目を検出できません。環境変数(
os.environ、os.getenv)の読み取り、実際のファイルシステムがあることを前提としたハードコードの絶対ファイルパスやPath.home()/Path.cwd()の使用、大容量のインメモリデータセット(WASM ノートブックは 2GB が上限です)。見つかった場合は指摘してください。 - 並行処理のセマンティクス。 WASM ノートブックでは、
threading.Thread、Event、local、ThreadPoolExecutor、wait、as_completedおよびプロセス形式のmultiprocessing.Process、Queue、SimpleQueue、Pool、ProcessPoolExecutorに対し、協調型アダプターが実行されます。API の形式は実際のものですが、OS スレッドや共有メモリはなく、真の並列処理も行われません。すべての処理は単一の Pyodide インタープリターで、一度に 1 タスクずつ実行されます。ノートブックが API の形式だけでなく実際の並列処理による高速化に依存している場合は、正しく実行されますが逐次実行になると警告してください。 - キャッシュ済みの実行がすでに設定されている場合。 ノートブックの
pyproject.toml(またはインラインの# /// scriptブロック)で、[tool.marimo.runtime] cache_cells = trueを確認してください。これが設定されている場合、sys_platform != 'emscripten'とマークされた互換性のないパッケージが、自動的に FAIL になるとは限りません。ステップ 4 の回避策を参照してください。
4. レポートを作成する
明確で、実行可能なレポートを出力します。
互換性:PASS / FAIL / WARN
- PASS — リントチェックとステップ 3 の両方で問題が見つかりませんでした。
- WARN — FAIL はありませんが、ステップ 3 で再確認すべき項目(PEP 723 メタデータの欠落、実行時にのみ発生するパターン、または並列ではなく逐次実行される並行処理)が見つかりました。
- FAIL — リントチェックで診断が報告されたか、ステップ 3 でまったく実行できない項目が見つかりました。
リントの指摘事項 — ステップ 2 の診断を(ファイル、行、コード、メッセージを含め)そのまま貼り付けます。
手動確認での指摘事項 — ステップ 3 で見つかった項目を、セルまたは行と修正案とともに列挙します。
推奨事項 — FAIL/WARN のノートブックには、具体的な修正案を提示します。
- 互換性のないパッケージを WASM 対応の代替パッケージに置き換える
- 互換性のないコードパターンを書き換える
WASM ビルドがないパッケージには、そのまま置き換えられる代替パッケージはありません。回避策は 2 つあり、それぞれ解決する問題が異なるため、ノートブックで実際に必要なものを確認してください。
-
到達可能なすべての結果を事前計算してキャッシュする。
sys_platform != 'emscripten'マーカーを使用して、パッケージを WASM の対象から除外します。すると marimo がサーバー側で実際の計算を一度実行し、その結果をエクスポートに含めます。# /// script # dependencies = [ # "marimo", # "torch; sys_platform != 'emscripten'", # ] # # [tool.marimo.runtime] # cache_cells = true # ///marimo export html-wasm notebook.py -o output_dir --executeこれにより、静的な単一の結果(プロットや一度限りの計算など)を直接扱えます。小規模で列挙可能な結果の集合(固定された選択肢を使うドロップダウンやスライダーなど)には、代わりに計算を
@mo.persistent_cache(method="lazy")でデコレートします。エクスポート前に、すべての選択肢についてその関数を一度呼び出すセルを追加してください。事前計算した値のキャッシュを参照してください。いずれの場合も、除外されたパッケージがブラウザーで実行されることはなく、ノートブックはキャッシュ済みの結果を読み取るだけです。 -
ブラウザーで実際の計算を実行する互換性レイヤーを使用する。 連続した範囲にわたるライブ推論をスライダーで操作する場合など、事前に列挙できない入力空間は、事前計算では対応できません。この場合、ノートブックには計算を実行する実際の WASM ネイティブ実装が必要です。
moutils.onnx.OnnxRuntimeは、このパターンの一例です。PyTorch または JAX のモデルを ONNX に変換し、元のフレームワークの代わりにブラウザーのonnxruntime-webで推論を実行するオブジェクトを返します。
追加のコンテキスト
- WASM ノートブックは、ブラウザー内で Pyodide を介して実行されます
- メモリは 2GB に制限されています
- ネットワークリクエストは機能しますが、CORS 対応のエンドポイントが必要な場合があります
- WASM のパフォーマンスは Chrome が最も優れています。Firefox、Edge、Safari もサポートされています
micropipを使用すると、実行時に PyPI から純粋な Python ホイールをインストールできます- marimo の WASM lint ルールの全一覧については、lint ルールのリファレンスを参照してください
- Pyodide に組み込まれたパッケージの手動管理によるスナップショットについては、pyodide-packages.mdを参照してください。すぐに確認できる、人が読みやすいリファレンスですが、
marimo check --select MW003は PyPI に直接問い合わせるため、自動的に最新の状態に保たれます