Integrieren eigener Modelltypen mittels serialisierter Dateien

Die Modellregistrierung unterstützt die Protokollierung integrierter Modelltypen direkt in der Registrierung. Wir bieten auch eine Methode zur Protokollierung anderer Modelltypen mit snowflake.ml.model.custom_model.CustomModel. Serialisierbare Modelle, die mit externen Tools trainiert wurden oder aus Open-Source-Repositories stammen, können mit CustomModel verwendet werden.

In dieser Anleitung wird Folgendes erklärt:

  • Erstellen Sie ein benutzerdefiniertes Modell.

  • Erstellen Sie einen Modellkontext mit Dateien und Modellobjekten.

  • Fügen Sie Ihrem Modell mit code_paths zusätzlichen Code hinzu.

  • Melden Sie das benutzerdefinierte Modell in der Snowflake-Modellregistrierung an.

  • Setzen Sie das Modell für die Inferenz ein.

Bemerkung

Dieser Quickstart bietet ein Beispiel für die Protokollierung eines benutzerdefinierten PyCaret-Modells.

Definieren des Modellkontexts durch Schlüsselwortargumente

Der snowflake.ml.model.custom_model.ModelContext kann mit benutzerdefinierten Schlüsselwortargumenten instanziiert werden. Die Werte können Zeichenfolgen-Dateipfade oder Instanzen von unterstützten Modelltypen sein. Die Dateien und serialisierten Modelle werden mit dem Modell gepackt, um sie in der Modellinferenz-Logik zu verwenden.

Verwendung von Modellobjekten im Arbeitsspeicher

Bei der Arbeit mit integrierten Modelltypen wird empfohlen, Modellobjekte im Arbeitsspeicher direkt an ModelContext zu übergeben. Dies ermöglicht Snowflake ML die automatische Verarbeitung der Serialisierung.

import pandas as pd
from snowflake.ml.model import custom_model

# Initialize ModelContext with an in-memory model object
# my_model can be any supported model type (e.g., sklearn, xgboost, lightgbm, and others)
model_context = custom_model.ModelContext(
    my_model=my_model,
)

# Define a custom model class that utilizes the context
class ExampleBringYourOwnModel(custom_model.CustomModel):
    def __init__(self, context: custom_model.ModelContext) -> None:
        super().__init__(context)

    @custom_model.inference_api
    def predict(self, input: pd.DataFrame) -> pd.DataFrame:
        # Use the model with key 'my_model' from the context to make predictions
        model_output = self.context['my_model'].predict(input)
        return pd.DataFrame({'output': model_output})

# Instantiate the custom model with the model context. This instance can be logged in the model registry.
my_model = ExampleBringYourOwnModel(model_context)
Copy

Bemerkung

Greifen Sie in Ihrer kundenspezifischen Modellklasse immer über den Modellkontext auf Modellobjekte zu. Verwenden Sie zum Beispiel self.model = self.context['my_model'], anstatt self.model = model direkt zuzuweisen (wobei model ein Modellobjekt im Arbeitsspeicher ist). Durch den direkten Zugriff auf das Modell wird eine zweite Kopie des Modells in einer Closure erfasst, was zu deutlich größeren Modelldateien während der Serialisierung führt.

Verwenden von serialisierten Dateien

Für Modelle oder Daten, die in serialisierten Dateien wie Python Pickles oder JSON gespeichert sind, können Sie Dateipfade zu Ihrem ModelContext angeben. Bei Dateien kann es sich um serialisierte Modelle, Konfigurationsdateien oder Dateien mit Parametern handeln. Dies ist nützlich, wenn Sie mit vortrainierten Modellen arbeiten, die auf der Festplatte gespeichert sind, oder mit Konfigurationsdaten.

import pickle
import pandas as pd
from snowflake.ml.model import custom_model

# Initialize ModelContext with a file path
# my_file_path is a local pickle file path
model_context = custom_model.ModelContext(
    my_file_path='/path/to/file.pkl',
)

# Define a custom model class that loads the pickled object
class ExampleBringYourOwnModel(custom_model.CustomModel):
    def __init__(self, context: custom_model.ModelContext) -> None:
        super().__init__(context)

        # Use 'my_file_path' key from the context to load the pickled object
        with open(self.context['my_file_path'], 'rb') as f:
            self.obj = pickle.load(f)

    @custom_model.inference_api
    def predict(self, input: pd.DataFrame) -> pd.DataFrame:
        # Use the loaded object to make predictions
        model_output = self.obj.predict(input)
        return pd.DataFrame({'output': model_output})

