記錄 MLflow 模型
本文說明如何將定型的模型 (或成品) 記錄為 MLflow 模型。 並探索如何自訂不同的 MLflow 封裝模型方式,以及其執行方式。
為何要記錄模型而不是成品?
從成品到 MLflow 中的模型描述與記錄 MLflow 模型相比,記錄成品或檔案之間的差異。
MLflow 模型也是成品。 但是,該模型具有特定結構,可作為模型建立者與想要使用模型者之間的合約。 此合約有助於在成品本身與其意義之間建立橋樑。
模型記錄具有下列優點:
- 您可以使用
mlflow.<flavor>.load_model
直接載入模型以進行推斷,而且可以使用predict
函式 - 管線輸入可以直接使用模型
- 無需指示評分指令碼或環境,您便可以部署模型
- Swagger 會自動在已部署的端點中啟用,而 Azure Machine Learning Studio 可以使用 Test 功能
- 您可以使用負責任的 AI 儀表板
本節說明如何在 Azure Machine Learning 中搭配 MLflow 使用模型的概念:
使用 autolog 記錄模型
您可以使用 MLflow autolog 功能。 Autolog 可讓 MLflow 指示相關聯架構,來記錄所有該架構視為相關的計量、參數、成品和模型。 根據預設,如果已啟用 autolog,則會記錄大部分的模型。 在某些情況下,某些變體可能不會記錄模型。 舉例來說,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)
提示
如果使用 Machine Learning 管線,例如 Scikit-Learn 管線,請使用該管線類別的 autolog
功能來記錄模型。 在管線物件上呼叫 fit()
方法時,模型記錄會自動開始。 使用 MLflow 筆記本訓練和追蹤 XGBoost 分類器 (英文) 會示範如何使用管線記錄含前置處理的模型。
記錄含有自訂簽章、環境或範例的模型
MLflow mlflow.<flavor>.log_model
方法可以手動記錄模型。 此工作流程可以控制模型記錄的不同層面。
使用此方法的時機:
- 您想要指出 pip 套件或 conda 環境與自動偵測到的項目不同
- 您想要包含輸入範例
- 您想要將特定成品包含在所需套件中
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)
# Signature
signature = infer_signature(X_test, y_test)
# Conda environment
custom_env =_mlflow_conda_env(
additional_conda_deps=None,
additional_pip_deps=["xgboost==1.5.2"],
additional_conda_channels=None,
)
# Sample
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 模型記錄。 自動 MLflow 模型記錄會在稍後進行,改為手動程序- 使用
infer_signature
方法嘗試直接從輸入和輸出推斷簽章 mlflow.utils.environment._mlflow_conda_env
方法是 MLflow SDK 中的隱藏方法。 在此範例中,它會讓程式碼更簡單,但請謹慎使用。 這在未來可能會變更。 或者,您可以手動產生 YAML 定義做為 Python 字典。
記錄在 predict 方法中具有不同行為的模型
使用 mlflow.autolog
或 mlflow.<flavor>.log_model
記錄模型時,模型類別會決定如何執行推斷,以及模型傳回的內容。 MLflow 不會依 predict
產生結果的方式強制執行任何特定行為。 某些情節中,您可能想要在執行模型之前和之後執行一些前置處理或後續處理。
此情況下,請實作機器學習管線,以從輸入直接移至輸出。 雖然此實作可行,有時也能夠改善效能,但要實現可能會有些困難。 在這些情況下,自訂模型處理推斷的方式會有所幫助 ,如下一節所述。
記錄自訂模型
MLflow 支援許多機器學習架構,包括
- CatBoost
- FastAI
- h2o
- Keras
- LightGBM
- MLeap
- MXNet Gluon
- ONNX
- Prophet
- PyTorch
- Scikit-Learn
- spaCy
- Spark MLLib
- statsmodels
- TensorFlow
- XGBoost
不過,您可能需要變更變體的運作方式、記錄 MLflow 原本不支援的模型,甚至記錄使用來自不同架構多個元素的模型。 在這類案例中,您可能需要建立自訂模型變體。
為了解決問題,MLflow 引進了 pyfunc
變體 (從 Python 函式開始)。 只要該物件符合兩個條件,這個變體就可以將任何物件記錄為模型:
- 您至少要實作
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):
# You don't have to keep the semantic meaning of `predict`. You can use here model.recommend(), model.forecast(), etc
return self._model.predict_proba(data)
# You can even add extra functions if you need to. Since the model is serialized,
# all of them will be available when you load your model back.
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
來推斷簽章。 我們的目標資料行具有目標類別,但模型現在卻傳回每個類別的兩個機率。