Slide 1

Slide 1 text

機械学習をアプリケーションに 組み込む様子を見てみよう

Slide 2

Slide 2 text

自己紹介 ➢ 名前:大嶋勇樹 ➢ サーバサイド・インフラ中心のエンジニア ○ Java、AWS、GCP、Docker、Kubernetes、etc… ➢ データ分析・機械学習関連の業務経験 ○ AWS 環境でのデータ分析基盤の構築 ○ Docker、Kubernetes などを活用した機械学習アプリケーションの基盤構築 ➢ 最近の興味 ○ MLOps、Linux、電子工作、VR ➢ Twitter:@oshima_123

Slide 3

Slide 3 text

今日のテーマ “ ” 機械学習をアプリケーションに組み込む様子を見てみよう 一方で、実際のアプリケーションに組み込むのに手こずっている例も少なくない 機械学習は一般に認知されるようになり、 R&D 的にデータサイエンティストが試行錯誤する段階の取り組みはかなり増えている

Slide 4

Slide 4 text

難しい理由の 1 つ 機械学習の知識と、アプリケーション開発の知識の壁 データサイエンティストや PM・PdM といったポジションの方には、 アプリケーション開発の知見がない場合も少なくない 機械学習の知識とアプリケーション開発の知識は全然異なる

Slide 5

Slide 5 text

そこで今日は 機械学習については前提知識のある 「データサイエンティスト」「PM」「PdM」 といった方を主な対象者として、 機械学習を実際にアプリケーションに組み込む例をお見せしつつ、 登場する技術要素を解説していきます 今日の目標 ● 機械学習をアプリケーションに組み込むイメージが、なんとなくつかめる ● 実際に自分で構築するためには、どんなことを勉強する必要がありそうか分かる

Slide 6

Slide 6 text

アジェンダ ● Web アプリケーションの基本 ● MNIST を使ったサンプルアプリケーションの紹介と、構成の概要解説 ● デモンストレーションと、ソースコードの解説 ● より本格的な構成について ※ 合計 1 時間程度の予定です

Slide 7

Slide 7 text

Web アプリケーションの基本

Slide 8

Slide 8 text

Web アプリケーションの前に... ● 世の中には、様々な「アプリケーション」がある ○ Web アプリケーション ○ モバイルアプリケーション ○ デスクトップアプリケーション ○ 組み込み ○ ゲーム ○ etc… 今回は最近 IT エンジニアが入門として学ぶケースが多い、 「Web アプリケーション」を題材にします

Slide 9

Slide 9 text

「Web アプリケーション」とは ● Wikipedia によると... ○ > ウェブアプリケーション(Web application)は、ウェブ(World Wide Web)技術を基盤としたアプリケー ションソフトウェアである。 ● 例えば ○ 検索エンジン ○ EC サイト ○ SNS ○ ブログ ○ etc… ● ざっくり言えば、Web ブラウザで利用できるサービス全般が「Web アプリケーション」 https://www.google.com https://www.amazon.com https://twitter.com/os1ma https://hatenablog.com/ 出展「ウェブアプリケーション - Wikipedia」(2021 年 12 月 17 日) https://ja.wikipedia.org/wiki/%E3%82%A6%E3%82%A7%E3%83%96%E3%82%A2%E3%83%97%E3 %83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3

Slide 10

Slide 10 text

「Web アプリケーション」と「静的サイト」の違い ● 静的サイト ○ 固定のデータで実現されているサイト ○ 例 ■ コーポレートサイト ○ 登場する技術要素 ■ HTML、CSS、JavaScript ■ Web サーバ ● Web アプリケーション ○ ユーザの入力や DB のデータに応じて、プログラムが HTML を動的に組み立てたりする ○ 例 ■ 検索エンジン、EC サイト、SNS、ブログ ○ 静的サイトの要素に加えて登場する技術要素 ■ アプリケーションサーバ・各種言語のプログラム ■ DB Web ブラウザ Web サーバ アプリケー ションサーバ DB HTML JavaScript プログラム CSS Web ブラウザ Web サーバ HTML JavaScript CSS ※ 実際にはもっと多数の方式があり、登場する技術要素も様々

Slide 11

Slide 11 text

MNIST を使ったサンプルアプリケーションの紹介と 構成の概要解説

