Re:ゼロから始めるML生活

どちらかといえばエミリア派です

Metaflowを使ってみた

f:id:nogawanogawa:20200716201308p:plain

結構前に、ワークフローライブラリをいくつか使ってみてました。

www.nogawanogawa.com

www.nogawanogawa.com

今回は、たまたまmetaflowについて調べる機会があり、せっかくなので使ってみたのでそのメモです。

Metaflow is なに?

MetaflowはNetflixが開発しているワークフローライブラリです。

metaflow.org

一応公式ドキュメントによれば、こんな感じで紹介されています。

docs.metaflow.org

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が設定されていないとエラーが出るようになっているようです。

github.com

そのため、設定していない場合には下記のように設定して実行すれば、問題なく動作します。

$ 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に掲載されています。

docs.metaflow.org

再実行

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!

参考にさせていただいた記事

下記の記事を非常に参考にさせていただきました。ありがとうございます。

qiita.com

qiita.com

data.gunosy.io

cyberagent.ai

感想

昨年Metaflowが発表されてからずっと使ってみようとは思っていたんですが、なかなかチャンスがなく、今回初めて触った次第です。 所感としては、軽量なワークフローエンジンとしては十分な機能を備えていると思いますし、シンプルにワークフローを記述したいという際には非常に有効かと思いました。

頑張ればワークフローの途中から実行もできるので、トライアンドエラーを繰り返すような状況では、非常に良い選択肢だと感じました。