Protokollieren von MLflow-Modellen

In diesem Artikel wird beschrieben, wie Sie Ihre trainierten Modelle (oder Artefakte) als MLflow-Modelle protokollieren. Es werden verschiedene Methoden untersucht, die Art und Weise anzupassen, wie MLflow Ihre Modelle verpackt und ausführt.

Warum Protokollierung von Modellen statt von Artefakten?

Von Artefakten zu Modellen in MLflow beschreibt den Unterschied zwischen Protokollierungsartefakten oder -dateien im Vergleich zur Protokollierung von MLflow-Modellen.

Ein MLflow-Modell ist auch ein Artefakt. Dieses Modell verfügt jedoch über eine bestimmte Struktur, die als Vertrag zwischen der Person, die das Modell erstellt hat, und der Person, die es verwenden möchte, dient. Dieser Vertrag hilft dabei, eine Brücke zwischen den Artefakten selbst und ihren Bedeutungen aufzubauen.

Die Modellprotokollierung bietet folgende Vorteile:

  • Sie können Modelle direkt für Rückschlüsse mit mlflow.<flavor>.load_model laden, und Sie können die Funktion predict verwenden.
  • Pipelineeingaben können Modelle direkt verwenden.
  • Sie können Modelle ohne Angabe eines Bewertungsskripts oder einer Umgebung bereitstellen.
  • Swagger wird automatisch in bereitgestellten Endpunkten aktiviert, und das Azure Machine Learning Studio kann das Feature Testen verwenden.
  • Sie können das Dashboard für verantwortungsvolle KI verwenden.

In diesem Abschnitt wird beschrieben, wie Sie das Konzept des Modells in Azure Machine Learning mit MLflow verwenden:

Protokollierung von Modellen mithilfe von Autolog

Sie können die Funktion für die automatische Protokollierung von MLflow verwenden. Mit der automatischen Protokollierung kann MLflow das Framework anweisen, alle Metriken, Parameter, Artefakte und Modelle zu protokollieren, die das Framework als relevant erachtet. Wenn die automatische Protokollierung aktiviert ist, werden die meisten Modelle standardmäßig protokolliert. In einigen Situationen protokollieren einige Varianten möglicherweise kein Modell. Beispielsweise protokolliert die PySpark-Variante keine Modelle, die eine bestimmte Größe überschreiten.

Verwenden Sie entweder mlflow.autolog() oder mlflow.<flavor>.autolog(), um die automatische Protokollierung zu aktivieren. In diesem Beispiel wird autolog() zum Protokollieren eines mit XGBoost trainierten Klassifizierermodells verwendet:

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)

Tipp

Wenn Sie Machine Learning-Pipelines verwenden, z. B. Scikit-Learn-Pipelines, verwenden Sie die autolog-Funktionalität dieser Pipelinevariante zum Protokollieren von Modellen. Modelle werden automatisch protokolliert, wenn die Methode fit() für das Pipelineobjekt aufgerufen wird. Das Notebook Trainieren und Nachverfolgen eines XGBoost-Klassifizierers mit MLflow zeigt, wie ein Modell mit Vorverarbeitung mithilfe von Pipelines protokolliert wird.

Protokollierung von Modellen mit benutzerdefinierten Signaturen, Umgebungen oder Beispielen

Die MLflow-Methode mlflow.<flavor>.log_model kann manuell Modelle protokollieren. Dieser Workflow kann verschiedene Aspekte der Modellprotokollierung steuern.

Verwenden Sie diese Methode unter folgenden Bedingungen:

  • Sie möchten PIP-Pakete oder eine Conda-Umgebung angeben, die sich von denen unterscheiden, die automatisch erkannt werden.
  • Sie möchten Eingabebeispiele einschließen.
  • Sie möchten bestimmte Artefakte in das erforderliche Paket einschließen.
  • Ihre Signatur wird nicht ordnungsgemäß von autolog abgeleitet. Dies ist wichtig, wenn Sie mit Tensoreingaben umgehen, bei denen die Signatur eine bestimmte Form haben muss.
  • Das Verhalten der automatischen Protokollierung deckt Ihren Zweck aus irgendeinem Grund nicht ab.

In diesem Beispielcode wird ein Modell für einen XGBoost-Klassifizierer protokolliert:

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)

