Jupyter Notebookを簡単にWebアプリ化して公開する仕組みを作った話

こんにちは!Lead Engineerの筒井です。
Insight EdgeにJOINして今月でちょうど一年、いくつかの案件に関わってきました。案件対応の中でJupyter Notebook(以下、Notebook)をWebアプリ化して公開する仕組みを作りましたので紹介します。

背景

今回のタスク(案件の中の1つのタスク)の背景は以下のようなものでした。

  • 事業会社(以下、A社)において、機械学習を利用した予測・分析を事業に活用している
  • A社内のデータサイエンティストが、Notebookを使ってさまざまな予測・分析に対するモデルを作成している
  • A社内の各部署から依頼を受けて、データサイエンティストがNotebook上で予測・分析処理を実行し、結果を提供している

この予測・分析処理を各部署が自分達で実行できるようにすることで、データサイエンティストの雑用を減らして本来業務に工数を集中させるとともに、 依頼から結果取得までの手数とリードタイムを減らして、各部署がいろいろなパターンのパラメータを試せるようにすることを目指します。

対応策の検討

とりあえずJupyter Notebookのコードをもらって改変し、適当なフレームワークに乗せてWebアプリ化すれば良さそうというのが最初の感想でしたが、 この方法では以下のような理由から手離れが悪く、工数が多くかかってしまいます。

  • 適切にコードを改変するには、実装内容の深い理解が必要になる
  • Notebook更新のたびに変更部分の改変とWebアプリへの反映が必要になる
  • 将来増えるものも含め、Notebookごとに都度対応が必要になる

良い方法が無いかと検討していたところ、NotebookをそのままWebアプリ化するMercuryというOSSを見つけ、これを利用することにしました。 また、単に1つのWebアプリを作って終わりではなく、NotebookからWebアプリ化するところもGitHub Actionsを使って仕組み化することにしました。

Mercuryの紹介

関係者ではないのですが、ここで簡単にMercuryを紹介します。

MercuryはNotebookをWebアプリ化するための パーフェクトツール です。

Mercury is a perfect tool to convert Python notebook to interactive web application and share with non-programmers.

基本的な機能

Mercuryの基本的な機能は、

  1. Webアプリ上でNotebookへの入力値を指定するためのウィジェットを作り、
  2. Webアプリ上でNotebookを実行し、実行結果を表示する

ことです。

1のウィジェットは簡単なYAML形式でNotebook上の最初のセルに記載し、その入力値をNotebook内で変数としてそのまま使うことができます。 また、その次のコードセルで、(Webアプリからでなく)直接Notebook環境上で実行した場合の変数の値を指定できる(Webアプリからの実行時はスキップされる)ため、 Pythonコード的には実行時に値を切り替えたい変数を集めたセルを作っているだけで、Notebookの開発やコードへの影響がほぼありません。

その他の機能

その他の機能としては以下のようなものがありますが、活発に開発が進んでおり、これら以外にも多彩な機能を持っているため、 興味が湧いた方はぜひ 公式サイトGitHubリポジトリ を覗いてみることをおすすめします。 なお、本記事の執筆時点で、MercuryにはAGPLv3のOSS版と、コピーレフト関連条項が無く機能追加された有償版(Mercury Pro)があります。

  • 入力内容に応じたウィジェットの作成(スライダーやチェックボックス、ファイルアップロードなど)
  • Pythonコードの表示/非表示切り替え
  • Pythonコードで出力したファイルのダウンロード
  • 複数Notebookのホスティングとポータルページ
  • ユーザー認証とアクセス権制御(Mercury Pro)

出来上がったもの

今回作ったものは下の図のような構成になりました。

Notebookリポジトリ
Webアプリ化したいNotebookを持つGitHubリポジトリ
MercuryRunnerリポジトリ
Notebookリポジトリ内のNotebookをWebアプリ化するのに必要なコードとGitHub ActionsのWorkflowを持つGitHubリポジトリ

利用手順の概要は以下です。

  • (1) Notebookを作成・更新する
  • (2) NotebookリポジトリやNotebookのパス、Cloud Runのスペック等を指定して、GitHub ActionsのWorkflowを手動実行する
  • (3) Notebookリポジトリから、必要なコードを取得する
  • (4) MercuryによってWebアプリ化したコンテナをビルドして、Cloud Run上で実行する
  • (5) Cloud Load BalancingとIAPで、Webアプリに必要な認証をかける(初回のみ)
  • (6) Webアプリを利用する

Notebookの更新をした場合でも、手順の(1)と(2)を実行するだけですぐにWebアプリに反映され、 初回に必要なGCPの設定もさほど難しくないため、Notebookをいつでも簡単に作成・更新できるようになりました。 MercuryRunnerリポジトリとNotebookリポジトリを分けることで、Webアプリのデプロイ時以外は、Mercuryのことを気にする必要が無いようにしています。

GitHubリポジトリやGCPプロジェクトの構成に対する制約と、利用手順の簡便さはトレードオフになるのですが、 今回の案件の状況や、他の事業会社の案件でも今後同じようなパターンがありそうという勝手な予想を鑑みて、その辺りのバランスを決めました。 例えば、GitHubリポジトリやファイルパスを指定する手間がかかる代わりに任意のNotebookリポジトリを指定できるようにしたり、 Cloud Load BalancingやIAPをWebアプリごとに設定する必要がある代わりに、任意のGCPプロジェクトへデプロイできるようにしたりしています。

まとめ

今回は、MercuryとGitHub ActionsとCloud Run(GCP)を使って、Notebookを簡単にWebアプリ化し、継続的にメンテナンスできる仕組みを紹介しました。

上記の通り他の案件でも同様の仕組みが使えないか、自社のメンバーにもこの内容を紹介し、実際他の案件で試しに使ってみてもらっています。もし今後需要があれば、需要の内容に応じていろいろな提供方法が考えられるなと夢想しています。

さて、今回紹介したタスクでは、できるだけInsight Edgeの手を離れ、事業会社のみで自走できることを目指した形になっています。 一般的な受託開発の文脈で考えると、顧客から都度開発・保守を依頼してもらった方が利益が生まれることになりますが、 顧客と利益相反することなく、住友商事グループとしての全体最適を考えられるのが、Insight Edgeの立ち位置の良いところだなぁと改めて感じています。

さまざまなドメインを持つ事業会社の課題解決へ技術面からアプローチしていくことに興味がある方はぜひ、Insight Edgeの公式サイト、採用ページをご覧ください!