# Instantiate the custom model with the model context. This instance can be logged in the model registry.
my_model = ExampleBringYourOwnModel(model_context)
Copy

Wichtig

When you combine a supported model type (such as XGBoost) with unsupported models or data, you don’t need to serialize the supported model yourself. Set the supported model object directly in the context (e.g., base_model = my_xgb_model) and it is serialized automatically.

Testen und Protokollieren eines benutzerdefinierten Modells

Sie können ein benutzerdefiniertes Modell testen, indem Sie es lokal ausführen.

my_model = ExampleBringYourOwnModel(model_context)
output_df = my_model.predict(input_df)
Copy

Wenn das Modell wie vorgesehen funktioniert, tragen Sie es in die Snowflake Model Registry ein. Wie im nächsten Codebeispiel gezeigt, geben Sie conda_dependencies (oder pip_requirements) an, um die Bibliotheken anzugeben, die die Modellklasse benötigt. Stellen Sie sample_input_data (ein pandas- oder Snowpark-DataFrame) zur Verfügung, um die Eingabesignatur für das Modell abzuleiten. Alternativ können Sie auch eine Modellsignatur bereitstellen.

reg = Registry(session=sp_session, database_name="ML", schema_name="REGISTRY")
mv = reg.log_model(my_model,
            model_name="my_custom_model",
            version_name="v1",
            conda_dependencies=["scikit-learn"],
            comment="My Custom ML Model",
            sample_input_data=train_features)
output_df = mv.run(input_df)
Copy

Einschließen von zusätzlichem Code mit code_paths

Verwenden Sie die code_paths-Parameter in Registry.log_model um Python-Code, wie z. B. Hilfsmodule, Dienstprogramme und Konfigurationsdateien, mit Ihrem Modell zu packen. Sie können diesen Code genau so importieren, wie Sie es lokal tun würden.

Sie können entweder Zeichenfolgenpfade zum Kopieren von Dateien oder Verzeichnissen angeben oder CodePath-Objekte. Die Objekte bieten mehr Kontrolle darüber, welche Unterverzeichnisse oder Dateien enthalten sind und welche Importpfade vom Modell verwendet werden.

Verwenden von Zeichenfolgenpfaden

Übergeben Sie eine Liste von Zeichenfolgenpfaden, um Dateien oder Verzeichnisse einzuschließen. Die letzte Komponente jedes Pfads wird zum Namen des importierbaren Moduls.

mv = reg.log_model(
    my_model,
    model_name="my_model",
    version_name="v1",
    code_paths=["src/mymodule"],  # import with: import mymodule
)
Copy

Verwenden von CodePath mit Filter

Verwenden Sie die CodePath-Klasse, wenn Sie nur einen Teil eines Verzeichnisbaums packen oder die von Ihrem Modell verwendeten Importpfade steuern möchten.

from snowflake.ml.model import CodePath
Copy

Ein CodePath hat zwei Parameter:

  • root: Ein Verzeichnis oder ein Dateipfad.

  • filter (optional): Ein relativer Pfad unter root, der ein Unterverzeichnis oder eine Datei auswählt.

Wenn filter bereitgestellt wird, lautet die Quelle root/filter, und der filter-Wert bestimmt den Importpfad. Beispiel: filter="utils" ermöglicht import utils``und ``filter="pkg/subpkg" ermöglicht import pkg.subpkg.

Beispiel: Bei dieser Projektstruktur:

my_project/src/
├── utils/
│   └── preprocessing.py
├── models/
│   └── classifier.py
└── tests/          # Not needed for inference
Copy

Um nur utils/ und models/ zu verpacken, ausgenommen tests/:

mv = reg.log_model(
    my_model,
    model_name="my_model",
    version_name="v1",
    code_paths=[
        CodePath("my_project/src/", filter="utils/"),
        CodePath("my_project/src/", filter="models/"),
    ],
)
Copy

Sie können auch eine einzelne Datei filtern:

code_paths=[
    CodePath("my_project/src/", filter="utils/preprocessing.py"),
]
# Import with: import utils.preprocessing
Copy

Beispiel: Protokollieren eines PyCaret-Modells

The following example uses PyCaret to log a custom model type. PyCaret is a low-code, high-efficiency third-party package that Snowflake doesn’t support natively. You can bring your own model types using similar methods.

Schritt 1: Modellkontext definieren

Before you log your model, define the model context. The model context refers to your own custom model type. The following example specifies the path to the serialized (pickled) model using the context’s model_file attribute. You can choose any name for the attribute as long as the name is not used for anything else.

pycaret_model_context = custom_model.ModelContext(
  model_file = 'pycaret_best_model.pkl',
)
Copy

