Snowflake Model Registry: Partitionierte benutzerdefinierte Modelle¶
Viele Datensätze lassen sich leicht in mehrere unabhängige Teilmengen partitionieren. Ein Datensatz, der die Verkaufsdaten einer Ladenkette enthält, kann z. B. nach Ladennummern partitioniert werden. Für jede Partition kann dann ein eigenes Modell trainiert werden. Trainings- und Inferenzoperationen auf den Partitionen können parallelisiert werden, so dass diese Operationen weniger Zeit in Anspruch nehmen. Da sich die einzelnen Läden wahrscheinlich etwas darin unterscheiden, wie sich ihre Features auf ihre Umsätze auswirken, kann dieser Ansatz sogar zu genaueren Schlussfolgerungen auf der Ladenebene führen.
Die Snowflake Model Registry unterstützt die verteilte Verarbeitung von Training und Inferenz von partitionierten Daten:
Das Dataset enthält eine Spalte, die Partitionen in den Daten zuverlässig identifiziert.
Die Daten in jeder einzelnen Partition sind unkorreliert mit den Daten in den anderen Partitionen und enthalten genügend Zeilen, um das Modell zu trainieren.
Das Modell ist zustandslos: Es führt bei jedem Aufruf sowohl die Anpassung (Training) als auch die Inferenz (Vorhersage) durch und behält zwischen den Aufrufen weder Gewichte noch andere Zustände des Modells bei.
Mit der Snowflake Model Registry implementieren Sie partitioniertes Training und Inferenz unter Verwendung von benutzerdefinierten Modellen. Wenn Sie das Modell verwenden, partitioniert die Registry den Datensatz, passt die Partitionen an, prognostiziert sie parallel unter Verwendung aller Knoten und Kerne in Ihrem Warehouse und kombiniert die Ergebnisse anschließend zu einem einzigen Datensatz.
Bemerkung
Partitioniertes Training und Inferenz erfordert Snowpark ML (snowflake-ml-python
-Paket) Version 1.5.0 oder höher.
Definieren und Protokollieren des benutzerdefinierten Modells¶
Wie in Schreiben der kundenspezifischen Modellklasse erläutert, deklarieren Sie benutzerdefinierte Modell-Inferenzmethoden mit dem Dekorator @custom_model.partitioned_inference_api
(Snowpark ML Version 1.5.4 oder höher) oder @custom_model.inference_api
(Snowpark ML Version 1.5.0 bis 1.5.3).
class ExampleForecastingModel(custom_model.CustomModel):
@custom_model.partitioned_inference_api
def predict(self, input: pd.DataFrame) -> pd.DataFrame:
# All data in the partition will be loaded in the input dataframe.
#… implement model logic here …
return output_df
my_model = ExampleForecastingModel()
Geben Sie bei der Protokollierung des Modells eine function_type
von TABLE_FUNCTION
im options
-Dictionary an, zusammen mit allen anderen Optionen, die Ihr Modell benötigt.
reg = Registry(session=sp_session, database_name="ML", schema_name="REGISTRY")
mv = reg.log_model(my_model,
model_name="my_model",
version_name="v1",
options={"function_type": "TABLE_FUNCTION"}, ###
conda_dependencies=["scikit-learn"],
sample_input_data=train_features
)
Wenn Ihr benutzerdefiniertes Modell auch reguläre (nicht-tabellarische) Funktionen als Methoden hat, können Sie stattdessen das method_options
-Dictionary verwenden, um den Typ jeder Methode anzugeben.
model_version = reg.log_model(my_model,
model_name="my_model",
version_name="v1",
options={
"method_options": { ###
"METHOD1": {"function_type": "TABLE_FUNCTION"}, ###
"METHOD2": {"function_type": "FUNCTION"} ###
}
}
conda_dependencies=["scikit-learn"],
sample_input_data=train_features
)
Training und Inferenz durchführen¶
Verwenden Sie die run
-Methode eines Python ModelVersion
-Objekts, um die Methoden der Tabellenfunktionen partitioniert aufzurufen. Übergeben Sie partition_column
, um den Namen der Spalte anzugeben, die einen numerischen oder Zeichenfolge-Wert enthält, der die Partition jedes Datensatzes identifiziert. Wie üblich können Sie einen Snowpark oder pandas-DataFrame übergeben (letzteres ist für lokale Tests nützlich). Sie erhalten die gleiche Art von DataFrame als Ergebnis. In diesen Beispielen erfolgt die Partitionierung anhand einer Ladennummer.
mv.run(
input_df,
function_name="PREDICT",
partition_column="STORE_NUMBER"
)
Sie können diese Methoden auch mit partitionierten Daten von SQL aufrufen, wie hier gezeigt.
SELECT OUTPUT1, OUTPUT2, PARTITION_COLUMN
FROM input_table,
table(
MY_MODEL!PREDICT(input_table.INPUT1, input_table.INPUT2)
OVER (PARTITION BY input_table.STORE_NUMBER)
)
ORDER BY input_table.STORE_NUMBER;
Die Eingabedaten werden automatisch auf die Knoten und Kerne in Ihrem Warehouse aufgeteilt, und die Partitionen werden parallel verarbeitet.
Tipp
Viele Datensätze können auf mehr als eine Weise partitioniert werden. Da die Partitionsspalte beim Aufruf des Modells angegeben wird und nicht beim Protokollieren, können Sie problemlos verschiedene Partitionsschemata ausprobieren, ohne das Modell zu ändern. In dem hypothetischen Datensatz zu den Ladenverkäufen könnten Sie zum Beispiel nach der Anzahl der Läden oder nach Bundesland oder Provinz partitionieren, um zu sehen, was die Vorhersagekraft erhöht.
Das bedeutet auch, dass Sie kein separates Modell für die unpartitionierte Verarbeitung benötigen. Wenn Sie keine Partitionsspalte angeben, wird keine Partitionierung vorgenommen, und alle Daten werden wie üblich zusammen verarbeitet.
Beispiel¶
Ein Beispiel mit Beispieldaten finden Sie im Partitioned Custom Model Quickstart Guide.