DatabricksのMLflowを用いたモデルのログ、ロード、登録、デプロイ

[Log, load, register, and deploy MLflow Models \| Databricks on AWS](https://docs.databricks.com/applications/mlflow/models.html) [2021/7/6時点]の翻訳です。

> [Databricksクイックスタートガイド](https://qiita.com/taka_yayoi/items/125231c126a602693610)のコンテンツです。

MLflowの[モデル](https://mlflow.org/docs/latest/models.html)は、様々な後段のツール、例えば、Apache Sparkにおけるバッチ推論やREST API経由のリアルタイムサービングで用いることができる機械学習モデルをパッケージングするための標準的なフォーマットです。このフォーマットは、別のモデル[サービングや推論プラットフォーム](https://www.mlflow.org/docs/latest/models.html#built-in-deployment-tools)で解釈できるように、様々な[フレーバー](https://www.mlflow.org/docs/latest/models.html#built-in-model-flavors)(python-function、pytorch、sklearnなど)でモデルを保存できるようなコンベンションを定義します。

# モデルのログ、ロード

Databricksランタイム8.4ML以降、モデルをログする際、MLflowは自動で`conda.yaml`と`requirements.txt`ファイルを記録します。`conda`や`pip`を用いて、モデル開発環境の再現と依存関係の再インストールを行う際にこれらのファイルを使用することができます。

## APIコマンド

MLflow[トラッキングサーバー](https://docs.databricks.com/applications/mlflow/tracking.html)にモデルを記録するには、`mlflow.<model-type>.log_model(model, ...)`を使用します。

推論やさらなる開発のために、以前ロギングしたモデルをロードするには、`mlflow.<model-type>.load_model(modelpath)`を使用し、`modelpath`は以下のいずれかになります。

- ランからの相対パス(例えば、`runs:/{run_id}/{model-path}`)
- DBFSパス
- [登録されたモデル](https://docs.databricks.com/applications/mlflow/model-registry.html)のパス(例えば、`models:/{model_name}/{model_stage}`)

MLflowモデルに対するオプションの完全なリストに関しては、[Referencing Artifacts in the MLflow documentation](https://www.mlflow.org/docs/latest/concepts.html#artifact-locations)を参照ください。

Python MLflowモデルにおいて、ジェネリックなPython関数としてモデルをロードするために、`mlflow.pyfunc.load_model()`で指定できるオプションがあります。モデルをロードし、データポイントのスコアリングを行う際、以下のコードスニペットを使用することができます。

```py:Python
model = mlflow.pyfunc.load_model(model_path)
model.predict(model_input)
```

あるいは、Sparkクラスターでスコアリングを行うために使用するApache Spark UDFとしてモデルをエクスポートすることもできます。

```py:Python
# load input data table as a Spark DataFrame
input_data = spark.table(input_table_name)
model_udf = mlflow.pyfunc.spark_udf(model_path)
df = input_data.withColumn("prediction", model_udf())
```

## MLflow UIにおいて自動で生成されるコードスニペット

Databricksノートブックでモデルをロギングした際、Databricksは自動でコードスニペットを生成するので、それをコピーし、モデルをロード、実行するために使用することができます。これらのコードスニペットを参照するには以下の手順を踏みます。

1. モデルを生成しRuns画面に移動します。(Runs画面をどのように表示するのかに関しては、[ノートブックエクスペリメントの参照](https://qiita.com/taka_yayoi/items/ba0c7f46ff7c3dbf87bb#%E3%83%8E%E3%83%BC%E3%83%88%E3%83%96%E3%83%83%E3%82%AF%E3%82%A8%E3%82%AF%E3%82%B9%E3%83%9A%E3%83%AA%E3%83%A1%E3%83%B3%E3%83%88%E3%81%AE%E5%8F%82%E7%85%A7)を参照ください)
1. **Artifacts**セクションまでスクロールします。
1. ロギングされたモデルの名前をクリックします。モデルをロードし、Sparkデータフレーム、pandasデータフレームに対して予測を行う際に使用できるコードが右側のパネルに表示されます。
![](https://docs.databricks.com/_images/code-snippets.png)

## サンプル

モデルをロギングするサンプルに関しては、[機械学習トレーニング実行トラッキングのサンプル](https://qiita.com/taka_yayoi/items/ba0c7f46ff7c3dbf87bb#%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%83%8E%E3%83%BC%E3%83%88%E3%83%96%E3%83%83%E3%82%AF)を参照ください。推論のために記録されたモデルをロードするサンプルに関しては、以下のサンプルを参照ください。

- [Model inference example](https://docs.databricks.com/applications/mlflow/model-example.html)

# モデルレジストリにモデルを登録

MLflowモデルの完全なライフサイクルを管理するためのUIと一連のAPIを提供する、集中管理されたモデルストアである[MLflowのモデルレジストリ](https://docs.databricks.com/applications/mlflow/model-registry.html)にモデルを登録することができます。モデルレジストリの一般的な情報に関しては、[DatabricksにおけるMLflowモデルレジストリ](https://qiita.com/taka_yayoi/items/e7a4bec6420eb7069995)を参照ください。Databricksでモデルを管理するためにどのようにモデルレジストリを使うのかに関しては、[Databricksにおける機械学習モデルの管理](https://qiita.com/taka_yayoi/items/2bf6e6a073456dce4fa1)をご覧ください。

APIを用いてモデルを登録するには、`mlflow.register_model("runs:/{run_id}/{model-path}", "{registered-model-name}")`を使用します。

# DBFSにモデルを保存

ローカルにモデルを保存するには、`mlflow.<model-type>.save_model(model, modelpath)`を使用します。`modelpath`には[DBFS](https://qiita.com/taka_yayoi/items/897264c486e179d72247#dbfs%E3%81%B8%E3%81%AE%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%82%B9%E3%83%88%E3%83%AC%E3%83%BC%E3%82%B8%E3%81%B8%E3%81%AE%E3%83%9E%E3%82%A6%E3%83%B3%E3%83%88)のパスを指定してください。例えば、プロジェクトの成果をDBFSの`dbfs:/my_project_models`に保存する場合には、モデルパスとして`/dbfs/my_project_models`を指定します。

```py:Python
  modelpath = "/dbfs/my_project_models/model-%f-%f" % (alpha, l1_ratio)
  mlflow.sklearn.save_model(lr, modelpath)
```

# モデルアーティファクトのダウンロード

様々なAPIを用いて、記録したモデルのアーティファクト(モデルファイル、プロット、メトリクスなど)をダウンロードすることができます。

[Python API](https://www.mlflow.org/docs/latest/python_api/mlflow.tracking.html#mlflow.tracking.MlflowClient.get_model_version_download_uri)のサンプル

```py:Python
from mlflow.store.artifact.models_artifact_repo import ModelsArtifactRepository

model_uri = MlflowClient.get_model_version_download_uri(model_name, model_version)
ModelsArtifactRepository(model_uri).download_artifacts(artifact_path="")
```

[Java API](https://mlflow.org/docs/latest/java_api/org/mlflow/tracking/MlflowClient.html#downloadModelVersion-java.lang.String-java.lang.String-)のサンプル

```java:Java
MlflowClient mlflowClient = new MlflowClient();
// Get the model URI for a registered model version.
String modelURI = mlflowClient.getModelVersionDownloadUri(modelName, modelVersion);

// Or download the model artifacts directly.
File modelFile = mlflowClient.downloadModelVersion(modelName, modelVersion);
```

[CLIコマンド](https://www.mlflow.org/docs/latest/cli.html#mlflow-artifacts-download)のサンプル

```
mlflow artifacts download --artifact-uri models:/<name>/<version|stage>
```

# オンラインサービングへのモデルのデプロイ

サードパーティのサービングフレームワークにモデルをデプロイするには、`mlflow.<deploy-type>.deploy()`を使用します。以下のサンプルをご覧ください。

あるいは、[DatabricksにおけるMLflowモデルサービング](https://docs.databricks.com/applications/mlflow/model-serving.html)を利用することもできます。

- [scikit\-learn model deployment on SageMaker](https://docs.databricks.com/applications/mlflow/scikit-learn-model-deployment-on-sagemaker.html)
- [MLeap model deployment on SageMaker](https://docs.databricks.com/applications/mlflow/mleap-model-deployment-on-sagemaker.html)

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)