Upgrade to Pro — share decks privately, control downloads, hide ads and more …

DynalystにおけるMLワークフローへのPrefect導入事例

 DynalystにおけるMLワークフローへのPrefect導入事例

第30回 MLOps 勉強会の資料
https://mlops.connpass.com/event/276894/

Satsuki Nagae

April 17, 2023
Tweet

More Decks by Satsuki Nagae

Other Decks in Programming

Transcript

  1. 7 DynalystのMLワークフロー N個のモデルの学習が毎⽇M回⾏われる データ取得 前処理 学習 オフライン評価 オンライン評価 データ分布評価 モデルデプロイ

    データ取得 前処理 学習 オフライン評価 データ取得 前処理 学習 オフライン評価 ・・・ 並列 実⾏ でワークフローを定期実⾏
  2. 8 DynalystのMLワークフロー ECS Taskでタスクを実⾏ データ取得 前処理 学習 オフライン評価 オンライン評価 データ分布評価

    モデルデプロイ データ取得 前処理 学習 オフライン評価 データ取得 前処理 学習 オフライン評価 ・・・ ECS Task ECS Task ECS Task ECS Task でタスク実⾏を制御
  3. 20 Prefectでワークフローを実装する Pythonでワークフローを作成 import pandas as pd import boot3 bucket

    = boto3.resource("s3").Bucket(s3_bucket) def extract(file_name: str) -> pd.DataFrame: bucket.download_file(Key=file_name, Filename=file_name) df = pd.read_csv(file_name) return df def transform(df: pd.DataFrame) -> pd.DataFrame: df_transformed = df.groupby(["type1"]).mean().reset_index() return df_transformed def load(df: pd.DataFrame, file_name: str) -> None: df.to_csv(file_name) bucket.upload_file(Key=file_name, Filename=file_name) def etl_flow(download_file_name: str, upload_file_name: str): extracted_df = extract(file_name=download_file_name) transformed_df = transform(extracted_df) load(transformed_df, file_name=upload_file_name) if __name__ == "__main__": etl_flow(download_file_name="extract.csv", upload_file_name="transformed.csv") Pythonでワークフローを作成 Flow・Taskをつくる Try and Errorで開発
  4. 21 Prefectでワークフローを実装する Flow・Taskをつくる from prefect import flow, task import pandas

    as pd import boot3 bucket = boto3.resource("s3").Bucket(s3_bucket) @task(name="extract task") def extract(file_name: str) -> pd.DataFrame: bucket.download_file(Key=file_name, Filename=file_name) df = pd.read_csv(file_name) return df @task(name="transform task",retries=3, retry_delay_seconds=60) # リトライ設定 def transform(df: pd.DataFrame) -> pd.DataFrame: df_transformed = df.groupby(["type1"]).mean().reset_index() return df_transformed @task(name="load task", timeout_seconds=30) # タイムアウト設定 def load(df: pd.DataFrame, file_name: str) -> None: df.to_csv(file_name) bucket.upload_file(Key=file_name, Filename=file_name) @flow(name="ETL Flow") def etl_flow(download_file_name: str, upload_file_name: str): extracted_df = extract(file_name=download_file_name) transformed_df = transform(extracted_df) load(transformed_df, file_name=upload_file_name) if __name__ == "__main__": etl_flow(download_file_name="extract.csv", upload_file_name="transformed.csv") Pythonでワークフローを作成 Flow・Taskをつくる Try and Errorで開発
  5. 22 Prefectでワークフローを実装する Try and Errorで開発 $ python etl_flow.py 15:35:30.208 |

    INFO | prefect.engine - Created flow run for flow 'ETL Flow' 15:35:32.454 | INFO | Flow run - Created task run 'extract task-0' for task 'extract task' 15:35:32.455 | INFO | Flow run - Executing 'extract task-0' immediately... 15:35:33.780 | INFO | Task run 'extract task-0' - Finished in state Completed() 15:35:34.033 | INFO | Flow run - Created task run 'transform task-0' for task 'transform task' 15:35:34.034 | INFO | Flow run - Executing 'transform task-0' immediately... 15:35:35.185 | INFO | Task run 'transform task-0' - Finished in state Completed() 15:35:35.487 | INFO | Flow run - Created task run 'load task-0' for task 'load task' 15:35:35.488 | INFO | Flow run - Executing 'load task-0' immediately... 15:35:36.556 | INFO | Task run 'load task-0' - Finished in state Completed() 15:35:36.557 | INFO | Flow run - ETL flow finished 15:35:36.830 | INFO | Flow run - Finished in state Completed('All states completed.') Pythonでワークフローを作成 Flow・Taskをつくる Try and Errorで開発
  6. 24 Prefectの構成要素を知る Flow Code Prefect Cloud Agent Deployment Flow 実⾏

    Storage Block Flow Code Infrastructure Block Flowの管理・実⾏設定のメタデータ 登録 アップロード ダウンロード Flow実⾏ Deoloymentに設定できるFlow管理・実⾏設定 Prefect CloudからFlowをポーリングし、 infrastructure上で実⾏する Flowの実⾏・管理を⾏うWeb UIサービ ス Deployment Storage/Infrastructure Block Agent Prefect Cloud
  7. 25 Prefectの構成要素を知る Flow Code Prefect Cloud Agent Deployment Flow 実⾏

    Storage Block Flow Code Infrastructur e Block Flowの管理・実⾏設定のメタデータ 登録 アップロード ダウンロード Flow実⾏ Deployment
  8. 26 Prefectの構成要素を知る Flow Code Agent Deployment Flow 実⾏ Storage Block

    Flow Code Infrastructur e Block 登録 アップロード ダウンロード Flow実⾏ Prefect Cloud Flowの実⾏・管理を⾏うWeb UIサービ ス Prefect Cloud
  9. 27 Prefectの構成要素を知る Flow Code Deployment Flow 実⾏ Storage Block Flow

    Code Infrastructur e Block 登録 アップロード ダウンロード Flow実⾏ Prefect Cloud Agent Prefect CloudからFlowをポーリングし、 infrastructure上で実⾏する Agent
  10. 28 Prefectの構成要素を知る Flow Code Deployment Flow 実⾏ Storage Block Flow

    Code Infrastructure Block 登録 アップロード ダウンロード Flow実⾏ Prefect Cloud Agent Deoloymentに設定できるFlow管理・実⾏設定 Storage/Infrastructure Block
  11. 29 Prefectの構成要素を知る Flow Code Prefect Cloud Agent Deployment Flow 実⾏

    Storage Block Flow Code Infrastructure Block Flowの管理・実⾏設定のメタデータ 登録 アップロード ダウンロード Flow実⾏ Deoloymentに設定できるFlow管理・実⾏設定 Prefect CloudからFlowをポーリングし、 infrastructure上で実⾏する Flowの実⾏・管理を⾏うWeb UIサービ ス Deployment Storage/Infrastructure Block Agent Prefect Cloud
  12. 30 Prefectでワークフローを運⽤する Blockの作成 Agentの登録 Deploymentの登録 Blockの作成 Prefect Cloudから実⾏ from prefect.filesystems

    import S3 import os block = S3(bucket_path="prefect-etl", aws_access_key_id=os.environ['AWS_ACCESS_KEY_ID'], aws_secret_access_key=os.environ['AWS_SECRET_ACCESS_KEY'] ) block.save("etl-s3-block") $ python storage_block.py
  13. 31 Prefectでワークフローを運⽤する Blockの作成 Agentの登録 Deploymentの登録 Blockの作成 Prefect Cloudから実⾏ from prefect.infrastructure

    import DockerContainer block = DockerContainer(env={ "EXTRA_PIP_PACKAGES": "s3fs pandas prefect-aws" }) block.save("etl-docker-container-block") $ python infrastructure_block.py
  14. 32 Prefectでワークフローを運⽤する Blockの作成 Agentの登録 Deploymentの登録 Agentの登録 Prefect Cloudから実⾏ $ prefect

    agent start -q etl Starting v2.9.0 agent connected to https://api.prefect.cloud/api/accounts/.../workspaces/... ___ ___ ___ ___ ___ ___ _____ _ ___ ___ _ _ _____ | _ ¥ _ ¥ __| __| __/ __|_ _| /_¥ / __| __| ¥| |_ _| | _/ / _|| _|| _| (__ | | / _ ¥ (_ | _|| .` | | | |_| |_|_¥___|_| |___¥___| |_| /_/ ¥_¥___|___|_|¥_| |_| Agent started! Looking for work from queue(s): etl... 23:42:09.694 | INFO | prefect.agent - Created work queue 'etl'.
  15. 33 Prefectでワークフローを運⽤する Blockの作成 Agentの登録 Deploymentの登録 Deploymentの登録 Prefect Cloudから実⾏ from etl

    import etl_flow from prefect.deployments import Deployment from prefect.filesystems import S3 from prefect.infrastructure.docker import DockerContainer from prefect.server.schemas.schedules import CronSchedule storage = S3.load("etl-s3-block") infrastructure = DockerContainer.load("etl-docker-container-block") deployment = Deployment.build_from_flow( flow=etl_flow, name="etl-flow-deployment", version=1, work_queue_name="etl", storage=storage, infrastructure=infrastructure, tags=['dev'], schedule=(CronSchedule(cron="0 0 * * *", timezone="Asia/Tokyo")) ) deployment.apply() $ python deployment.py
  16. 35 Prefectでワークフローを運⽤する Blockの作成 Agentの登録 Deploymentの登録 Prefect Cloudから実⾏ Prefect Cloudから実⾏ Prefect

    Cloud Agent elt.pyダウンロード Docker containerとしてFlow実⾏ etl.py ダウンロード Flow実⾏
  17. 39 Prefect移⾏後のイメージ 39 オンライン評価 データ分布評価 モデルデプロイ データ取得 前処理 学習 オフライン評価

    ・・・ ECS Task ECS Task ECS Task ECS Task ・ワークフローツールだけ変える ・既存のアプリケーションコードは変えない 変える・変えない要素
  18. 41 Prefectを導⼊するために考えたこと Flowの実⾏ Flowの管理 Prefectの設定管理 CI/CD 既存システムに合わせECS Taskで実⾏ stg, prodはECS

    Taskで実⾏、開発はローカルDocker環境で 実⾏するために、Docker Imageで管理 既存システムのインフラ管理に合わせTerraformで管理 既存システムに合わせてGitHub Actionを利⽤
  19. 48 MLワークフローの組み⽅ ECS Taskを実⾏するタスクを組み合わせる @flow("ML Workflow") def ml_workflow(model): train_model =

    train_model_task(model) update_model = update_model_task(train_model) validate_data = validate_data_distribution_task(train_model) validate_model = validate_model_online_performance_task(train_model) モデル学習 モデルデプロイ データ分布評価 オンライン評価 ML Workflow CPU=4048 memory=8096 CPU=512 memory=1024 CPU=2048 memory=4048 CPU=1024 memory=2048 Taskごとに リソースを変更
  20. 49 DynalystのPrefect運⽤ ディレクトリ構成 ├ .github/workflows... Deployment登録・image build/push ├ ml_workflows .......

    MLワークフローの実装 ├ Dockerfile ......... Prefectで実⾏するコンテナ⽤Dockerfile └ prefect_flows ...... Prefect Flowの実装 ├ flows └ tasks ワークフローツールの仕様に合わせて、アプリケーションコードを変更したくない → アプリケーションコードの実装と、Prefectの実装は分けた
  21. 50 DynalystのPrefect運⽤ CI/CD ECR prod-flow:latest ECS Task Block image= prod-flow:latest

    ECS Task Flow実⾏ Agent (ECS Service) Flow image download ・FlowのimageをECRで管理 ・ECS Task Blockの 実⾏imageに指定 Flow image push deployment 登録