Slide 12

Slide 12 text

MNIST を使ったサンプルアプリケーション ● 機能 ○ MNIST で学習したモデルに対して、自分が手書きした文字で推論を試すことができる ○ 書いた文字は履歴として保存され、モデルを更新した際は、新しいモデルで推論し直すことができる (あとで詳しく説明します)

Slide 13

Slide 13 text

推論の様子 ● 0 〜 9 まで推論を試してみる ● 実際に手書きした文字に対して、最も確率が高い値はどれか、履歴が保存されていく ※ 最初のモデルでは、あえて精度が低くなるようになっています

Slide 14

Slide 14 text

構成の全体像 アプリケーション部分 学習部分 Web ブラウザ Web サーバ (nginx) アプリケーションサーバ (Uvicorn + Gunicorn + FastAPI) DB (MySQL) HTML JavaScript Python MLflow UI PyTorch ./mlruns ONNX ./images FastAPI コンテナ イメージ ● 簡易的な構成にするため、1 台のマシン 上でこれらをそれぞれ Docker コンテナ として実行するようにしています ONNX ONNX

Slide 15

Slide 15 text

デモンストレーションと ソースコードの解説

Slide 16

Slide 16 text

学習部分について ● PyTorch ○ ディープラーニングのフレームワーク ○ 今回はシンプルなネットワークを使用 ● MLflow ○ 実験管理ツール ○ どんなパラメータでどんな結果だったかなどを管理するために使用 ○ Web の UI から様々な操作が可能 ● ONNX ○ 機械学習モデルの形式 ○ PyTorch のモデルは最終的に ONNX 形式で MLflow 管理下のディレクトリに保存 学習部分 MLflow UI PyTorch ./mlruns ONNX self.linear_relu_stack = nn.Sequential( nn.Linear(n_input, n_hidden), nn.ReLU(), nn.Linear(n_hidden, n_output), )

Slide 17

Slide 17 text

学習の様子 ● n_hidden = 10、n_hidden = 128 など、値を変えて実行 $ make train_gpu : 2021-12-22 08:13:44,860 - INFO - model = MNISTModel( (linear_relu_stack): Sequential( (0): Linear(in_features=784, out_features=10, bias=True) (1): ReLU() (2): Linear(in_features=10, out_features=10, bias=True) ) ) 100%|████████████████████████████████████████████████| 938/938 [00:07<00:00, 119.43it/s] 2021-12-22 08:13:52,718 - INFO - Epoch [1/5] train loss: 0.64784, acc: 0.80790 2021-12-22 08:13:53,915 - INFO - Epoch [1/5] valid loss: 0.38300, acc: 0.89070 100%|████████████████████████████████████████████████| 938/938 [00:07<00:00, 118.71it/s] 2021-12-22 08:14:01,819 - INFO - Epoch [2/5] train loss: 0.37280, acc: 0.89393 2021-12-22 08:14:03,024 - INFO - Epoch [2/5] valid loss: 0.35724, acc: 0.89690 100%|████████████████████████████████████████████████| 938/938 [00:07<00:00, 119.12it/s] 2021-12-22 08:14:10,901 - INFO - Epoch [3/5] train loss: 0.34369, acc: 0.90180 2021-12-22 08:14:12,099 - INFO - Epoch [3/5] valid loss: 0.33862, acc: 0.90290 100%|████████████████████████████████████████████████| 938/938 [00:07<00:00, 118.21it/s] 2021-12-22 08:14:20,037 - INFO - Epoch [4/5] train loss: 0.32955, acc: 0.90513 2021-12-22 08:14:21,240 - INFO - Epoch [4/5] valid loss: 0.33413, acc: 0.90330 100%|████████████████████████████████████████████████| 938/938 [00:07<00:00, 119.53it/s] 2021-12-22 08:14:29,090 - INFO - Epoch [5/5] train loss: 0.31951, acc: 0.90883 2021-12-22 08:14:30,267 - INFO - Epoch [5/5] valid loss: 0.31779, acc: 0.91120 2021-12-22 08:14:30,268 - INFO - export onnx model :

Slide 18

Slide 18 text

