この記事では、トレーニング済みの機械学習モデルまたは成果物を MLflow モデルとしてログに記録する方法について説明します。 MLflow は、機械学習ワークフローを管理するためのオープンソース フレームワークです。 この記事では、MLflow がモデルをパッケージ化して実行する方法をカスタマイズするためのさまざまなオプションについて説明します。
[前提条件]
- MLflow SDK
mlflow
パッケージ
アーティファクトの代わりにモデルをログに記録する理由
MLflow モデルは成果物の一種です。 ただし、モデルには、モデルを作成するユーザーと使用するユーザーとの間のコントラクトとして機能する特定の構造があります。 このコントラクトは、成果物自体とその意味の間を橋渡しするために役立ちます。
アーティファクトまたはファイルのログ記録と MLflow モデルのログ記録の違いについては、 MLflow の成果物とモデルに関するページを参照してください。
モデルのファイルは成果物としてログに記録できますが、モデル ログには次の利点があります。
mlflow.<flavor>.load_model
を使用して推論用のモデルを直接読み込み、predict
関数を使用できます。- パイプライン入力では、モデルを直接使用できます。
- スコア付けスクリプトや環境を指定せずにモデルをデプロイできます。
- Swagger は、デプロイされたエンドポイントで自動的にオンになります。 その結果、Azure Machine Learning Studio のテスト機能を使用してモデルをテストできます。
- 責任ある AI ダッシュボードを使用できます。 詳細については、「 Azure Machine Learning Studio で責任ある AI ダッシュボードを使用する」を参照してください。
自動ログ記録を使用してモデルをログに記録する
MLflow autolog
機能を使用して、モデルを自動的にログに記録できます。 自動ログ記録を使用すると、MLflow は、フレームワーク内のすべての関連メトリック、パラメーター、成果物、およびモデルをキャプチャします。 ログに記録されるデータは、フレームワークによって異なります。 既定では、自動ログ記録が有効になっている場合、ほとんどのモデルがログに記録されます。 状況によっては、モデルをログに記録しないフレーバーもあります。 たとえば、PySpark フレーバーでは、特定のサイズを超えるモデルはログされません。
自動ログ記録をアクティブにするには、 mlflow.autolog
または mlflow.<flavor>.autolog
を使用します。 次のコードでは、 autolog
を使用して、XGBoost でトレーニングされた分類子モデルをログに記録します。
import mlflow
from xgboost import XGBClassifier
from sklearn.metrics import accuracy_score
mlflow.autolog()
model = XGBClassifier(use_label_encoder=False, eval_metric="logloss")
model.fit(X_train, y_train, eval_set=[(X_test, y_test)], verbose=False)
y_pred = model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
ヒント
scikit-learn パイプラインなどの機械学習パイプラインを使用する場合は、そのパイプラインフレーバーのautolog
機能を使用してモデルをログに記録します。 fit
メソッドがパイプライン オブジェクトで呼び出されると、モデル ログが自動的に実行されます。 モデルをログに記録し、前処理を含み、パイプラインを使用するノートブックについては、「 MLflow を使用した XGBoost 分類子のトレーニングと追跡」を参照してください。
カスタム署名、環境、またはサンプルを使用するログ モデル
MLflow mlflow.<flavor>.log_model
メソッドを使用して、モデルを手動でログに記録できます。 このワークフローでは、モデル ログのさまざまな側面を制御できます。
この方法は次のような場合に使用します。
- 自動的に検出されたパッケージまたは環境とは異なる Conda 環境または pip パッケージを指定する必要があります。
- 入力例を含める必要があります。
- 必要な特定の成果物をパッケージに含める必要があります。
autolog
メソッドがシグネチャを正しく推論しません。 このケースは、特定の図形を持つ署名が必要なテンソル入力を使用する場合に発生します。autolog
メソッドは、すべてのニーズを満たしているわけではありません。
次のコードは、XGBoost 分類子モデルをログに記録します。
import mlflow
from xgboost import XGBClassifier
from sklearn.metrics import accuracy_score
from mlflow.models import infer_signature
from mlflow.utils.environment import _mlflow_conda_env
mlflow.autolog(log_models=False)
model = XGBClassifier(use_label_encoder=False, eval_metric="logloss")
model.fit(X_train, y_train, eval_set=[(X_test, y_test)], verbose=False)
y_pred = model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
# Infer the signature.
signature = infer_signature(X_test, y_test)
# Set up a Conda environment.
custom_env =_mlflow_conda_env(
additional_conda_deps=None,
additional_pip_deps=["xgboost==1.5.2"],
additional_conda_channels=None,
)
# Sample the data.
input_example = X_train.sample(n=1)
# Log the model manually.
mlflow.xgboost.log_model(model,
artifact_path="classifier",
conda_env=custom_env,
signature=signature,
input_example=input_example)
注
autolog
の呼び出しでは、log_models=False
の構成が使用されます。 この設定により、MLflow モデルの自動ログ記録がオフになります。log_model
メソッドは、後でモデルを手動でログに記録するために使用されます。infer_signature
メソッドは、入力と出力から署名を直接推論するために使用されます。mlflow.utils.environment._mlflow_conda_env
メソッドは、MLflow SDK のプライベート メソッドです。 この例では、コードを効率化します。 ただし、この方法は将来変更される可能性があるため、注意して使用してください。 代わりに、YAML 定義を Python ディクショナリとして手動で生成できます。
変更された予測動作を使用するログ モデル
mlflow.autolog
またはmlflow.<flavor>.log_model
を使用してモデルをログに記録すると、モデルフレーバーによって推論の実行方法が決まります。 フレーバーによって、モデルが返す内容も決まります。 MLflow では、 predict
結果の生成に関する特定の動作は強制されません。 一部のシナリオでは、データの前処理または後処理が必要になる場合があります。
このような状況では、入力から出力に直接移動する機械学習パイプラインを実装できます。 この種の実装ではパフォーマンスが向上することがありますが、実現するのは困難な場合があります。 このような場合は、モデルが推論を処理する方法をカスタマイズすると便利です。 詳細については、次のセクション「 カスタム モデルのログ記録」を参照してください。
カスタム モデルをログに記録する
MLflow では、次のような多くの機械学習フレームワークがサポートされています。
- CatBoost
- FastAI
- H₂O
- Keras
- LightGBM
- MLeap
- ONNX
- 予言者
- PyTorch
- scikit-learn(サイキット・ラーン)
- spaCy
- Spark MLlib
- statsmodels(スタッツモデルズ)
- TensorFlow
- XGBoost
完全な一覧については、「 モデルフレーバーBuilt-In 参照してください。
ただし、フレーバーの動作方法を変更したり、MLflow でネイティブにサポートされていないモデルをログに記録したりする必要がある場合があります。 または、さまざまなフレームワークの複数の要素を使用するモデルをログに記録する必要がある場合があります。 このような場合は、カスタム モデル フレーバーを作成できます。
この問題を解決するために、MLflow は Python モデルの既定のモデル インターフェイスである PyFunc フレーバーを提供します。 このフレーバーは、そのオブジェクトが次の 2 つの条件を満たしている限り、任意のオブジェクトをモデルとしてログに記録できます。
- 少なくとも
predict
メソッドを実装します。 - Python オブジェクトは、
mlflow.pyfunc.PythonModel
クラスから継承します。
ヒント
scikit-learn API を実装するシリアル化可能なモデルでは、scikit-learn を使用してモデルが構築されたかどうかに関係なく、scikit-learn フレーバーを使用してモデルをログに記録できます。 Pickle 形式でモデルを保持でき、オブジェクトに少なくとも predict
メソッドと predict_proba
メソッドがある場合は、 mlflow.sklearn.log_model
を使用して MLflow 実行内でモデルをログに記録できます。
カスタム モデルのフレーバーを作成する最も簡単な方法は、既存のモデル オブジェクトのラッパーを作成することです。 MLflow はモデルをシリアル化してパッケージ化します。 Python オブジェクトは、オブジェクトをファイル システムにファイル (通常は Pickle 形式) として格納できる場合、シリアル化できます。 実行時に、そのファイルからオブジェクトを読み込むことができます。 読み込みでは、保存時に使用できるすべての値、プロパティ、およびメソッドが復元されます。
この方法は次のような場合に使用します。
- Pickle 形式でモデルをシリアル化できます。
- トレーニング直後のモデルの状態を維持する必要があります。
predict
関数の動作をカスタマイズしたい。
次のコードは、XGBoost フレーバーの既定の実装とは動作が異なるように、XGBoost で作成されたモデルをラップします。 クラスの代わりに確率が返されます。
from mlflow.pyfunc import PythonModel, PythonModelContext
class ModelWrapper(PythonModel):
def __init__(self, model):
self._model = model
def predict(self, context: PythonModelContext, data):
# The next line uses a prediction function. However, you could also use model.recommend(), model.forecast(), or a similar function instead.
return self._model.predict_proba(data)
# You can add extra functions if you need to. Because the model is serialized,
# all of them are available when you load your model.
def predict_batch(self, data):
pass
実行中にカスタム モデルをログに記録するには、次のコードを使用します。
import mlflow
from xgboost import XGBClassifier
from sklearn.metrics import accuracy_score
from mlflow.models import infer_signature
mlflow.xgboost.autolog(log_models=False)
model = XGBClassifier(use_label_encoder=False, eval_metric="logloss")
model.fit(X_train, y_train, eval_set=[(X_test, y_test)], verbose=False)
y_probs = model.predict_proba(X_test)
accuracy = accuracy_score(y_test, y_probs.argmax(axis=1))
mlflow.log_metric("accuracy", accuracy)
signature = infer_signature(X_test, y_probs)
mlflow.pyfunc.log_model("classifier",
python_model=ModelWrapper(model),
signature=signature)
ヒント
前のコードでは、 infer_signature
メソッドは y_probs
を使用してシグネチャを推論します。 ターゲット列にはターゲット クラスが含まれていますが、モデルはクラスごとに 2 つの確率を返します。