MLflow2.0: MLflow1.xよりの重要な変更点、主要な機能の追加と改良

:::note warn
本書は自分の理解を含めて<a href="https://mlflow.org/news/2022/11/14/2.0.1-release/index.html" target="_blank">MLflow 2.0.1のリリースノート</a>に基づいて作成したものです。正確な内容に関しては原文を参照ください。
:::

MLflowの2.0.1バージョンは、エンドツーエンドのMLOpsワークフローの管理の簡素化、新機能の提供、production-readyのMLOps機能の拡張に焦点を当てた、大きなマイルストーンとなるリリースです。MLflow 2.0の<a href="https://www.databricks.com/blog/2022/11/15/announcing-availability-mlflow-20.html" target="_blank">Databricks MLflow 2.0ブログ記事</a>（<a href="https://www.linuxfoundation.org/blog/announcing-availability-of-mlflow-2.0" target="_blank">Linux FoundationのオープンソースMLflow 2.0 ブログ記事</a>）で、詳細な解説をご覧ください。

このリリースには、1.xAPIよりいくつかの重要な変更点、主要な機能の追加と改良が含まれています。

## 機能の追加と改良

### MLflow Recipes

- MLflow PipelinesをMLflow Recipesに改名しました。MLflow Recipesはデータサイエンティストが高品質のモデルを迅速に開発し、本番環境にデプロイするためのフレームワークです。詳細は、以下のビデオとドキュメントをご覧ください。
:::note info
- <a href="https://mlflow.org/docs/latest/recipes.html" target="_blank">MLflow Recipesのドキュメント</a>
- <a href="https://player.vimeo.com/video/771204653?h=81ec9bc89e&badge=0&autopause=0&player_id=0&app_id=58479" target="_blank">デモビデオ</a>
:::

- MLflow Recipesに分類モデル構築のサポートを追加しました。
:::note info
- 回帰問題の場合、<a href="https://github.com/mlflow/recipes-regression-template" target="_blank">recipes-regression-template</a>をご使用ください。
- 分類問題の場合、<a href="https://github.com/mlflow/recipes-classification-template" target="_blank">recipes-classification-template</a>をご使用ください。
:::

### UI
- 実験UIで、ランのピン留めのサポートを追加しました。
- 実験UIの表示を簡素化し、メトリクス、パラメータ、タグのカスタマイズした表示を提供しました。
- 実験UIでランのフィルタリングとランのランキングを簡単化しました。

### Tracking
- モデルが参照するrequirementファイルをgetするように`mlflow.pyfunc.get_model_dependencies()`を更新しました。
:::note info
- <a href="https://www.mlflow.org/docs/latest/python_api/mlflow.pyfunc.html#mlflow.pyfunc.get_model_dependencies" target="_blank">mlflow.pyfunc.get_model_dependencies(model_uri, format='pip')</a>
:::

- `mlflow.tensorflow.autolog()`でKerasモデルの`save_format`を選択できるようにサポートします。
:::note info
- <a href="https://www.mlflow.org/docs/latest/python_api/mlflow.tensorflow.html#mlflow.tensorflow.autolog" target="_blank">mlflow.tensorflow.autolog()</a>のkeras_model_kwargs引数にsave_formatを'tf'あるいは'h5'を指定して、Kerasモデルのsave_model（save）メソッドに渡すことができるようになりました。
:::

### Models 
- `mlflow.evaluate()`が安定なproduction-ready APIになりました。
:::note info 
mlflow.evaluate(model: str, data, *, targets, model_type: str, dataset_path=None, feature_names: Optional[list] = None, evaluators=None, evaluator_config=None, custom_metrics=None, custom_artifacts=None, validation_thresholds=None, baseline_model=None, env_manager='local')
:::
- `mlflow.evaluate()`によるモデル評価時にカスタムメトリクスやカスタム成果物を指定するためのAPIを簡素化しました。
:::note info
カスタマメトリクスの使用例：
```
import mlflow
import numpy as np

def root_mean_squared_error(eval_df, _builtin_metrics):
    return np.sqrt((np.abs(eval_df["prediction"] - eval_df["target"]) ** 2).mean)

rmse_metric = mlflow.models.make_metric(
    eval_fn=root_mean_squared_error,
    greater_is_better=False,
)
mlflow.evaluate(..., custom_metrics=[rmse_metric])
```
:::

