本当に小さく機械学習プロダクトを始めるには

# TL;DR
マイクロサービス基盤がない、潤沢にエンジニアリソースがない、そんな現場にも機械学習プロジェクトをいい感じにプロダクトに乗せていく今風のやり方について考えたい。そのために現状世の中にある機械学習ツールを俯瞰したい。
プロダクトに乗せるとすると、デプロイで終わりではなくて、モデル再学習やモニタリングなども含めて考えたい。

# はじめに
機械学習のサービスは内部のアルゴリズムが複雑であっても、そのサービス自体に求められることが多くなかったり、学習と推論時で必要なリソースが異なったりというところからマイクロサービスアーキテクチャと相性が良いと言われています。実際に機械学習をプロダクトで使うことについて意欲的に取り組んでいる企業、特にWeb系企業では既にマイクロサービスアーキテクチャを採用した基盤があり、その上で効率的に機械学習モデルをデプロイするための方法を検討しています。一方で、そうでない現場で機械学習をプロダクトに載せる知見がまだまだ溜まっていないように感じます。モデル開発や最初のデプロイはもちろん、その後、少ないエンジニアリソースでも機械学習モデルを継続的に使っていくためには、どのようなツールをどのように組み合わせていくのが良いのでしょうか。正直、ビジネス要件に依る部分がだいｂ大きいので決めきれるもんではないのですが、少なくとも選択肢は知っておきたいなと思って調べてみました。

# 本当に何も無い現場で始めるMLプロダクト
機械学習プロジェクトは、
1.  新しい取り組みであり、開発者もユーザーも機械学習によって何がどの程度できるようになるのかわかっていない
2. 機械学習モデルの精度によって、ユーザーとプロダクトの関わり方が変わってくる
3. 運用の技術的習熟が必要となる、新しい技術が多く出てくる＆データの質が時間の経過と共に変化する可能性がある
などの理由から、小さく初めて試行錯誤し、少しずつプロダクトに仕上げていく進め方が良いとされています。では、活用できる基盤もない、エンジニアリソースも少ないような環境において、機械学習をインフラも含めたプロダクト全体を、イチから小さく開発していくには、どのようなツールを活用して進めるのが良いのでしょうか。デプロイとモデルのメンテナンスという観点から見ていこうと思います。

