調和技研 技術ブログ

調和技研で取り組んでいる技術を公開していきます

MLflowの導入(1) 〜プロジェクトの課題とMLflowが何を解決しうるのか〜

 
調和技研では会社規模の拡大(現在、札幌、東京、バングラデッシュに拠点あり)と人材の多様化(国籍複数)が進んだことで、開発環境の標準化が急務となっている。
この記事ではその一環としてMLflowの導入を検討したので、導入背景について書きたい。
只今試用中なので、使ってみてどうだったかについては別のエントリとして書く予定である。
 
対象読者
  • 機械学習を仕事・研究に使っていてチームでの開発手法について悩んでいる人
  • まだMLflowの公式チュートリアルを読み通しておらず、ざっくり何を解決するものなのか知りたい人
 
書いていないこと
  • KubeflowやAirflowといった他のツールとの比較はしていない
  • 上述の通り、使ってみた具体的な感想などは書いていない
 
機械学習のプロジェクトは簡単に複雑になり管理ができなくなる、と思う。それを一部解決してくれるのがMLflowである。本題に入る前に、まずは我々が直面していた課題についてしっかりと言語化しておきたい。もちろん読み飛ばしても構わない。
 
私は画像処理系のエンジニアなので偏りや漏れがある点はご承知おき頂きたい。

これまでどんな問題があったのか

機械学習の課題
機械学習における難関は「検証の条件と結果」の管理だと思う。
プロジェクトが進むに連れて、過去の検証の条件と現在の検証の条件は刻々と変化していく。それは必ずしも最良の結果に対して漸近的な過程ではなく、思いつきやお試し的なものを含む乱雑な過程である。よくある問題は、過去の実験の結果だけが残っているのに対し、それを再現する条件の一部が不明になってしまうことである。どのソースコードにどのパラメタでどんな入力を入れた時に最良の結果が出たのかを管理するのは簡単ではない。
 
またそれに関連して「データの管理」も重要である。前処理やクレンジングなどで元のデータと機械学習に利用するデータは異なるものであることが多い。実験の条件をメモしていても、実験の時と同じデータが何であるかを把握していないとやはり再現ができない。最悪なのは実験者のローカルフォルダにデータが存在していて、それが日々変化して実験当初のデータがどこにも存在していないという場合だ。これはもう致命的としか言いようがない。
 
これらは検証結果に関しての信頼性を損なうことにつながる。
 
深層学習の課題
深層学習は基本的にNVIDIAGPUを必要としCUDAを利用することになる。(もちろんTPUなどの例外もある)
このCUDA周りの依存性を管理しないとソースコードの可搬性が損なわれることになる。それによって環境のセットアップが煩雑化し、無駄なコミュニケーションが発生する。
 
機械学習以外の周辺技術のキャッチアップ
当社は大学研究室から生まれた会社であり、機械学習に関する専門的知識・ノウハウを強みに急速に成長する一方、機械学習以外の周辺知識のキャッチアップが必要となっていると個人的に考えている。
 
簡単なREST APIを書いたり、客先で動くようにDockerizeしたりすることも少なくはないが、OS・ネットワーク周りの知識がかけていることで、苦労することがあるように思う。餅は餅屋というが、REST APIを作るためにDockerが得意なエンジニアに要件を伝えて作ってもらうのはオーバヘッドが生じることになる。簡単なAPIを作るぐらいは誰でもできたほうがよいと私は思う。
 
ソフトウェアエンジニアのスキルは色々あるが、再現性、可搬性、保守性、文章化を常に心がけて実践することがとても重要である。それができないことがソースコードの再利用性を下げ、ソフトウェア資産の蓄積を阻む障壁になると思う。
 
容易に環境はサイロ化していき、職人芸が進んでいく。それは本当に職人芸だろうか?ただの属人化というネガティブな言葉で置き換えられないだろうか。
 
業界全体の問題だが、PoCだけを繰り返していると自分の書いたソースコードを数年間保守したり、それを誰かに引き継ぐという経験ができない。その経験は再現性、可搬性、保守性、文章化の重要性について身を以って知るために必要なものだ。

MLflowとは?

公式ページでは以下のように説明されている。
MLflow is an open source platform to manage the ML lifecycle, including experimentation, reproducibility and deployment. It currently offers three components:
意訳するとMLflowはOSSで、機械学習の実験、再現性、デプロイを含むライフサイクルを管理する。現在は以下の3つのコンポーネントを提供している。
  • MLflow Tracking: 実験を記録し提供する
  • MLflow Projects: あらゆるプラットフォームで再現可能な実行パッケージのフォーマット
  • MLflow Models: 様々なデプロイツールにモデルを送るための一般的なフォーマット
ちょっと翻訳が難しかったので伝わりにくい日本語になってしまったが、チュートリアルを読み通すと以下のようなものであることがわかる。
  • MLflow Tracking → 実験結果の管理を行うWebサーバ。Gitのcommitのハッシュ値と学習のパラメタと各種メトリックとモデルの重みが紐付いて保存できる仕組み。
  • MLflow Projects → ソースコードの再現性を高めるためのソースツリーやメタファイルの仕様。MLflow Projectsの仕様にしがってソースコードを書くことで、可搬性が担保されたり、エントリーポイントが自動的に判別できるようになる。例えば $ mlflow run  GithubURI とするだけで必要なパッケージがインストールされ学習が始動するようになる。
  • MLflow Models → モデルをクラウドやローカルにデプロイするための仕組み。モデルをREST APIにしたり、それをAWS SageMakerにコマンド一発でできるようになる。
 
