MLflow での成果物からモデルまで

この記事では、MLflow 成果物と MLflow モデルの違いと、そのどちらかから他方に移行する方法について説明します。 また、Azure Machine Learning で MLflow モデルの概念を使って合理化されたデプロイ ワークフローを実現する方法についても説明します。

成果物とモデルの違いは何ですか?

MLflow に慣れていない場合、成果物またはファイルのログと MLflow モデルのログの違いを意識していないかもしれません。 これら 2 つには基本的な違いはありません。

Artifact

"成果物" とは、実験の実行またはジョブから生成された (および取り込まれた) ファイルです。 成果物は、pickle ファイルとしてシリアル化されたモデル、PyTorch または TensorFlow モデルの重み、または線形回帰の係数を含むテキスト ファイルを表す場合があります。 モデル自体とは何の関係もない成果物もあります。さらに、モデルを実行するための構成、前処理情報、サンプル データなどが含まれる場合もあります。 成果物にはさまざまな形式があります。

既に成果物をログしている可能性があります。

filename = 'model.pkl'
with open(filename, 'wb') as f:
  pickle.dump(model, f)

mlflow.log_artifact(filename)

モデル

MLflow の "モデル" も成果物です。 ただし、この種の成果物については、より強力な前提条件があります。 このような仮定は、保存されたファイルとその意味との間に明確なコントラクトを提供します。 モデルを成果物 (単純なファイル) としてログする場合は、モデルをどのように読み込んで推論するかを理解するには、モデル ビルダーがこれらの各ファイルに対して何を意図していたかを把握する必要があります。 一方、MLflow モデルは、MLModel 形式で指定したコントラクトを使って読み込むことができます。

Azure Machine Learning では、ログ モデルには次の利点があります。

  • スコアリング スクリプトや環境を用意することなく、リアルタイムまたはバッチ エンドポイントにデプロイできます。
  • モデルをデプロイすると、そのデプロイによって Swagger が自動的に生成され、Azure Machine Learning スタジオでテスト機能を使用できるようになります。
  • モデルはパイプラインの入力として直接使用できます。
  • モデルには責任ある AI ダッシュボードを使用できます。

MLflow SDK を使ってモデルをログすることができます。

import mlflow
mlflow.sklearn.log_model(sklearn_estimator, "classifier")

MLmodel 形式

MLflow では、成果物とそれらが表すものの間にコントラクトを作成する方法として MLmodel 形式を採用しています。 MLmodel 形式では、フォルダーに資産が保存されます。 これらの資産の中には、MLmodel という名前のファイルがあります。 このファイルは、モデルを読み込んで使用する方法に関する唯一の情報源です。

次のスクリーンショットは、Azure Machine Learning スタジオ内のサンプル MLflow モデルのフォルダーを示しています。 モデルは credit_defaults_model というフォルダーに配置されます。 このフォルダーの名前付けに関する特定の要件はありません。 このフォルダーには、他のモデル成果物と共に MLmodel ファイルが格納されています。

A screenshot showing assets of a sample MLflow model, including the MLmodel file.

次のコードは、fastai を使ってトレーニングされたコンピューター ビジョン モデルの MLmodel ファイルがどのようになるかを示す例では。

MLmodel

artifact_path: classifier
flavors:
  fastai:
    data: model.fastai
    fastai_version: 2.4.1
  python_function:
    data: model.fastai
    env: conda.yaml
    loader_module: mlflow.fastai
    python_version: 3.8.12
model_uuid: e694c68eba484299976b06ab9058f636
run_id: e13da8ac-b1e6-45d4-a9b2-6a0a5cfac537
signature:
  inputs: '[{"type": "tensor",
             "tensor-spec": 
                 {"dtype": "uint8", "shape": [-1, 300, 300, 3]}
           }]'
  outputs: '[{"type": "tensor", 
              "tensor-spec": 
                 {"dtype": "float32", "shape": [-1,2]}
            }]'

モデル フレーバー

MLflow では、使用できる多数の機械学習フレームワークを考慮し、すべての機械学習フレームワークに対して機能する独自のコントラクトを提供する方法として、"フレーバー" の概念を導入しました。 フレーバーは、特定のフレームワークで作成された特定のモデルに対して想定されることを示します。 たとえば、TensorFlow には独自のフレーバーがあり、TensorFlow モデルを永続化して読み込む方法を指定します。 特定のフレームワークのモデルを永続化して読み込む方法は各モデル フレーバーで示すので、MLmodel 形式では、すべてのモデルがサポートする必要がある 1 つのシリアル化メカニズムが強制されません。 この決定により、各フレーバーは、MLmodel 標準との互換性を損なうことなく、ベスト プラクティスに従って最適なパフォーマンスまたは最適なサポートを提供するメソッドを使用できます。

次のコードは、fastai モデルの flavors セクションの一例です。

flavors:
  fastai:
    data: model.fastai
    fastai_version: 2.4.1
  python_function:
    data: model.fastai
    env: conda.yaml
    loader_module: mlflow.fastai
    python_version: 3.8.12

モデル シグネチャ

MLflow のモデル シグネチャは、モデルとモデルを実行しているサーバー間のデータ コントラクトとして機能するため、モデルの仕様の重要な部分を占めています。 モデル シグネチャは、デプロイ時にモデルの入力の種類を解析して適用する場合にも重要です。 シグネチャを使用できる場合、データがモデルに送信されるときに、MLflow によって入力の種類が適用されます。 詳細については、MLflow シグネチャの適用に関する記事を参照してください。