## デプロイ観点
[裏freeeさんアドカレ](https://adventar.org/calendars/3140)に["機械学習プロジェクトをいい感じにプロダクトに載せていく今風のやり方について考える"](https://aflc.qrunch.io/entries/dQqtdFHRumPAYJcj)という記事があり、アプリへのモデルの組み込み方が整理されいたました。デプロイという観点ではこの中の①や②、③が本当に何も無い現場で機械学習プロダクトを開発するには良さそうなパターンに見えます。

> 2.モデルをWeb application framework（Flaskなど）で包んでAPIサーバーを作る
> 3.モデルをWeb application framework（Flaskなど）で包んでコンテナイメージ化し、AWS Fargate、Azure Container Instance, (Managed) Kubernetesなどで管理する
> 引用元:[機械学習プロジェクトをいい感じにプロダクトに載せていく今風のやり方について考える](https://aflc.qrunch.io/entries/dQqtdFHRumPAYJcj)

## モデルメンテナンス観点
機械学習モデルがプロダクトにデプロイされた後の運用は、下記のようなワークフローが必要になります。

- TFXから引用。

スモールスタートで始めたばかりの機械学習プロジェクトであれば、パイプラインはシンプルなことが多い一方で、運用する人を貼り付けておくほどリソースはない場合が多いのではないでしょうか。
 

この2つの観点から、「API化された機械学習モデルがデプロイされているようなサービング環境において、シンプルなイプラインを手間をかけずに構築＆維持し、継続的にMlを活用し続ける」ことを助けられるツールやその組み合わせを探してみたいと思います。機械学習モデルを開発し、Webサービスとして提供するために必要そうなコンポーネントは以下あたりでしょう。

- 開発環境: Jupyter: ある程度開発し、運用に乗ると毎日改良を重ねるようなことは少なくなるのではないでしょうか。だとするとクラウドサービスを活用した方が、初期環境構築の手間など削減できて良さそう。SageMaker, Datalab, colab
- preprocess: 機械学習モデルへデータを学習させるまでのデータの加工部分です。モデルデプロイの後、推論の流すためのデータを処理したり、再学習時の処理の再に必要です。SQLで処理したり、pythonスクリプトで良いじゃんってのもありますが、場合によってはDataflow, Amazon Batchなどの使用も選択肢に。
- 学習環境: 機械学習モデルの学習は推論時よりも計算リソースがかかることが多いため、こちらもクラウドサービスでアドホックに使うのが良いのではないでしょうか。また、学習時のハイパラ調整や特徴量選択などの実験結果の記録を残しておくことは、プロダクト全体の保守性の観点からは重要となるでしょう。
- デプロイ:  
- ワークフローエンジン: 上記のようなデータの取得から前処理、学習、デプロイといった機械学習プロダクトの全体のワークフローを属人化させないためにシンプルであってもタスクランナーが重要となるでしょう。機械学習モデルを「作った人しかメンテナンスできない」は最悪の状態です。


## クラウドサービスを組み合わせるパターン
- 開発環境
  - ローカルで開発環境を立てられるのであればそれに越したことはないでしょうが、環境設置コストとの兼ね合いでは、Amazon SageMakerやCloud DatalabでJupyterのインスタンスを立ててしまうか、Colaboratoryを使うかなども選択肢に入るでしょう。
- ETL
    - 「何を作るのか」に一番引っ張られやすい部分ですが、基本的にはGoogle BigQuery, Cloud Dataflow、Amazon Redshift、Amazon Batch、などの組み合わせになるんでしょうね。これらをワークフローエンジンで回してあげる。DataflowがApach Beamを基盤にしており、オートスケール、パイプライン可視化などが便利な点は個人的には好きです。
 
- 学習環境
    - 推論時に比べて学習時の計算リソースが大きくなる機械学習プロダクト特有の課題を考えるとML系のクラウドサービスを使うのが楽は楽ですが、SageMakerはカスタムモデルの学習はコンテナ化する必要あるし、ML EngineはTensorFlowやscikit-learn以外でモデルの自由度高く学習させようとするとちょっと学習コスト高い印象。それぞれでもscikit-learnだけでやるならそんなにかも知れませんが。jupyterでそのまま学習させてしまうという手段もあるでしょう。[Netflix](https://medium.com/netflix-techblog/notebook-innovation-591ee3221233)や[リクルートライフスタイルさん](https://engineer.recruit-lifestyle.co.jp/techblog/2018-10-04-ml-platform/)のように、jupyterそのまんまでちゃんとしたワークフロー流せるようになるためには結構な工夫が必要そうで、そのための基盤づくりはそれなりに大変そうで、きっと手が出せないんじゃないでしょうか。
- Deploy
    - ここはSageMakerやML Engineでやっている事例多そうであまり心配なさそう。
- ワークフローエンジン
    - Digdag、Luigiなどある中で、Cloud Composerがあったり、[SageMakerの統合](https://aws.amazon.com/jp/about-aws/whats-new/2018/11/amazon-sagemaker-is-now-integrated-with-apache-airflow/)が進んでいたりと一旦はAirflowで良いのでは感がある。著者はどれにしても比較できるほど使いこなしていないので、何とも言えませんが。


「AWS, GCPでのML系のクラウドサービスを組み合わせ、デプロイ後の運用においてはAirflowでワークフローを定義してやることでオペレーション上の属人性を排除する」、で良さげ。組み合わせ方によって大きく差が出てくる印象はない。しかし、これだけでは下記の点が不十分であり、工夫が必要。

- いつ、どのような試行錯誤を実施し、どのような結果になったのかが、運用者以外の第三者でもわかるようになっていること
- データ自体の版管理。ここは機械学習プロダクトの鬼門ではないか。シンプルなプロダクトにおいては、特定のディレクトリやDBから任意のデータを引っ張ってくるようなことをしがちだが、同じ名前だからといって同じデータとは限らない。どこまでコストをかけてチェックするかは悩みどころ。
  

### MLflowについて
[MLflow](https://www.mlflow.org/docs/latest/tracking.html)は[Databricks](https://databricks.com/)からOSSとして提供されている、機械学習モデルのライフサイクルをE2Eで管理するためのツールです。主に、モデル構築の実験を一覧性を持って記録してくれるMLflow Traking、パイプラインそのものをパッケージにしてしまい再利用可能にするためのMLflow Projects、機械学習モデルをサービングするためにフォーマットしてくれるMLflow Modelsの3つのコンポーネントがあります。この中でML Trackingは割と手軽に実験の結果のログを残してくれるのツールとして期待しています。下記のように記録したい対象を設定してやるだけ。

- 写真

同様の機能は例えばSageMakerであればハイパラの自動チューニングの結果表示として使ってやる必要があり、カスタムのDockerをアップロードしてやるなど、多少手間がかかる印象です。MLflowの他の機能としては、Projectsはワークフローエンジンの位置づけ、ModelsはSageMakerやML Engineでのサービング機能の位置づけにありますが、敢えてマイナーかつベータ版であるMLflowを使うことはエンジニアリソースの少ない環境ではハマりポイントになりそうです。一方で、MLflow Trackingは現状でMLのパイプライン全体に影響は及ばさず、仮にこれが動かなくても機械学習機能をサービスすることができる点も実運用の観点からは大きいのではないでしょうか。実際に[こちらの記事](https://qiita.com/ieiringoo/items/3d255912452b24e7cfe4)のようにクラウドサービスを中心にパイプラインを構築した上で、学習の実験管理の部分だけMLflowにしたものを試していいますが、ぼちぼち良い感じ。ツールの進歩が激しい領域なのでそのうち改変はされるでしょうが、良いものを模索していきたいです。
 
 
 
### kubeflow pipeline
Kubeflow pipelinesは機械学習ツールキットとして注目されているKubeflowの新しいコンポーネントであり、機械学習システムのワークフローを管理できるツールです。Kubernetes上に機械学習モデルを開発&プロダクトに乗せて運用するための様々なコンポーネントが展開されます。

- 開発環境
    - JupyterHunが立ち上がるのでその上で開発。
- ETL
    - 特徴的なのは、[TFX](https://www.tensorflow.org/tfx/)のいちコンポーネントであるTensorflow Transform(TFT)を使えるところでしょう。さらに、その設定項目に"preprocess-mode"というものがあり、Kubernetes上ではなくDataflow上で動作させることもできます。そこまでやらんでいいやん、みたいなところありそうですけど。
- 学習環境
    - こちらも特徴的なのが[TFjob](https://www.kubeflow.org/docs/guides/components/tftraining/)をKubernetesのcustom resourceを活用して分散学習を定義することも可能なところ。
- Deploy
    - Kuberenetes上にTensorFlow Serving上にデプロイしたり、ML EngineのPrediction serviceに展開できたりします。
- ワークフローエンジン
    - [Argo](https://argoproj.github.io/)がベースとなっているワークフローエンジンが使われています。ワークフローの定義はPythonをベースにしたDSLで記述し、その中でTFXのコンポーネントを活用する事ができます。


ワークフローごとに異なる設定をして実験(Experiment)を実施したログが残せたり、ワークフローがちゃんと動いているかモニタリングができるようになっていたりと、機会学習システムのモデリング以外に必要な機能が整備されています。ワークフローマネジメント自体はKubeflowのCoreComponentである、Argoが動いているらしいですが、UIが整ったことでやっと統一感があるpipeline管理ツールが出てきたなというところです。とは言え、ちょっと重厚感強すぎて何もないところから始める機械学習プロジェクトでは気軽には取り掛かれない印象ですね。既に基盤とエンジニアが整っているWeb系企業向けでしょうか。

# まとめ
世の中にツールが乱立して、自分自身の認識もとっ散らかってきた感ありますたので、調べがてらまとめました。現状では機械学習のワークフローをE2Eでサポートできそうなツールはなく、色々なツールの良いところを組み合わせる形でスモールスタートするのが良さそうです。今後もツールの発展で状況変わっていきそうですが、機械学習プロダクトの運用は鬼門が多いため、楽になれるものが出てくることを期待しています。レポートにもならない感想文みたいな記事になってしまいましたが、ご参考に頂ければ幸いです。