Schritt 2: Benutzerdefinierte Modellklasse erstellen

Definieren Sie eine benutzerdefinierte Modellklasse, um einen Modelltyp ohne native Unterstützung zu protokollieren. In diesem Beispiel wird eine PyCaretModel-Klasse definiert, die von CustomModel abgeleitet ist, damit das Modell in der Registry protokolliert werden kann.

from pycaret.classification import load_model, predict_model

class PyCaretModel(custom_model.CustomModel):
    def __init__(self, context: custom_model.ModelContext) -> None:
        super().__init__(context)
        model_dir = self.context["model_file"][:-4]  # Remove '.pkl' suffix
        self.model = load_model(model_dir, verbose=False)
        self.model.memory = '/tmp/'  # Update memory directory

    @custom_model.inference_api
    def predict(self, X: pd.DataFrame) -> pd.DataFrame:
        model_output = predict_model(self.model, data=X)
        return pd.DataFrame({
            "prediction_label": model_output['prediction_label'],
            "prediction_score": model_output['prediction_score']
        })
Copy

Bemerkung

Legen Sie, wie gezeigt, das Speicherverzeichnis des Modells auf /tmp/ fest. Die Warehouse-Knoten von Snowflake haben einen eingeschränkten Zugriff auf Verzeichnisse. /tmp ist immer beschreibbar und ist eine sichere Wahl, wenn das Modell einen Platz zum Schreiben von Dateien benötigt. Bei anderen Typen von Modellen ist dies möglicherweise nicht erforderlich.

Schritt 3: Benutzerdefiniertes Modell testen

Testen Sie das PyCaret-Modell lokal mit einem Code wie dem folgenden.

test_data = [
    [1, 237, 1, 1.75, 1.99, 0.00, 0.00, 0, 0, 0.5, 1.99, 1.75, 0.24, 'No', 0.0, 0.0, 0.24, 1],
    # Additional test rows...
]
col_names = ['Id', 'WeekofPurchase', 'StoreID', 'PriceCH', 'PriceMM', 'DiscCH', 'DiscMM',
            'SpecialCH', 'SpecialMM', 'LoyalCH', 'SalePriceMM', 'SalePriceCH',
            'PriceDiff', 'Store7', 'PctDiscMM', 'PctDiscCH', 'ListPriceDiff', 'STORE']

test_df = pd.DataFrame(test_data, columns=col_names)

my_pycaret_model = PyCaretModel(pycaret_model_context)
output_df = my_pycaret_model.predict(test_df)
Copy

Schritt 4: Modellsignatur definieren

In diesem Beispiel verwenden Sie die Beispieldaten, um eine Modellsignatur zur Eingabevalidierung abzuleiten:

predict_signature = model_signature.infer_signature(input_data=test_df, output_data=output_df)
Copy

Schritt 5: Modell protokollieren

Der folgende Code protokolliert (registriert) das Modell in der Snowflake Model Registry.

snowml_registry = Registry(session)

custom_mv = snowml_registry.log_model(
    my_pycaret_model,
    model_name="my_pycaret_best_model",
    version_name="version_1",
    conda_dependencies=["pycaret==3.0.2", "scipy==1.11.4", "joblib==1.2.0"],
    options={"relax_version": False},
    signatures={"predict": predict_signature},
    comment = 'My PyCaret classification experiment using the CustomModel API'
)
Copy

Schritt 6: Modell in der Registry überprüfen

Um zu überprüfen, ob das Modell in der Model Registry verfügbar ist, verwenden Sie die Funktion show_models.

snowml_registry.show_models()
Copy

Schritt 7: Vorhersagen mit dem registrierten Modell machen

Verwenden Sie die Funktion run, um das Modell für die Vorhersage aufzurufen.

snowpark_df = session.create_dataframe(test_data, schema=col_nms)

custom_mv.run(snowpark_df).show()
Copy

Nächste Schritte

Nachdem Sie ein PyCaret-Modell über die Snowflake Model Registry bereitgestellt haben, können Sie das Modell in Snowsight anzeigen. Wählen Sie im Navigationsmenü die Option AI & ML » Models aus. Wenn Sie es dort nicht sehen, vergewissern Sie sich, dass Sie die ACCOUNTADMIN-Rolle oder die Rolle verwenden, die Sie zum Protokollieren des Modells verwendet haben.

Um das Modell von SQL aus zu verwenden, nutzen Sie SQL wie folgt:

SELECT
    my_pycaret_model!predict(*) AS predict_dict,
    predict_dict['prediction_label']::text AS prediction_label,
    predict_dict['prediction_score']::double AS prediction_score
from pycaret_input_data;
Copy