JAWS DAYS 2019 登壇資料です. 無 Bトラック #jd2019_b 10:10〜10:30
JAWS DAYS 2019EngineerAkihisa Takeda[AI/ML] PythonとSageMakerで始めるMLチームのみで完結するAPIの構築事例1
View Slide
事業紹介弁護士によって行われる契約書のレビュー*を機械学習によって行うあなたのためのリーガルサービス(The Legal Service For You)を提供2※「レビュー」…条項別のリスク判定/修正案の提案/修正意図の提案など
自己紹介Akihisa Takeda@ababa831活動● 2018年11月~ GVA TECH 正社員○ ML/NLPエンジニア(見習い)■ MLアルゴリズム研究開発~APIの構築まで■ AWSは入社後に触れ始める 修行中!● Kaggler (Competitions Expert)3
内容● ML API構築の課題● 本講演の目的● Amazon SageMakerについて● カスタムアルゴリズムによるAPIの実装● APIの管理● 得られた効果Note: 研究開発(機械学習(ML),自然言語処理)の話はいたしません4
ML API構築の課題5
データ分析・ML開発業務で求められること検証結果をAPI化し,プロダクトに反映して,初めてユーザに体感してもらえ,サービスの価値が生まれる検証〜プロダクト反映までのスピードが会社の利益に直結分析・検証学習・モデル変換APIのデプロイアルゴリズム開発プロダクトに反映ユーザに初めて届く6
データ分析・ML開発業務で求められること検証結果をAPI化し,プロダクトに反映して,初めてユーザに体感してもらえ,サービスの価値が生まれる検証〜プロダクト反映までのスピードが会社の利益に直結分析・検証学習・モデル変換APIのデプロイアルゴリズム開発プロダクトに反映ユーザに初めて届くこの流れをできる限り高速化したい!7
検証〜プロダクト反映の高速化を阻む課題⭕ 左半分までは普段の業務でカバー可能❌ APIの構築に関しては,普段の業務では扱わない別種のスキルセットが必要分析・検証学習・モデル変換APIのデプロイアルゴリズム開発プロダクトに反映別種のスキルセット普段の業務範囲MLチームにとって,APIの構築が大きな壁となる8
EC2を利用してAPIを構築する場合● 初期環境設定(Linux, サーバ フレームワーク etc.)周りに手間がかかる &作業する人によって設定の差分が発生しやすい● 運用管理(Kernel更新,脆弱性対応)に手間がかかる● APIをデプロイするための(インフラ, CI/CD)基盤を作るのがつらい● 負荷分散の対応が必要9
EC2を利用してAPIを構築する場合● 初期環境設定(Linux, サーバ フレームワーク etc.)周りに手間がかかる &作業する人によって設定の差分が発生しやすい● 運用管理(Kernel更新,脆弱性対応)に手間がかかる● APIをデプロイするための(インフラ, CI/CD)基盤を作るのがつらい● 負荷分散の対応が必要インフラの構築・管理の知識やリソースが必要10
EC2を利用してAPIを構築する場合● 初期環境設定(Linux, サーバ フレームワーク etc.)周りに手間がかかる &作業する人によって設定の差分が発生しやすい● 運用管理(Kernel更新,脆弱性対応)に手間がかかる● APIをデプロイするための(インフラ, CI/CD)基盤を作るのがつらい● 負荷分散の対応が必要インフラの構築・管理の知識やリソースが必要データサイエンティスト・MLエンジニアが本業に集中できず生産性が落ちる11
WEB・インフラチームがAPIの構築を担当する場合● WEB,インフラエンジニアの人的コストがかかる● データサイエンティスト・MLエンジニアが作成したコードを読むスキルがWEB側に要求される(MLの知識,やんちゃなコードの解読)12
WEB・インフラチームがAPIの構築を担当する場合● WEB,インフラエンジニアの人的コストがかかる● データサイエンティスト・MLエンジニアが作成したコードを読むスキルがWEB側に要求される(MLの知識,やんちゃなコードの解読)高速化の代わりにコスト面が犠牲に連携がうまく行かず,あまり高速化できない13
本講演の目的14
本講演の目的Amazon SageMaker+検証・モデリングに使ったコードをそのまま利用MLチームだけでAPIの構築・運用して,検証〜API化までを高速化した事例を紹介15
Amazon SageMakerについて16
Amazon SageMakerフルマネージド型の機械学習サービスデータサイエンスのワークフロー全体をカバー● 調査・分析あらかじめ環境構築されたJupyter notebookで手軽に分析● 開発・学習SageMaker Python SDKで簡単に学習可能● デプロイ・運用フルマネージドなのでEC2でAPIを構築・運用するときの問題を考えなくてよい17
Amazon SageMakerフルマネージド型の機械学習サービスデータサイエンスのワークフロー全体をカバー● 調査・分析あらかじめ環境構築されたJupyter notebookで手軽に分析● 開発・学習SageMaker Python SDKで簡単に学習可能● デプロイ・運用フルマネージドなのでEC2でAPIを構築・運用するときの問題を考えなくてよいWEB・インフラに詳しくないデータサイエンティスト・MLエンジニアでも簡単にMLモデルのAPI化が可能18
SageMakerで使用できるアルゴリズムの選択肢● 組み込みアルゴリズムSageMakerで標準的に実装されている標準的なアルゴリズムMLアルゴリズムの選択,パラメータ値の設定だけで簡単に学習・推論可能● カスタムアルゴリズム自分で用意したMLのアルゴリズムをSageMakerで使えるようにしたものSageMakerで動く学習・推論用のDockerコンテナをカスタマイズ19
組み込みアルゴリズムの特徴⭕ 主要なMLフレームワーク(scikit-learn, TensorFlow, Chainer, etc.)に対応❌ 使用できるMLアルゴリズムは多くない❌ 組み込みアルゴリズムの文法を覚える学習コストがかかる❌ 検証で使ったMLコードを組み込みアルゴリズムに改変する工数がそれなりにかかるNote: script modeの登場で大分改変しやすくなったが,まだ対応アルゴリズムは多くない20⭕: 長所, ❌: 短所
組み込みアルゴリズムの特徴⭕ 主要なMLフレームワーク(scikit-learn, TensorFlow, Chainer, etc.)に対応❌ 使用できるMLアルゴリズムは多くない❌ 組み込みアルゴリズムの文法を覚える学習コストがかかる❌ 検証で使ったMLコードを組み込みアルゴリズムに改変する工数がそれなりにかかるNote: script modeの登場で大分改変しやすくなったが,まだ対応アルゴリズムは多くない検証の成果を素早くサービスに反映させたいデータサイエンティスト・MLエンジニアのニーズにあわない21⭕: 長所, ❌: 短所
カスタムアルゴリズムの特徴⭕ 手元のMLコードをほとんど改変せずにSageMaker用のコンテナ化できる❌ 自分でコンテナを作成する必要がある→DockerfileとECR(Elastic Container Registry)にコンテナイメージをpushするスクリプトを初回用意して,SageMakerコンテナ内のコードを少し改変するだけ22⭕: 長所, ❌: 短所
カスタムアルゴリズムの特徴⭕ 手元のMLコードをほとんど改変せずにSageMaker用のコンテナ化できる❌ 自分でコンテナを作成する必要がある→DockerfileとECR(Elastic Container Registry)にコンテナイメージをpushするスクリプトを初回用意して,SageMakerコンテナ内のコードを少し改変するだけ検証に使ったMLコードを生かして素早くAPI化したいので,カスタムアルゴリズムを利用する23⭕: 長所, ❌: 短所
カスタムアルゴリズムによるAPIの実装24
AWS構成学習済みモデルのUP学習時に行われることDocker imageのpush時に行われることデプロイ時に行われることAPI利用時に行われることVPCECRSageMaker APIEC2 web/appリクエスト&レスポンス学習済みモデル(S3に配置)Docker imageのDL開発したMLコードが入ったDocker Imageをpushローカル開発環境モデルDL25
学習済みモデルのUP学習時に行われることDocker imageのpush時に行われることデプロイ時に行われることAPI利用時に行われることVPCECRSageMaker APIEC2 web/appリクエスト&レスポンス学習済みモデル(S3に配置)Docker imageのDL開発したMLコードが入ったDocker Imageをpushローカル開発環境モデルDLフルマネージドなため● ALB● API GateWayが不要AWS構成26
学習済みモデルのUP学習時に行われることDocker imageのpush時に行われることデプロイ時に行われることAPI利用時に行われることVPCECRSageMaker APIEC2 web/appリクエスト&レスポンス学習済みモデル(S3に配置)Docker imageのDL開発したMLコードが入ったDocker Imageをpushローカル開発環境モデルDL処理の流れ27
学習済みモデルのUP学習時に行われることDocker imageのpush時に行われることデプロイ時に行われることAPI利用時に行われることVPCECRSageMaker APIEC2 web/appリクエスト&レスポンス学習済みモデル(S3に配置)Docker imageのDL開発したMLコードが入ったDocker Imageをpushローカル開発環境モデルDL処理の流れ28
学習済みモデルのUP学習時に行われることDocker imageのpush時に行われることデプロイ時に行われることAPI利用時に行われることVPCECRSageMaker APIEC2 web/appリクエスト&レスポンス学習済みモデル(S3に配置)Docker imageのDL開発したMLコードが入ったDocker Imageをpushローカル開発環境モデルDL処理の流れ29
学習済みモデルのUP学習時に行われることDocker imageのpush時に行われることデプロイ時に行われることAPI利用時に行われることVPCECRSageMaker APIEC2 web/appリクエスト&レスポンス学習済みモデル(S3に配置)Docker imageのDL開発したMLコードが入ったDocker Imageをpushローカル開発環境モデルDL処理の流れ30
ディレクトリ構成と各階層の役割公式のリポジトリのscikit-learn用サンプルコード*をベースにカスタマイズ* 「scikit_bring_your_own」で検索.├── container│ ├── Dockerfile│ ├── build_and_push.sh│ └── custom_algorithm│ ├── apps│ │ ├── .temps/│ │ ├── 検証・学習用コード群│ │ ├── main.py│ │ └── s3_upload.py│ ├── predictor.py│ ├── debug_api.py│ ├── test_api.py│ ├── train│ ├── serve│ ├── nginx.conf│ └── wsgi.py├── dummy_data├── generate_endpoint.py└── test_endpoint.pyhttps://github.com/awslabs/amazon-sagemaker-examples/tree/master/advanced_functionality/scikit_bring_your_own31
ディレクトリ構成と各階層の役割● ./container/custom_algorithm/apps検証・学習用コードを利用してS3に学習済みモデルをupload.├── container│ ├── Dockerfile│ ├── build_and_push.sh│ └── custom_algorithm│ ├── apps│ │ ├── .temps/│ │ ├── 検証・学習用コード群│ │ ├── main.py│ │ └── s3_upload.py│ ├── predictor.py│ ├── debug_api.py│ ├── test_api.py│ ├── train│ ├── serve│ ├── nginx.conf│ └── wsgi.py├── dummy_data├── generate_endpoint.py└── test_endpoint.py 32
ディレクトリ構成と各階層の役割● ./container/custom_algorithm/apps検証・学習用コードを利用してS3に学習済みモデルをupload● ./container/custom_algorithmSageMakerで動かすAPIサーバ(Flask),デバッグ用ローカルAPIサーバ(Flask),学習済みモデルをSageMakerでDLするスクリプト.├── container│ ├── Dockerfile│ ├── build_and_push.sh│ └── custom_algorithm│ ├── apps│ │ ├── .temps/│ │ ├── 検証・学習用コード群│ │ ├── main.py│ │ └── s3_upload.py│ ├── predictor.py│ ├── debug_api.py│ ├── test_api.py│ ├── train│ ├── serve│ ├── nginx.conf│ └── wsgi.py├── dummy_data├── generate_endpoint.py└── test_endpoint.pyサンプルをそのまま利用33
ディレクトリ構成と各階層の役割● ./container/custom_algorithm/apps検証・学習用コードを利用してS3に学習済みモデルをupload● ./container/custom_algorithmSageMakerで動かすAPIサーバ(Flask),デバッグ用ローカルAPIサーバ(Flask),学習済みモデルをSageMakerでDLするスクリプト● ./containerカスタムアルゴリズムを入れたSageMaker用Docker imageをECRにpushする.├── container│ ├── Dockerfile│ ├── build_and_push.sh│ └── custom_algorithm│ ├── apps│ │ ├── .temps/│ │ ├── 検証・学習用コード群│ │ ├── main.py│ │ └── s3_upload.py│ ├── predictor.py│ ├── debug_api.py│ ├── test_api.py│ ├── train│ ├── serve│ ├── nginx.conf│ └── wsgi.py├── dummy_data├── generate_endpoint.py└── test_endpoint.py 34
ディレクトリ構成と各階層の役割● ./container/custom_algorithm/apps検証・学習用コードを利用してS3に学習済みモデルをupload● ./container/custom_algorithmSageMakerで動かすAPIサーバ(Flask),デバッグ用ローカルAPIサーバ(Flask),学習済みモデルをSageMakerでDLするスクリプト● ./containerカスタムアルゴリズムを入れたSageMaker用Docker imageをECRにpushする● .エンドポイントの作成とAPIの動作確認.├── container│ ├── Dockerfile│ ├── build_and_push.sh│ └── custom_algorithm│ ├── apps│ │ ├── .temps/│ │ ├── 検証・学習用コード群│ │ ├── main.py│ │ └── s3_upload.py│ ├── predictor.py│ ├── debug_api.py│ ├── test_api.py│ ├── train│ ├── serve│ ├── nginx.conf│ └── wsgi.py├── dummy_data├── generate_endpoint.py└── test_endpoint.py 35
PC(ローカル)上に次を用意● 手元の検証用 MLコード● 一時的に保存したモデルをS3にUploadするコードmain.pyの実行1. モデルの学習2. 学習済みモデルをローカルに一時的に保存3. モデルをS3にUploadapps検証用MLコード.tmpsそのまま利用s3_upload.pymain.pymain.pypy検証用MLコード.tmps学習 UPS3 Bucketpy実装のポイント [学習 & モデルのUpload]36
Flaskでルーティング受信,推論,レスポンス処理predictor.py(抜粋)apps.tmpss3_upload.pymain.py検証用MLコードcustom_algorithmpredictor.py実装のポイント [推論用 API]37
Flaskでルーティング受信,推論,レスポンス処理predictor.py(抜粋)apps.tmpss3_upload.pymain.py検証用MLコードcustom_algorithmpredictor.py具体的な推論処理はapps内で!アルゴリズム変更時にここを変えなくて良い推論結果実装のポイント [推論用 API]38頻繁に変更
デプロイ時にtrainスクリプトが走る→このとき,boto3でS3からSageMaker用コンテナにDLされるようにコードを作成custom_algorithmpredictor.pyappstrain# (省略)model_path = '/opt/ml/model'class Train(object):def train(self):# (省略)self.download_from_s3(model_s3_path, dst_filename)# (省略)def download_from_s3(self, obj_s3_path, dst_filename):# (省略)dst = os.path.join(model_path, dst_filename)with open(dst, 'wb') as data:s3.download_fileobj(bucket_name, obj_s3_path, data)デプロイ時に走る実装のポイント [デプロイ時にSageMaker用コンテナにモデルをDL]39
デプロイ時にtrainスクリプトが走る→このとき,boto3でS3からSageMaker用コンテナにDLされるようにコードを作成custom_algorithmpredictor.pyappstrain# (省略)model_path = '/opt/ml/model'class Train(object):def train(self):# (省略)self.download_from_s3(model_s3_path, dst_filename)# (省略)def download_from_s3(self, obj_s3_path, dst_filename):# (省略)dst = os.path.join(model_path, dst_filename)with open(dst, 'wb') as data:s3.download_fileobj(bucket_name, obj_s3_path, data)SageMakerが想定するモデルの配置先実装のポイント [デプロイ時にSageMaker用コンテナにモデルをDL]40
デプロイ時にtrainスクリプトが走る→このとき,boto3でS3からSageMaker用コンテナにDLされるようにコードを作成custom_algorithmpredictor.pyappstrain# (省略)model_path = '/opt/ml/model'class Train(object):def train(self):# (省略)self.download_from_s3(model_s3_path, dst_filename)# (省略)def download_from_s3(self, obj_s3_path, dst_filename):# (省略)dst = os.path.join(model_path, dst_filename)with open(dst, 'wb') as data:s3.download_fileobj(bucket_name, obj_s3_path, data)Trainクラス > trainメソッドにS3からモデルをDL実装のポイント [デプロイ時にSageMaker用コンテナにモデルをDL]41
1. ローカル上でAPIの動作確認をできるように,次のコードを用意● local_api.pypredictor.pyに,Flaskのdebugモードを追記● test_api.pyurllib.requestを用いて,適当なデータを送信し,結果を取得custom_algorithmpredictor.pyappstrainlocal_api.pytest_api.py実装のポイント [ローカルでAPIのdebug]42
2. ECRにpushするDocker imageを使い,ローカル上でコンテナを起動● APIサーバ側● クライアント側a. `docker ps`で起動中コンテナIDを確認b. `docker exec`でAPIを叩く実装のポイント [ローカルでAPIのdebug]43
カスタムアルゴリズム入りDocker imageをつくるため,ローカルの`custom_algorithm`ディレクトリをコンテナにコピペするコードをDockerfileに記述COPY custom_algorithm /opt/programWORKDIR /opt/programDockerfile(抜粋)custom_algorithmコピーcustom_algorithmcontainerDockerfilebuild_and_push.sh実装のポイント [Dockerfile]44
Docker image作成して,ECRにpushするシェルスクリプトをつくる# ECRリポジトリの確認aws ecr describe-repositories --repository-names "${image}" > /dev/null 2>&1# 該当するリポジトリが一覧になければ,新規作成if [ $? -ne 0 ]thenaws ecr create-repository --repository-name "${image}" > /dev/nullfi# ECRにログイン$(aws ecr get-login --profile ${profile} --region ${region} --no-include-email)# Docker image 作成→ECRへpushdocker build -t ${image} .docker tag ${image} ${fullname}docker push ${fullname}build_and_push.sh(公式リポジトリ*引用, Dockerfileと同ディレクトリ)実装のポイント [Docker imageのpush用コード]45https://github.com/awslabs/amazon-sagemaker-examples/blob/master/advanced_functionality/scikit_bring_your_own/container/build_and_push.sh
AWS上でIAM, VPC周りを設定した後,APIをデプロイしてエンドポイント作成APIをデプロイするためにはSageMaker SDK+組み込みアルゴリズムを介す必要あり# 学習用ダミーデータセットをS3に配置data_location = session.upload_data('./dummy_data.pkl', key_prefix=s3_prefix)# (中略)# SageMaker SDKの学習器を設定clf = sagemaker.estimator.Estimator(training_image,arn_iam_role,train_instance_count=1,train_instance_type='ml.m4.xlarge',sagemaker_session=session,subnets=subnets,security_group_ids=secur_group_ids)# 空学習clf.fit(data_location)実際の学習済みモデルは,デプロイ中に前述のtrainスクリプトが走り,S3からSageMakerコンテナにDL実装のポイント [エンドポイントの作成]ダミー組み込みアルゴリズムを空学習46
● boto3で確認● AWS CLIで確認SageMaker側のログはCloudWatchで確認できるruntime_client = boto3.client('runtime.sagemaker')response = runtime_client.invoke_endpoint(EndpointName=sagemaker_endpoint_path,ContentType='application/json', # リクエストのMIMEタイプBody=test_serialized, # 送るデータの中身Accept='application/json' # レスポンスのMIMEタイプ)$ aws sagemaker-runtime invoke-endpoint --endpoint-name 'hoge' ¥> --body '{"input": 1}' --content-type 'application/json' output.txt実装のポイント [APIの動作確認]47
APIの管理48
APIのモニタリング(負荷,scaling)エンドポイントの管理(確認,削除)機能AWSコンソール > Amazon SageMakerAPIの管理49
APIのモニタリング(負荷,scaling)エンドポイントの管理(確認,削除)機能AWSコンソール > Amazon SageMakerAPIの管理API運用に関する知見の少ないデータサイエンティスト・MLエンジニアにとっても扱いやすい50
得られた効果51
● SageMakerによって,API構築がMLチームで完結○ EC2の初期環境設定の工数(数日)→ 不要○ EC2のメンテナンス((不)定期 x 日/回)→ 不要→分析業務にリソースを割ける!APIの数が増えても平気!● 検証用コードの改変自由度が高く,(ほぼ)そのまま使える→ 新version APIリリースが1日で!● フルマネージド+SageMaker APIの管理機能○ リクエスト数が増えた時のスケールアウトを勝手にやってくれる○ 過去作成したエンドポイントへの切り替えが簡単 → WEB側もその切り替えのみで対応可能得られた効果52
● SageMakerによって,API構築がMLチームで完結○ EC2の初期環境設定の工数(数日)→ 不要○ EC2のメンテナンス((不)定期 x 日/回)→ 不要→分析業務にリソースを割ける!APIの数が増えても平気!● 検証用コードの改変自由度が高く,(ほぼ)そのまま使える→ 新version APIリリースが1日で!● フルマネージド+SageMaker APIの管理機能○ リクエスト数が増えた時のスケールアウトを勝手にやってくれる○ 過去作成したエンドポイントへの切り替えが簡単 → WEB側もその切り替えのみで対応可能得られた効果53検証の成果をプロダクトへ素早く反映できる体制が整った
最後に...We're Hiring!54Wantedly GVA TECH