カスタム ML モデルを MLflow 形式のモデルに変換する

この記事では、カスタム ML モデルを MLflow 形式に変換する方法について説明します。 MLflow は、機械学習の実験のライフサイクルを管理するためのオープンソース ライブラリです。 場合によっては、組み込みの MLflow モデル フレーバーのサポートなしで機械学習フレームワークを使用することがあります。 この組み込みの MLflow モデル フレーバーがない場合、モデルをログに記録することや、MLflow モデル fluent API に登録することができません。 この問題を解決するために、モデルを MLflow 形式に変換できます。この形式では、Azure Machine Learning と MLflow モデルの次の利点を適用できます。

Azure Machine Learning では、MLflow モデルで次のような追加の利点を得ることができます。

  • コードなしのデプロイ
  • オープン ソース標準形式としての移植性
  • ローカルとクラウドの両方にデプロイ可能

MLflow では、scikit-learn、Keras、Pytorch など、さまざまな機械学習フレームワークがサポートされます。 MLflow では、すべてのユース ケースがカバーされるわけではありません。 たとえば、MLflow でネイティブにサポートされていないフレームワークを使用して MLflow モデルを作成できます。 ジョブの実行時にモデルが前処理または後処理を行う方法を変更できます。 MLflow モデルの詳細については、「MLflow での成果物からモデルまで」を参照してください。

MLFlow を使用してモデルをトレーニングしておらず、Azure Machine Learning の MLflow のコードなしのデプロイ オファリングを使用したい場合は、カスタム モデルを MLFLow に変換する必要があります。 詳細については、「カスタム Python モデル」を参照してください。

前提条件

  • mlflow パッケージのインストール

モデルの Python ラッパーを作成する

モデルを MLflow でサポートされている形式に変換する前に、モデルの Python ラッパーを作成する必要があります。 次のコードは、sklearn モデルの Python ラッパーを作成する方法を示しています。


# Load training and test datasets
from sys import version_info
import sklearn
import mlflow.pyfunc


PYTHON_VERSION = "{major}.{minor}.{micro}".format(major=version_info.major,
                                                  minor=version_info.minor,
                                                  micro=version_info.micro)

# Train and save an SKLearn model
sklearn_model_path = "model.pkl"

artifacts = {
    "sklearn_model": sklearn_model_path
}

# create wrapper
class SKLearnWrapper(mlflow.pyfunc.PythonModel):

    def load_context(self, context):
        import pickle
        self.sklearn_model = pickle.load(open(context.artifacts["sklearn_model"], 'rb'))
    
    def predict(self, model, data):
        return self.sklearn_model.predict(data)

Conda 環境を作成する

次に、必要なすべての依存関係を含む新しい MLflow モデルの Conda 環境を作成します。 この環境が指定されていない場合、現在のインストールから推論されます。 指定されていない場合は指定できます。


import cloudpickle
conda_env = {
    'channels': ['defaults'],
    'dependencies': [
      'python={}'.format(PYTHON_VERSION),
      'pip',
      {
        'pip': [
          'mlflow',
          'scikit-learn=={}'.format(sklearn.__version__),
          'cloudpickle=={}'.format(cloudpickle.__version__),
        ],
      },
    ],
    'name': 'sklearn_env'
}

MLFlow 形式のモデルを読み込み、予測をテストする

環境の準備ができたら、SKlearnWrapper、Conda 環境、および新しく作成した成果物ディクショナリを mlflow.pyfunc.save_model() メソッドに渡します。 これを行うと、モデルがディスクに保存されます。

mlflow_pyfunc_model_path = "sklearn_mlflow_pyfunc_custom"
mlflow.pyfunc.save_model(path=mlflow_pyfunc_model_path, python_model=SKLearnWrapper(), conda_env=conda_env, artifacts=artifacts)

新しく保存した MLflow 形式のモデルが保存中に変更されていないか確認するために、モデルを読み込み、テスト予測を出力して元のモデルと比較します。

次のコードは、mlflow 形式のモデルからのテスト予測と、sklearn モデルからのテスト予測を出力します。 比較のためにテスト予測をディスクに保存します。

loaded_model = mlflow.pyfunc.load_model(mlflow_pyfunc_model_path)

input_data = "<insert test data>"
# Evaluate the model
import pandas as pd
test_predictions = loaded_model.predict(input_data)
print(test_predictions)

# load the model from disk
import pickle
loaded_model = pickle.load(open(sklearn_model_path, 'rb'))
result = loaded_model.predict(input_data)
print(result)

MLflow 形式のモデルを登録する

モデルが正しく保存されたことを確認したら、テスト実行を作成できます。 MLflow 形式のモデルを登録し、モデル レジストリに保存します。


mlflow.start_run()

mlflow.pyfunc.log_model(artifact_path=mlflow_pyfunc_model_path, 
                        loader_module=None, 
                        data_path=None, 
                        code_path=None,
                        python_model=SKLearnWrapper(),
                        registered_model_name="Custom_mlflow_model", 
                        conda_env=conda_env,
                        artifacts=artifacts)
mlflow.end_run()

重要

場合によっては、組み込みの MLflow モデル フレーバーのサポートなしで機械学習フレームワークを使用することがあります。 たとえば、vaderSentiment ライブラリは、感情分析に使用される標準の自然言語処理 (NLP) ライブラリです。 これには、組み込みの MLflow モデル フレーバーがないため、モデルをログに記録することや、MLflow モデル fluent API に登録することができません。 サポートされている組み込みの MLflow モデル フレーバーがないモデルを保存、ログに記録、登録する方法の例については、「サポートされていない機械学習モデルの登録」を参照してください。