💭

Cloud RunでMLflowを動かす

2021/02/16に公開

やったこと

Google Cloud RunでMLflowを動かしている記事がほとんど見つからなかったのでとりあえず動かしました。
前回の記事ではtensorboardで動かしたものになります。
今回はMLflowで動かして、その他にも認証周りの煩雑な設定手順を極力減らしてみました。

利点

  • アクセス制御をGoogleアカウントで可能です。この記事ではドメインで制御していますが、個人のメールアドレスで制御できます。
  • 社内での実験やkaggleのチームでの共有が容易です
  • VMやAppEngineよりも安いです

使えなくなるタイミング

  • Cloud RunにCloud IAPが導入されたら、あまり意味がなくなるだろうと思っています。

費用

今の構成だと、

  • Cloud Storge : 結果のサイズ次第
  • Cloud SQL : 42円/日
  • Cloud Run : アクセス時のみ
    • 少量の実験であれば、ゼロにスケーリングする期間が長いので1円未満/日。
    • 深層学習でバッチごとにデータを転送するとCloud Runの値段は跳ねそう。

固定費が50円/日くらいと考えると、1500円/月なので、kaggleをやるときに払ってもいいかな、ぐらいの費用になりますね!

認証付きMLflow

コードはこちら

使い方

  1. GCPのプロジェクトにterraform状態を保存するバケットを作る。
  2. 認証情報の設定をGCPのプロジェクトで作る。
  3. terraformの変数の設定を更新する。
  4. terraform init → terraform apply (後述)
  5. github actionsのワークフローを起動するために、github secretsのアップデート

github actionsの稼働が要らないのであれば、1.と5.は不要です。

必要な環境

  • gcloud CLIコマンド
  • terraform

Optional Aを参照

0. GCPの設定

0-1. 認証情報の設定

ナビゲーションメニューから APIとサービス認証情報を選択

img01

+認証情報を作成OAuthクライアントIDをクリックする。

img02

アプリケーションの種類のプルダウンから、ウェブアプリケーションを選択して名前を適当につけて、作成します。

img03

ここで得られるクライアントIDクライアントシークレットをterraform実行時に使います。

img04

0-2. terraform stateを保存するバケットの作成(Optional)

export PROJECT_ID=$(gcloud info --format='value(config.project)')
gcloud config set project $PROJECT_ID
expoert TF_BUCKET=${PROJECT_ID}-tfstate-hoge
gcloud mb gs://${TF_BUCKET}

TF_BUCKETinfra/tf-tensorboardまたはinfra/tf-mlflow以下のprovider.tf


  backend "gcs" {
    bucket = ${TF_BUCKET}
  }

を書き換えてください。立ち上げるサービスごとに別々のBUCKETが必要でので、適宜hogeを書き換えて使ってください。

1. MLFlow with Cloud Run

git clone (このレポジトリ)
export PROJECT_ID=$(gcloud info --format='value(config.project)')
cd mlflow-cloudrun
gcloud builds submit --tag asia.gcr.io/${PROJECT_ID}/mlflow-cloudrun --project ${PROJECT_ID}

infra/tf-mlflow/sandbox.tfvars(YOUR_PROJECT)を自分のプロジェクトに書き換えてください。

#provider
project = "(YOUR_PROJECT)" #ここ
region  = "asia-northeast1"
zone    = "asia-northeast1-a"
env     = "sandbox"

# cloud run 
dashboard_name             = "mlflow-cloudrun"
dashboard_cpu              = "2000"
dashboard_memory           = "1024"
autoscaling_max_num        = "4"
mlflow_artifact_store_name = "mlflow-artifact"

# auth cloud run 
auth_name      = "pomerium-mlflow"
auth_cpu       = "1000"
auth_memory    = "512"
encoded_policy = "data"

# db
db_name = "mlflow"

github actionsを使ったCI/CDを行わない場合には、
infra/tf-mlflow/provider.tf


  backend "gcs" {
    bucket = ${TF_BUCKET}
  }

を削除しておいてください。

設定が終われば、

cd infra/tf-mlflow
terraform init
terraform apply -var-file=sandbox.tfvars \
                -var="idp_client_id=(0-1で取得したクライアントID)" \
                -ver="idp_client_secret=(0-1で取得したクライアントシークレット)"

で、サービスがすべて立ち上がるので、OAuth2.0の承認済みのリダイレクト URIに認証サーバーのURIを以下のように登録してください。

https://(認証サーバーのURL)/callback
https://(認証サーバーのURL)/oauth2/callback

img05

使い方

GCPのナビゲーションメニューから IAMと管理サービスアカウントを選択すると、mlflow-cloudrun-invvoker@...というアカウントが作成されています。

img06

上記赤枠から鍵を作成JSONを選択すると、ローカルPCに鍵が保存されます。MLflowで学習を保存させる場合にはこの鍵を利用します。

動かすためには以下のライブラリがローカルマシンに必要です。

pip install --upgrade google-auth
pip install mlflow

使い方の例

import os

from google.auth.transport.requests import AuthorizedSession
from google.oauth2 import service_account
import mlflow

mlflow_url = '(CLOUD_RUN_MLFLOW_URL)'
PATH_TO_CREDENTIAL = '(DOWNLOADED_CREDENTIAL_PATH)'


def set_mlflow_env(mlflow_url):
    creds = service_account.IDTokenCredentials.from_service_account_file(
        PATH_TO_CREDENTIAL,
        target_audience=mlflow_url)

    authed_session = AuthorizedSession(creds)
    authed_session.get(mlflow_url)
    token = creds.token
    os.environ["MLFLOW_TRACKING_TOKEN"] = token

if __name__ == '__main__':
    set_mlflow_env(mlflow_url)
    # DO SOMETHING

    mlflow.set_tracking_uri(mlflow_url)
    mlflow.start_run()
    mlflow.log_param('hoge', hoge)
    mlflow.log_metric('score', your_score)
    mlflow.sklearn.log-model(your_model, "ml_models")
    mlflow.end_run()

2. github actionsの設定

github actionsをつかってCI/CD化しています。
github secretの以下のパラメータをアップデートしてください。

パラメータ 説明
GCLOUD_PROJECT_ID GCPのプロジェクト名
GCLOUD_SERVICE_KEY projectのservice account key のcredential
IDP_CLIENT_ID 0-1で取得したクライアントID
IDP_CLIENT_SECRET 0-1で取得したクライアントシークレット

詳しくは公式を参考にしてください。

3. github actionsを動かす

terraformが書き換わっているので、pull request→mergeすると、github actionsが動いてGCP上にデプロイされます。

まとめ

MLflowをCloud Runで動かしてみました。インフラ周りをterraformでコード化しているため、再現性/再利用性も担保されていると思っています。
気軽にお使いいただければ嬉しく思います。

ただ、機械学習のダッシュボードは色んなウェブサービスがあるので、個人でやるならそちらを使うのが吉だと思います。
チームになると有料になりますが、会社であれば支払えばいいと個人的には思います。

Discussion