Hinweis

  • autolog weist die Konfiguration log_models=False auf. Dadurch wird die automatische MLflow-Modellprotokollierung verhindert. Die automatische MLflow-Modellprotokollierung erfolgt später als manueller Prozess.
  • Verwenden Sie die Methode infer_signature, um die Signatur direkt von Eingaben und Ausgaben abzuleiten.
  • Die Methode mlflow.utils.environment._mlflow_conda_env ist eine private Methode im MLflow SDK. In diesem Beispiel wird der Code damit einfacher, verwenden Sie sie aber mit Vorsicht. Sie kann in Zukunft geändert werden. Alternativ können Sie die YAML-Definition manuell als Python-Wörterbuch generieren.

Protokollieren von Modellen mit einem anderen Verhalten in der Prognosemethode

Bei der Protokollierung eines Modells mit mlflow.autolog oder mlflow.<flavor>.log_model bestimmt die Modellvariante, wie der Rückschluss ausgeführt wird und was das Modell zurückgibt. MLflow erzwingt kein bestimmtes Verhalten zur Generierung von predict-Ergebnissen. In einigen Szenarien sollten Sie jedoch vor und nach der Ausführung des Modells einige Vorverarbeitungen oder Nachbearbeitungen durchführen.

Implementieren Sie in dieser Situation Machine Learning-Pipelines, die direkt von Eingaben zu Ausgaben wechseln. Obwohl diese Implementierung möglich und manchmal ratsam ist, um die Leistung zu verbessern, kann die Umsetzung schwierig werden. In diesen Fällen kann es hilfreich sein, anzupassen, wie Ihr Modell Rückschlüsse behandelt, wie im nächsten Abschnitt erläutert.

Protokollierung benutzerdefinierter Modelle

MLflow unterstützt viele Machine Learning Frameworks, einschließlich

  • CatBoost
  • FastAI
  • h2o
  • Keras
  • LightGBM
  • MLeap
  • MXNet Gluon
  • ONNX
  • Prophet
  • PyTorch
  • Scikit-Learn
  • spaCy
  • Spark MLLib
  • statsmodels
  • TensorFlow
  • XGBoost

Möglicherweise müssen Sie die Funktionsweise einer Variante ändern, ein von MLflow nicht nativ unterstütztes Modell protokollieren oder sogar ein Modell protokollieren, das mehrere Elemente aus verschiedenen Frameworks verwendet. In diesen Fällen müssen Sie ggf. eine benutzerdefinierte Modellvariante erstellen.

Um das Problem zu lösen, führt MLflow die Variante pyfunc ein (ausgehend von einer Python-Funktion). Diese Variante kann jedes Objekt als Modell protokollieren, sofern dieses Objekt zwei Bedingungen erfüllt:

  • Sie implementieren die Methode predict (mindestens).
  • Das Python-Objekt erbt von mlflow.pyfunc.PythonModel.

Tipp

Serialisierbare Modelle, die die Scikit-learn-API implementieren, können unabhängig davon, ob das Modell mit Scikit-learn erstellt wurde, die Scikit-learn-Variante verwenden, um das Modell zu protokollieren. Wenn Ihr Modell im Pickle-Format beibehalten werden kann, und das Objekt (mindestens) die Methoden predict() und predict_proba() aufweist, können Sie mlflow.sklearn.log_model() verwenden, um es in einer MLflow-Ausführung zu protokollieren.

Wenn Sie einen Wrapper um Ihr vorhandenes Modellobjekt erstellen, wird es am einfachsten, eine Variante für Ihr benutzerdefiniertes Modell zu erstellen. MLflow serialisiert und verpackt es für Sie. Python-Objekte sind serialisierbar, wenn das Objekt als Datei im Dateisystem gespeichert werden kann (im Allgemeinen im Pickle-Format). Zur Laufzeit kann das Objekt aus dieser Datei materialisiert werden. Dadurch werden alle Werte, Eigenschaften und Methoden wiederhergestellt, die beim Speichern verfügbar waren.

Verwenden Sie diese Methode unter folgenden Bedingungen:

  • Sie können Ihr Modell im Pickle-Format serialisieren.
  • Sie möchten den Zustand des Modells beibehalten, wie er unmittelbar nach dem Training war.
  • Sie möchten die Funktionsweise der Funktion predict anpassen.

In diesem Codebeispiel wird ein Modell umschlossen, das mit XGBoost erstellt wurde, damit es sich anders verhält als die Standardimplementierung der XGBoost-Variante. Stattdessen werden die Wahrscheinlichkeiten statt der Klassen zurückgegeben:

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

Protokollieren Sie ein benutzerdefiniertes Modell bei der Ausführung:

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)

Tipp

Hier verwendet die Methode infer_signaturey_probs, um die Signatur abzuleiten. Unsere Zielspalte hat die Zielklasse, aber unser Modell gibt jetzt die beiden Wahrscheinlichkeiten für jede Klasse zurück.

Nächste Schritte