Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Notebook as Web API ~Turn your notebook into Web API~

Kazuki Yokoishi
September 18, 2018

Notebook as Web API ~Turn your notebook into Web API~

Presentation slides for PyCon JP 2018

Kazuki Yokoishi

September 18, 2018
Tweet

Other Decks in Technology

Transcript

  1. 1 © NEC Corporation 2018 Notebook as Web API ~Turn

    your notebook into Web API~ PyCon JP 2018 NEC 横石 和貴
  2. 4 © NEC Corporation 2018 自己紹介 横石和貴 NECソリューションイノベータ 分析プラットフォーム”NEC Advanced

    Analytics Platform”の開発 データサイエンティストに分析環境、分析ツールを提供するプラットフォーム
  3. 6 © NEC Corporation 2018 Notebook as Web API? ▌Notebookに書いた処理をアプリケーションから使いたいことがある

    私の担当する分析プラットフォーム“NEC Advanced Analytics Platform”の場合 NEC Advanced Analytics Platform 1. Notebookを使っ てアヤメを分類する モデルをつくる データサイエンティスト アプリケーション 開発者 3. 予測処理を アプリに組み込む アヤメ仕分け アプリ アヤメを分類 するモデル 学習 Notebook 2. Notebookに予測処理 (アヤメを分類する処理) を書く 予測 Notebook OUT IN アヤメの分類機能 を使いたい Notebookの予測処理を アプリケーションから Web APIで呼びたい
  4. 8 © NEC Corporation 2018 Notebookに書いたコードのWeb API化 ▌Notebookに書いたコードをWeb APIにするのは手間がかかる Web

    APIとして呼び出すまでのステップ 1. Notebook作成 2. Pythonスクリプト作成 3. Web API実装 4. Web APIサーバ起動 5. Web API実行 Notebookに書いたコードを また書かなければいけない… 予測機能を使いたいだけなのに リクエストをパースしたり、 レスポンスを組み立てないと…
  5. 10 © NEC Corporation 2018 Notebookに書いたコードのWeb API化 ▌1. Notebook作成 -

    学習用データセットを準備 target アヤメの名前 0 setosa 1 versicolor 2 virginica
  6. 13 © NEC Corporation 2018 ### iris.py ### import pickle

    import pandas as pd def classify_iris( sepal_length, sepal_width, petal_length, petal_width, model_file): # In [1] with open(model_file, 'rb') as f: clf = pickle.load(f) # In [3] IRIS_NAMES = { 0: 'setosa', 1: 'versicolor', 2: 'virginica' } result = clf.predict([ [sepal_length, sepal_width, petal_length, petal_width] ]) return IRIS_NAMES[result[0]] Notebookに書いたコードのWeb API化 ▌2. Pythonスクリプト作成 - 予測するコードをPythonスクリプト化 Notebookに書いたコードを また書かなくてはならない
  7. 14 © NEC Corporation 2018 Notebookに書いたコードのWeb API化 ▌3. Web API実装

    ### app.py ### from bottle import request, route, run, HTTPResponse import json from .iris import classify_iris @route('/iris', method='GET') def iris(): res = HTTPResponse(headers={'Content-Type': 'application/json'}) try: sep_len = float(request.query['sepalLength']) sep_wid = float(request.query['sepalWidth']) pet_len = float(request.query['petalLength']) pet_wid = float(request.query['petalWidth']) except KeyError as e: res.status = 400 err = {'err': '{} must be specified'.format(e)} res.body = json.dumps(err) return res except ValueError as e: res.status = 400 err = {'err': 'query param must be float type'} res.body = json.dumps(err) return res res.status = 200 result = classify_iris(sep_len, sep_wid, pet_len, pet_wid) res.body = json.dumps({'iris_name': result}) return res run(host='localhost', port=8080) 少なくともこれくらいの コード量を書く必要あり
  8. 15 © NEC Corporation 2018 Notebookに書いたコードのWeb API化 ▌3. Web API実装

    ### app.py ### from bottle import request, route, run, HTTPResponse import json from .iris import classify_iris @route('/iris', method='GET') def iris(): res = HTTPResponse(headers={'Content-Type': 'application/json'}) try: sep_len = float(request.query['sepalLength']) sep_wid = float(request.query['sepalWidth']) pet_len = float(request.query['petalLength']) pet_wid = float(request.query['petalWidth']) except KeyError as e: res.status = 400 err = {'err': '{} must be specified'.format(e)} res.body = json.dumps(err) return res except ValueError as e: res.status = 400 err = {'err': 'query param must be float type'} res.body = json.dumps(err) return res res.status = 200 result = classify_iris(sep_len, sep_wid, pet_len, pet_wid) res.body = json.dumps({'iris_name': result}) return res run(host='localhost', port=8080) 多くがボイラープレート ・APIのルーティング設定 ・HTTPヘッダの設定 ・クエリストリングからパラメータの取得 ・ステータスコードの設定 ・レスポンスボディのJSONシリアライズ ・APIサーバの設定、起動
  9. 16 © NEC Corporation 2018 Notebookに書いたコードのWeb API化 ▌4. Web APIサーバ起動

    ▌5. Web API実行 $ python app.py $ curl -H 'Accept: application/json' -G ¥ --data-urlencode 'sepalLength=5.8' ¥ --data-urlencode 'sepalWidth=4.0' ¥ --data-urlencode 'petalLength=1.2' ¥ --data-urlencode 'petalWidth=0.2' ¥ 'http://localhost:8080/iris' # => {"iris_name": "setosa"}
  10. 17 © NEC Corporation 2018 Notebookに書いたコードのWeb API化 ▌Notebookに書いたコードをWeb APIにするのは大変 1.

    NotebookからPythonスクリプトに実装しなおさなければならない 2. Web APIとして呼び出すためのボイラープレートコードを多く書かなければならない NotebookをWeb APIにするためのよいしくみがないものか まずはOSSを探してみる
  11. 19 © NEC Corporation 2018 NotebookをWeb APIにする既存のしくみ ▌Jupyter Kernel Gateway

    Jupyterのオフィシャルプロジェクト • https://github.com/jupyter/kernel_gateway notebook-http mode • Jupyter Kernel Gatewayの実行モードの1つ – 資料で”Jupyter Kernel Gateway”という場合この実行モードを指す • NotebookのセルをWeb APIとしてアクセス可能にする calc.ipynb Jupyter Kernel Gateway HTTP Client GET /calc/add?x=10&y=5 {“result”: 15.0} GET /calc/sub?x=10&y=5 {“result”: 5.0} エンドポイントの設定 リクエスト情報が渡される
  12. 20 © NEC Corporation 2018 NotebookをWeb APIにする既存のしくみ ▌Jupyter Kernel Gatewayによる予測NotebookのWeb

    API化 予測するNotebookのコードを別のNotebookの1つのセルに移す ボイラープレートは 減らせた! セルをコピペするのは 変わらない
  13. 21 © NEC Corporation 2018 NotebookをWeb APIにする既存のしくみ ▌Jupyter Kernel Gatewayによる予測NotebookのWeb

    API化 Jupyter Kernel Gatewayを起動 Web APIを実行 $ curl -H 'Accept: application/json' –G ¥ --data-urlencode "sepalLength=3.0" ¥ --data-urlencode "sepalWidth=4.8" ¥ --data-urlencode "petalLength=1.2" ¥ --data-urlencode "petalWidth=0.2" ¥ 'http://localhost:8888/iris' # => setosa $ jupyter-kernelgateway ¥ --KernelGatewayApp.api="kernel_gateway.notebook_http" ¥ --KernelGatewayApp.seed_uri="iris-predict.ipynb"
  14. 22 © NEC Corporation 2018 NotebookをWeb APIにする既存のしくみ ▌Jupyter Kernel Gatewayを使った場合のWeb

    API化のステップ 1. Notebook作成 2. Pythonスクリプト作成 3. Web API実装 4. Web APIサーバ起動 5. Web API実行 1. Notebook作成 2. Jupyter Kernel Gateway用Notebook作成 4. Web API実行 Jupyter Kernel Gatewayを使えば 手間は減るが… Notebookの良さで ある対話的なコード の実行ができない 3. Jupyter Kernel Gateway起動
  15. 23 © NEC Corporation 2018 NotebookをWeb APIにする既存のしくみ ▌Jupyter Kernel Gatewayの課題

    NotebookをWeb APIとして 実行するしくみをつくろう! REQUESTという独自の変数を セルに持つ必要がある Jupyter Kernel Gatewayが値を 注入する変数なので対話的に 実行すれば未定義の変数である Web API化する Notebookは対話的に 実行可能ではない Webフレームワーク使うのも大変… 使えるツールもまだない…
  16. 25 © NEC Corporation 2018 nbexecとは NotebookをWeb APIとして実行するためにつくったJupyter extension 2018/09/18時点では社内プロジェクトで非公開(OSS化にむけて検討中です)

    PyPIに公開されているnbexecは別のもの nbexecを使えばNotebookをそのままWeb APIとして呼び出せる nbexecを使うと... 1. Notebook作成 2. Pythonスクリプト作成 3. Web API実装 4. Web APIサーバ起動 5. Web API実行 1. Notebook作成 2. Web API実行
  17. 26 © NEC Corporation 2018 nbexecを使ってできること 1. HTTPリクエストでNotebookを実行 2. セルへパラメータを定義

    3. NotebookからWeb APIドキュメントを生成 POST /api/executions {“notebook”: “hello.ipynb”} Notebook Server Notebook HTTP Client Notebook {“hello”: “world”} execute hello.ipynb Notebook Server read generate
  18. 27 © NEC Corporation 2018 nbexecでできること 1. Notebookの実行 ▌予測するNotebookをそのままWeb APIとして実行

    実行 Web API化のための ボイラープレートを 書く必要はない! $ curl -X POST ¥ -H 'Accept: application/json' ¥ --data-urlencode "notebook=iris-predict.ipynb ¥ http://localhost:8888/api/executions Notebook ServerのURL 実行するNotebook localhost:8888/notebooks/iris-predict.ipynb
  19. 28 © NEC Corporation 2018 ▌Notebook実行の仕組み Notebookを実行するExecutionHandlerを実装 Notebook Serverへエンドポイント”/api/executions”を拡張 もう少し詳しい話は付録に記載

    HTTP Client Notebook Server Notebook (.ipynb) POST /api/executions execute HTTP response ExecutionHandler nbexecでできること 1. Notebookの実行
  20. 31 © NEC Corporation 2018 nbexecでできること 2. パラメータ定義 ▌パラメータ定義に特別なコードは不要 パラメータ定義はただのコメント+dictの作成

    デフォルト値の設定は変数への代入 デフォルト値さえあれば、 Notebookを対話的に 実行できる!
  21. 32 © NEC Corporation 2018 nbexecでできること 2. パラメータ定義 ▌HTTPリクエストからパラメータを渡す $

    curl -X POST ¥ -H 'Accept: application/json' ¥ -H "X-Response-Encoding: chunked" ¥ --data-urlencode "token=my-token" ¥ --data-urlencode "notebook=iris-predict.ipynb" ¥ --data-urlencode "sepal_length=5.1" ¥ --data-urlencode "sepal_width=2.0" ¥ --data-urlencode "petal_length=2.2" ¥ --data-urlencode "petal_width=0.8" ¥ "http://localhost:8888/api/executions"
  22. 34 © NEC Corporation 2018 nbexecでできること 3. Web APIドキュメント生成 ▌NotebookからWeb

    APIのドキュメントを生成する パラメータ定義セルをもとに APIのパラメータ仕様を表示
  23. 35 © NEC Corporation 2018 nbexecでできること 3. Web APIドキュメント生成 ▌NotebookからWeb

    APIのドキュメントを生成する すぐに試せるように curlを使ったexampleを表示 非同期実行のexample 同期実行のexample
  24. 36 © NEC Corporation 2018 nbexecでできること 3. Web APIドキュメント生成 ▌NotebookからWeb

    APIのドキュメントを生成する 実行内容も合わせて見れるように もとのNotebookを表示
  25. 37 © NEC Corporation 2018 nbexecまとめ ▌HTTPリクエストからNotebookを実行できるようにした Notebookを書いたらWeb APIとしてすぐに呼び出せる Web

    API化のためのボイラープレートをもう書くことはない ▌Notebookにパラメータを定義できるようにした パラメータはコメントとdictで定義できるので特別なコードを書かなくてよい Web API化するNotebookは対話的にも実行可能 ▌NotebookからWeb APIのドキュメントを生成できるようにした Web APIを呼び出す人はNotebookさえあれば仕様を確認できる
  26. 39 © NEC Corporation 2018 まとめ ▌Notebookに書かれたコードをWeb APIにしたいことがある Notebookに書いた機械学習のモデルを使った予測機能をアプリが利用したい場合など ▌NotebookのコードをWeb

    API化するのは大変 NotebookのコードをPythonスクリプトとして再実装する必要がある Web APIとしてのボイラープレートコードを多く書く必要がある ▌NotebookをWeb APIとして実行するツールは世の中にあるが課題がある Web APIからしか実行できないNotebookになってしまう ▌NotebookをWeb APIとして実行するためにnbexecをつくった NotebookをそのままWeb APIとして実行するエンドポイントを拡張した Notebookにパラメータを定義できるようにした NotebookからWeb APIドキュメントを生成できるようにした
  27. Q&A

  28. 42 © NEC Corporation 2018 NEC Advanced Analytics Platform AI活用における検証~導入~活用フェーズを同一基盤でシームレスに接続

    スキルの異なるプロフェッショナルの協働による迅速な価値実現を支援 * 本紙に掲載されている社名、商品名、サービス名などは、各社の商標または登録商標です。 検証 導入 活用 アプリケーション開発者 ユーザー & 運用管理者 データサイエンティスト NEC the WISE x 世界標準OSSを統合 マルチユーザー & スケールアウト対応 API化された分析手順や モデルを容易にAP組込 クラウド/オンプレ両対応に より導入迅速化 ダッシュボード連携による分 析結果の可視化 予測モデルの自動的な 再学習と更新※ NEC Advanced Analytics Platform AI開発環境 AI-API ダッシュボード※  異種混合学習  RAPID機械学習※  決定木  SVM (判別/回帰)  ランダムフォレスト  クラスタリング  主成分分析 … ※ 順次強化・搭載予定 scikit-learn Docker Apache Spark(※) Jupyter Python 特 長 分 析 P F ア ク タ
  29. 44 © NEC Corporation 2018 nbexecのNotebook実行のしくみ HTTP Client Notebook Server

    $ jupyter nbexec Notebook(.ipynb) POST /api/executions execute command execute notebook stdout HTTP response ExecutionHandler nbexecによる実装
  30. 45 © NEC Corporation 2018 jupyter nbexecコマンド ▌jupyter nbexecコマンド Notebookを実行するCLI

    実行状況をセル単位で標準出力に出力する 実行結果のNotebookは別のファイルとして保存する
  31. 50 © NEC Corporation 2018 jupyter nbexecコマンド ▌jupyter nbexecコマンド nbconvert.preprocessors.ExecutePreprocessorを拡張

    • nbconvertはNotebookを.html, .py, .pdfなどのフォーマットへ変換するツール • nbconvertが持つNotebookのセルを実行するPreprocessorの1つ • jupyter nbconvertコマンドの--executeを指定すると設定されるPreprocessor Notebookのセルに定義されたパラメータのパースとコマンドライン引数からパラメータ への値の適用などの機能を追加している
  32. 51 © NEC Corporation 2018 ExecutionHandler ▌ExecutionHandler Notebookの実行に関連するエンドポイントを拡張 • POST

    /api/executions … Notebookの実行 • GET /api/executions/<exec_id> … Notebookの実行状態の取得 • DELETE /api/execuions/<exec_id> … 実行中のNotebookの停止 など POSTリクエストではAPIHandlerでjupyter nbexecコマンドを実行して実行結果を HTTPレスポンスとして返す • HTTPリクエストのパラメータをjupyter nbexecの--paramsに渡す HTTP Client $ jupyter nbexec --params ¥ ‘{“x”: 10, “y”: 5}’ add.ipynb ExecutionHandler POST /api/executions { “notebook”: “add.ipynb”, “x”: 10, “y”: 5 }
  33. 52 © NEC Corporation 2018 ExecutionHandler ▌ExecutionHandler Notebookの実行情報を"Execution"という単位で管理 これによってNotebookを非同期実行しておいて定期的に進捗を取得したり、過去の実行 情報を参照することができる

    Notebook Server sqlite exec_id: 8c1701d6 POST /api/executions (Notebookの実行) exec_id: 62ac6a57 GET /api/executions/8c1701d6 DELETE /api/executions/62ac6a57 (実行中であればNotebookの停止)