Slide 1

Slide 1 text

©2024 CyberAgent Inc. Distribution prohibited AI Shift 干飯 啓太 MLOps実践編

Slide 2

Slide 2 text

©2024 CyberAgent Inc. Distribution prohibited 本講義のゴール 2 MLOpsを意識した技術選定 機械学習システムの運用

Slide 3

Slide 3 text

©2024 CyberAgent Inc. Distribution prohibited 自己紹介 干飯 啓太(ほしい けいた) 職種: ML Engineer/Data Scientist 所属: AI Shift 最近のタスク: ● LLMを使った要約プロダクトの開発・立ち上げ ● MLOps(GKE・Argo Workflows) 3 @hosimesi11_ @hosimesi

Slide 4

Slide 4 text

©2024 CyberAgent Inc. Distribution prohibited ハンズオンレポジトリ 4 https://github.com/hosimesi/aws-mlops-practice

Slide 5

Slide 5 text

©2024 CyberAgent Inc. Distribution prohibited アジェンダ 5 1. MLOps 2. 事前準備 3. 推論サーバの自動更新 4. ログの収集と継続的な学習 5. サニティチェック 6. カナリアリリース 7. メトリクスの可視化 8. まとめ

Slide 6

Slide 6 text

©2024 CyberAgent Inc. Distribution prohibited 今日使う技術 6 ECS ECR S3 StepFunctions ALB AWS DynamoDB Route 53 Cloud Map Redshift Grafana Fluentd Prometheus その他 Lambda

Slide 7

Slide 7 text

©2024 CyberAgent Inc. Distribution prohibited 今日使う技術 7 Linter/Formatter/Test ● tox ○ 仮想環境上でのタスク自動化ツール ● pytest ○ テストフレームワーク ● mypy ○ 静的型チェック ● ruff ○ Rust製のリンター兼フォーマッター

Slide 8

Slide 8 text

©2024 CyberAgent Inc. Distribution prohibited 皆さんに作ってもらうもの 8 ● 学習パイプラインの並列実行 ● 推論サーバの自動更新・バージョニング ● デプロイ前のサニティチェック ● カナリアリリース ● 学習ログ基盤 ● 機械学習のモニタリングシステム

Slide 9

Slide 9 text

©2024 CyberAgent Inc. Distribution prohibited 01 MLOps 9

Slide 10

Slide 10 text

©2024 CyberAgent Inc. Distribution prohibited MLOps研修前半で扱った領域 10 ● コンテナ ● 実験管理 ● CI/CD/CT ● 学習パイプライン構築 ● 推論サーバ構築 重要な部分をMLOps研修前半で扱いました

Slide 11

Slide 11 text

©2024 CyberAgent Inc. Distribution prohibited MLOpsはこれだけで十分? 11 ● コンテナ ● 実験管理 ● CI/CD/CT ● 学習パイプライン構築 ● 推論サーバ構築 全てすごく大事だが、実務では十分?

Slide 12

Slide 12 text

©2024 CyberAgent Inc. Distribution prohibited MLOpsとは 12 Machine Learning ✖ Operations 機械学習 運用

Slide 13

Slide 13 text

©2024 CyberAgent Inc. Distribution prohibited DevOpsとは 13 ChatGPTによると DevOpsは、ソフトウェア開発(Dev)と運用(Ops)を統合するための概念・実践・文化のことを 指します。これは、開発と運用の間のコミュニケーションとコラボレーションを強化し、製品のリ リースと新機能の更新をより迅速かつ頻繁に行うことを可能にすることを目指しています。 DevOpsの主な目標は、組織の効率性と生産性を向上させることです。これは、自動化、継続的イン テグレーション(CI)、継続的デリバリー(CD)、マイクロサービス、コンテナ化、クラウドコン ピューティングなどの技術を活用して達成されます。 DevOpsの採用により、開発と運用のチームは一緒に働くことで、問題を早期に特定し、解決策を迅 速に実装することが可能となります。これにより、製品の品質が向上し、顧客満足度が向上するとと もに、組織全体の生産性と効率性が向上します。

Slide 14

Slide 14 text

©2024 CyberAgent Inc. Distribution prohibited MLシステムがある意義 14 ● DSPにおけるCTR・CVR予測モデル ○ 枠の価値に対して最適な入札をすることで利益を最大化 ● 広告クリエイティブの効果を推定 ○ 広告効果の高いクリエイティブ制作を効率化 ● ボイスボットの音声認識・自然言語理解 ○ 精度とUXを向上させ複雑なタスクに応用 ビジネス価値を最大化すること そのために、機械学習をより迅速にスケールアップする必要がある

Slide 15

Slide 15 text

©2024 CyberAgent Inc. Distribution prohibited MLシステムはなぜ難しい? 15 ● 継続的に学習しないと精度が劣化する ○ 時間、データの変化でパフォーマンスが変動 ○ MLモデルはコードによらず確率的なふるまい ● モデルが複雑であり、多数のステークホルダーがいる ○ データサイエンティスト、MLエンジニア、ソフトウェアエンジニア ○ 役割が縦割りになり、システムもそれに合わせたアーキテクチャに なりやすい ● データの管理が必要(学習データと本番データ)

Slide 16

Slide 16 text

©2024 CyberAgent Inc. Distribution prohibited DevOpsとMLOpsの関係(基礎編の再掲) 16 DevOps for ML 歴史的には がMLOpsの立ち位置

Slide 17

Slide 17 text

©2024 CyberAgent Inc. Distribution prohibited MLOpsはDevOpsの派生に過ぎない 17 特徴量 エンジニアリング データ準備 モデリング 評価 モニタリング 継続的学習 ログ収集 評価 ML開発 運用

Slide 18

Slide 18 text

©2024 CyberAgent Inc. Distribution prohibited これまで扱ってきた内容 18 特徴量 エンジニアリング データ準備 モデリング 評価 モニタリング 継続的学習 ログ収集 評価 ML開発

Slide 19

Slide 19 text

©2024 CyberAgent Inc. Distribution prohibited 実践編で扱う内容 19 特徴量 エンジニアリング データ準備 モデリング 評価 モニタリング 継続的学習 ログ収集 評価 運用

Slide 20

Slide 20 text

©2024 CyberAgent Inc. Distribution prohibited 再掲: MLOps基礎編 20 機械学習システムを運用するには ソフトウェアエンジニアリングのスキルが必須 この講義はソフトウェアっぽい話も多いです 盛りだくさんになっているので、時間内に全部できなくても大丈夫です 頭の中にインデックスを貼ってもらえればOKです

Slide 21

Slide 21 text

©2024 CyberAgent Inc. Distribution prohibited 02 事前準備 21

Slide 22

Slide 22 text

©2024 CyberAgent Inc. Distribution prohibited Prerequisites 22 ● Docker Desktop ● docker-buildx(Docker Desktopに内包されていると思います) ● python 3.11(本講義では3.11.7を使用しています) ● poetry ● awscli ● direnv ● terraform(本講義ではv1.4.5を使用しています) ● make

Slide 23

Slide 23 text

©2024 CyberAgent Inc. Distribution prohibited 余談: 最近のPython事情 23 Rust製ツールが人気 uv: ● https://astral.sh/blog/uv ● package manager rye: ● https://github.com/astral-sh/rye ● package manager ruff: ● https://github.com/astral-sh/ruff ● linter & formatter

Slide 24

Slide 24 text

©2024 CyberAgent Inc. Distribution prohibited 余談: Python事情の変遷 24 ● pytest ● mypy ● black ● flake8 ● isort ● pytest ● mypy ● ruff Pythonプロジェクトの開始時に入れるべきライブラリ群がアップデート

Slide 25

Slide 25 text

©2024 CyberAgent Inc. Distribution prohibited 応用編で作成したMLシステム 25

Slide 26

Slide 26 text

©2024 CyberAgent Inc. Distribution prohibited 応用編とほぼ同構成を再作成 26 $ git clone https://github.com/hosimesi/aws-mlops-practice $ cd aws-mlops-practice ハンズオンレポジトリをクローン https://github.com/hosimesi/aws-mlops-practice

Slide 27

Slide 27 text

©2024 CyberAgent Inc. Distribution prohibited コマンドが通るか確認 27 $ aws sts get-caller-identity --profile mlops-practice { "UserId": “XXXXXXXXXXXXXXX:keita_hoshii", "Account": "0123456789", "Arn": "arn:aws:sts::0123456789:assumed-role/xxxxxxxx/keita_hoshii" } 結果が返ってこればOK

Slide 28

Slide 28 text

©2024 CyberAgent Inc. Distribution prohibited 環境変数の設定 28 $ cp .env.example .env $ $EDITOR .env AWS_REGION=ap-northeast-1 AWS_ACCOUNT_ID=0123456789 AWS_PROFILE=mlops-practice AWS_ALB_DNS= USER_NAME=xxxxx S3_BUCKET=${USER_NAME}-mlops-practice TF_VAR_aws_region=${AWS_REGION} TF_VAR_aws_profile=${AWS_PROFILE} TF_VAR_aws_account_id=${AWS_ACCOUNT_ID} TF_VAR_name=${USER_NAME} 自分の名前(AWSリソースのprefix) 変更しない 自分のAWSのアカウントID $EDITORは自身が使いたいものに任意で変えてください ex. vim, code

Slide 29

Slide 29 text

©2024 CyberAgent Inc. Distribution prohibited 環境変数の読み込み 29 $ direnv allow . $ echo $AWS_PROFILE direnv: loading ~hoge/fuga/.envrc direnv: export +AWS_ACCOUNT_ID +AWS_ALB_DNS +AWS_PROFILE +AWS_REGION +TF_VAR_aws_account_id +TF_VAR_aws_profile +TF_VAR_aws_region +TF_VAR_name +USER_NAME mlops-practice 設定されていたらOK うまくいかない場合、direnvの設定を再確認(次ページに詳細載っているので参照してください) https://github.com/direnv/direnv/blob/master/man/direnv.1.md

Slide 30

Slide 30 text

©2024 CyberAgent Inc. Distribution prohibited Tips: direnvの設定 30 $ $EDITOR ~/.bashrc Bashの場合 direnvの設定を記述する $ source ~/.bashrc $ eval "$(direnv hook bash)" $ $EDITOR ~/.zshrc Zshの場合 $ source ~/.zshrc $ eval "$(direnv hook zsh)"

Slide 31

Slide 31 text

©2024 CyberAgent Inc. Distribution prohibited State用S3バケットの作成 31 TerraformのState管理用のバケットの作成 S3 →「バケットを作成」をクリック https://ap-northeast-1.console.aws.amazon.com/s3/home?region=ap-northeast-1

Slide 32

Slide 32 text

©2024 CyberAgent Inc. Distribution prohibited State用S3バケットの作成 32 バケットタイプ 汎用 バケット名 {名前}-mlops-practice-tfstate バケットのバージョニング 有効にする 以下のコマンドでも同様の操作が可能 $ aws s3 mb s3://{名前}-mlops-practice-tfstate --region ap-northeast-1 aws s3api put-bucket-versioning --bucket ${名前}-mlops-practice-tfstate --versioning-configuration Status=Enabled

Slide 33

Slide 33 text

©2024 CyberAgent Inc. Distribution prohibited Tips 33 required_version = "~> 1.4" required_providers { aws = { source = "hashicorp/aws" version = "~> 4.60" } } backend "s3" { bucket = "{名前}-mlops-practice–tfstate" region = "ap-northeast-1" key = "terraform.tfstate" encrypt = true } } 実際のプロダクトではチーム全員が同一リソースを触るため、 StateファイルをS3に置きチームで共有 backendとしてs3を指定 ※ Stateファイル用のバケットが作成済みなことを確認 Terraform内でStateファイルの置き場を管理しようとすると、Stateファイル 自体の保存先が分からないため、置き場だけは手動作成する必要がある

Slide 34

Slide 34 text

