結構前に、ワークフローライブラリをいくつか使ってみてました。
今回は、たまたまmetaflowについて調べる機会があり、せっかくなので使ってみたのでそのメモです。
Metaflow is なに?
MetaflowはNetflixが開発しているワークフローライブラリです。
一応公式ドキュメントによれば、こんな感じで紹介されています。
Metaflow is a human-friendly Python library that helps scientists and engineers build and manage real-life data science projects. Metaflow was originally developed at Netflix to boost productivity of data scientists who work on a wide variety of projects from classical statistics to state-of-the-art deep learning. Metaflow provides a unified API to the infrastructure stack that is required to execute data science projects, from prototype to production. What is Metaflow - Metaflow
今やワークフローライブラリは世の中に多く存在しますが、重厚長大なものから比較的簡素なものまで、特徴は様々です。
metaflowはどちらかというと軽量な部類で、ダッシュボードなどの可視化機能はありません。 そのため、シンプルなワークフローエンジンといった位置づけになります。 また、AWSを強く意識しているようで、S3とのデータ連携のAPIが提供されていたりするなど、何かとAWSを使用する際には便利機能が用意されているようです。 AWSで開発を行っていたり、軽量なワークフローエンジンをお探しという場合には、検討に値するかと思います。
使ってみる
それでは実際に使ってみます。
インストール
インストールは下記のコマンドだけです。
pip install metaflow
これだけです。
ワークフローの書き方
Metaflowでは、一つのワークフローは1つのクラスとして記述します。 個々のタスクはメソッドで記述し、前後関係は"self.next(self.next_method)"のような形で前->後の繋がりを記述します。
from metaflow import FlowSpec, step class HelloFlow(FlowSpec): """ A flow where Metaflow prints 'Hi'. Run this flow to validate that Metaflow is installed correctly. """ @step def start(self): """ This is the 'start' step. All flows must have a step named 'start' that is the first step in the flow. """ print("HelloFlow is starting.") self.next(self.hello) @step def hello(self): """ A step for metaflow to introduce itself. """ print("Metaflow says: Hi!") self.next(self.end) @step def end(self): """ This is the 'end' step. All flows must have an 'end' step, which is the last step in the flow. """ print("HelloFlow is all done.") if __name__ == '__main__': HelloFlow()
最低限の決まりごととしては
- それぞれのステップは@stepデコレータによって指定します。
- ワークフローのエントリポイントはstartメソッド
- ワークフローの終端はendメソッド
- 実行は、定義したワークフローをインスタンス化することで開始
くらいです。 後は淡々とワークフローを書いていくだけなので、非常にシンプルであるということがお分かりいただけるかと思います。
実行
実行時の引数はざっくりこんな形になっています。
- show : workflowに関する説明(コメント)の表示
- run : ワークフローをローカルで実行
- help : その他のオプションの表示
細かいオプションはhelpを見てください。 こちらを踏まえて、実行する際にはこんな感じ。
$ python hello.py run
実行に関して、一点注意として、環境変数でUSERNAMEが設定されていないとエラーが出るようになっているようです。
そのため、設定していない場合には下記のように設定して実行すれば、問題なく動作します。
$ export USERNAME='YOUR_NAME'
中間生成物の確認
実行すると、.metaflowというディレクトリが生成され、その中に各実行の記録がstepごとに格納されていきます。 これを利用することで、過去の実行時のインスタンスの状態を確認することができたりします。
from metaflow import Flow for run in Flow('HelloFlow').runs(): print(run) # Run('HelloFlow/1594916711341436') # Run('HelloFlow/1594915795568427')
これを使用して、
from metaflow import Run run = Run('HelloFlow/1594915795568427') run.data # <MetaflowData: name> run.data.name # 'HelloFlow'
のように、過去の実行時のデータの状態を確認することができるようになっています。
jupyter-notebookと組み合わせて、効率よくデバッグするやり方がtutorialに掲載されています。
再実行
Metaflowでは、ワークフローを途中から再実行することができます。 再実行の場合には、開始時点より前のstepの処理は、過去の実行結果を参照することで代用しています。
resumeコマンドとその後に再開するstepを指定してあげることで、途中から実行することが可能になっています。
$python3 hello.py resume end Metaflow 2.0.5 executing HelloFlow for user:USER Validating your flow... The graph looks good! Running pylint... Pylint is happy! 2020-07-16 16:25:11.350 Gathering required information to resume run (this may take a bit of time)... 2020-07-16 16:25:11.481 Workflow starting (run-id 1594916711341436): 2020-07-16 16:25:11.502 [1594916711341436/start/1] Cloning results of a previously run task 1594915795568427/start/1 2020-07-16 16:25:11.922 [1594916711341436/hello/2] Cloning results of a previously run task 1594915795568427/hello/2 2020-07-16 16:25:12.339 [1594916711341436/end/3 (pid 41)] Task is starting. 2020-07-16 16:25:12.736 [1594916711341436/end/3 (pid 41)] HelloFlow is all done. 2020-07-16 16:25:12.822 [1594916711341436/end/3 (pid 41)] Task finished successfully. 2020-07-16 16:25:12.834 Done!
参考にさせていただいた記事
下記の記事を非常に参考にさせていただきました。ありがとうございます。
感想
昨年Metaflowが発表されてからずっと使ってみようとは思っていたんですが、なかなかチャンスがなく、今回初めて触った次第です。 所感としては、軽量なワークフローエンジンとしては十分な機能を備えていると思いますし、シンプルにワークフローを記述したいという際には非常に有効かと思いました。
頑張ればワークフローの途中から実行もできるので、トライアンドエラーを繰り返すような状況では、非常に良い選択肢だと感じました。