:::note info
カスタム成果物の使用例：
```
import mlflow
import matplotlib.pyplot as plt

def scatter_plot(eval_df, builtin_metrics, artifacts_dir):
    plt.scatter(eval_df['prediction'], eval_df['target'])
    plt.xlabel('Targets')
    plt.ylabel('Predictions')
    plt.title("Targets vs. Predictions")
    plt.savefig(os.path.join(artifacts_dir, "example.png"))
    plt.close()
    return {"pred_target_scatter": os.path.join(artifacts_dir, "example.png")}

def pred_sample(eval_df, _builtin_metrics, _artifacts_dir):
    return {"pred_sample": pred_sample.head(10)}

mlflow.evaluate(..., custom_artifacts=[scatter_plot, pred_sample])
```
:::

- `mlflow.evaluate()`で二値分類モデルを評価する場合、正例ラベルを使用することになりました。
- `mlflow.tensorflow.autolog()`が有効にするときにデフォルトでtensorflowとkerasモデルのsignatureの自動ロギングを有効になります。
:::note info
mlflow.tensorflow.autolog(every_n_iter=1, log_models=True, disable=False, exclusive=False, disable_for_unsupported_versions=False, silent=False, registered_model_name=None, log_input_examples=False, **log_model_signatures=True**, saved_model_kwargs=None, keras_model_kwargs=None)
:::

- `mlflow.tensorflow`でKerasとTensorflowのネイティブのCoreモデルをサポートします。
:::note info
`mlflow.tensorflow.load_model(model_uri, dst_path=None, saved_model_kwargs=None, keras_model_kwargs=None)`でtensorflow2コアモデルとKerasコアモデルをロードできるようになりました。
:::

- `mlflow.xgboost.save_model()`/`log_model()`で`model_format`を定義するようになりました。
:::note info
mlflow.xgboost.save_model(xgb_model, path, conda_env=None, code_paths=None, mlflow_model=None, signature: mlflow.models.signature.ModelSignature = None, input_example: Union[pandas.core.frame.DataFrame, numpy.ndarray, dict, list, csr_matrix, csc_matrix] = None, pip_requirements=None, extra_pip_requirements=None, `model_format='xgb'`)

mlflow.xgboost.log_model(xgb_model, artifact_path, conda_env=None, code_paths=None, registered_model_name=None, signature: mlflow.models.signature.ModelSignature = None, input_example: Union[pandas.core.frame.DataFrame, numpy.ndarray, dict, list, csr_matrix, csc_matrix] = None, await_registration_for=300, pip_requirements=None, extra_pip_requirements=None, `model_format=None`, **kwargs)
:::

### Scoring
- モデルスコアリングREST APIを改良し、入力にフォーマットのindicatorsを導入し、複数の出力フィールドをサポートします。
:::note info
<a href="https://qiita.com/sphereSky/items/d6fec52c282eb0396b0e" target="_blank">MLflow2.0: Classical Model ServingにおけるスコアリングAPIのアップデート</a>をご参照ください。
:::
- モデルのSignatureに不規則配列（ragged array）をサポートします。
### Java 
- Javaクライアントに`getModelVersion`APIを追加しました。

## 重要な変更点
以下の変更点リストは、各カテゴリーの中で重要度の高い順に並べたものです。
### Core 
- Python 3.7 のサポートは終了しました。MLflow には Python >=3.8が必要です。
### MLflow Recipes
- `mlflow.pipelines`のAPIは`mlflow.recipes`に置き換わりました。
### Tracking / Registry
- TrackingとModel RegistryのREST APIの/previewルートを削除しました。
### Tracking
- Python、Java、R、REST APIから実験、モデル、実行の非推奨のリストAPIを削除しました。
:::note info
- `list_experiments()`の代わりに`search_experiments()`を使用 
- `list_run_infos()`の代わりに`search_runs()`を使用 
- `list_registered_models()`の代わりに`search_registered_models()`を使用
:::
- Get Experiment REST APIのレスポンスから非推奨のrunsに関するレスポンスフィールドを削除しました。
- 非推奨の`MlflowClient.download_artifacts`APIを削除しました。
- `MLFLOW_EXPERIMENT_NAME`に関する環境変数の取り扱いを変更し、実験作成時に常にその値が使用されるようにしました。
:::note info
**変更前:**
環境変数の`experiment_name`または`experiment_id`が追跡サーバーに存在しない場合は、デフォルトの`experiment_id`を使用します。