©2024 CyberAgent Inc. Distribution prohibited Terraformファイルの編集 34 $ $EDITOR infra/main.tf variable "name" { description = "The name of the resources to create." } provider "aws" { region = var.aws_region profile = var.aws_profile } terraform { required_version = "~> 1.4" required_providers { aws = { source = "hashicorp/aws" version = "~> 4.60" } } backend "s3" { # FIXME: {your_name}-mlops-practice-tfstate bucket = "hoshii-mlops-practice-tfstate" region = "ap-northeast-1" key = "terraform.tfstate" encrypt = true } } 先ほど作成したbucket名 {名前}-mlops-practice-tfstate

Slide 35

Slide 35 text

©2024 CyberAgent Inc. Distribution prohibited AWSのリソース作成 35 $ terraform -chdir=infra init Terraformでリソース作成する まずは、S3とECRのみ作成 $ terraform -chdir=infra plan $ terraform -chdir=infra apply

Slide 36

Slide 36 text

©2024 CyberAgent Inc. Distribution prohibited Terraform plan 36 現在のリソースとの差分 適用前に意図しないChangeやDestroyが ないか確認 + request_payer = (known after apply) + tags_all = (known after apply) + website_domain = (known after apply) + website_endpoint = (known after apply) } # module.stepfunctions.aws_sfn_state_machine.mlops_practice will be created + resource "aws_sfn_state_machine" "mlops_practice" { + arn = (known after apply) + creation_date = (known after apply) + definition = (known after apply) + description = (known after apply) + id = (known after apply) + name = "hoshii-mlops-practice-ml-pipeline" + name_prefix = (known after apply) + publish = false + revision_id = (known after apply) + role_arn = (known after apply) + state_machine_version_arn = (known after apply) + status = (known after apply) + tags_all = (known after apply) + type = "STANDARD" + version_description = (known after apply) } Plan: 87 to add, 0 to change, 0 to destroy.

Slide 37

Slide 37 text

©2024 CyberAgent Inc. Distribution prohibited Stateファイル確認 37 https://ap-northeast-1.console.aws.amazon.com/s3/buckets?region=ap-northeast-1&bucketType=general&region=ap-northeast-1

Slide 38

Slide 38 text

©2024 CyberAgent Inc. Distribution prohibited Stateファイルとは 38 Terraform経由で作成したインフラの現在の状態をバージョン管理するもの どのリソースが更新・削除されるべきかを判断するために使用される GitHubと同じでStateをローカルで管理するよりもリモートに保存することで、複数人が同じ Terraform設定を使用して作業する場合、全員が同じリソースのビューを持つことが可能 ※ Stateファイルには機密情報も含まれているため、Gitでの管理も非推奨 https://spacelift.io/blog/terraform-s3-backend

Slide 39

Slide 39 text

©2024 CyberAgent Inc. Distribution prohibited イメージを作成してECRにプッシュする 39 $ make build-ml build-predictor $ make push-ml push-predictor イメージが登録済みなことを確認 学習パイプライン用のイメージ(ml)と推論サーバ用のイメージ(predictor)を作成 https://ap-northeast-1.console.aws.amazon.com/ecr /private-registry/repositories?region=ap-northeast- 1

Slide 40

Slide 40 text

©2024 CyberAgent Inc. Distribution prohibited Notice: イメージ作成コマンド 40 MakeでWrapしたコマンドの中身 docker build --platform=linux/amd64 --build-arg NAME=$(USER_NAME) --target ml -t $(ECR_REPOSITORY)/$(DOCKER_ML_IMAGE):$(SHORT_SHA) -f $(DOCKERFILE_REPOSITORY)/$(DOCKERFILE_ML) . docker tag $(ECR_REPOSITORY)/$(DOCKER_ML_IMAGE):$(SHORT_SHA) $(ECR_REPOSITORY)/$(DOCKER_ML_IMAGE):$(DOCKER_TAG) build-ml push-ml aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin $(ECR_REPOSITORY) docker push $(ECR_REPOSITORY)/$(DOCKER_ML_IMAGE):$(SHORT_SHA) && docker push $(ECR_REPOSITORY)/$(DOCKER_ML_IMAGE):$(DOCKER_TAG) Dockerfileを元にビルド イメージへのタグ付け ECRログイン イメージのECRへのプッシュ

Slide 41

Slide 41 text

©2024 CyberAgent Inc. Distribution prohibited 使用するデータ 41 Avazu Dataset

Slide 42

Slide 42 text

©2024 CyberAgent Inc. Distribution prohibited 学習データのアップロード 42 $ unzip data.zip ※ カレントディレクトリにdataフォルダができたことを確認 $ make upload 学習データの準備をする ローカルにdata.zipがあるのでそれを回答する https://ap-northeast-1.console.aws.amazon.com/s3/buckets?region=ap-n ortheast-1&bucketType=general&region=ap-northeast-1

Slide 43

Slide 43 text

©2024 CyberAgent Inc. Distribution prohibited 学習の実行(ローカル) 43 $ make run-ml 学習の実行 学習済みモデルが上がっていることを確認 $ docker network create mlops-practice ネットワークの作成

Slide 44

Slide 44 text

©2024 CyberAgent Inc. Distribution prohibited 学習の実行(ECS Task) 44 Step FunctionsからMLモデルをキック https://ap-northeast-1.console.aws.amazon.com/states/home?region=ap-northeast-1#/statemachines

Slide 45

Slide 45 text

©2024 CyberAgent Inc. Distribution prohibited ECS Taskでの学習の実行 45 「実行を開始」(SGD_CLASSIFIER_CTR_MODEL)

Slide 46

Slide 46 text

©2024 CyberAgent Inc. Distribution prohibited ECS Taskでの学習の実行 46 エラーが出ていなければOK イメージ図 https://ap-northeast-1.console.aws.amazon.com/ecs/v2/clusters?region=ap-northeast-1

Slide 47

Slide 47 text

©2024 CyberAgent Inc. Distribution prohibited 推論サーバをローカルで動かす 47 ローカルで推論サーバを立ち上げる $ docker compose up --build リクエストを投げる https://github.com/hosimesi/aws-mlops-practice/blob/4dbed6a59641aeda70ef03a687187fc489885206/Makefile#L198C1-L208C1 $ make predict {"prediction":0.5002767055606515,"model":"sgd_classifier_ctr_model"} {"prediction":0.49770948950373656,"model":"sgd_classifier_ctr_optuna_model"} {"prediction":0.5002766695014028,"model":"sgd_classifier_ctr_model"} {"prediction":0.49770948950373656,"model":"sgd_classifier_ctr_optuna_model"} 結果が返ってくればOK ローカルで推論サーバを立ち上げるための事前準備をする

Slide 48

Slide 48 text

©2024 CyberAgent Inc. Distribution prohibited ECSサービスを更新する 48 学習済みモデルがS3にアップロードされる前にデプロイされているため、ECSを更新する https://ap-northeast-1.console.aws.amazon.com/e cs/v2/clusters?region=ap-northeast-1

Slide 49

Slide 49 text

©2024 CyberAgent Inc. Distribution prohibited ECS上の推論サーバにリクエストを送る 49 $ $EDITOR .env AWS_REGION=ap-northeast-1 AWS_ACCOUNT_ID=0123456789 AWS_PROFILE=mlops-practice AWS_ALB_DNS= USER_NAME=xxxxx S3_BUCKET=${USER_NAME}-mlops-practice TF_VAR_aws_region=${AWS_REGION} TF_VAR_aws_profile=${AWS_PROFILE} TF_VAR_aws_account_id=${AWS_ACCOUNT_ID} TF_VAR_name=${USER_NAME} https://ap-northeast-1.console.aws.amazon.com/ec2/home?region=ap-northeast-1#LoadBalancers: Makeコマンドでリクエストが送れるように、ALBのDNSを.envに 追記する

Slide 50

Slide 50 text

©2024 CyberAgent Inc. Distribution prohibited 推論サーバの動作確認(ECS) 50 環境変数の再読み込み $ direnv allow . リクエストを投げる $ make predict-ecs {"prediction":0.5002767055606515,"model":"sgd_classifier_ctr_model"} {"prediction":0.49770948950373656,"model":"sgd_classifier_ctr_optuna_model"} {"prediction":0.5002766695014028,"model":"sgd_classifier_ctr_model"} {"prediction":0.49770948950373656,"model":"sgd_classifier_ctr_optuna_model"} 結果が返ってくればOK .PHONY: predict-ecs predict-ecs: while read line; do \ curl -X 'POST' '$(AWS_ALB_DNS)/predict' \ -H 'accept: application/json' \ -H 'Content-Type: application/json' \ -d "$$line"; \ echo; \ sleep 1; \ done < ./data/sample.jsonl predict-ecsコマンドの中身

Slide 51

Slide 51 text

©2024 CyberAgent Inc. Distribution prohibited 51 ここまでで応用編と同等の リソース作成が完了しました

Slide 52

Slide 52 text

©2024 CyberAgent Inc. Distribution prohibited 03 推論サーバの自動更新 52

Slide 53

Slide 53 text

©2024 CyberAgent Inc. Distribution prohibited CASE1. 複数モデルの並列学習 53 複数のモデルを並列で学習させたい 現在の構成では新規にモデルは学習・作成できるが、モデルは一つずつしか 学習できない → 学習パイプラインが複数モデルを並列で動かせるように変更する

Slide 54

Slide 54 text

©2024 CyberAgent Inc. Distribution prohibited CASE2. 推論サーバの自動更新 54 新規の学習済みモデルが自動で推論サーバに載って欲しい 現在の構成では新規にモデルは学習・作成されるが、推論サーバに載っている モデルは変わらない ● 新しいモデルは学習されるたびにS3に保存 ● しかし、推論サーバは自動で新モデルをロードしないため、新モデルを利 用するには手動でサーバを更新する必要がある → 学習パイプラインの最後に推論サーバを自動で更新する

Slide 55

Slide 55 text

©2024 CyberAgent Inc. Distribution prohibited 作成するもの 55 ● モデルを並列に同時学習 ○ SGD_CLASSIFIER_CTR_MODEL ○ SGD_CLASSIFIER_CTR_OPTUNA_MODEL ● 両モデルの学習終了後、推論サーバを新しいモデルを載せたものに更新 ○ 各モデル名で保存されているモデルのうち、最新のオブジェクトをそれぞれ取得

Slide 56

Slide 56 text

©2024 CyberAgent Inc. Distribution prohibited 構成図 56 推論サーバ更新のステップの追加

Slide 57

Slide 57 text

©2024 CyberAgent Inc. Distribution prohibited Step Functionsの作成 57 StepFunctionsのページで「ステートマシンの作成」をクリック https://ap-northeast-1.console.aws.amazon.com/states/home?region=ap-northeast-1#/statemachines

Slide 58

Slide 58 text

©2024 CyberAgent Inc. Distribution prohibited Step Functionsの作成 58 テンプレートの選択で「Blank」を選択

Slide 59

Slide 59 text

©2024 CyberAgent Inc. Distribution prohibited 並列学習の設定 59 フローからParallelを選択し、ドラッグ&ドロップ

Slide 60

Slide 60 text

©2024 CyberAgent Inc. Distribution prohibited 並列学習の設定 60 アクションからECS Taskを選択し、ドラッグ&ドロップ

Slide 61

Slide 61 text

©2024 CyberAgent Inc. Distribution prohibited 定義の設定 61 Branchesに2つのブロックがあり、それぞれを今回のモデル定義で上書き ● SGD_CLASSIFIER_CTR_MODEL ● SGD_CLASSIFIER_CTR_OPTUNA_MODEL

Slide 62

Slide 62 text

©2024 CyberAgent Inc. Distribution prohibited { "StartAt": "ECS RunTask sgd_classifier_ctr_optuna_model", "States": { "ECS RunTask sgd_classifier_ctr_optuna_model": { "Type": "Task", "Resource": "arn:aws:states:::ecs:runTask.sync", "Parameters": { "LaunchType": "FARGATE", "Cluster": "{cluster_arn}", "TaskDefinition": "{task_definition_arn}", "NetworkConfiguration": { "AwsvpcConfiguration": { "AssignPublicIp": "DISABLED", "SecurityGroups": [ "{security_group}" ], "Subnets": [ "{subnet}" ] } }, "Overrides": { "ContainerOverrides": [ { "Name": "ml-pipeline", "Environment": [ { "Name": "MODEL", "Value": "sgd_classifier_ctr_optuna_model" } ] } ] } }, "End": true } } } { "StartAt": "ECS RunTask sgd_classifier_ctr_model", "States": { "ECS RunTask sgd_classifier_ctr_model": { "Type": "Task", "Resource": "arn:aws:states:::ecs:runTask.sync", "Parameters": { "LaunchType": "FARGATE", "Cluster": "{cluster_arn}", "TaskDefinition": "{task_definition_arn}", "NetworkConfiguration": { "AwsvpcConfiguration": { "AssignPublicIp": "DISABLED", "SecurityGroups": [ "{security_group}" ], "Subnets": [ "{subnet}" ] } }, "Overrides": { "ContainerOverrides": [ { "Name": "ml-pipeline", "Environment": [ { "Name": "MODEL", "Value": "sgd_classifier_ctr_model" } ] } ] } }, "End": true } } } Step Functionsの設定 62 ECS ClusterのARN ECS ML Pipelineのタスク定義のARN ※ revisionは省略 {名前}-mlops-practice-ml-pipeline-sgのID {名前}-mlops-practice-private-subnet-1aのID {モデル名} ECS RunTask {モデル名} sgd_classifier_ctr_modelの場合 sgd_classifier_ctr_optuna_modelの場合 https://github.com/CyberAgentAI/dsc-onboarding-mlops-2024/blob/main/4-mlops-practice/infra/modules/stepfunctions/definition/execute_ml_pipeline_parallel.json

Slide 63

Slide 63 text

©2024 CyberAgent Inc. Distribution prohibited ここまでの定義 63 参考 https://github.com/hosimesi/aws-mlops-practice/blob/main/infra/modules/stepfunctions/definition/execute_ml_pipeline_parallel.json

Slide 64

Slide 64 text

©2024 CyberAgent Inc. Distribution prohibited 全体の設定 64 「設定」をクリック

Slide 65

Slide 65 text

©2024 CyberAgent Inc. Distribution prohibited パイプラインを作成する 65 ステートマシン名: {名前}-mlops-practice-ml-pipeline-parallel 実行ロール: {名前}-mlops-practice-step-functions-role 作成をクリック

Slide 66

Slide 66 text

©2024 CyberAgent Inc. Distribution prohibited 実行 66 ここまでで一度実行し、2つのモデルが並列で学習されるか確認する Step Functionsの画面 ECSの画面(https://ap-northeast-1.console.aws.amazon.com/ecs/v2/clusters?region=ap-northeast-1)

Slide 67

Slide 67 text

©2024 CyberAgent Inc. Distribution prohibited 実行の確認 67

Slide 68

Slide 68 text

©2024 CyberAgent Inc. Distribution prohibited 推論サーバ更新の設定 68 推論サーバを自動で更新するステップを導入

Slide 69

Slide 69 text

©2024 CyberAgent Inc. Distribution prohibited 推論サーバ更新の設定 69

Slide 70

Slide 70 text

©2024 CyberAgent Inc. Distribution prohibited APIパラメータ 70 { "LaunchType": "FARGATE", "Cluster": "${cluster_arn}", "TaskDefinition": "${update_server_task_definition_arn}”, "NetworkConfiguration": { "AwsvpcConfiguration": { "AssignPublicIp": "DISABLED", "SecurityGroups": [ "sg~" ], "Subnets": [ "subnet~" ] } } } ECS ClusterのARN ECS Update Serverのタスク定義のARN {名前}-mlops-practice-ml-pipeline-sgのID {名前}-mlops-practice-private-subnet-1aのID

Slide 71

Slide 71 text

©2024 CyberAgent Inc. Distribution prohibited ステートマシンの保存 71 保存をクリック

Slide 72

Slide 72 text

©2024 CyberAgent Inc. Distribution prohibited ここまでで詰まった方 72 terraformを準備してるので、同リソースを作成しましょう ※ 時間ある時に復習してみてください resource "aws_sfn_state_machine" "mlops_practice_parallel" { name = "${var.name}-mlops-practice-ml-pipeline-parallel" role_arn = var.stepfunctions_role_arn definition = templatefile("./modules/stepfunctions/definition/execute_ml_pipeline_parallel.json", { cluster_arn = "${var.cluster_arn}", task_definition_arn = "${var.task_definition_arn}", update_server_task_definition_arn = "${var.update_server_task_definition_arn}", security_group = "${var.security_group}", subnet = "${var.subnet}" }) } 以下をコメントインし、make apply https://github.com/hosimesi/aws-mlops-practice/blob/main/infra/modules/stepfunctions/main.tf $ make apply

Slide 73

Slide 73 text

©2024 CyberAgent Inc. Distribution prohibited Notice: ECSの更新 73 def update_ecs_service(cluster: str, service: str) -> None: ecs = boto3.client("ecs") logger.info(f"Start updating ECS service: {service} in cluster: {cluster}") try: response = ecs.update_service(cluster=cluster, service=service, forceNewDeployment=True) logger.info(f"Started ECS service update: {response}") except Exception as e: logger.error(f"Failed to update ECS service: {service} in cluster: {cluster}, error: {str(e)}") boto3を使ってECSサービスを更新する https://github.com/hosimesi/aws-mlops-practice/blob/cf2d9f380bc5515fd485d0a2458f7c7d8769ff 11/ml/utils/aws_controller.py#L116C1-L123C104

Slide 74

Slide 74 text

©2024 CyberAgent Inc. Distribution prohibited Notice: 最新のモデルの取得 74 @asynccontextmanager async def lifespan(app: FastAPI) -> AsyncGenerator: app.state.predictor_models = get_predictor_models(revision=os.getenv("REVISION")) app.state.instance = get_ecs_instance_id() if os.getenv("SYSTEM_ENV") == "local": app.state.pushgateway_url = "pushgateway:9091" else: app.state.pushgateway_url = f"pushgateway.{INTERNAL_NAMESPACE}:9091" logger.info(f"Instance ID: {app.state.instance}") logger.info(f"Pushgateway URL: {app.state.pushgateway_url}") logger.info("start server") yield logger.info("shutdown server") サーバの開始と終了時に最新のモデルを S3から取得する関数を定義 https://github.com/hosimesi/aws-mlops-practice/blob/cf2d9f380bc5515fd485d0a2458f7c7d8769ff11/predictor/main.p y#L22C1-L36C1

Slide 75

Slide 75 text

©2024 CyberAgent Inc. Distribution prohibited 実行してみる 75 成功すればOK

Slide 76

Slide 76 text

©2024 CyberAgent Inc. Distribution prohibited 最新のモデルに変わっているか確認 76 ECSのPredictor Serverを確認 Update Server Taskのログ Predictorのログ

Slide 77

Slide 77 text

©2024 CyberAgent Inc. Distribution prohibited 最新のモデルに更新するだけで十分? 77 現在だとモデル名ごとにS3から最新のモデルを取得して更新している がこれだけで十分か? ex. もし学習済みモデルの精度が意図せず劣化していたら? モデルの切り戻しはできる?

Slide 78

Slide 78 text

©2024 CyberAgent Inc. Distribution prohibited MLシステムと通常システムの違い 78 MLシステムでは、コードのバージョン管理とモデルのバージョン管理の両方が重要 ● コードのバージョン管理 ○ 特定のバージョンのコードでモデルを学習・推論した結果を再現するため → Git、Image Tag ● モデルのバージョン管理 ○ 特定のバージョンのモデルを利用した結果を再現するため ○ 新しいモデルがパフォーマンスを落とした場合に古いモデルに切り戻すため ● データのバージョン管理 ○ 学習を再現するため ○ 今回はデータは一意に定まるようになっている、学習前にS3に保存している ● 学習時のパラメータ ○ 学習を再現するため

Slide 79

Slide 79 text

©2024 CyberAgent Inc. Distribution prohibited 学習済みモデルのバージョン管理 79 モデルのRevision、名前、S3のパスを管理するためにDynamoDBを使 用 DynamoDB 高パフォーマンスを実現する、サーバーレス NoSQL フルマネージドデータベース https://aws.amazon.com/jp/dynamodb/

Slide 80

Slide 80 text

©2024 CyberAgent Inc. Distribution prohibited 学習済みモデルのバージョン管理構成図 80

Slide 81

Slide 81 text

©2024 CyberAgent Inc. Distribution prohibited 推論サーバ側構成図 81

Slide 82

Slide 82 text

©2024 CyberAgent Inc. Distribution prohibited DynamoDBの作成 82 DynamoDB 「テーブルの作成」 https://ap-northeast-1.console.aws.amazon.com/dynamodbv2/home?region=ap-northeast-1#tables

Slide 83

Slide 83 text

©2024 CyberAgent Inc. Distribution prohibited DynamoDBの作成 83 テーブル名 {名前}-mlops-practice パーティションキー revision(文字列) ソートキー logged_at(文字列)

Slide 84

Slide 84 text

©2024 CyberAgent Inc. Distribution prohibited DynamoDBの作成 84 テーブル設定 設定をカスタマイズ テーブルクラス DynamoDB標準

Slide 85

Slide 85 text

©2024 CyberAgent Inc. Distribution prohibited DynamoDBの作成 85 キャパシティーモード プロビジョンド 読み込みキャパシティー(Auto Scaling) オフ 書き込みキャパシティー(Auto Scaling) オフ →「テーブルの作成」

Slide 86

Slide 86 text

©2024 CyberAgent Inc. Distribution prohibited 作成を確認 86 ※ 注意点 本来はECRやS3と同様にVPC Endpointの作成やDynamoDBへアクセスするためのRoleの 付与をする必要があるが、今回は運営で用意して適用済み ※ VPC Endpointとは VPC内のサービスとVPC外のサービスをプライベート接続で通信するためのコンポーネント

Slide 87

Slide 87 text

©2024 CyberAgent Inc. Distribution prohibited from ml.steps import ( extract_step, preprocess_step, train_step, create_model_revision_step, ) : : ml_model = train_step(preprocessed=preprocessed, ml_model=model_info.ml_model(), revision=revision, name=model_info.name) create_model_revision_step( revision=revision, name=model_info.name, s3_path=os.path.join(revision, model_info.name), ) Revisionの登録 87 学習パイプラインの最後に、Revisionを登録するstepを追加 追加 $ $EDITOR ml/main.py 追加

Slide 88

Slide 88 text

©2024 CyberAgent Inc. Distribution prohibited 学習パイプラインを実行する 88 学習パイプラインのイメージをアップデートする $ make build-ml push-ml https://ap-northeast-1.console.aws.amazon.com/states/home?region=ap-northeast-1#/statemachines 学習パイプラインを実行する

Slide 89

Slide 89 text

©2024 CyberAgent Inc. Distribution prohibited DynamoDBを確認する 89 DynamoDBに以下の形式で入っていればOK https://ap-northeast-1.console.aws.amazon.com/dynamodbv2/home?region=ap-northeast-1#tables

Slide 90

Slide 90 text

©2024 CyberAgent Inc. Distribution prohibited 推論サーバ側のモデル取得ロジック 90 モデルの取得ロジックは以下 ● Revisionを指定するとDynamoDBから決まったRevisionのモデルを取得する ● 指定しなければ最新のバージョンを取得する $ cat infra/modules/ecs/container_definitions/predictor.json from predictor.utils.setup import get_ecs_instance_id, get_predictor_models : @asynccontextmanager async def lifespan(app: FastAPI) -> AsyncGenerator: app.state.predictor_models = get_predictor_models(revision=os.getenv("REVISION")) : コードを確認する

Slide 91

Slide 91 text

©2024 CyberAgent Inc. Distribution prohibited モデルのバージョンを固定する 91 ex. もし最新のモデルに異常があった場合、一つ前のバージョンに戻したい DynamoDB → 項目を探索 ※ revisionの値はサンプルです

Slide 92

Slide 92 text

©2024 CyberAgent Inc. Distribution prohibited モデルのバージョンを固定してみる 92 $ $EDITOR infra/modules/ecs/container_definitions/predictor.json "mountPoints": [ { "readOnly": null, "containerPath": "/var/logs", "sourceVolume": "logs" } ], "essential": true, "environment": [ { "name": "REVISION", "value": "" } ], 戻したいDynamoDBのrevisionを指定 ex. { “name”: “REVISION”, “value”: “2024/05/15/10” } $ make apply デプロイする

Slide 93

Slide 93 text

©2024 CyberAgent Inc. Distribution prohibited モデルのバージョンが固定されているか確認する 93

Slide 94

Slide 94 text

©2024 CyberAgent Inc. Distribution prohibited 04 ログの収集と継続的な学習 94

Slide 95

Slide 95 text

©2024 CyberAgent Inc. Distribution prohibited 継続的に学習を回すには? 95 継続的に学習を回すには新たなデータが必要 例えば、広告配信サーバの場合 ● 入札した広告が表示されたかどうか ● 表示された広告がクリックされたかどうか ● クリックされた広告の商品が購入されたかどうか これらのデータを適切に集約し、新たな学習データとして使用できる状態 にして保存する必要がある

Slide 96

Slide 96 text

©2024 CyberAgent Inc. Distribution prohibited 学習データの準備の難しい点 96 実際は、学習データに使用するログがたまるタイミングは異なる ● 実際にきたリクエスト ○ 入札したタイミング ● 入札した広告が表示されたかどうか ○ 広告が表示されたタイミング ● 表示された広告がクリックされたかどうか ○ 広告がクリックされたタイミング ● クリックされた広告の商品が購入されたかどうか ○ 商品が購入されたタイミング

Slide 97

Slide 97 text

©2024 CyberAgent Inc. Distribution prohibited 学習データの準備方法 97 全てのタイミングでどの広告のイベントかを判定できるように、リクエスト 単位などで共通のIDを発行 それぞれをDWHなどに集約して、Joinして学習データに使用する

Slide 98

Slide 98 text

©2024 CyberAgent Inc. Distribution prohibited 今から作成するもの 98 クリックしたかどうかは別のサーバで得られたとして、あらかじめ用意済み (click.tsv.gz) リクエストの情報を適切にログに落として、学習できる状態にする

Slide 99

Slide 99 text

©2024 CyberAgent Inc. Distribution prohibited Fluentd 99 データの収集・変換・転送をするOSS リクエストをログとして収集して学習データに再利用 https://www.fluentd.org/ Fluentd is an open source data collector for unified logging layer. Fluentd allows you to unify data collection and consumption for a better use and understanding of data.

Slide 100

Slide 100 text

©2024 CyberAgent Inc. Distribution prohibited 構成 100 Predictorと同じECS ServiceにサイドカーとしてFluentdコンテナを立ててPredictorコンテナの ログを収集 サイドカーコンテナはメインのコンテナと並行して動作し、追加サービスを提供するもの ex. ロギング、モニタリング

Slide 101

Slide 101 text

©2024 CyberAgent Inc. Distribution prohibited 構成 101 1. FastAPIがファイルにログを書き出す 2. サイドカーに立てたFluentdがファイル を読み込んで、S3に転送

Slide 102

Slide 102 text

©2024 CyberAgent Inc. Distribution prohibited Predictorのログの変更 102 学習に使えるように、Predictorでログをファイルに吐くように変更 通常のログと識別できるように新たなLoggerを追加 $ $EDITOR predictor/main.py from ml.utils.logger.logger_config import get_response_logger : logger = get_logger(__name__) : end_time = time.time() logger.info(f"Prediction time: {end_time - start_time}") : end_time = time.time() logger.info(f"Prediction time: {end_time - start_time}") import datetime as dt from ml.utils.logger.logger_config import get_logger, get_response_logger from predictor.schemas.response_log import BidResponseLog : logger = get_logger(__name__) response_logger = get_response_logger(f"{__name__}_response") : end_time = time.time() logger.info(f"Prediction time: {end_time - start_time}") bid_response_log = BidResponseLog( **bid_request.dict(), hostname=env, prediction=pred, logged_at=dt.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S") ) response_logger.info(json.dumps(bid_response_log.dict()))

Slide 103

Slide 103 text

©2024 CyberAgent Inc. Distribution prohibited @type tail format json path /var/logs/bid_response.log pos_file /var/logs/bid_response.log.pos tag log.bid_response @type s3 s3_bucket "#{ENV['USER_NAME']}-mlops-practice" profile_name mlops-practice path logs/local/ buffer_path /var/logs/fluent time_slice_format %Y%m%d%H time_slice_wait 10m utc buffer_chunk_limit 1m buffer_queue_limit 64 flush_interval 120s retry_wait 5s max_retry_wait 30 num_threads 8 # NOTICE: column mapping format tsv keys logged_at,id,hour,C1,banner_pos,site_id,site_domain,s ite_category,app_id,app_domain,app_category,device_id ,device_ip,device_model,device_type,device_conn_type, C14,C15,C16,C17,C18,C19,C20,C21,hostname,prediction store_as gzip Fluent.confの追加 103 $ $EDITOR fluentd/local/fluent.conf /var/logsをpredictorコンテナとfluentdコンテナで共有 集めたlogの保存先のS3 Bucket zip形式で保存

Slide 104

Slide 104 text

©2024 CyberAgent Inc. Distribution prohibited compose.yamlの編集 104 compose.yamlにfluentdコンテナを追加 : fluentd: container_name: fluentd build: context: . dockerfile: ./docker/Dockerfile.fluentd volumes: - ./fluentd/local:/fluentd/etc - ./predictor/logs:/var/logs - $HOME/.aws:/root/.aws:ro env_file: - .env networks: - mlops-practice networks: mlops-practice: external: true Predictorコンテナのログを/var/logsでfluentdコンテナと共有 $ $EDITOR compose.yaml

Slide 105

Slide 105 text

©2024 CyberAgent Inc. Distribution prohibited envの読み込み&立ち上げ 105 $ docker compose up --build CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ************ aws-mlops-practice-fluentd "tini -- /bin/entryp…" * minutes ago Up * seconds 5140/tcp, 24224/tcp fluentd ************ aws-mlops-practice-predictor "gunicorn -b 0.0.0.0…" * hours ago Up * seconds 0.0.0.0:8080->8080/tcp predictor $ docker ps コンテナを確認

Slide 106

Slide 106 text

©2024 CyberAgent Inc. Distribution prohibited ローカルの推論サーバにリクエストを送る 106 $ make predict 別のターミナルを開く $ tail -f predictor/logs/bid_response.log リクエストを送る ログがたくさん吐かれていたらOK ログがたくさん吐かれていたらOK(流し続けてください) {"logged_at": "2024-05-19 14:04:00", "id": "4.802063106841714e+18", "hour": "14102813", "C1": "1005", "banner_pos": "0", "site_id": "85f751fd", "site_domain": "c4e18dd6", "site_category": "50e219e0", "app_id": "54c5d545", "app_domain": "2347f47a", "app_category": "0f2161f8", "device_id": "4619756c", "device_ip": "34c0711c", "device_model": "a59d0d6d", "device_type": "1", "device_conn_type": "0", "C14": "23454", "C15": "320", "C16": "50", "C17": "2688", "C18": "1", "C19": "33", "C20": "-1", "C21": "212", "hostname": "predictor", "prediction": 0.5002767055606515} : : : 上記の形式でログがファイルに保存されます

Slide 107

Slide 107 text

©2024 CyberAgent Inc. Distribution prohibited ECRにイメージプッシュ 107 $ make push-predictor push-fluentd $ make build-predictor build-fluentd ECSで使えるようにECRにイメージをプッシュする

Slide 108

Slide 108 text

©2024 CyberAgent Inc. Distribution prohibited ログが溜まっているか確認する 108 https://ap-northeast-1.console.aws.amazon.com/s3/buckets?region=ap-northeast-1&bucketType=general&region=ap-northeast-1 {名前}-mlops-practice → logs → local

Slide 109

Slide 109 text

©2024 CyberAgent Inc. Distribution prohibited コンテナ定義を確認する 109 $ cat infra/modules/ecs/container_definitions/predictor.json [ { "name": "predictor", "image": "${predictor_ecr_uri}:latest", : "mountPoints": [ { "readOnly": null, "containerPath": "/var/logs", "sourceVolume": "logs" } ], "essential": true, : } Fluentdと共有するために ボリュームにマウント コンテナ内部の/var/logsをホストマシンのlogsという名前のボリュームにマウント $ cat infra/modules/ecs/main.tf resource "aws_ecs_task_definition" "predictor" { family = "${var.name}-predictor" network_mode = "awsvpc" cpu = 1024 memory = 2048 requires_compatibilities = ["FARGATE"] container_definitions = templatefile("./modules/ecs/container_definitions/predictor.json", { predictor_ecr_uri = "${var.predictor_ecr_uri}", fluentd_ecr_uri = "${var.fluentd_ecr_uri}", ecs_exporter_ecr_uri = "${var.ecs_exporter_ecr_uri}", name = "${var.name}" }) volume { name = "logs" } task_role_arn = var.ecs_task_role_arn execution_role_arn = var.ecs_task_execution_role_arn }

Slide 110

Slide 110 text

©2024 CyberAgent Inc. Distribution prohibited コンテナ定義の編集(Fluentdコンテナ) 110 $ $EDITOR infra/modules/ecs/container_definitions/predictor.json : { "name": "fluentd", "image": "${fluentd_ecr_uri}:latest", "mountPoints": [ { "readOnly": null, "containerPath": "/var/logs", "sourceVolume": "logs" } ], "environment": [ { "name": "USER_NAME", "value": "${name}" } ], "logConfiguration": { "logDriver": "awslogs", "options": { "awslogs-create-group": "true", "awslogs-group": "/ecs/${name}-mlops-practice-predictor", "awslogs-region": "ap-northeast-1", "awslogs-stream-prefix": "ecs" } } } ] Predictorコンテナの下にFluentdコンテナを追加 Fluentdコンテナをサイドカーに設定 Predictorコンテナからのログファイルを共有で きるようにホストマシンのlogsという名前の ボリュームにマウント

Slide 111

Slide 111 text

©2024 CyberAgent Inc. Distribution prohibited Docker ComposeとECS Taskの定義の違い 111 ローカルで複数コンテナを立ち上げるdocker composeと比較してみる version: "3" : fluentd: container_name: fluentd build: context: . dockerfile: ./docker/Dockerfile.fluentd volumes: - ./fluentd/local:/fluentd/etc - ./predictor/logs:/var/logs - $HOME/.aws:/root/.aws:ro env_file: - .env networks: - mlops-practice { "name": "fluentd", "image": "${fluentd_ecr_uri}:latest", "mountPoints": [ { "readOnly": null, "containerPath": "/var/logs", "sourceVolume": "logs" } ], "environment": [ { "name": "USER_NAME", "value": "{name}" } ], : } ] v v

Slide 112

Slide 112 text

©2024 CyberAgent Inc. Distribution prohibited /var/logsはどこからでてきた? 112 $ cat ml/utils/logger/logger_config.py def get_response_logger(name: str) -> Logger: logger = getLogger(name) fmt = "%(message)s" handler = FileHandler('/var/logs/bid_response.log') handler.setFormatter(coloredlogs.ColoredFormatter(fmt)) # Add the handler to the logger logger.addHandler(handler) logger.setLevel("INFO") return logger Predictorコンテナで/var/logsにログを出力するように設定している

Slide 113

Slide 113 text

©2024 CyberAgent Inc. Distribution prohibited デプロイ 113 $ make apply コンテナが2つできていることを確認 ● predictor ● fluentd

Slide 114

Slide 114 text

©2024 CyberAgent Inc. Distribution prohibited ECSにリクエストを送る 114 $ make predict-ecs ⚠ ローカルからリクエストを送りすぎるとIPバンされる可能性があるので注意してください {"prediction":0.4977068651182549,"model":"sgd_classifier_ctr_optuna_model"} {"prediction":0.49770977922636167,"model":"sgd_classifier_ctr_optuna_model"} {"prediction":0.49771618073871404,"model":"sgd_classifier_ctr_optuna_model"} {"prediction":0.497712282765125,"model":"sgd_classifier_ctr_optuna_model"} {"prediction":0.5002767108656835,"model":"sgd_classifier_ctr_model"} {"prediction":0.5002767105991618,"model":"sgd_classifier_ctr_model"} {"prediction":0.4977042330180624,"model":"sgd_classifier_ctr_optuna_model"} : :

Slide 115

Slide 115 text

©2024 CyberAgent Inc. Distribution prohibited S3にログがあるか確認する 115 S3 → {名前}-mlops-practice → 「logs/ecs」

Slide 116

Slide 116 text

©2024 CyberAgent Inc. Distribution prohibited DWHへの自動連携 116 S3に入ったログを分析や学習がしやすいように自動でDWH(後述)にImport されるようにする Q. S3にあるデータをそのまま使用するのはダメ? A. 複数ファイルをJOINしたりしたい場合は、S3のままでは少し難しい Athenaなどもあるのでプロダクトにあったものを導入したい 今回はAWSのマネージドDWHであるRedshiftを使用する ※ Athena: SQLを使用してS3内のデータを直接分析することができるクエリサービス

Slide 117

Slide 117 text

©2024 CyberAgent Inc. Distribution prohibited Redshiftとは? 117 ● AWSが提供するデータウェアハウスサービス ○ 各社同じようなサービスを提供 ■ BigQuery・Snowflake ● 大規模データ読出に最適化 ● 並列コンピューティング ● 列指向ストレージ Redshift Serverless ● 実際に使用した秒単位で課金 https://aws.amazon.com/jp/redshift/

Slide 118

Slide 118 text

©2024 CyberAgent Inc. Distribution prohibited DWHの比較 118 Redshift ● AWSが提供しているDWH BigQuery ● Google Cloudが提供しているDWH ● サーバーレスアーキテクチャ Snowflake ● Snowflakeが提供しているDWH ● データアプリケーションの講義で使用 ● コンピューティングとストレージを分離

Slide 119

Slide 119 text

©2024 CyberAgent Inc. Distribution prohibited Redshiftの準備 119 Redshift 無料トライアル or Serverless作成 https://ap-northeast-1.console.aws.amazon.com/redshiftv2/home?region=ap-northeast-1#serverless-dashboard

Slide 120

Slide 120 text

©2024 CyberAgent Inc. Distribution prohibited Redshiftの準備 120 設定 設定をカスタマイズ ターゲットの名前空間 {名前}-mlops-practice ワークグループの名前 {名前}-workgroup

Slide 121

Slide 121 text

©2024 CyberAgent Inc. Distribution prohibited IAMロールの紐付け 121 IAMロール(すでに運営で作成済みです) {名前}-mlops-practice-redshift-role {名前}-mlops-practice-ecs-task-role {名前}-mlops-practice-lambda-role 許可しているアクション ● redshiftに対する全てのアクション ○ "redshift:*" ● s3からデータをimportするためのアク ション ○ "s3:GetObject" ○ "s3:ListBucket"

Slide 122

Slide 122 text

©2024 CyberAgent Inc. Distribution prohibited Redshiftの準備 122 ベース容量 24 VPC {名前}-mlops-practiceのID セキュリティグループ {名前}-mlops-practice-redshift-sgのID サブネット {名前}-mlops-practice-public-subnet-1a {名前}-mlops-practice-public-subnet-1c {名前}-mlops-practice-public-subnet-1d 拡張されたVPCのルーティング ✅ VPC経由のアクセスになる

Slide 123

Slide 123 text

©2024 CyberAgent Inc. Distribution prohibited ワークグループ編集 123 ローカルからも繋ぎたいため、「パブリックにアクセス可能」にチェック ※ 注意点 実務ではパブリックにアクセス可能にしないが、簡単化 のための設定

Slide 124

Slide 124 text

©2024 CyberAgent Inc. Distribution prohibited クエリエディタへの接続 124 Availableを確認し、「データをクエリ」をクリック

Slide 125

Slide 125 text

©2024 CyberAgent Inc. Distribution prohibited クエリエディタへの接続 125

Slide 126

Slide 126 text

©2024 CyberAgent Inc. Distribution prohibited 作るテーブル 126 ● imp log ○ Predictorで先ほど吐き出したリクエストのログが溜まるテーブル ○ 入札したものが全て表示された前提 ● click log ○ クリックしたかどうかのログが溜まるテーブル ○ 事前に準備しているclick.tsv.gzをそのまま入れる

Slide 127

Slide 127 text

©2024 CyberAgent Inc. Distribution prohibited テーブル作成(imp_log) 127 DROP TABLE IF EXISTS imp_log; CREATE TABLE IF NOT EXISTS imp_log ( logged_at varchar(255), id varchar(255), hour varchar(255), C1 varchar(255), banner_pos varchar(255), site_id varchar(255), site_domain varchar(255), site_category varchar(255), app_id varchar(255), app_domain varchar(255), app_category varchar(255), device_id varchar(255), device_ip varchar(255), device_model varchar(255), device_type varchar(255), device_conn_type varchar(255), C14 varchar(255), C15 varchar(255), C16 varchar(255), C17 varchar(255), C18 varchar(255), C19 varchar(255), C20 varchar(255), C21 varchar(255), hostname varchar(255), prediction float8, primary key (id) ) DISTKEY (id) SORTKEY(logged_at); 左上の「Run」をクリック

Slide 128

Slide 128 text

©2024 CyberAgent Inc. Distribution prohibited テーブル作成(click_log) 128 DROP TABLE IF EXISTS click_log; CREATE TABLE IF NOT EXISTS click_log ( id varchar(255) not null, click int, primary key (id) ) DISTKEY (id); 左上の「Run」をクリック

Slide 129

Slide 129 text

©2024 CyberAgent Inc. Distribution prohibited データ挿入(click_log) 129 COPY click_log FROM 's3://{名前}-mlops-practice/train_data/click.tsv.gz' GZIP IAM_ROLE 'arn:aws:iam::0123456789:role/{名前}-mlops-practice-redshift-role' FORMAT AS CSV DELIMITER '\t' IGNOREHEADER 1 REGION 'ap-northeast-1'; 本来はclick_logもclickが起こったタイミングでログ収集→保存する必要あり 今回は事前に用意したclick.tsv.gzを使用 S3のpath s3://{名前}-mlops-practice/train_data/click.tsv.gz IAMロール {名前}-mlops-practice-redshift-roleのARN ※ RedshiftではS3からのLoadもquery likeに書くことが可能

Slide 130

Slide 130 text

©2024 CyberAgent Inc. Distribution prohibited クエリを書いてみる 130 SELECT id, click FROM click_log LIMIT 10; ※ 今回はデータが少ないため使用していますが、LIMITはフルスキャンが走るので実務では他の方法でサンプリングする ※ *も使わない。カラムを指定する

Slide 131

Slide 131 text

©2024 CyberAgent Inc. Distribution prohibited 自動でS3からRedshiftにインポートする 131 PredictorからのログがS3に上がり、Redshiftに自動でインポートさせる S3へのputイベントをトリガーに、Lambdaでインポートを動かす ※ Preview版ではあるが、S3から直接Redshiftにインポートが可能 GAになる日は近いかも? https://aws.amazon.com/jp/blogs/news/simplify-data-ingestion-from-amazon-s3-to-am azon-redshift-using-auto-copy-preview/

Slide 132

Slide 132 text

©2024 CyberAgent Inc. Distribution prohibited 構成 132

Slide 133

Slide 133 text

©2024 CyberAgent Inc. Distribution prohibited 権限作成 133 CREATE USER "IAMR:{名前}-mlops-practice-lambda-role" PASSWORD DISABLE; CREATE GROUP lambda; ALTER GROUP lambda ADD USER "IAMR:{名前}-mlops-practice-lambda-role"; GRANT USAGE, CREATE ON SCHEMA public TO GROUP lambda; GRANT SELECT, INSERT ON ALL TABLES IN SCHEMA public TO GROUP lambda; LambdaのRoleに権限をつけていく Role IAMR:{名前}-mlops-practice-lambda-role SELECT usename, has_table_privilege(usename, 'imp_log', 'insert') AND has_table_privilege(usename, 'imp_log', 'select') FROM pg_user;

Slide 134

Slide 134 text

©2024 CyberAgent Inc. Distribution prohibited 権限作成 134 CREATE USER "IAMR:{名前}-mlops-practice-ecs-task-role" PASSWORD DISABLE; CREATE GROUP ecs; ALTER GROUP ecs ADD USER "IAMR:{名前}-mlops-practice-ecs-task-role"; GRANT USAGE, CREATE ON SCHEMA public TO GROUP ecs; GRANT SELECT ON ALL TABLES IN SCHEMA public TO GROUP ecs; ECS TaskのRoleに権限をつけていく Role IAMR:{名前}-mlops-practice-ecs-task-role SELECT usename, has_table_privilege(usename, 'imp_log', 'select') FROM pg_user;

Slide 135

Slide 135 text

©2024 CyberAgent Inc. Distribution prohibited NOTICE: 各コマンドの説明 135 CREATE USER "IAMR:{名前}-mlops-practice-ecs-task-role" PASSWORD DISABLE; ユーザーの作成 GRANT SELECT ON ALL TABLES IN SCHEMA public TO GROUP ecs; CREATE GROUP ecs; ALTER GROUP ecs ADD USER "IAMR:{名前}-mlops-practice-ecs-task-role"; GRANT USAGE, CREATE ON SCHEMA public TO GROUP ecs; グループの作成 グループにユーザーの追加 グループにUSAGEとCREATE権限を付与(USAGEは使用権限・CREATEはテーブルなどの作成権限) グループに全てのテーブルに対するSELECT権限を付与

Slide 136

Slide 136 text

©2024 CyberAgent Inc. Distribution prohibited Lambdaとは 136 $ make build-importer ECRにイメージをPushする $ make push-importer サーバレスのファンクション(FaaS) インフラを意識せずアプリケーションに注力 Lambdaを使ってS3とRedshiftでデータ連携する https://aws.amazon.com/jp/lambda/

Slide 137

Slide 137 text

©2024 CyberAgent Inc. Distribution prohibited NOTICE: importerの中身 137 def handler(event, context): redshift_workgroup = os.getenv("REDSHIFT_WORKGROUP") redshift_db = os.getenv("REDSHIFT_DATABASE") lambda_iam_role_arn = os.getenv("LAMBDA_IAM_ROLE_ARN") bucket = event["Records"][0]["s3"]["bucket"]["name"] file_path = event["Records"][0]["s3"]["object"]["key"] full_sql = sql.format(bucket=bucket, lambda_iam_role_arn=lambda_iam_role_arn, file_path=file_path) client = boto3.client("redshift-data") response = client.execute_statement( WorkgroupName=redshift_workgroup, Database=redshift_db, Sql=full_sql, ) print(response) ログが保存されるS3のパスをRedshiftに流すだけ

Slide 138

Slide 138 text

©2024 CyberAgent Inc. Distribution prohibited Data Importerの作成 138 Lambda →「関数の作成」をクリック https://ap-northeast-1.console.aws.amazon.com/lambda/home?region=ap-northeast-1#/functions

Slide 139

Slide 139 text

©2024 CyberAgent Inc. Distribution prohibited Data Importerの作成 139 関数名: {名前}-mlops-practice-importer コンテナイメージURI: ImporterのECRのURI

Slide 140

Slide 140 text

©2024 CyberAgent Inc. Distribution prohibited Data Importerの作成 140 メモリ 128MB エフェメラルストレージ 512MB タイムアウト 1分 実行ロール: {名前}-mlops-practice-lambda-role

Slide 141

Slide 141 text

©2024 CyberAgent Inc. Distribution prohibited 環境変数の設定 141 REDSHIFT_WORKGROUP {名前}-workgroup REDSHIFT_DATABASE dev LAMBDA_IAM_ROLE_ARN Lambdaに紐づけているIAM RoleのARN

Slide 142

Slide 142 text

©2024 CyberAgent Inc. Distribution prohibited トリガーの作成 142 S3の該当パスにログがPutされた時に Lambdaをキックする Bucket {名前}-mlops-practice Event types PUT Prefix logs/ecs/ Suffix .gz

Slide 143

Slide 143 text

©2024 CyberAgent Inc. Distribution prohibited ECSにリクエストを送る 143 $ make request-ecs ⚠ ローカルからリクエストを送りすぎるとIPバンされる可能性があるので注意してください ⚠ 送りすぎるとLambdaが起動し続けるので気をつけてください SELECT id, logged_at, hour FROM imp_log WHERE logged_at > LOCALTIMESTAMP - interval '60 minutes'; imp_logにレコードが入っていたらOK(入るまで数分かかります)

Slide 144

Slide 144 text

©2024 CyberAgent Inc. Distribution prohibited DWHのデータで学習 144 S3にあるtrain.tsvではなく、DWHに入っているデータを使って学習してみる $ $EDITOR ml/main.py from ml.steps import create_model_revision_step, extract_step, preprocess_step, train_step : : extracted = extract_step(name=model_info.name, revision=revision, train_args=model_info.train_args) from ml.steps import create_model_revision_step, extract_from_redshift_step, preprocess_step, train_step : : extracted = extract_from_redshift_step(name=model_info.name, revision=revision, train_args=model_info.train_args) イメージのプッシュ後、Step Functionsで実行 $ make build-ml push-ml extract_from_redshift_stepに差し替える https://ap-northeast-1.console.aws.amazon.com/states/home?region=ap-northeast-1#/statemachines

Slide 145

Slide 145 text

©2024 CyberAgent Inc. Distribution prohibited 実際に学習できているか確認 145

Slide 146

Slide 146 text

©2024 CyberAgent Inc. Distribution prohibited 05 サニティチェック 146

Slide 147

Slide 147 text

©2024 CyberAgent Inc. Distribution prohibited サニティチェック 147 継続的に学習を回すと、モデルの精度を監視する必要あり 新モデルのデプロイ前に旧モデルと精度を比較し、勝っている場合のみデプロイしたい 学習済みモデルに対する精度を評価するevaluate_stepと 過去モデルとの優劣を評価するsanity_check_stepを導入 旧モデルに比べてloglossが改善している場合のみ、新モデルをデプロイする

Slide 148

Slide 148 text

©2024 CyberAgent Inc. Distribution prohibited from ml.steps import create_model_revision_step, extract_from_redshift_step, preprocess_step, train_step, evaluate_step, sanity_check_step : eval_metrics, data_metrics = evaluate_step(preprocessed=preprocessed, ml_model=ml_model) : s3_path = sanity_check_step( revision=revision, name=model_info.name, preprocessed=preprocessed, evaluate_metrics=eval_metrics, ) : create_model_revision_step(revision=revision, s3_path=s3_path, name=model_info.name) サニティチェックの導入 148 $ $EDITOR ml/main.py 追加 追加 新旧モデルで精度の良い方のモデルのS3のパスが返ってくる 追加

Slide 149

Slide 149 text

©2024 CyberAgent Inc. Distribution prohibited def evaluate_step( preprocessed: dict[DatasetType, FeatureTarget], ml_model: BaseMLModel ) -> tuple[EvaluateMetrics, DataMetrics]: : logloss = log_loss(test_data.target, predictions) accuracy = accuracy_score(test_data.target, pred_bin) auc = roc_auc_score(test_data.target, predictions) : eval_metrics = EvaluateMetrics( logloss=logloss, accuracy=accuracy, auc=auc, precision=precision, recall=recall, calibration=calibration ) logger.info(f"Evaluation Metrics: {eval_metrics}") data_metrics = DataMetrics( train_data_ammount=preprocessed[DatasetType.TRAIN].feature.shape[0], test_data_ammount=test_data.feature.shape[0], valid_data_ammount=preprocessed[DatasetType.VALID].feature.shape[0], ) : return eval_metrics, data_metrics NOTICE: Evaluate Step 149 $ cat ml/steps/evaluate_step.py テストデータに対するモデルの精度評価 データに関するメトリクスも取得

Slide 150

Slide 150 text

©2024 CyberAgent Inc. Distribution prohibited def sanity_check_step(revision: str, name: str, test_data: str, evaluate_metrics: EvaluateMetrics) -> str: ; download_from_s3( s3_bucket=S3_BUCKET_NAME, s3_key=item["s3_keys"][name], file_path=os.path.join(LOCAL_BASE_ARTIFACT_DIR, f"{name}.pkl") ) : model = MODELS.retrieve(name=name) ; test_data = model.preprocessor().transform(test_data) predictions = model.ml_model().batch_predict(test_data) logloss = log_loss(test_data.target, predictions) # Compare the new model with the old model by logloss. if logloss < evaluate_metrics.logloss: logger.warning("New model is worse than the old model.") logger.warning(f"Old Model Metrics: {logloss}, New Model Metrics: {evaluate_metrics}") return item["s3_keys"][name] else: logger.info("New model is better than the old model.") logger.info(f"Old Model Metrics: {logloss}, New Model Metrics: {evaluate_metrics}") return s3_path NOTICE: Sanity Check Step 150 $ cat ml/steps/sanity_check_step.py 現在のモデル取得 現在のモデルを使ってテストデータを評価 新モデルと現在のモデルでloglossを比較し、 性能の良い方のmodel_pathを返す

Slide 151

Slide 151 text

©2024 CyberAgent Inc. Distribution prohibited サニティチェックの導入 151 イメージをプッシュして、Step Functionsで実行 $ make build-ml push-ml

Slide 152

Slide 152 text

©2024 CyberAgent Inc. Distribution prohibited 06 カナリアリリース 152

Slide 153

Slide 153 text

©2024 CyberAgent Inc. Distribution prohibited カナリアリリースとは 153 新しいバージョンのソフトウェアを全ユーザーに対して一度に リリースせず、まず一部のユーザーに対してリリースすること メリット ● リスクヘッジ: 事故が起きた際、影響を最小限に抑えること デメリット ● 管理コスト: ロールバック・インフラ管理

Slide 154

Slide 154 text

©2024 CyberAgent Inc. Distribution prohibited 実際に起きた事例 154 こちらは実際に自分が起こしてしまった事例です これを機にカナリアリリースの機構を導入することになりました 1. 機械学習の前処理部分のコードを少し変更 2. 推論サーバに全台適用(リリースタイミングのミス) 3. 学習済みモデルで使用していた前処理からずれが起き、予測値異常に 4. 損害: 💰💰💰

Slide 155

Slide 155 text

©2024 CyberAgent Inc. Distribution prohibited 推論サーバのカナリア構成図 155 ALBのリスナールールでターゲット グループごとの重み付けで実現 システムの発展系としてA/Bテストも可能

Slide 156

Slide 156 text

©2024 CyberAgent Inc. Distribution prohibited 作成するもの 156 1. ALBのリスナールールのターゲットグループ にカナリア用のターゲットグループを追加 2. ルーティングの重みを変更

Slide 157

Slide 157 text

©2024 CyberAgent Inc. Distribution prohibited 推論サーバのカナリアイメージ準備 157 $ make build-predictor-canary $ make push-predictor-canary ※ ECRレポジトリはTerraformで作成済み イメージの中身自体はPredictorと同等

Slide 158

Slide 158 text

©2024 CyberAgent Inc. Distribution prohibited カナリア用タスク定義作成 158 追加 resource "aws_ecs_task_definition" "predictor_canary" { family = "${var.name}-predictor-canary" network_mode = "awsvpc" cpu = 1024 memory = 2048 requires_compatibilities = ["FARGATE"] container_definitions = templatefile("./modules/ecs/container_definitions/predictor_canary.json", { predictor_canary_ecr_uri = "${var.predictor_canary_ecr_uri}", fluentd_ecr_uri = "${var.fluentd_ecr_uri}", ecs_exporter_ecr_uri = "${var.ecs_exporter_ecr_uri}", name = "${var.name}" }) volume { name = "logs" } task_role_arn = var.ecs_task_role_arn execution_role_arn = var.ecs_task_execution_role_arn } $ $EDITOR infra/modules/ecs/main.tf

Slide 159

Slide 159 text

©2024 CyberAgent Inc. Distribution prohibited カナリア用ECSサービス作成(追加) 159 resource "aws_ecs_service" "predictor_canary" { name = "${var.name}-predictor-canary-service" cluster = aws_ecs_cluster.mlops_practice.name task_definition = aws_ecs_task_definition.predictor_canary.arn desired_count = 1 deployment_minimum_healthy_percent = 0 deployment_maximum_percent = 200 launch_type = "FARGATE" network_configuration { security_groups = [ "${var.predictor_security_group}" ] subnets = var.private_subnets } load_balancer { target_group_arn = var.predictor_canary_target_group_arn container_name = "predictor-canary" container_port = 8080 } } name {name}-predictor-canary-service task_definition カナリア用のtask定義のarn target_group_arn カナリア用のtarget groupのarn Predictorと同一のもの ● cluster ● security group ● subnet

Slide 160

Slide 160 text

©2024 CyberAgent Inc. Distribution prohibited カナリア用オートスケーリング設定(追加) 160 resource "aws_appautoscaling_target" "predictor_canary" { max_capacity = 3 min_capacity = 1 resource_id = "service/${aws_ecs_cluster.mlops_practice.name}/${aws_ecs_service.predictor_canary.name}" scalable_dimension = "ecs:service:DesiredCount" service_namespace = "ecs" } resource_id: カナリア用のECS Serviceを指定 オートスケーリングの範囲は1台から3台

Slide 161

Slide 161 text

©2024 CyberAgent Inc. Distribution prohibited カナリア用オートスケーリングポリシー(追加) 161 resource "aws_appautoscaling_policy" "predictor_canary" { name = "${var.name}-predictor-canary-auto-scaling-policy" policy_type = "TargetTrackingScaling" resource_id = aws_appautoscaling_target.predictor_canary.resource_id scalable_dimension = aws_appautoscaling_target.predictor_canary.scalable_dimension service_namespace = aws_appautoscaling_target.predictor_canary.service_namespace target_tracking_scaling_policy_configuration { predefined_metric_specification { predefined_metric_type = "ECSServiceAverageCPUUtilization" } scale_in_cooldown = 60 scale_out_cooldown = 60 target_value = 70.0 } } resource_id 先ほど作成したカナリア用の resource_id

Slide 162

Slide 162 text

©2024 CyberAgent Inc. Distribution prohibited リスナールールの設定 162 resource "aws_lb_listener_rule" "mlops_practice_predictor" { listener_arn = aws_lb_listener.mlops_practice_predictor.arn action { type = "forward" target_group_arn = aws_lb_target_group.mlops_practice_predictor.arn } condition { path_pattern { values = ["/", "/predict"] } } } 通常のPredictor リクエストの90% カナリアのPredictor リクエストの10% resource "aws_lb_listener_rule" "mlops_practice_predictor" { listener_arn = aws_lb_listener.mlops_practice_predictor.arn action { type = "forward" forward { target_group { arn = aws_lb_target_group.mlops_practice_predictor.arn weight = 90 } target_group { arn = aws_lb_target_group.mlops_practice_predictor_canary.arn weight = 10 } } } condition { path_pattern { values = ["/", "/predict"] } } } 修正する $ $EDITOR infra/modules/alb/main.tf

Slide 163

Slide 163 text

©2024 CyberAgent Inc. Distribution prohibited デプロイ 163 $ make apply AWSのターゲットグループが複数になっているか確認 ECSサービスも更新 https://ap-northeast-1.console.aws.amazon.com/ec2/home?region=ap-northeast-1#LoadBalancers: カナリアをデプロイする

Slide 164

Slide 164 text

©2024 CyberAgent Inc. Distribution prohibited リクエストを送ってみる(再掲) 164 $ make predict-ecs AWS_REGION=ap-northeast-1 AWS_ACCOUNT_ID=0123456789 AWS_PROFILE=mlops-practice AWS_ALB_DNS= USER_NAME=xxxxx S3_BUCKET=${USER_NAME}-mlops-practice TF_VAR_aws_region=${AWS_REGION} TF_VAR_aws_profile=${AWS_PROFILE} TF_VAR_aws_account_id=${AWS_ACCOUNT_ID} TF_VAR_name=${USER_NAME} 埋めてない場合は埋める ⚠ ローカルからリクエストを送りすぎるとIPバンされる可能性があるので注意してください

Slide 165

Slide 165 text

©2024 CyberAgent Inc. Distribution prohibited リクエストの割り振り確認 165 9:1になるように設定したので、意図通りになっているか確認 Redshiftのエディターでクエリを投げる SELECT date_trunc('minute', CAST(logged_at AS timestamp) + interval '9 hours') as minute, COUNT(CASE WHEN hostname='predictor' THEN 1 ELSE NULL END) as predictor_count, COUNT(CASE WHEN hostname='predictor-canary' THEN 1 ELSE NULL END) as predictor_canary_count FROM imp_log WHERE logged_at > LOCALTIMESTAMP - interval '60 minutes' GROUP BY minute ORDER BY minute ASC;

Slide 166

Slide 166 text

©2024 CyberAgent Inc. Distribution prohibited リクエストの割り振り確認 166 大体9:1になっていればOK

Slide 167

Slide 167 text

©2024 CyberAgent Inc. Distribution prohibited まとめ 167 ヘルスチェック的な意味合いでのカナリアリリースを作成 1. 監視の重要性: 新バージョンのパフォーマンスを監視し、問題がないことを確認。何を もって異常と判断するかの指標と、それらを監視する機構を準備する必要性 2. 管理コスト: インフラ管理コストは増える 小規模なプロダクトの場合、カナリア自体不要になることもある 開発リソースを含めたプロダクトの規模やビジネス上クリティカルに なるか判断し、導入を検討

Slide 168

Slide 168 text

©2024 CyberAgent Inc. Distribution prohibited Tips: カナリアからの移行手順 168 評価指標を定めてそれを元に適用比率を段階的に引き上げる 指標によってタイムスパンは異なるが以下一例 ● 1%適用 ○ ヘルスチェック ○ 数時間から数日 ● 10%適用 ○ メトリクスが悪化してないか ○ 数日から1週間程度 ● 50%適用 ○ 評価指標(KPI)が悪化してないか ○ 数週間程度 ● 100%適用

Slide 169

Slide 169 text

©2024 CyberAgent Inc. Distribution prohibited 07 メトリクスの可視化 169

Slide 170

Slide 170 text

©2024 CyberAgent Inc. Distribution prohibited なぜ監視するのか 170 ● システムの正常性(予防とリカバリー) ○ MLの予測値やシステムのアウトプットそのものがビジネスにクリティカルなので システムの異常やエラーを早期に検知し、問題が大きくなる前に対応する ● パフォーマンスチューニング ○ 監視データを分析することで、システムのパフォーマンスを最適化する ○ UXの向上や、システムコストの削減 ビジネスへの負の影響を最小化し、正の影響を最大化するため

Slide 171

Slide 171 text

©2024 CyberAgent Inc. Distribution prohibited ML特有の監視項目 171 ● データ品質 ○ データの品質にモデルのパフォーマンスは大きく影響を受ける ○ 欠損値・異常値などを監視 ● モデルパフォーマンス ○ モデルの精度(Logloss、Accuracy、AUCなど) ○ 予測のレイテンシやスループット ● ドリフト検出 ○ データの分布が学習時と推論時で異なることでモデルのパフォーマンス に影響を及ぼす ○ 特徴量の分布や予測の分布を監視 ● Software Metrics

Slide 172

Slide 172 text

©2024 CyberAgent Inc. Distribution prohibited 全ての項目を監視するのか 172 ● 人的リソースがいくらあっても足りない ● 誰も見ないダッシュボード ● アラート疲れ No

Slide 173

Slide 173 text

©2024 CyberAgent Inc. Distribution prohibited なにから監視するのか 173 MLOpsはDevOpsの特定領域を切り取っただけ → 通常のソフトウェアメトリクスから手をつける → その後MLの監視 大事なこと ● 監視すべき対象をしっかり絞る ● ビジネスインパクトの大きいものから。その後にリソースの監視 ● チームの状況を考える

Slide 174

Slide 174 text

©2024 CyberAgent Inc. Distribution prohibited 使用技術 174 Grafana Grafana Labsが公開しているログ・データ可視化 ツール AWSマネージドサービスもある Prometheus システム監視およびアラートツールで、メトリクス を時系列データとして収集して保存 AWSマネージドサービスもある

Slide 175

Slide 175 text

©2024 CyberAgent Inc. Distribution prohibited 注意点 175 今回はモニタリングツールとしてGrafana、Prometheusを使用して いますが、実際にプロダクトで使用する場合は、チームの状況 (リソース、達成したいこと、ビジネスフェーズetc)に合わせて 技術選定してください ex. ● Datadog ● ELK Stack ● Sentry :

Slide 176

Slide 176 text

©2024 CyberAgent Inc. Distribution prohibited 監視システムの構成 176

Slide 177

Slide 177 text

©2024 CyberAgent Inc. Distribution prohibited Grafanaの設定(compose.yaml) 177 grafana: container_name: grafana build: context: . dockerfile: ./docker/Dockerfile.grafana healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3000/api/health"] interval: 30s timeout: 10s retries: 5 ports: - 3000:3000 volumes: - .local/grafana:/var/lib/grafana - ./grafana/local/datasource.yaml:/etc/grafana/provisioning/datasources/datasource.yaml - ./grafana/local/dashboard.yaml:/etc/grafana/provisioning/dashboards/dashboard.yaml - ./grafana/dashboards:/var/lib/grafana/dashboards environment: - GF_SECURITY_ADMIN_USER=admin - GF_SECURITY_ADMIN_PASSWORD=admin networks: - mlops-practice 追加する $ $EDITOR compose.yaml

Slide 178

Slide 178 text

©2024 CyberAgent Inc. Distribution prohibited Prometheusの設定(compose.yaml) 178 prometheus: container_name: prometheus build: context: . dockerfile: ./docker/Dockerfile.prometheus volumes: - ./prometheus/local/prometheus.yaml:/etc/prometheus/prometheus.yaml - .local/prometheus:/prometheus command: - "--config.file=/etc/prometheus/prometheus.yaml" ports: - 9090:9090 networks: - mlops-practice 追加する $ $EDITOR compose.yaml

Slide 179

Slide 179 text

©2024 CyberAgent Inc. Distribution prohibited Pushgatewayの設定(compose.yaml) 179 pushgateway: container_name: pushgateway build: context: . dockerfile: ./docker/Dockerfile.pushgateway ports: - 9091:9091 networks: - mlops-practice 追加する Pushgatewayとは Prometheusのコンポーネントの一つで、短期的なジョブからのメトリクスを収集するためのツール PrometheusがPullに対して、PushgatewayにPushしPrometheusからはPushgatewayをpullする 推論サーバの予測値を取る際に使用 $ $EDITOR compose.yaml

Slide 180

Slide 180 text

©2024 CyberAgent Inc. Distribution prohibited compose.yaml(完成版) 180 version: "3" services: predictor: container_name: predictor build: context: . dockerfile: ./docker/Dockerfile target: local args: - NAME=hoshii restart: always tty: true ports: - 8080:8080 volumes: - ./ml:/app/ml - ./predictor:/app/predictor - ./predictor/logs:/var/logs - $HOME/.aws/credentials:/root/.aws/credentials:ro entrypoint: ["gunicorn", "-b", "0.0.0.0:8080", "-k", "uvicorn.workers.UvicornWorker", "-w", "4", "--access-logfile", "-", "--error-logfile", "-", "--log-level", "info", "--timeout", "60", "predictor.main:app", ] env_file: - .env environment: - ENV=predictor - SYSTEM_ENV=local networks: - mlops-practice fluentd: container_name: fluentd build: context: . dockerfile: ./docker/Dockerfile.fluentd volumes: - ./fluentd/local:/fluentd/etc - ./predictor/logs:/var/logs - $HOME/.aws:/root/.aws:ro env_file: - .env networks: - mlops-practice prometheus: container_name: prometheus build: context: . dockerfile: ./docker/Dockerfile.prometheus volumes: - ./prometheus/local/prometheus.yaml:/etc/prometheus/prometheus.yaml - .local/prometheus:/prometheus command: - "--config.file=/etc/prometheus/prometheus.yaml" ports: - 9090:9090 networks: - mlops-practice grafana: container_name: grafana build: context: . dockerfile: ./docker/Dockerfile.grafana healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3000/api/health"] interval: 30s timeout: 10s retries: 5 ports: - 3000:3000 volumes: - .local/grafana:/var/lib/grafana - ./grafana/local/datasource.yaml:/etc/grafana/provisioning/datasources/datasource.y aml - ./grafana/local/dashboard.yaml:/etc/grafana/provisioning/dashboards/dashboard.ya ml - ./grafana/dashboards:/var/lib/grafana/dashboards environment: - GF_SECURITY_ADMIN_USER=admin - GF_SECURITY_ADMIN_PASSWORD=admin networks: - mlops-practice pushgateway: container_name: pushgateway build: context: . dockerfile: ./docker/Dockerfile.pushgateway ports: - 9091:9091 networks: - mlops-practice networks: mlops-practice: external: true https://github.com/hosimesi/aws-mlops-practice/blob/main/ compose.yaml

Slide 181

Slide 181 text

©2024 CyberAgent Inc. Distribution prohibited from prometheus_client import CollectorRegistry, Counter, Gauge, Histogram, push_to_gateway : : response_logger = get_response_logger(f"{__name__}_response") # Prometheus metrics registry = CollectorRegistry() response_time = Histogram( "response_time_seconds", "Response time in seconds", ["env", "instance", "model_name"], registry=registry ) request_count = Counter( "request_count", "Total Request Count", ["env", "instance", "model_name", "status_code"], registry=registry ) prediction_value = Gauge("prediction_value", "Predicted value", ["env", "instance", "model_name"], registry=registry) 推論サーバからメトリクスを送る 181 $ $EDITOR predictor/main.py 赤枠の部分を追加する スループット計測 リクエスト数 予測値

Slide 182

Slide 182 text

©2024 CyberAgent Inc. Distribution prohibited @app.exception_handler(HTTPException) async def http_exception_handler(request, exc): request_count.labels(env=env, instance=app.state.instance, model_name="", status_code="4xx").inc() return JSONResponse( status_code=exc.status_code, content={"message": str(exc.detail)}, ) @app.exception_handler(Exception) async def exception_handler(request, exc): request_count.labels(env=env, instance=app.state.instance, model_name="", status_code="5xx").inc() return JSONResponse( status_code=500, content={"message": str(exc)}, ) 推論サーバからメトリクスを送る 182 $ $EDITOR predictor/main.py 赤枠の部分を追加する 400系のリクエスト数 500系のリクエスト数

Slide 183

Slide 183 text

©2024 CyberAgent Inc. Distribution prohibited response_logger.info(json.dumps(bid_response_log.dict())) # Update metrics response_time.labels(env=env, instance=app.state.instance, model_name=model_name).observe(time.time() - start_time) prediction_value.labels(env=env, instance=app.state.instance, model_name=model_name).set(pred) request_count.labels(env=env, instance=app.state.instance, model_name=model_name, status_code="2xx").inc() except Exception as e: logger.error(f"Error occurred: {str(e)}") # Push metrics to Prometheus Pushgateway push_to_gateway(app.state.pushgateway_url, job="predict", registry=registry) return {"prediction": pred, "model": model_name} 推論サーバからメトリクスを送る 183 $ $EDITOR predictor/main.py 赤枠の部分を追加する メトリクスの送信

Slide 184

Slide 184 text

©2024 CyberAgent Inc. Distribution prohibited from ml.steps import ( create_model_revision_step, evaluate_step, extract_from_redshift_step, preprocess_step, sanity_check_step, send_metrics_step, train_step, ) eval_metrics, data_metrics = evaluate_step(preprocessed=preprocessed, ml_model=ml_model) send_metrics_step( current_time_jst=args.current_time_jst, eval_metrics=eval_metrics, data_metrics=data_metrics, model_name=model_info.name, extracted=extracted, ) s3_path = sanity_check_step( revision=revision, name=model_info.name, preprocessed=preprocessed, evaluate_metrics=eval_metrics, ) 学習パイプラインからメトリクスを送る 184 $ $EDITOR ml/main.py 赤枠の部分を追加する

Slide 185

Slide 185 text

©2024 CyberAgent Inc. Distribution prohibited Dockerコンテナの立ち上げ 185 $ docker compose up --build $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES xxxxxxxxxxx aws-mlops-practice-fluentd "tini -- /bin/entryp…" xx minutes ago Up xx minutes 5140/tcp, 24224/tcp fluentd xxxxxxxxxxx aws-mlops-practice-predictor "gunicorn -b 0.0.0.0…" xx hours ago Up xx minutes 0.0.0.0:8080->8080/tcp predictor xxxxxxxxxxx aws-mlops-practice-pushgateway "/bin/pushgateway" xx days ago Up xx minutes 0.0.0.0:9091->9091/tcp pushgateway xxxxxxxxxxx aws-mlops-practice-grafana "/run.sh" xx days ago Up xx minutes (healthy) 0.0.0.0:3000->3000/tcp grafana xxxxxxxxxxx aws-mlops-practice-prometheus "/bin/prometheus --c…" xx days ago Up xx minutes 0.0.0.0:9090->9090/tcp prometheus コンテナが5つ立っていたらOK

Slide 186

Slide 186 text

©2024 CyberAgent Inc. Distribution prohibited データの送信 186 $ make build-ml push-ml 推論サーバのイメージビルド MLパイプラインのイメージビルド&プッシュ $ make build-predictor build-predictor-canary $ make run-ml データを貯めるため、学習を何回か回す 推論サーバにリクエストを送る $ make predict

Slide 187

Slide 187 text

©2024 CyberAgent Inc. Distribution prohibited Grafanaへのアクセス 187 http://localhost:3000/ にアクセス Email or username admin Password admin

Slide 188

Slide 188 text

©2024 CyberAgent Inc. Distribution prohibited Prometheusをデータソースとして登録 188 Name prometheus Connection http://prometheus:9090

Slide 189

Slide 189 text

©2024 CyberAgent Inc. Distribution prohibited ダッシュボード作成 189 DashboardsからNewをクリック

Slide 190

Slide 190 text

©2024 CyberAgent Inc. Distribution prohibited Visualization作成 190 Add Visualization

Slide 191

Slide 191 text

©2024 CyberAgent Inc. Distribution prohibited Visualization作成 191

Slide 192

Slide 192 text

©2024 CyberAgent Inc. Distribution prohibited Visualization作成 192 少し時間取るので、色々触ってみてください Metrics browserに取れるメトリクスが一覧になってます

Slide 193

Slide 193 text

©2024 CyberAgent Inc. Distribution prohibited モデル評価の可視化(AUC) 193 クエリ: avg(evaluate_metrics{metric="auc"}) by (model_name) Title: AUC Save & Apply

Slide 194

Slide 194 text

©2024 CyberAgent Inc. Distribution prohibited 学習データの可視化 194 Add → Visualization

Slide 195

Slide 195 text

©2024 CyberAgent Inc. Distribution prohibited 学習データの可視化(データボリューム) 195 クエリ: sum(data_amount) by (dataset) Title: Data Amount Save & Apply

Slide 196

Slide 196 text

©2024 CyberAgent Inc. Distribution prohibited データ分布の可視化(Click数) 196 クエリ: sum(data_distribution{column="click"}) by (value) Title: Click Distribution Save & Apply

Slide 197

Slide 197 text

©2024 CyberAgent Inc. Distribution prohibited 推論サーバの可視化 197 クエリ: avg_over_time(prediction_value{model_name="sgd_classifier_ctr_model"}[1m]) avg_over_time(prediction_value{model_name="sgd_classifier_ctr_model"}[1m]) Title: AVG Prediction Value Save & Apply

Slide 198

Slide 198 text

©2024 CyberAgent Inc. Distribution prohibited 出来上がったものを保存する 198

Slide 199

Slide 199 text

©2024 CyberAgent Inc. Distribution prohibited できたダッシュボードを保存 199 jsonをコピー & ./grafana/dashboards/mlops-practice.jsonにペースト GrafanaではDashboardの構成がjsonでexportできるので、同じDashboardが再現可能

Slide 200

Slide 200 text

©2024 CyberAgent Inc. Distribution prohibited Tips: データドリフトの検知 200 Amazon SageMaker Model Monitorなどで行うことが可能 ● データの記述統計量など ● データ品質 ● モデル品質 ● データキャプチャ 実際導入する際はオーバーエンジニアリングになってないか・監視することで何を達成したいかに 即して考える もしかしたらGrafanaだけで事足りるかもしれない ● 学習データに含まれるclickの数が変わったタイミングでアラートを上げる ● trainデータの数が変わったタイミングでアラートを上げる

Slide 201

Slide 201 text

©2024 CyberAgent Inc. Distribution prohibited ECSにデプロイ 201 PrometheusはPrivate Subnetに置いて、外部に公開しなくてもOK この場合、ECSサービス間でInternal通信したい ● サービスディスカバリ ● サービスメッシュ ● 直Private IP ● ALB(Internal) ● ECS Service Connect

Slide 202

Slide 202 text

©2024 CyberAgent Inc. Distribution prohibited サービスディスカバリとは 202 ネットワーク上のサービスを自動的に検出し、 その位置や設定を特定するプロセス ex オートスケールしたPrivate IPを持つ インスタンスをDNSのような仕組みを用いて 自動で登録できたりする AWS Cloud Map

Slide 203

Slide 203 text

©2024 CyberAgent Inc. Distribution prohibited Cloud Mapの作成 203 Cloud Map → 「名前空間の作成」

Slide 204

Slide 204 text

©2024 CyberAgent Inc. Distribution prohibited 名前空間の作成 名前空間名 {名前}-mlops-practice.internal インスタンスの検出 API呼び出しとVPCのDNSクエリ VPC {名前}-mlops-practice TTL 300 「名前空間の作成」 204

Slide 205

Slide 205 text

©2024 CyberAgent Inc. Distribution prohibited 作成の確認 205 Route 53にも作成済みなことを確認

Slide 206

Slide 206 text

©2024 CyberAgent Inc. Distribution prohibited サービスの作成(pushgateway) 206 サービス名 pushgateway サービス検出検出方法 APIとDNS DNSの設定 WEIGHTED TTL 300 「サービスの作成」

Slide 207

Slide 207 text

©2024 CyberAgent Inc. Distribution prohibited サービスの作成(prometheus) 207 サービス名 prometheus サービス検出検出方法 APIとDNS DNSの設定 WEIGHTED TTL 300 「サービスの作成」

Slide 208

Slide 208 text

©2024 CyberAgent Inc. Distribution prohibited サービスの作成(predictor) 208 サービス名 predictor サービス検出検出方法 APIとDNS DNSの設定 WEIGHTED TTL 300 「サービスの作成」

Slide 209

Slide 209 text

©2024 CyberAgent Inc. Distribution prohibited サービスの作成(predictor-canary) 209 サービス名 predictor-canary サービス検出検出方法 APIとDNS DNSの設定 WEIGHTED TTL 300 「サービスの作成」

Slide 210

Slide 210 text

©2024 CyberAgent Inc. Distribution prohibited ServiceのArnを取得 210 $ aws servicediscovery get-service --id {サービスID} --region ap-northeast-1 全て得られたArnをコピーしておく ● prometheus ● pushgateway ● predictor ● predictor-canary

Slide 211

Slide 211 text

©2024 CyberAgent Inc. Distribution prohibited Terraformの修正(pushgateway) 211 resource "aws_ecs_service" "pushgateway" { name = "${var.name}-pushgateway-service" cluster = aws_ecs_cluster.mlops_practice_dashboard.name task_definition = aws_ecs_task_definition.pushgateway.arn desired_count = 1 deployment_minimum_healthy_percent = 0 deployment_maximum_percent = 200 launch_type = "FARGATE" network_configuration { security_groups = [ "${var.pushgateway_security_group}" ] subnets = var.private_subnets } service_registries { registry_arn = "your_registry_arn" container_name = "pushgateway" } } 追加 得られたArnに書き換え $ $EDITOR infra/modules/ecs/main.tf

Slide 212

Slide 212 text

©2024 CyberAgent Inc. Distribution prohibited Terraformの修正(prometheus) 212 resource "aws_ecs_service" "prometheus" { name = "${var.name}-prometheus-service" cluster = aws_ecs_cluster.mlops_practice_dashboard.name task_definition = aws_ecs_task_definition.prometheus.arn desired_count = 1 deployment_minimum_healthy_percent = 0 deployment_maximum_percent = 200 launch_type = "FARGATE" network_configuration { security_groups = [ "${var.prometheus_security_group}" ] subnets = var.private_subnets } service_registries { registry_arn = "your_registry_arn" container_name = "prometheus" } } 追加 得られたArnに書き換え $ $EDITOR infra/modules/ecs/main.tf

Slide 213

Slide 213 text

©2024 CyberAgent Inc. Distribution prohibited Terraformの修正(predictor) 213 resource "aws_ecs_service" "predictor" { name = "${var.name}-predictor-service" cluster = aws_ecs_cluster.mlops_practice.name task_definition = aws_ecs_task_definition.predictor.arn desired_count = 1 deployment_minimum_healthy_percent = 0 deployment_maximum_percent = 200 launch_type = "FARGATE" network_configuration { security_groups = [var.predictor_security_group] subnets = var.private_subnets } load_balancer { target_group_arn = var.predictor_target_group_arn container_name = "predictor" container_port = 8080 } service_registries { registry_arn = "your_registry_arn" container_name = "predictor" } } 追加 得られたArnに書き換え $ $EDITOR infra/modules/ecs/main.tf

Slide 214

Slide 214 text

©2024 CyberAgent Inc. Distribution prohibited Terraformの修正(predictor-canary) 214 resource "aws_ecs_service" "predictor_canary" { name = "${var.name}-predictor-canary-service" cluster = aws_ecs_cluster.mlops_practice.name task_definition = aws_ecs_task_definition.predictor_canary.arn desired_count = 1 deployment_minimum_healthy_percent = 0 deployment_maximum_percent = 200 launch_type = "FARGATE" network_configuration { security_groups = [var.predictor_security_group] subnets = var.private_subnets } load_balancer { target_group_arn = var.predictor_canary_target_group_arn container_name = "predictor-canary" container_port = 8080 } service_registries { registry_arn = "your_registry_arn" container_name = "predictor-canary" } } 追加 得られたArnに書き換え $ $EDITOR infra/modules/ecs/main.tf

Slide 215

Slide 215 text

©2024 CyberAgent Inc. Distribution prohibited Prometheus.yamlの修正 215 global: scrape_interval: 15s evaluation_interval: 15s scrape_configs: - job_name: 'prometheus' honor_labels: true static_configs: - targets: ['localhost:9090'] - job_name: 'pushgateway' honor_labels: true static_configs: - targets: ['pushgateway.{名前}-mlops-practice.internal:9091'] - job_name: 'predictor_ecs_exporter' honor_labels: true static_configs: - targets: ['predictor.{名前}-mlops-practice.internal:9543'] - job_name: 'predictor_canary_ecs_exporter' honor_labels: true static_configs: - targets: ['predictor-canary.{名前}-mlops-practice.internal:9543'] 先ほど作ったservice名に変更(pushgateway) $ $EDITOR prometheus/ecs/prometheus.yaml 先ほど作ったservice名に変更(predictor) 先ほど作ったservice名に変更(predictor-canary) {サービス名}.{名前}-mlops-practice.internal

Slide 216

Slide 216 text

©2024 CyberAgent Inc. Distribution prohibited datasource.yamlの修正 216 apiVersion: 1 datasources: - name: Prometheus type: prometheus access: proxy # FIXME: Change the URL to the internal DNS name of the Prometheus server url: http://prometheus.{名前}-mlops-practice.internal:9090 isDefault: true 先ほど作ったservice名に変更 $ $EDITOR grafana/ecs/datasource.yaml prometheus.{名前}-mlops-practice.internal:9090

Slide 217

Slide 217 text

©2024 CyberAgent Inc. Distribution prohibited イメージのプッシュ 217 $ make build-grafana build-prometheus build-pushgateway イメージのビルド&プッシュ $ make push-grafana push-prometheus push-pushgateway push-predictor push-predictor-canary

Slide 218

Slide 218 text

©2024 CyberAgent Inc. Distribution prohibited SoftWareメトリクスの取得 218 ecs exporterをサイドカーコンテナとして立てる ecs exporterがECSのメトリクスをPrometheusに送信する ex. cpu使用率、メモリ使用率

Slide 219

Slide 219 text

©2024 CyberAgent Inc. Distribution prohibited exporterのECRプッシュ 219 $ make build-ecs-exporter $ make push-ecs-exporter イメージのビルド&プッシュ

Slide 220

Slide 220 text

©2024 CyberAgent Inc. Distribution prohibited ECS Exporterコンテナの追加 220 $ $EDITOR infra/modules/ecs/container_definitions/predictor.json { "name": "ecs_exporter", "image": "${ecs_exporter_ecr_uri}:latest", "portMappings": [ { "name": "ecs-exporter-9779-tcp", "containerPort": 9779, "hostPort": 9779, "protocol": "tcp", "appProtocol": "http" } ], "logConfiguration": { "logDriver": "awslogs", "options": { "awslogs-create-group": "true", "awslogs-group": "/ecs/${name}-mlops-practice-ecs-exporter", "awslogs-region": "ap-northeast-1", "awslogs-stream-prefix": "ecs" } } } $ $EDITOR infra/modules/ecs/container_definitions/predictor-canary.json { "name": "ecs_exporter", "image": "${ecs_exporter_ecr_uri}:latest", "portMappings": [ { "name": "ecs-exporter-9779-tcp", "containerPort": 9779, "hostPort": 9779, "protocol": "tcp", "appProtocol": "http" } ], "logConfiguration": { "logDriver": "awslogs", "options": { "awslogs-create-group": "true", "awslogs-group": "/ecs/${name}-mlops-practice-ecs-exporter", "awslogs-region": "ap-northeast-1", "awslogs-stream-prefix": "ecs" } } }

Slide 221

Slide 221 text

©2024 CyberAgent Inc. Distribution prohibited デプロイ 221 $ make apply Dashboard用のALBのドメインをクリック https://ap-northeast-1.console.aws.amazon.com/ec2/home?region=ap-northeast-1#LoadBalancers Grafanaの画面が見れればOK デプロイする

Slide 222

Slide 222 text

©2024 CyberAgent Inc. Distribution prohibited データソースに繋ぐ 222 Private DNS経由で繋ぐ ● http://prometheus.{名前}-mlops-practice.internal:9090

Slide 223

Slide 223 text

©2024 CyberAgent Inc. Distribution prohibited ダッシュボード 223 先ほど作成したダッシュボードがECSで動いていることを確認 作ったものが見えたらOK(データはないと思います)

Slide 224

Slide 224 text

©2024 CyberAgent Inc. Distribution prohibited ソフトウェアメトリクスをとってみる 224 Add → Visualization

Slide 225

Slide 225 text

©2024 CyberAgent Inc. Distribution prohibited ソフトウェアメトリクスをとってみる 225 sum(rate(ecs_cpu_seconds_total{container="predictor"}[1m])) * 100 sum(rate(ecs_cpu_seconds_total{container="predictor-canary"}[1m])) * 100

Slide 226

Slide 226 text

©2024 CyberAgent Inc. Distribution prohibited サンプルのダッシュボード 226 サンプルのダッシュボードも作ってあるので確認してみてください

Slide 227

Slide 227 text

©2024 CyberAgent Inc. Distribution prohibited 注意点 227 ● 時間の都合上、ML側のメトリクスの可視化からしたが通常のソフトウェアの メトリクスから取る ● 幅広く可視化したがチーム・事業によって見るべきメトリクスは変わるので、 取捨選択する ○ 誰にもみられないダッシュボードにしない ● 監視対象のビジネス的な閾値を設定することで、アラートを上げることも可能 ○ このときも何でもアラートを上げるのではなく取捨選択する 他にもいろんな機能があるので色々触ってみてください Tableauなどもそうですが、DSは可視化能力も大事です

Slide 228

Slide 228 text

©2024 CyberAgent Inc. Distribution prohibited 08 まとめ 228

Slide 229

Slide 229 text

©2024 CyberAgent Inc. Distribution prohibited 機械学習システムの難しさ 229 Team skills: In an ML project, the team usually includes data scientists or ML researchers, who focus on exploratory data analysis, model development, and experimentation. These members might not be experienced software engineers who can build production-class services. https://cloud.google.com/architecture/mlops-continuous-delivery-and-automation-pipelines-in-machine-learning データサイエンティストのみで機械学習サービスを構築・運用するのは大変です ソフトウェアエンジニア・フロントエンド・データサイエンティスト・リサーチャーに かかわらず、機械学習システムを一緒に作る上でハマりどころなどを共有し、 互いにリスペクトして協力しながら開発・事業を作っていきましょう

Slide 230

Slide 230 text

©2024 CyberAgent Inc. Distribution prohibited 終わりに 230 かなりいろいろ紹介しましたが、今日の講義はプロダクトによってはオーバースペックです ※ 一人でできる必要もありません 運用していく上で色々できることはありますが、 チーム・事業にとってクリティカルなものだけに絞りましょう 大事なこと ● 何を達成したいかを考える ● 誰にも見られないリッチなダッシュボードより、簡素でもビジネスにとって重要なもの をまとめたダッシュボードの方が良い ● DevOpsからスモールに始める ● サードパーティのツールをうまく組み合わせる

Slide 231

Slide 231 text

©2024 CyberAgent Inc. Distribution prohibited 231 MLOps実践編は以上です 作成したリソースを削除しましょう

Slide 232

Slide 232 text

©2024 CyberAgent Inc. Distribution prohibited 手動で削除するリソース 232 ● Cloud Map ● Route 53 ● ECR ● S3(tfstate以外の中身) ● Dynamo DB ● Lambda ● Redshift $ make destroy Destroy

Slide 233

Slide 233 text

©2024 CyberAgent Inc. Distribution prohibited