上の図のような機械学習のライフサイクルを管理する、というのがMLflowの役割である。(実際はライフサイクルはもっと複雑だが、簡単のために便宜上このようにしている)MLflow Projectsはモデルの開発を管理し、MLflow Trackingは主に実験フェーズを管理し、MLflow Modelsはデプロイフェーズを管理する。ちなみにこの記事では何度か指摘するが、データの作成フェーズについては特にMLflowでは考慮されていないように見える。

MLflowが解決すること

MLflowが解決するのは上述の問題の一部であるが、比較的多くの悩みが解決されそうに見えた。
解決されそうなことは以下である
  • 再現性、可搬性が高くなる
    • 検証条件と結果が管理される
    • CUDA周りの依存が管理される(はず)
    • エントリポイントが分かる
  • REST APIが簡単に作れる
 
検証条件と結果が管理される
MLflowは大きくわけて3つのコンポーネントにわかれている。
その中の一つであるMLflow Trackingは検証条件(入力パラメタとGitのコミットのハッシュ値など)とメトリック(正解率、F値等)とモデルのパラメタ(重み)を管理するためのものである。
基本的に実験に(データを除く)関係しているものはすべて保存されることになる。これで同じ実験を再現することが容易になる。また学習の結果のパラメタ(重み)が保存されるので、学習済みモデルの管理が容易になる。
 
CUDA周りの依存が管理される(はず)
CUDA周りの依存については、Anacondaであればcudatoolkitに対する依存を記述できるし、DockerfileはPythonにかかわらない部分もすべて記述できるので、どちらかを使えば良い。MLflow Projectsがこの2つを前提にしているのはそのためだろう。Pipは私が知っている限りcudaの依存は記述できない。つまりGPUを使った学習が必要なプロジェクトのソースコードをMLflow Projectsに則った場合はAnacondaのcudatookitかcudaがインストール済みのDockerコンテナを使うはずなので問題が解決される。
 
エントリポイントが分かる
MLflow ProjectsのEntry Pointによって、学習がどの .pyで行われ、渡されるパラメタが何で、というのが簡単に把握できるようになる。ありがちなREADME.mdもなく、docstringもないような .pyしかないレポジトリを読み解く苦労はこれによって半減するだろう。
 
MLflow Modelsはコマンド一行でモデルの入出力をREST APIにする。またそのAPIをSageMakerへデプロイするのもコマンド一発である。(当然だがAWSのセットアップは必要だけれども)。デプロイまで面倒を見てくれるのであれば、リサーチャっぽい人の代わりにエンジニアがクラウドにデプロイするというめんどくさいやり取りが不要になる。

MLflowが解決しないこと

  • データのバージョン管理
  • 保守性・文章化
 
データのバージョン管理
データは前述の通り、前処理や思いつきによって変化が生じる。ソースコードと同様に修正頻度が高い場合もあるが、Gitでのデータ管理は厳しい。しかしMLflowはデータのバージョン管理には全く触れていない。ソースコードのバージョンと入力のパラメタが決まれば、あとは同じデータを入れれば結果を再現できるはずなので、画竜点睛を欠いているように感じる。これを解決するのはおそらくDVCなどの他のフレームワークだろう。
 
保守性・文章化
保守性・文章化というのはMLflowでは解決しない。
どうしたら可読性が高く、保守するために再利用性が高く、関心が分離されたコードがかけるのかは別の問題である。そして経験と勉強を必要とする。

まとめ

めんどくさいことは、めんどくさいままにせず、自動化して省力化しようとすることがエンジニアに求められる素質だと勝手に思っている。その観点でMLflowは検証内容の管理追跡を自動化することを可能とし、チーム内で認識を共有できる素晴らしいツールだと思う。
また専門化のための分業は必要だと思うが、広い分野を扱えるほうが高速な開発ができるし、その速度そのものが価値になると思う。MLflowはプロジェクトの価値を高めるツールだと思う。
とりあえずTrackingとProjectsを実プロジェクトで試すところから始めようと思っている。試用することで見えてくることが色々あるだろうから、また別の記事で紹介したいと思う。

その他

MLflowを色々触りながら試しているが、各所で使いにくい印象を受けた。
例えばGoogle Cloud Storage(GCS)にモデルのパラメタ(重み)を保存しようとするとGCSにPythonからアクセスするためのパッケージが不足しているとエラーが出るし、Databricksのクラスタへのデプロイを試してみたが、エラーを解決しきれなかった。まだこなれていないというのが実情なのかもしれない。
 
また、OSSとしてクラウドベンダーを選ばず使えるのは良い点だと思うが、一方でマネージドなものが欲しい場合にはDatabricksとAWS(もしくはAzure)の2つに課金するのがめんどくさい。個人的にはAWSもしくはGCPに完全に統合された形で提供されているとより使いやすいんじゃないかと思う。
 
データのバージョン管理を考えるとMLflowだけでは完結せず、DVCとの連携等が必要だが、こうなると学習コストが増大し、布教の障壁になるんじゃないかと心配になってくる。