実験管理の様子 ● MLflow を使うことで、学習のパラメータやメトリクス、アーティファクトを簡単に管理できる ● どんなパラメータだと精度が高かったかなどを、後から見直したり再現したりしやすい def main(): with mlflow.start_run(): mlflow.log_artifact('./src/') seed = 123 mlflow.log_param('seed', seed) : : torch.onnx.export(net, dummy_input, MODEL_OUTPUT_FILE, verbose=True, input_names=['input'], output_names=['output']) mlflow.log_artifact(MODEL_OUTPUT_FILE)

Slide 19

Slide 19 text

アプリケーションの構成 ● Web サーバ + アプリケーションサーバ + DB という典型的な構成 ● Web サーバ ○ HTML、JavaScript という静的(固定の)コンテンツをブラウザに返す ● アプリケーションサーバ ○ ブラウザ上で実行される JavaScript からのリクエストに応じて、 ○ 推論の実行や履歴の DB への読み書きといった処理を実行する アプリケーション部分 Web サーバ (nginx) アプリケーションサーバ (Uvicorn + Gunicorn + FastAPI) DB (MySQL) HTML JavaScript ./images Web ブラウザ Python ONNX

Slide 20

Slide 20 text

HTML、JavaScript のソースコード(抜粋) ● 推論のボタンが押されたら、通信して Python の Web API を呼び出している document.querySelector('#submit-button') .addEventListener('click', async () => { : const headers = { 'content-type': 'multipart/form-data' } const data = new FormData() data.append('image', blob, 'number.png') const response = await axios.post('/api/predictions', data, headers) : 推論実行

Slide 21

Slide 21 text

Python のソースコード(抜粋) ● model.onnx というモデルのファイルを読み込み、推論を実行している @router.post('/api/predictions') async def post_predict(image: UploadFile = File(...)): : # predict result = predictor.predict(resized) : def predict(resized_image): input = _preprocess(resized_image) # predict onnx_session = onnxruntime.InferenceSession(MODEL_FILE) input_name = onnx_session.get_inputs()[0].name output = onnx_session.run(None, {input_name: input}) # 確率に変換 return softmax(output[0]).tolist() MODEL_FILE = '/model.onnx'

Slide 22

Slide 22 text

状況の整理 アプリケーション部分 学習部分 Web ブラウザ Web サーバ (nginx) アプリケーションサーバ (Uvicorn + Gunicorn + FastAPI) DB (MySQL) HTML JavaScript MLflow UI PyTorch ./mlruns ONNX ./images Python ONNX PyTorch が出力したモデルの ファイルをコピーして、FastAPI のアプリケーションで推論に 使っている

Slide 23

Slide 23 text

モデルの改善 ● 最初にアプリケーションに組み込んだモデルを使い続けたいとは限らない ○ 後日より良いモデルを作ることができた場合、そちらに変更したくなる ○ 現実では、入力データが変化することで、モデルの精度が下がっていくことがある(データドリフト) ● モデルの更新の流れの自動化 ○ 新しくこのモデルを使うと決めたあと、手動で ONNX ファイルをコピーする運用では、操作ミスしやすく、 システム障害などに繋がりやすい ○ モデルをアプリケーションに反映する流れを自動化することで、操作ミスを防ぐことができ、アプリケー ションの改善も高速化できる

Slide 24

Slide 24 text

新しいモデルをアプリケーションに反映する流れ ● 今回の例では、アプリケーションや関連ファイルをまとめて持ち運ぶためによく利用される、 「Docker」というツールを採用している アプリケーションサーバ (Uvicorn + Gunicorn + FastAPI) ./mlruns ONNX FastAPI コンテナ イメージ Python ONNX ONNX ビルド処理 指定したモデルのファイルを含む Docker の「コンテナイメージ」という、 持ち運びやすい形式のデータに変換 デプロイ処理 ビルド処理で作成した Docker の「コンテナイメージ」をもとに、 新しいモデルを含むアプリケーションを起動

Slide 25

Slide 25 text

ビルド・デプロイの様子 ● ビルド ● デプロイ $ make deploy_api RUN_ID=99f9d77426de474aa112471e92d71d34 API_DOCKER_TAG="99f9d77426de474aa112471e92d71d34" docker-compose up --no-deps -d api Recreating mnist-app_api_1 ... done $ make build_api RUN_ID=99f9d77426de474aa112471e92d71d34 : Building api Sending build context to Docker daemon 2.58MB Step 1/6 : FROM tiangolo/uvicorn-gunicorn-fastapi:python3.8-slim ---> 24a351926e6f : Successfully built 9c7ef746e31e Successfully tagged mnist-mlops-app_api:99f9d77426de474aa112471e92d71d34

Slide 26

Slide 26 text

推論の精度が改善された様子 ● モデルを変更したことで、手書き文字に対する推論精度が向上した様子を見ることができる

Slide 27

Slide 27 text

構成の全体像(再掲) アプリケーション部分 学習部分 Web ブラウザ Web サーバ (nginx) アプリケーションサーバ (Uvicorn + Gunicorn + FastAPI) DB (MySQL) HTML JavaScript MLflow UI PyTorch ./mlruns ONNX ./images FastAPI コンテナ イメージ ● 簡易的な構成にするため、これらを 1 台 のマシン上でそれぞれ Docker コンテナ として実行するようにしています Python ONNX ONNX

Slide 28

Slide 28 text

より本格的な構成について

Slide 29

Slide 29 text

学習環境と稼働環境の分離 ● 今回は 1 台のマシンで各要素を動かしてみたが、実際には実験環境とアプリケーションの実行環境 を分けたりする ● 本番環境以外にも、テスト環境・ステージング環境など、様々な環境を作ったりもする 実験環境 アプリケーション 本番環境 実験環境 アプリケーション テスト環境 アプリケーション 本番環境 アプリケーション ステージング環境

Slide 30

Slide 30 text

データの収集や、データ基盤の構築 ● 独自のデータを使う場合は、データの収集やデータレイクなど構築も必要 ● キーワード ○ データレイク ○ ETL ○ DVC ○ 特徴量ストア ○ データパイプライン 出典:https://aws.amazon.com/jp/big-data/datalakes-and-analytics/what-is-a-data-lake/

Slide 31

Slide 31 text

機械学習のコード以外にも、必要な要素はたくさんある 出典「Hidden Technical Debt in Machine Learning Systems」 https://proceedings.neurips.cc/paper/2015/file/86df7dcfd896fcaf2674f757a2463eba-Paper.pdf

Slide 32

Slide 32 text

MLOps ● 「MLOps 」の定義は色々ありますが、ここでは GCP のドキュメントでの解説を引用します ● > MLOps は、ML システム開発(Dev )と ML シス テム オペレーション(Ops )の統合を目的とする ML エンジニアリングの文化と手法です ● > MLOps を実践すると、統合、テスト、リリー ス、デプロイ、インフラストラクチャ管理な ど、ML システム構築のすべてのステップで自動化 とモニタリングを推進できます GCP のドキュメントより引用 https://cloud.google.com/architecture/mlops-continuous-deliver y-and-automation-pipelines-in-machine-learning?hl=ja 出典:https://ml-ops.org/content/mlops-principles

Slide 33

Slide 33 text

MLOps のプラクティスの例 ● 実験管理 ○ 実行したコードやパラメータ、モデル、評価 などを保存して再現可能にする ● 各種バージョン管理 ○ DVC によるデータのバージョン管理や、作成 したモデルのバージョン管理を行う ● テスト ○ モデルが性能を満たすかなどをテスト ● サービング ○ ONNX Runtime や Tensorflow Serving などに より、モデルを本番環境にシームレスにデプ ロイする ● リリース ○ カナリアリリースなどの手法で、本番トラ フィックでもモデルをテストする ● ワークフロー管理 ○ データ取得・前処理・学習・評価・デプロイ のワークフローを自動化する 出典:https://martinfowler.com/articles/cd4ml.html

Slide 34

Slide 34 text

まとめ

Slide 35

Slide 35 text

まとめ ● 機械学習をアプリケーションに組み込むイメージがつけられるよう、MNIST を使ったサンプル アプリケーションでデモンストレーションしてみた ● より本格的な構成として紹介した要素は、必ずしも全てをしっかり実施する必要はないが、 高品質なアプリケーションを改良し続けるには、そのような考慮が必要になってくる まずは実際にこのくらいのアプリケーションを作ってみると アプリケーション開発に登場する要素の理解も進むので、とてもおすすめです

Slide 36

Slide 36 text

機械学習をアプリケーションに 組み込む様子を見てみよう