シグネチャはモデルがログされるときに示され、MLmodel ファイルの signature セクションに保持されます。 MLflow の自動ログ機能は、ベスト エフォートの方法で自動的にシグネチャを推論します。 ただし、推論されたシグネチャが必要なものではない場合は、必要に応じてモデルを手動でログします。 詳細については、「How to log models with signatures」(シグネチャを使ってモデルをログする方法) を参照してください。

シグネチャには、2 つの種類があります。

  • 列ベースのシグネチャ: このシグネチャは表形式データに対して機能します。 この種のシグネチャを持つモデルの場合、MLflow は pandas.DataFrame オブジェクトを入力として提供します。
  • テンソルベースのシグネチャ: このシグネチャは n 次元配列またはテンソルに対して機能します。 このシグネチャを持つモデルの場合、MLflow は、numpy.ndarray (または名前付きテンソルの場合は numpy.ndarray の辞書) を入力として提供します。

次の例は、fastai でトレーニングされたコンピューター ビジョン モデルに対応しています。 このモデルは、シェイプ (300, 300, 3) のテンソルとして表される画像のバッチとそれらの RGB 表現 (符号なし整数) を受け取ります。 このモデルにより、2 つのクラスの予測 (確率) のバッチが出力されます。

MLmodel

signature:
  inputs: '[{"type": "tensor",
             "tensor-spec": 
                 {"dtype": "uint8", "shape": [-1, 300, 300, 3]}
           }]'
  outputs: '[{"type": "tensor", 
              "tensor-spec": 
                 {"dtype": "float32", "shape": [-1,2]}
            }]'

ヒント

Azure Machine Learning により、シグネチャが使用できる MLflow モデルのデプロイ用の swagger ファイルが生成されます。 その結果、Azure Machine Learning スタジオを使ったデプロイのテストが簡単になります。

モデル環境

実行するモデルの要件は、conda.yaml ファイルで指定されます。 MLflow を使って依存関係を自動的に検出することや、mlflow.<flavor>.log_model() メソッドを呼び出して手動で依存関係を示すことができます。 後者は、環境に含まれているライブラリが使う予定のものではない場合に役立ちます。

次のコードは、fastai フレームワークで作成されたモデルに使う環境の一例です。

conda.yaml

channels:
- conda-forge
dependencies:
- python=3.8.5
- pip
- pip:
  - mlflow
  - astunparse==1.6.3
  - cffi==1.15.0
  - configparser==3.7.4
  - defusedxml==0.7.1
  - fastai==2.4.1
  - google-api-core==2.7.1
  - ipython==8.2.0
  - psutil==5.9.0
name: mlflow-env

Note

MLflow 環境と Azure Machine Learning 環境の違いは何ですか?

"MLflow 環境" はモデルのレベルで機能しますが、"Azure Machine Learning 環境" はワークスペース (登録済み環境の場合) またはジョブおよびデプロイ (匿名環境の場合) レベルで機能します。 Azure Machine Learning に MLflow モデルをデプロイすると、モデルの環境がビルドされ、デプロイに使用されます。 または、この動作を Azure Machine Learning CLI v2 でオーバーライドし、特定の Azure Machine Learning 環境を使って MLflow モデルをデプロイすることもできます。

Predict 関数

すべての MLflow モデルには、predict 関数が含まれています。 この関数は、コードなしのデプロイ エクスペリエンスを使ってモデルをデプロイするときに呼び出されますpredict 関数から返される内容 (たとえば、クラス、確率、予測など) は、トレーニングに使われたフレームワーク (つまり、フレーバー) によって変わります。 各フレーバーのドキュメントを参照して、返される内容を確認してください。

同じケースの場合、必要に応じてこの predict 関数をカスタマイズして推論の実行方法を変更します。 そのような場合は、predict メソッドで別の動作のモデルをログするか、カスタム モデルのフレーバーをログする必要があります。

MLflow モデルを読み込むためのワークフロー

MLflow モデルとして作成されたモデルは、次のような複数の場所から読み込むことができます。

  • モデルがログされた実行から直接
  • モデルが保存されているファイル システムから
  • モデルが登録されているモデル レジストリから。

MLflow は、場所に関係なく、これらのモデルを読み込む一貫した方法を提供します。

モデルの読み込みに使用できるワークフローは 2 つあります:

  • ログされたものと同じオブジェクトと型を読み込む: MLflow SDK を使ってモデルを読み込み、トレーニング ライブラリに属する型のモデルのインスタンスを取得できます。 たとえば、ONNX モデルは ModelProto を返しますが、scikit-learn を使ってトレーニングされたデシジョン ツリー モデルは DecisionTreeClassifier オブジェクトを返します。 mlflow.<flavor>.load_model() を使って、ログされたものと同じモデル オブジェクトと型を読み込みます。

  • 推論を実行するためのモデルを読み込む: MLflow SDK を使ってモデルを読み込み、predict 関数の存在を MLflow が保証するラッパーを取得できます。 どのフレーバーを使っているかは関係ありません。すべての MLflow モデルに predict 関数があります。 さらに、(モデルのシグネチャに応じて) pandas.DataFramenumpy.ndarray、または dict[string, numpyndarray] 型の引数を使ってこの関数を呼び出せることは MLflow で保証されています。 MLflow により、モデルで想定される入力の型への型変換が処理されます。 mlflow.pyfunc.load_model() を使って、推論を実行するためのモデルを読み込みます。