Slide 1

Slide 1 text

1 © NEC Corporation 2018 Notebook as Web API ~Turn your notebook into Web API~ PyCon JP 2018 NEC 横石 和貴

Slide 2

Slide 2 text

2 © NEC Corporation 2018 Notebookとは ▌Jupyter Notebook OSSのWebアプリケーション Notebookと呼ばれるファイルにブラウザからプログラムを書いて対話的に実行したり、 テキストを書いたり、グラフを描画したりできる。

Slide 3

Slide 3 text

3 © NEC Corporation 2018 今日はなすこと ▌NotebookをそのままWeb APIとして実行できるようにした話 Notebookを書いて Web APIとして実行

Slide 4

Slide 4 text

4 © NEC Corporation 2018 自己紹介 横石和貴 NECソリューションイノベータ 分析プラットフォーム”NEC Advanced Analytics Platform”の開発 データサイエンティストに分析環境、分析ツールを提供するプラットフォーム

Slide 5

Slide 5 text

Notebook as Web API?

Slide 6

Slide 6 text

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で呼びたい

Slide 7

Slide 7 text

Notebookに書いたコードのWeb API化

Slide 8

Slide 8 text

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に書いたコードを また書かなければいけない… 予測機能を使いたいだけなのに リクエストをパースしたり、 レスポンスを組み立てないと…

Slide 9

Slide 9 text

9 © NEC Corporation 2018 Notebookに書いたコードのWeb API化 ▌1. Notebook作成 アヤメの花びら(petal)とがく(sepal)からアヤメ(iris)を分類するNotebookを作成する petal_length モデル sepal_length sepal_width petal_width

Slide 10

Slide 10 text

10 © NEC Corporation 2018 Notebookに書いたコードのWeb API化 ▌1. Notebook作成 - 学習用データセットを準備 target アヤメの名前 0 setosa 1 versicolor 2 virginica

Slide 11

Slide 11 text

11 © NEC Corporation 2018 Notebookに書いたコードのWeb API化 ▌1. Notebook作成 - モデルを作成、保存

Slide 12

Slide 12 text

12 © NEC Corporation 2018 Notebookに書いたコードのWeb API化 ▌1. Notebook作成 - 保存したモデルを読み込んで予測

Slide 13

Slide 13 text

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に書いたコードを また書かなくてはならない

Slide 14

Slide 14 text

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) 少なくともこれくらいの コード量を書く必要あり

Slide 15

Slide 15 text

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サーバの設定、起動

Slide 16

Slide 16 text

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"}

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

NotebookをWeb APIにする既存のしくみ Jupyter Kernel Gateway

Slide 19

Slide 19 text

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} エンドポイントの設定 リクエスト情報が渡される

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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"

Slide 22

Slide 22 text

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起動

Slide 23

Slide 23 text

23 © NEC Corporation 2018 NotebookをWeb APIにする既存のしくみ ▌Jupyter Kernel Gatewayの課題 NotebookをWeb APIとして 実行するしくみをつくろう! REQUESTという独自の変数を セルに持つ必要がある Jupyter Kernel Gatewayが値を 注入する変数なので対話的に 実行すれば未定義の変数である Web API化する Notebookは対話的に 実行可能ではない Webフレームワーク使うのも大変… 使えるツールもまだない…

Slide 24

Slide 24 text

nbexec

Slide 25

Slide 25 text

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実行

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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の実行

Slide 29

Slide 29 text

29 © NEC Corporation 2018 nbexecでできること 2. パラメータ定義 ▌定義方法 パラメータを定義するセルの宣言

Slide 30

Slide 30 text

30 © NEC Corporation 2018 nbexecでできること 2. パラメータ定義 ▌デフォルト値の定義 デフォルト値はパラメータ定義より前に同名の変数を定義する

Slide 31

Slide 31 text

31 © NEC Corporation 2018 nbexecでできること 2. パラメータ定義 ▌パラメータ定義に特別なコードは不要 パラメータ定義はただのコメント+dictの作成 デフォルト値の設定は変数への代入 デフォルト値さえあれば、 Notebookを対話的に 実行できる!

Slide 32

Slide 32 text

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"

Slide 33

Slide 33 text

33 © NEC Corporation 2018 nbexecでできること 3. Web APIドキュメント生成 ▌NotebookからWeb APIのドキュメントを生成する

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

36 © NEC Corporation 2018 nbexecでできること 3. Web APIドキュメント生成 ▌NotebookからWeb APIのドキュメントを生成する 実行内容も合わせて見れるように もとのNotebookを表示

Slide 37

Slide 37 text

37 © NEC Corporation 2018 nbexecまとめ ▌HTTPリクエストからNotebookを実行できるようにした Notebookを書いたらWeb APIとしてすぐに呼び出せる Web API化のためのボイラープレートをもう書くことはない ▌Notebookにパラメータを定義できるようにした パラメータはコメントとdictで定義できるので特別なコードを書かなくてよい Web API化するNotebookは対話的にも実行可能 ▌NotebookからWeb APIのドキュメントを生成できるようにした Web APIを呼び出す人はNotebookさえあれば仕様を確認できる

Slide 38

Slide 38 text

まとめ

Slide 39

Slide 39 text

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ドキュメントを生成できるようにした

Slide 40

Slide 40 text

Q&A

Slide 41

Slide 41 text

付録① NEC Advanced Analytics Platform

Slide 42

Slide 42 text

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 ア ク タ

Slide 43

Slide 43 text

付録② nbexecのNotebook実行のしくみ

Slide 44

Slide 44 text

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による実装

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

46 © NEC Corporation 2018 jupyter nbexecコマンド ▌Notebookの実行状況を標準出力に出力 このNotebookをjupyter nbexecコマンドで実行する

Slide 47

Slide 47 text

47 © NEC Corporation 2018 jupyter nbexecコマンド ▌Notebookの実行状況を標準出力に出力

Slide 48

Slide 48 text

48 © NEC Corporation 2018 jupyter nbexecコマンド ▌Notebookの実行状況をjson形式で出力

Slide 49

Slide 49 text

49 © NEC Corporation 2018 jupyter nbexecコマンド ▌Notebookの実行状況をjson形式で出力

Slide 50

Slide 50 text

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のセルに定義されたパラメータのパースとコマンドライン引数からパラメータ への値の適用などの機能を追加している

Slide 51

Slide 51 text

51 © NEC Corporation 2018 ExecutionHandler ▌ExecutionHandler Notebookの実行に関連するエンドポイントを拡張 • POST /api/executions … Notebookの実行 • GET /api/executions/ … Notebookの実行状態の取得 • DELETE /api/execuions/ … 実行中の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 }

Slide 52

Slide 52 text

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の停止)

Slide 53

Slide 53 text

No content