Sdílet prostřednictvím


Protokolování modelů MLflow

Tento článek popisuje, jak protokolovat trénované modely (nebo artefakty) jako modely MLflow. Prozkoumá různé způsoby přizpůsobení způsobu, jakým MLflow zabalí vaše modely a jak tyto modely spouští.

Proč protokolování modelů místo artefaktů?

Od artefaktů po modely v MLflow popisuje rozdíl mezi artefakty protokolování nebo soubory v porovnání s protokolováním modelů MLflow.

Model MLflow je také artefaktem. Tento model má ale specifickou strukturu, která slouží jako smlouva mezi osobou, která model vytvořila, a osobou, která ji hodlá použít. Tento kontrakt pomáhá sestavit most mezi samotnými artefakty a jejich významy.

Protokolování modelu má tyto výhody:

  • Modely můžete přímo načíst pro odvozování pomocí mlflow.<flavor>.load_modelfunkce a můžete ji použít.predict
  • Vstupy kanálů můžou používat modely přímo
  • Modely můžete nasadit bez označení hodnoticího skriptu nebo prostředí.
  • Swagger je v nasazených koncových bodech automaticky povolený a studio Azure Machine Learning může použít funkci Testování.
  • Můžete použít řídicí panel Zodpovědné AI.

Tato část popisuje, jak používat koncept modelu ve službě Azure Machine Learning s MLflow:

Protokolování modelů pomocí automatického protokolu

Můžete použít funkci automatického protokolu MLflow. Autolog umožňuje MLflow instruovat architekturu, aby protokoloval všechny metriky, parametry, artefakty a modely, které architektura považuje za relevantní. Ve výchozím nastavení se většina modelů protokoluje, pokud je povolený automatický protokol. V některých situacích nemusí některé varianty model protokolovat. Například příchuť PySpark nepíše modely, které překračují určitou velikost.

Použijte buď mlflow.autolog() nebo mlflow.<flavor>.autolog() aktivujte automatické protokolování. Tento příklad používá autolog() k protokolování klasifikátoru natrénovaného pomocí 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)

Tip

Pokud používáte kanály Machine Learning, například kanály Scikit-Learn, použijte autolog funkce této příchutě kanálu k protokolování modelů. Protokolování modelu se automaticky provede, když fit() je metoda volána v objektu kanálu. Trénování a sledování klasifikátoru XGBoost s poznámkovým blokem MLflow ukazuje, jak pomocí kanálů protokolovat model s předzpracováním.

Protokolování modelů pomocí vlastního podpisu, prostředí nebo ukázek

Metoda MLflow mlflow.<flavor>.log_model může ručně protokolovat modely. Tento pracovní postup může řídit různé aspekty protokolování modelu.

Tuto metodu použijte v těchto případech:

  • Chcete označit balíčky pip nebo prostředí conda, které se liší od těch, které se automaticky detekují.
  • Chcete zahrnout příklady vstupu
  • Do potřebného balíčku chcete zahrnout konkrétní artefakty.
  • autolog neodvozuje váš podpis správně. Záleží na tom, když se zabýváte vstupy tensoru, kde podpis potřebuje specifické obrazce.
  • Chování automatického protokolu se z nějakého důvodu nevztahuje na váš účel.

Tento příklad kódu zaznamená model pro klasifikátor 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)

Poznámka:

  • autologlog_models=False má konfiguraci. Tím se zabrání automatickému protokolování modelu MLflow. Automatické protokolování modelu MLflow proběhne později jako ruční proces.
  • infer_signature Použití metody k pokusu o odvození podpisu přímo ze vstupů a výstupů
  • Tato mlflow.utils.environment._mlflow_conda_env metoda je privátní metoda v sadě MLflow SDK. V tomto příkladu je kód jednodušší, ale používejte ho s opatrností. V budoucnu se to může změnit. Jako alternativu můžete definici YAML generovat ručně jako slovník Pythonu.

Protokolování modelů s jiným chováním v metodě predict

Při protokolování modelu buď mlflow.autolog nebo mlflow.<flavor>.log_model, příchuť modelu určuje, jak provést odvozování a co model vrátí. MLflow nevynucuje žádné konkrétní chování při generování predict výsledků. V některých scénářích můžete chtít před provedením a po spuštění modelu provést předběžné zpracování nebo následné zpracování.

V této situaci implementujte kanály strojového učení, které se přímo přesouvají ze vstupů na výstupy. I když je tato implementace možná a někdy se doporučuje zlepšit výkon, může být náročné dosáhnout. V těchto případech vám může pomoct přizpůsobit způsob, jakým model zpracovává odvozování , jak je vysvětleno v další části.

Protokolování vlastních modelů

MLflow podporuje mnoho architektur strojového učení, včetně

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

Možná ale budete muset změnit způsob, jakým příchuť funguje, protokolovat model, který MLflow nativně nepodporuje, nebo dokonce protokolovat model, který používá více prvků z různých architektur. V těchto případech možná budete muset vytvořit vlastní příchuť modelu.

K vyřešení problému MLflow zavádí příchuť pyfunc (počínaje funkcí Pythonu). Tato příchuť může protokolovat libovolný objekt jako model, pokud tento objekt splňuje dvě podmínky:

  • Implementujete metodu metody predict alespoň
  • Objekt Pythonu dědí z mlflow.pyfunc.PythonModel

Tip

Serializovatelné modely, které implementují rozhraní API Scikit-learn, můžou používat příchuť Scikit-learn k protokolování modelu bez ohledu na to, jestli byl model sestaven pomocí Scikit-learn. Pokud můžete model zachovat ve formátu Pickle a objekt obsahuje predict() metody a predict_proba() metody (alespoň), můžete mlflow.sklearn.log_model() model protokolovat uvnitř spuštění MLflow.

Pokud kolem existujícího objektu modelu vytvoříte obálku, stane se nejjednodušší vytvořit pro vlastní model příchuť. MLflow serializuje a zabalí ho za vás. Objekty Pythonu lze serializovat, pokud lze objekt uložit v systému souborů jako soubor, obecně ve formátu Pickle. Za běhu může objekt materializovat z daného souboru. Tím se obnoví všechny hodnoty, vlastnosti a metody, které jsou k dispozici při uložení.

Tuto metodu použijte v těchto případech:

  • Model můžete serializovat ve formátu Pickle.
  • Chcete zachovat stav modelu, protože byl těsně po trénování.
  • Chcete přizpůsobit fungování predict funkce.

Tato ukázka kódu zabalí model vytvořený pomocí XGBoost, aby se choval jinak než výchozí implementace příchutě XGBoost. Místo tříd vrátí pravděpodobnosti:

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

Zapište vlastní model do spuštění:

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)

Tip

Zde metoda infer_signature používá y_probs k odvození podpisu. Náš cílový sloupec má cílovou třídu, ale náš model teď vrátí dvě pravděpodobnosti pro každou třídu.

Další kroky