**変更後:**
アクティブな実験が存在する場合は、その実験を使用します (環境変数を無視します)。
存在しない場合は：
- 環境変数で`experiment_name`が指定されている場合は、`experiment_name`が追跡サーバーに存在することを確認します。`experiment_name`が存在しないない場合は、例外が発生します。
- `experiment_name`と`experiment_id`の両方が指定されている場合は、`experiment_name`が追跡サーバーに登録されていること、および追跡サーバーからの`experiment_id`が環境変数`experiment_id`と一致していることを確認します。そうでない場合は、例外が発生します。
- `experiment_id`が指定されている場合は、追跡サーバーに登録されているかを検証します。登録されていない場合は、環境変数が問題の原因であることを説明するカスタム例外が発生します (`experiment_id`が見つからないという一般的な追跡サーバーの例外ではありません)。
:::
- mlflowサーバがデフォルトで`--serve-artifacts`モードで実行されるように更新しました。
- スレッドセーフな並行処理を可能にするため、Filestoreバックエンドの実験 IDの生成を更新しました。
:::note info
FileStore内の`experiment_id`の生成を、スレッドセーフではない単調増加のidの値から、固定長のランダムなint64の値に変更しました。
:::
- `mlflow.evaluate()`のメトリックキーから`dataset_name`と`on_data_{name | hash}`サフィックスを削除しました。

### モデル/ Scoring / プロジェクト
- モデルの推論とプロジェクトの実行において、デフォルトの環境マネージャーを`conda`から`virtualenv`に変更しました。
:::note info
- モデル環境を復元するときは、デフォルトで`virtualenv`を使用します。
- MLプロジェクトを実行するときは、デフォルトで`virtualenv`を使用します。
:::

### Models
- KerasのモデルロギングAPIを`mlflow.tensorflow`のフレーバーに移動し、`TensorFlow Estimators`のサポートを終了した。
:::note info
mlflow.tensorflow.log_model(model, artifact_path, custom_objects=None, conda_env=None, code_paths=None, signature: mlflow.models.signature.ModelSignature = None, input_example: Union[pandas.core.frame.DataFrame, numpy.ndarray, dict, list, csr_matrix, csc_matrix] = None, registered_model_name=None, await_registration_for=300, pip_requirements=None, extra_pip_requirements=None, saved_model_kwargs=None, **keras_model_kwargs=None**)
:::
- 非推奨の`mlflow.sklearn.eval_and_log_metrics()`APIを削除し、代わりに`mlflow.evaluate()`APIをサポートします。
- `mlflow.evaluate()`のモデル入力にURIを指定することを必須となりました。 
- `mlflow.evaluate()`を使用したときに同じ関数からカスタムメトリックと成果物を返すサポートを終了し、`custom_artifacts`を使用するようになりました。
- PyFuncModel仕様を拡張して`conda`と`virtualenv`のサブフィールドをサポートします。

### Scoring
- `Content-Type`ヘッダを使った入力フォーマットの定義のサポートを終了しました。
- ネイティブサービングのCLIオプション引数 `--no-conda`を`--env-manager='local'`に置き換えました。
- mlflow.sagemaker.deploy()とmlflow.sagemaker.delete()の公開APIを削除し、mlflow deployments -t sagemakerのようなMLflow deployments APIsを採用しました。
:::note info
`mlflow.sagemaker.deploy() & mlflow.sagemaker.delete()` の代わりに、`mlflow.deployments.get_deployment_client('sagemaker')` (SageMakerDeploymentClient) を使用することになりました。
:::
- mlflow.deployments.predict()メソッドの入力引数dfをinputsにリネームしました。
:::note info
`abstractpredict(deployment_name=None, inputs=None, endpoint=None)[source]`
:::

### Projects
- MLflow Projectsの実行CLIコマンドのuse_conda引数をenv_manager引数に置き換えました。
- MLflow Projectsのdockerイメージのビルドのオプションを変更し、`--skip-image-build`を`--build-image`に変更し、デフォルトを**False**にしました。
 
### Integrations/Azure 
- 非推奨のmlflow.azuremlモジュールをMLflowから削除し、azure-mlflowのデプロイメント・プラグインを採用しました。
:::note info
参考：https://learn.microsoft.com/en-us/azure/machine-learning/how-to-deploy-mlflow-models?tabs=fromjob%2Cmir%2Ccli
:::
### R
- Rクライアントとのcondaの統合を削除しました。

## バグの修正
- 【Recipes】プロファイルカードポリフィル（profile cards polyfill）のレンダリングに関する問題を修正しました。
- 【トラッキング】`MLflow.start_run()`のtags引数にMLflow Run名を指定すると、正しく設定できました。
- 【Tracking】`mlflow.runName`タグが設定されていて、MLflowのRun名の割り当てが競合する場合の問題を修正しました。
- 【Scoring】SageMakerデプロイメントのクライアント`predict()`API の不正なペイロード・コンストラクタ・エラー（payload constructor error）を修正しました。
- 【Scoring】Sagemakerのデプロイメントを更新する際に`DataCaptureConfig`の情報が保存されない問題を修正しました。

詳細の変更点の一覧は、<a href="https://github.com/mlflow/mlflow/releases/tag/v2.0.1" target="_blank">リリースの変更履歴</a>を参照し、mlflow.orgの最新ドキュメントを確認ください。