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_pathszusä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)
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)
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)
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)
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
)
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
Ein CodePath hat zwei Parameter:
root: Ein Verzeichnis oder ein Dateipfad.filter(optional): Ein relativer Pfad unterroot, 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
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/"),
],
)
Sie können auch eine einzelne Datei filtern:
code_paths=[
CodePath("my_project/src/", filter="utils/preprocessing.py"),
]
# Import with: import utils.preprocessing
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',
)
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']
})
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)
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)
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'
)
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()
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()
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;