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

Vertex Pipelines ではじめるサーバーレス機械学習パイプライン

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
Avatar for Asei Sugiyama Asei Sugiyama
October 13, 2021

Vertex Pipelines ではじめるサーバーレス機械学習パイプライン

資料中で出てくるサンプルには次の URL からアクセスできます

GitHub: https://github.com/reproio/lab_sample_pipelines/tree/main/kfp
解説ブログ: https://tech.repro.io/entry/2021/06/22/125113
Colab : https://gist.github.com/AseiSugiyama/d189a43f656a3313837e820bc54f873b

Avatar for Asei Sugiyama

Asei Sugiyama

October 13, 2021
Tweet

More Decks by Asei Sugiyama

Other Decks in Technology

Transcript

  1. 自己紹介 杉山 阿聖 (@K_Ryuichirou) Software Engineer @ Repro 機械学習基盤の設計構 築

    Advisor @ moneyforward TensorFlow User Group TFX & Kubeflow Pipeline 機械学習図鑑 共著
  2. Hello, world def hello_world(text: str): print(text) hello_world("Hello, world") # Hello,

    world この関数を実行する機械学習パイプラインをこれから作成
  3. Python の関数からコンポーネントの作成 from kfp.v2 import components hw_op = components.component_factory.create_component_from_func( hello_world,

    output_component_file="hw.yaml" ) 関数 hello_world を実行するコンポーネントを準備 hw_op はコンポーネントを生成するファクトリ関数 hw.yaml については後ほど
  4. @component デコレーター from kfp.v2.dsl import component @component(output_component_file='hw.yaml') def hw_op(text: str):

    print(text) 同様のことを @component デコレーターを用いると短く記述可能
  5. パイプラインの定義 from kfp.v2 import dsl GCS_PIPELINE_ROOT = "gs://your-gcs-bucket/" @dsl.pipeline( name="hello-world",

    description="A simple intro pipeline", pipeline_root=f"{GCS_PIPELINE_ROOT}helloworld/" ) def hello_world_pipeline(text: str = "hi there"): hello_world_task = hw_op(text) pipeline_root はパイプラインの生成物を保管する先のバケット
  6. ComponentSpec (抜粋) inputs: - {name: text, type: String} # 入力

    text の定義 # outputs: # 出力は outputs として定義 implementation: container: image: python:3.7 # 動かすコンテナの指定 command: # コンテナで動かすコマンドの指定 - sh - -ec ... args: # コンテナに与える引数の指定 - --text - {inputValue: text} # パイプラインで与えた値が入る
  7. Producer / Consumer Pipeline (1/2) @dsl.component def echo(text: str) ->

    str: return text @dsl.pipeline( name="producer-consumer-pipeline", pipeline_root=f"{GCS_PIPELINE_ROOT}producer-consumer/" ) def producer_consumer_pipeline(text: str = "hi there"): producer = echo(text) consumer = echo(producer.output) # producer の出力を利用
  8. 明示的な実行順の定義 @dsl.pipeline( name="producer-consumer", pipeline_root=f"{GCS_PIPELINE_ROOT}producer-consumer/" ) def use_after_pipeline(text: str = "hi

    there"): producer = echo(text) consumer = echo(text).after(producer) # producer のあとに実行 after を使うことで明示的に実行順を定義可能 キャッシュは必ずしも担保されないので注意
  9. GPU の利用 @dsl.pipeline( name="hello-world-with-gpu", pipeline_root=f"{GCS_PIPELINE_ROOT}helloworld/" ) def hello_world_pipeline_with_gpu(text: str =

    "hi accelerator"): hello_world_task = (hw_op(text) .add_node_selector_constraint( # GPU の追加を宣言 'cloud.google.com/gke-accelerator', # 利用できる GPU の種類は 'nvidia-tesla-k80') # Custom Training に同じ .set_gpu_limit(1)) コンポーネントで CPU やメモリ、 GPU の指定が可能 確保に失敗することもあるので注意
  10. ディレクトリ構造 % tree . . ├── README.md ├── components │

    ├── data_generator # コンポーネントごとのディレクトリ │ │ ├── Dockerfile # コンポーネントの Dockerfile │ │ ├── README.md # コンポーネントの仕様 │ │ ├── data_generator.yaml # ComponentSpec │ │ ├── src # ソースコード一式 │ │ └── tests # テストコード一式 │ ... └── pipeline.py # パイプラインの定義 Kubeflow Pipelines のドキュメントと同じ
  11. コンポーネントの実装 if __name__ == "__main__": # 引数をパース artifacts = Artifacts.from_args()

    # main 関数で処理 train_data, eval_data = main(artifacts.component_arguments) # 与えられた出力先に CSV ファイルを保存 write_csv( artifacts.output_destinations.train_data_path, train_data) write_csv( artifacts.output_destinations.eval_data_path, eval_data) コンポーネントは普通の CLI アプリケーション
  12. 単体テスト import pytest class TestTrainModel: def test_train_model_from_small_dataset(self): source = np.array(

    [(0, 1, 2, 3, 4), (1, 2, 3, 4, 5), (0, 3, 4, 5, 6)], ... model = trainer.train(source, "species_xf") assert model is not None assert model.predict([[1, 2, 3, 4]]) == [0] pytest で単体テストを実装 経験上、可能な限り単体テストを書くべき
  13. ComponentSpec (data-generator) name: data_generator outputs: - { name: train_data_path, type:

    { GCPPath: { data_type: CSV } } } - { name: eval_data_path, type: { GCPPath: { data_type: CSV } } } implementation: container: image: us.gcr.io/your-project-id/kfp-sample-data-generator:v0.0.0 args: - { outputPath: train_data_path } - { outputPath: eval_data_path } kfp 1.8.4 では command を書かなくてもコンパイルできる 将来的には command が必須に
  14. パイプラインの実装 (一部) @kfp.dsl.pipeline( name=PIPELINE_NAME, pipeline_root=f"gs://{GCP_GCS_PIPELINE_ROOT}/", ) def kfp_sample_pipeline(suffix: str =

    "_xf"): data_generator = _data_generator_op() transform = _transform_op( train_data_path=data_generator.outputs[GeneratedData.TrainData.value], eval_data_path=data_generator.outputs[GeneratedData.EvalData.value], suffix=suffix, ) 出力が複数あるときには outputs に出力変数名を渡す