Model Serving in Snowpark Container Services¶
Bemerkung
Dieses Feature ist in den kommerziellen Regionen von AWS und Azure verfügbar. Es ist in Regionen für Regierungsbehörden nicht verfügbar.
Bemerkung
Die Möglichkeit, Modelle in Snowpark Container Services (SPCS) auszuführen, die in diesem Thema beschrieben wird, ist in snowflake-ml-python
Version 1.8.0 und später verfügbar.
Die Snowflake Model Registry ermöglicht es Ihnen, Modelle entweder in einem Warehouse (die Standardeinstellung) oder in einem Snowpark Container Services (SPCS) Computepool über Model Serving auszuführen. Die Ausführung von Modellen in einem Warehouse bringt einige Beschränkungen in Bezug auf die Größe und die Art der Modelle mit sich, die Sie verwenden können (insbesondere kleine bis mittelgroße nur-CPU-Modelle, deren Abhängigkeiten von Paketen erfüllt werden können, die im Snowflake conda-Kanal verfügbar sind).
Die Ausführung von Modellen auf Snowpark Container Services (SPCS) erleichtert diese Einschränkungen oder beseitigt sie ganz. Sie können alle Pakete verwenden, die Sie möchten, auch die aus dem Python Package Index (PyPI) oder aus anderen Quellen. Große Modelle können auf verteilten Clustern von GPUs ausgeführt werden. Und Sie müssen nichts über Container-Technologien wie Docker oder Kubernetes wissen. Snowflake Model Serving kümmert sich um alle Details.
Die wichtigsten Konzepte¶
Nachfolgend finden Sie einen vereinfachten Überblick über die Architektur des Snowflake Modells Serving Inference.

Die Hauptkomponenten der Architektur sind:
Inferenzserver: Der Server, der das Modell ausführt und Vorhersagen liefert. Der Inferenzserver kann mehrere Inferenzprozesse verwenden, um die Fähigkeiten des Knotens voll auszuschöpfen. Anfragen an das Modell werden über die Zulassungskontrolle abgewickelt, die die Warteschlange für eingehende Anfragen verwaltet, um zu verhindern, dass der Speicher überlastet wird, und die Clients abweist, wenn der Server überlastet ist. Heute bietet Snowflake einen einfachen und flexiblen Inferenzserver auf Python-Basis, der Inferenzen für alle Arten von Modellen durchführen kann. Snowflake plant, im Laufe der Zeit InferenzsServer anzubieten, die für bestimmte Modelle optimiert sind.
Modellspezifische Python-Umgebung: Um die Latenz beim Starten eines Modells zu verringern, zu der auch die Zeit gehört, die für das Herunterladen der Abhängigkeiten und das Laden des Modells benötigt wird, erstellt Snowflake einen Container, der die Abhängigkeiten des spezifischen Modells kapselt.
Dienstfunktionen: Um von einem im Warehouse ausgeführten Code aus mit dem Inferenzserver zu kommunizieren, erstellt Snowflake Model Serving-Funktionen, die dieselbe Signatur wie das Modell haben, aber stattdessen den Inferenzserver über das externe Funktionsprotokoll aufrufen.
Ingress-Endpunkt: Damit Anwendungen außerhalb von Snowflake das Modell aufrufen können, kann Snowflake Model Serving einen optionalen HTTP Endpunkt bereitstellen, der über das öffentliche Internet zugänglich ist.
Wie funktioniert das?¶
Das folgende Diagramm zeigt, wie das Snowflake Model Serving Modelle entweder in einem Warehouse oder auf SPCS bereitstellt und bedient.

Wie Sie sehen, ist der Pfad zur Bereitstellung von SPCS komplexer als der Pfad zur Bereitstellung des Warehouse, aber Snowflake Model Serving übernimmt die gesamte Arbeit für Sie, einschließlich der Erstellung des Container-Images, das das Modell und seine Abhängigkeiten enthält, und der Erstellung des Inferenzservers, der das Modell ausführt.
Voraussetzungen¶
Bevor Sie beginnen, vergewissern Sie sich, dass Sie Folgendes haben:
Ein Snowflake-Konto in einer kommerziellen AWS- oder Azure-Region. Gov-Regionen werden nicht unterstützt.
Version 1.6.4 oder höher des
snowflake-ml-python
Python-Pakets.Ein Modell, das Sie auf Snowpark Container Services ausführen möchten.
Vertrautheit mit dem Snowflake Model Registry.
Vertrautheit mit dem Snowpark Container Services. Insbesondere sollten Sie Computepools, Image-Repositorys und die damit verbundenen Berechtigungen verstehen.
Einen Computepool erstellen¶
Snowpark Container Services (SPCS) führt Container-Images in Computepools aus. Wenn Sie noch keinen geeigneten Computepool haben, erstellen Sie einen solchen wie folgt:
CREATE COMPUTE POOL IF NOT EXISTS mypool
MIN_NODES = 2
MAX_NODES = 4
INSTANCE_FAMILY = 'CPU_X64_M'
AUTO_RESUME = TRUE;
Eine Auflistung der gültigen Instanzfamilien finden Sie in der Familiennamen-Tabelle.
Stellen Sie sicher, dass die Rolle, die das Modell ausführt, Eigentümer des Computepools ist oder die Berechtigung USAGE oder OPERATE für den Pool besitzt.
Image-Repository erstellen¶
Snowflake Model Serving erstellt ein Container-Image, das das Modell und seine Abhängigkeiten enthält. Um dieses Image zu speichern, benötigen Sie ein Image-Repository. Wenn Sie noch keines haben, erstellen Sie es wie folgt:
CREATE IMAGE REPOSITORY IF NOT EXISTS my_inference_images
Wenn Sie ein Image-Repository verwenden, dessen Eigentümer Sie nicht sind, stellen Sie sicher, dass die Rolle, die das Container-Image erstellt, über die Berechtigungen READ WRITE, SERVICE READ, SERVICE und WRITE für das Repository verfügt. Gewähren Sie diese Berechtigungen wie folgt:
GRANT READ ON IMAGE REPOSITORY my_inference_images TO ROLE myrole;
GRANT WRITE ON IMAGE REPOSITORY my_inference_images TO ROLE myrole;
GRANT SERVICE READ ON IMAGE REPOSITORY my_inference_images TO ROLE myrole;
GRANT SERVICE WRITE ON IMAGE REPOSITORY my_inference_images TO ROLE myrole;
Erforderliche Berechtigungen¶
Model Serving läuft auf Snowpark Container Services. Um Model Serving zu verwenden, benötigt ein Benutzer die folgenden Berechtigungen:
USAGE oder OWNERSHIP auf einem Computepool, auf dem der Dienst laufen wird.
Ein Image-Repository mit allen vier Berechtigungen: READ, WRITE, SERVICE READ, und SERVICE WRITE. Wenn der Benutzer Eigentümer des Image-Repositorys ist, werden alle Berechtigungen automatisch gewährt.
Wenn ein Ingress-Endpunkt auf dem Model Serving gewünscht wird, muss der Benutzer über die Berechtigung BIND SERVICE ENDPOINT auf dem Konto verfügen.
Nur die Besitzer des Modells können das Modell für Serving bereitstellen. Um Nicht-Eigentümern den Zugriff auf Inferenz zu ermöglichen, müssen Eigentümer den Dienst bereitstellen und dann die Dienstrolle
INFERENCE_SERVICE_FUNCTION_USAGE
zur gemeinsamen Nutzung von Dienstfunktionen undALL_ENDPOINTS_USAGE
zur gemeinsamen Nutzung von Ingress-Endpunkten gewähren.
Einschränkungen¶
Die folgenden Einschränkungen gelten für Modelle, die in Snowpark Container Services eingesetzt werden.
Nur der Eigentümer eines Modells kann es bei Snowpark Container Services einsetzen
Die Größe des Compute-Clusters wird nicht automatisch skaliert. Sie können die Anzahl der Instanzen zur Laufzeit mit
ALTER SERVICE myservice MIN_INSTANCES = n
manuell ändern. In einigen Fällen führt dies dazu, dass bestehende Knoten ausfallen.Die Skalierung von Services und Computepools verläuft langsamer als erwartet.
Inferenzdienste, bei denen Ingress aktiviert ist, können nicht ausgesetzt werden.
Die Bilderstellung schlägt fehl, wenn sie mehr als eine Stunde dauert.
Tabellenfunktionen werden nicht unterstützt. Modelle ohne reguläre Funktion können derzeit nicht in Snowpark Container Services eingesetzt werden.
Ein Modell für SPCS bereitstellen¶
Entweder protokolliert eine neue Version des Modells (über reg.log_model
) oder erhält einen Verweis auf eine bestehende Version des Modells (reg.get_model(...).version(...)
). In beiden Fällen erhalten Sie einen Verweis auf ein ModelVersion
-Objekt.
Modell-Abhängigkeiten und Eignung¶
Die Abhängigkeiten eines Modells bestimmen, ob es in einem Warehouse, in einem SPCS-Dienst oder in beiden laufen kann. Sie können bei Bedarf absichtlich Abhängigkeiten angeben, um ein Modell für die Ausführung in einer dieser Umgebungen ungeeignet zu machen.
Der Snowflake conda-Kanal ist nur in Warehouses verfügbar und ist die einzige Quelle für Abhängigkeiten von Warehouses. Standardmäßig beziehen die conda-Abhängigkeiten für SPCS-Modelle ihre Abhängigkeiten aus conda-forge.
Wenn Sie eine Modellversion protokollieren, werden die Abhängigkeiten des Modells mit dem Snowflake conda-Kanal abgeglichen. Wenn alle Abhängigkeiten des Modells dort verfügbar sind, kann das Modell in einem Warehouse ausgeführt werden. Er kann auch in einem SPCS-Dienst laufen, wenn alle seine Abhängigkeiten in der conda-forge verfügbar sind. Dies wird jedoch erst geprüft, wenn Sie einen Dienst erstellen.
Modelle, die mit PyPI Abhängigkeiten protokolliert wurden, müssen auf SPCS ausgeführt werden. Die Angabe von mindestens einer PyPI-Abhängigkeit ist eine Möglichkeit, ein Modell von der Ausführung in einem Warehouse auszuschließen. Wenn Ihr Modell nur Abhängigkeiten von conda hat, geben Sie mindestens eine mit einem expliziten Kanal an (auch conda-forge), wie im folgenden Beispiel gezeigt.
# reg is a snowflake.ml.registry.Registry object
reg.log_model(
model_name="my_model",
version_name="v1",
model=model,
conda_dependencies=["conda-forge::scikit-learn"])
Für SPCS-bereitgestellte Modelle werden zuerst die conda-Abhängigkeiten, falls vorhanden, installiert, dann werden alle PyPI-Abhängigkeiten in der conda-Umgebung mit pip
installiert.
Dienst erstellen¶
Um einen SPCS-Dienst zu erstellen und das Modell darin einzusetzen, rufen Sie die create_service
-Methode der Modellversion auf, wie im folgenden Beispiel gezeigt.
# mv is a snowflake.ml.model.ModelVersion object
mv.create_service(service_name="myservice",
service_compute_pool="my_compute_pool",
image_repo="mydb.myschema.my_image_repo",
ingress_enabled=True,
gpu_requests=None)
Nachfolgend sind die erforderlichen Arguments an create_service
zu sehen:
service_name
: Der Name des zu erstellenden Services. Dieser Name muss innerhalb des Kontos eindeutig sein.service_compute_pool
: Der Name des Computepools, der für die Ausführung des Modells verwendet werden soll. Der Computepool muss bereits existieren.image_repo
: Der Name des Image-Repositorys, das zum Speichern des Container-Images verwendet werden soll. Das Projektarchiv muss bereits existieren und der Benutzer muss über die Berechtigung SERVICE WRITE (oder OWNERSHIP) verfügen.ingress_enabled
: Wenn „True“, wird der Dienst über einen HTTP-Endpunkt zugänglich gemacht. Um den Endpunkt zu erstellen, muss der Benutzer über die Berechtigung BIND SERVICE ENDPOINT verfügen.gpu_requests
: Eine Zeichenfolge, die die Anzahl der GPUs angibt. Bei einem Modell, das entweder auf CPU oder GPU ausgeführt werden kann, bestimmt dieses Argument, ob das Modell auf CPU oder auf GPUs ausgeführt wird. Wenn es sich bei dem Modell um einen bekannten Typ handelt, der nur auf CPU ausgeführt werden kann (z. B. scikit-learn-Modelle), schlägt die Image-Erstellung fehl, wenn GPUs angefragt wird.
Wenn Sie ein neues Modell einrichten, kann die Erstellung des Dienstes 5 Minuten bei CPU-gestützten Modellen und bei GPU-gestützten Modellen 10 Minuten dauern. Wenn der Computepool nicht ausgelastet ist oder seine Größe geändert werden muss, kann es länger dauern, den Dienst zu erstellen.
Dieses Beispiel zeigt nur die erforderlichen und am häufigsten verwendeten Argumente. Eine vollständige Auflistung der Argumente finden Sie in der Referenz ModelVersion API.
Standard Konfiguration des Dienstes¶
Standardmäßig verwendet Inferenzserver benutzerfreundliche Standardeinstellungen, die für die meisten Anwendungsfälle geeignet sind. Diese Einstellungen sind:
Anzahl der Worker-Threads: Bei CPU-gestützten Modell verwendet der Server die doppelte Anzahl von CPUs plus einen Worker-Prozess. GPU-gestützte Modelle verwenden einen Worker-Prozess. Sie können dies mit dem
num_workers
-Argument im Aufrufcreate_service
überschreiben.Threadsicherheit: Einige Modelle sind nicht Thread-sicher. Daher lädt der Dienst für jeden Worker-Prozess eine eigene Kopie des Modells. Dies kann bei großen Modellen zu einer Erschöpfung der Ressourcen führen.
Knotennutzung: Standardmäßig fordert eine Inferenzserverinstanz den gesamten Knoten an, indem sie die gesamte CPU und den gesamten Speicher des Knotens anfordert, auf dem sie läuft. Um die Ressourcenzuweisung pro Instanz anzupassen, verwenden Sie Argumente wie
cpu_requests
,memory_requests
, undgpu_requests
.Endpunkt: Der Endpunkt hat den Namen
inference
und verwendet Port 5000. Diese können nicht angepasst werden.Automatisch anhalten: Inferenzdienste werden nach dreißig Minuten Inaktivität automatisch ausgesetzt, es sei denn, sie haben einen Ingress-Endpunkt. Ein unterbrochener Dienst wird automatisch wieder aufgenommen, wenn er eine Anfrage erhält.
Verhaltensweise bei der Erstellung von Container-Images¶
Standardmäßig erstellt Snowflake Model Serving das Container-Image unter Verwendung desselben Computepools, der für die Ausführung des Modells verwendet wird. Dieser Inferenz-Computepool ist für diese Aufgabe wahrscheinlich überfordert (zum Beispiel werden GPUs nicht für die Erstellung von Container-Images verwendet). In den meisten Fällen wird dies keine nennenswerten Auswirkungen auf die Kosten haben, aber wenn es ein Problem darstellt, können Sie einen weniger leistungsfähigen Pool für die Erstellung von Images wählen, indem Sie das Argument image_build_compute_pool
angeben.
create_service
ist eine idempotente Funktion. Ein mehrfacher Aufruf löst nicht jedes Mal die Image-Erstellung aus. Container-Images können jedoch auf der Grundlage von Updates im Inferenzdienst neu erstellt werden, einschließlich Korrekturen für Sicherheitslücken in abhängigen Paketen. Wenn dies geschieht, löst create_service
automatisch eine Neuerstellung des Images aus.
Bemerkung
Modelle, die mit Snowpark ML-Modellierungsklassen entwickelt wurden, können nicht in Umgebungen eingesetzt werden, die eine GPU haben. Als Problemumgehung können Sie das native Modell extrahieren und es bereitstellen. Beispiel:
# Train a model using Snowpark ML from snowflake.ml.modeling.xgboost import XGBRegressor regressor = XGBRegressor(...) regressor.fit(training_df) # Extract the native model xgb_model = regressor.to_xgboost() # Test the model with pandas dataframe pandas_test_df = test_df.select(['FEATURE1', 'FEATURE2', ...]).to_pandas() xgb_model.predict(pandas_test_df) # Log the model in Snowflake Model Registry mv = reg.log_model(xgb_model, model_name="my_native_xgb_model", sample_input_data=pandas_test_df, comment = 'A native XGB model trained from Snowflake Modeling API', ) # Now we should be able to deploy to a GPU compute pool on SPCS mv.create_service( service_name="my_service_gpu", service_compute_pool="my_gpu_pool", image_repo="my_repo", max_instances=1, gpu_requests="1", )
Benutzeroberfläche¶
Sie können eingesetzte Modelle in der Modellregistrierung Snowsight UI verwalten. Weitere Informationen dazu finden Sie unter Dienste zur Modellinferenz.
Verwendung eines Modells, eingesetzt für SPCS¶
Sie können die Methoden eines Modells über SQL, Python oder einen HTTP-Endpunkt aufrufen.
SQL¶
Snowflake Model Serving erstellt Funktionen für Dienste, wenn ein Modell auf SPCS bereitgestellt wird. Diese Funktionen dienen als Brücke von SQL zu dem Modell, das im SPCS-Computepool läuft. Für jede Methode des Modells wird eine Dienstfunktion erstellt, die wie service_name!method_name
benannt ist. Wenn das Modell beispielsweise zwei Methoden mit den Namen PREDICT
und EXPLAIN
hat und für einen Dienst mit dem Namen MY_SERVICE
bereitgestellt wird, lauten die resultierenden Funktionen des Dienste MY_SERVICE!PREDICT
und MY_SERVICE!EXPLAIN
.
Bemerkung
Die Dienstefunktionen sind im Service enthalten. Aus diesem Grund haben sie nur einen einzigen Punkt für die Zugriffssteuerung, den Service. Sie können keine unterschiedlichen Zugriffssteuerungsrechte für verschiedene Funktionen in einem einzigen Dienst haben.
Der Aufruf der Dienstfunktionen eines Modells in SQL erfolgt über Code wie den folgenden:
-- See signature of the inference function in SQL.
SHOW FUNCTIONS IN MODEL my_native_xgb_model VERSION ...;
-- Call the inference function in SQL following the same signature (from `arguments` column of the above query)
SELECT MY_SERVICE!PREDICT(feature1, feature2, ...) FROM input_data_table;
Python¶
Rufen Sie die Methoden eines Service mit der Methode run
eines Objekts der Modellversion auf, einschließlich des Arguments service_name
zur Angabe des Serfvices, in dem die Methode ausgeführt wird. Beispiel:
# Get signature of the inference function in Python
# mv is a snowflake.ml.model.ModelVersion object
mv.show_functions()
# Call the function in Python
service_prediction = mv.run(
test_df,
function_name="predict",
service_name="my_service")
Wenn Sie das Argument service_name
nicht angeben, läuft das Modell in einem Warehouse.
HTTP-Endpunkt¶
Wenn Sie einen Dienst mit aktiviertem Eingang bereitstellen, wird ein HTTP-Endpunkt erstellt, über den Sie den Dienst aufrufen können. Sie können den Endpunkt mit dem Befehl SHOW ENDPOINTS IN SERVICE
finden.
SHOW ENDPOINTS IN SERVICE my_service;
Beachten Sie die Spalte ingress_url
, die wie random_str-account-id.snowflakecomputing.app
aussehen sollte. Es gelten die DNS-Namensbeschränkungen. In einer URL wird ein Unterstrich (_) im Methodennamen durch einen Bindestrich (-) ersetzt (z. B. URL von predict_proba
ist url/predict-proba
).
Benutzer können den Dienst über den öffentlichen Endpunkt programmatisch aufrufen. Anwendungen verwenden die Authentifizierung mit dem Schlüsselpaar </user-guide/key-pair-auth>, um Anfragen an den öffentlichen Endpunkt zu authentifizieren. Erzeugen Sie ein JSON Web Token (JWT) aus dem Schlüsselpaar, tauschen Sie das JWT Token mit Snowflake gegen ein OAuth Token aus und verwenden Sie das OAuth Token zur Authentifizierung von Anfragen an den öffentlichen Endpunkt eines Dienstes. Ein Beispiel finden Sie unter Greifen Sie auf den öffentlichen Endpunkt programmgesteuert zu.
Weitere Informationen über das erforderliche Format der Daten finden Sie unter Eingabe- und Ausgabedatenformate von Remotediensten.
Unter Einsatz eines Hugging Face-Satzumwandlers für GPU-gestützte Inferenz finden Sie ein Beispiel für die Verwendung eines Modelldienst-HTTP-Endpunkts.
Verwalten von Diensten¶
Snowpark Container-Dienste bieten eine SQL-Weboberfläche für die Verwaltung von Diensten. Sie können die Befehle DESCRIBE SERVICE und ALTER SERVICE für SPCS-Dienste verwenden, die von Snowflake Model Serving erstellt wurden, genauso wie für die Verwaltung aller anderen SPCS-Dienste. Sie können beispielsweise Folgendes tun:
Ändern Sie MIN_INSTANCES und andere Eigenschaften eines Dienstes
Einen Dienst verwerfen (löschen)
Einen Dienst für ein anderes Konto freigeben
Änderung der Eigentümerschaft eines Dienstes (der neue Eigentümer muss Zugriff auf das Modell haben)
Bemerkung
Wenn der Eigentümer eines Dienstes aus irgendeinem Grund den Zugriff auf das zugrunde liegende Modell verliert, funktioniert der Dienst nach einem Neustart nicht mehr. Er läuft weiter, sobald er neu gestartet wird.
Um die Reproduzierbarkeit und Fehlersuche zu gewährleisten, können Sie die Spezifikation eines bestehenden Inferenzdienstes nicht ändern. Sie können jedoch die Spezifikation kopieren, sie anpassen und die angepasste Spezifikation verwenden, um Ihren eigenen Dienst zum Hosten des Modells zu erstellen. Diese Methode schützt jedoch nicht davor, dass das zugrunde liegende Modell gelöscht wird. Darüber hinaus verfolgt es nicht die Abstammung. Am besten ist es, wenn Sie Snowflake Model Serving erlauben, Dienste zu erstellen.
Aussetzen von Diensten¶
Wenn Sie den Dienst nur von der SQL aus über Dienstfunktionen nutzen, setzen Sie den Parameter ingress_enabled
nicht auf „True“. Das Aktivieren von Ingress bedeutet, dass der Dienst ständig laufen muss, damit er auf eingehende HTTP-Anfragen reagieren kann. Wenn der Ingress nicht aktiviert ist, wird der Inferenzdienst nach dreißig Minuten Inaktivität automatisch angehalten und automatisch wieder aufgenommen, wenn er eine Anfrage erhält.
Um einen Dienst manuell auszusetzen, verwenden Sie den Befehl ALTER SERVICE.
ALTER SERVICE my_service SUSPEND;
Die automatische Wiederaufnahme des Dienstes nach Erhalt einer neuen Anfrage unterliegt Verzögerungen bei der Planung und beim Start. Die Verzögerung bei der Zeitplanung hängt von der Verfügbarkeit des Computepools ab, und die Verzögerung beim Start hängt von der Größe des Modells ab.
Löschen von Modellen¶
Sie können Modelle und Modellversionen wie gewohnt über die SQL-Weboberfläche oder die Python-API verwalten, mit der Einschränkung, dass ein Modell oder eine Modellversion, das/die von einem Dienst verwendet wird (unabhängig davon, ob es/sie läuft oder ausgesetzt ist), nicht gelöscht werden kann. Um ein Modell oder eine Version zu löschen, müssen Sie zuerst den Dienst löschen.
Beispiele¶
Diese Beispiele gehen davon aus, dass Sie bereits einen Computepool und ein Image-Repository erstellt und die erforderlichen Berechtigungen erteilt haben. Weitere Informationen dazu finden Sie unter Voraussetzungen.
Einsatz eines XGBoost-Modells für CPU-gestützte Inferenz¶
THe der folgende Code veranschaulicht die Schlüsselschritte bei der Bereitstellung eines XGBoost Modells für die Inferenz in SPCS und der anschließenden Verwendung des bereitgestellten Modells für die Inferenz. Ein Notizbuch für dieses Beispiel ist verfügbar unter.
from snowflake.ml.registry import registry
from snowflake.ml.utils.connection_params import SnowflakeLoginOptions
from snowflake.snowpark import Session
from xgboost import XGBRegressor
# your model training code here output of which is a trained xgb_model
# Open model registry
reg = registry.Registry(session=session, database_name='my_registry_db', schema_name='my_registry_schema')
# Log the model in Snowflake Model Registry
model_ref = reg.log_model(
model_name="my_xgb_forecasting_model",
version_name="v1",
model=xgb_model,
conda_dependencies=["scikit-learn","xgboost"],
sample_input_data=pandas_test_df,
comment="XGBoost model for forecasting customer demand"
)
# Deploy the model to SPCS
model_ref.create_service(
service_name="forecast_model_service",
service_compute_pool="my_cpu_pool",
image_repo="my_image_repo",
ingress_enabled=True)
# See all services running a model
model_ref.list_services()
# Run on SPCS
model_ref.run(pandas_test_df, function_name="predict", service_name="forecast_model_service")
# Delete the service
model_ref.delete_service("forecast_model_service")
Da bei diesem Modell der Ingress aktiviert ist, können Sie den HTTP-Endpunkt wie folgt aufrufen.
import json
import numpy as np
from pprint import pprint
import requests
import snowflake.connector
# Generate headers including authorization.
# This example uses session token authorization. Ideally key-pair authentication is used for API access.
def initiate_snowflake_connection():
connection_parameters = SnowflakeLoginOptions("connection_name")
connection_parameters["session_parameters"] = {"PYTHON_CONNECTOR_QUERY_RESULT_FORMAT": "json"}
snowflake_conn = snowflake.connector.connect(**connection_parameters)
return snowflake_conn
def get_headers(snowflake_conn):
token = snowflake_conn._rest._token_request('ISSUE')
headers = {'Authorization': f'Snowflake Token=\"{token["data"]["sessionToken"]}\"'}
return headers
headers = get_headers(initiate_snowflake_connection())
# Put the endpoint url with method name `predict`
# The endpoint url can be found with `show endpoints in service <service_name>`.
URL = 'https://<random_str>-<organization>-<account>.snowflakecomputing.app/predict'
# Prepare data to be sent
data = {"data": np.column_stack([range(pandas_test_df.shape[0]), pandas_test_df.values]).tolist()}
# Send over HTTP
def send_request(data: dict):
output = requests.post(URL, json=data, headers=headers)
assert (output.status_code == 200), f"Failed to get response from the service. Status code: {output.status_code}"
return output.content
# Test
results = send_request(data=data)
pprint(json.loads(results))
Einsatz eines Hugging Face-Satzumwandlers für GPU-gestützte Inferenz¶
Der folgende Code trainiert und setzt einen Hugging Face Satzumwandler ein, einschließlich eines HTTP-Endpunkts.
Dieses Beispiel erfordert das Paket sentence-transformers
, einen GPU Computepool und ein Image-Repository.
from snowflake.ml.registry import registry
from snowflake.ml.utils.connection_params import SnowflakeLoginOptions
from snowflake.snowpark import Session
from sentence_transformers import SentenceTransformer
session = Session.builder.configs(SnowflakeLoginOptions("connection_name")).create()
reg = registry.Registry(session=session, database_name='my_registry_db', schema_name='my_registry_schema')
# Take an example sentence transformer from HF
embed_model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2')
# Have some sample input data
input_data = [
"This is the first sentence.",
"Here's another sentence for testing.",
"The quick brown fox jumps over the lazy dog.",
"I love coding and programming.",
"Machine learning is an exciting field.",
"Python is a popular programming language.",
"I enjoy working with data.",
"Deep learning models are powerful.",
"Natural language processing is fascinating.",
"I want to improve my NLP skills.",
]
# Log the model with pip dependencies
pip_model = reg.log_model(
embed_model,
model_name="sentence_transformer_minilm",
version_name="pip",
sample_input_data=input_data, # Needed for determining signature of the model
pip_requirements=["sentence-transformers", "torch", "transformers"], # If you want to run this model in the Warehouse, you can use conda_dependencies instead
)
# Force Snowflake to not try to check warehouse
conda_forge_model = reg.log_model(
embed_model,
model_name="sentence_transformer_minilm",
version_name="conda_forge_force",
sample_input_data=input_data,
# setting any package from conda-forge is sufficient to know that it can't be run in warehouse
conda_dependencies=["sentence-transformers", "conda-forge::pytorch", "transformers"]
)
# Deploy the model to SPCS
pip_model.create_service(
service_name="my_minilm_service",
service_compute_pool="my_gpu_pool", # Using GPU_NV_S - smallest GPU node that can run the model
image_repo="my_image_repo",
ingress_enabled=True,
gpu_requests="1", # Model fits in GPU memory; only needed for GPU pool
max_instances=4, # 4 instances were able to run 10M inferences from an XS warehouse
)
# See all services running a model
pip_model.list_services()
# Run on SPCS
pip_model.run(input_data, function_name="encode", service_name="my_minilm_service")
# Delete the service
pip_model.delete_service("my_minilm_service")
In SQL können Sie die Dienstfunktion wie folgt aufrufen:
SELECT my_minilm_service!encode('This is a test sentence.');
Auf ähnliche Weise können Sie den HTTP-Endpunkt wie folgt aufrufen.
import json
from pprint import pprint
import requests
# Put the endpoint url with method name `encode`
URL='https://<random_str>-<account>.snowflakecomputing.app/encode'
# Prepare data to be sent
data = {
'data': []
}
for idx, x in enumerate(input_data):
data['data'].append([idx, x])
# Send over HTTP
def send_request(data: dict):
output = requests.post(URL, json=data, headers=headers)
assert (output.status_code == 200), f"Failed to get response from the service. Status code: {output.status_code}"
return output.content
# Test
results = send_request(data=data)
pprint(json.loads(results))
Einsatz eines PyTorch-Modells für GPU-gestützte Inferenz¶
Unter finden Sie in diesem Quickstart ein Beispiel für das Training und den Einsatz eines PyTorch Deep Learning-Empfehlungsmodells (DLRM) auf SPCS für GPU-Inferenz.
Best Practices¶
- Gemeinsame Nutzung des Image-Repositorys
Es ist üblich, dass mehrere Benutzer oder Rollen dasselbe Modell verwenden. Durch die Verwendung eines einzigen Image-Repositorys kann das Image einmal erstellt und von allen Benutzern wiederverwendet werden, was Zeit und Kosten spart. Alle Rollen, die das Repository verwenden, benötigen die Berechtigungen SERVICE READ, SERVICE WRITE, READ und WRITE für das Repository. Da das Image möglicherweise neu erstellt werden muss, um Abhängigkeiten zu aktualisieren, sollten Sie die Schreibrechte behalten und sie nicht widerrufen, nachdem das Image ursprünglich erstellt wurde.
- Skalierung des Inferencedienstes
Die automatische Skalierung von Snowpark Container-Dienstets ist sehr konservativ und skaliert nicht schnell genug für die meisten ML-Workloads. Aus diesem Grund empfiehlt Snowflake, sowohl MIN_INSTANCES als auch MAX_INSTANCES auf denselben Wert einzustellen und diese Werte so zu wählen, dass Sie die Leistung erhalten, die Sie für Ihre typischen Workloads benötigen. Verwenden Sie SQL wie folgt:
ALTER SERVICE myservice SET MIN_INSTANCES = <new_num> MAX_INSTANCES = <new_num>;
Aus demselben Grund akzeptiert die Methode
create_service
bei der anfänglichen Erstellung des Dienstes mit Python API nurmax_instances
und verwendet denselben Wert fürmin_instances
.- Auswahl des Knotentyps und der Anzahl der Instanzen
Verwenden Sie den kleinsten GPU-Knoten, bei dem das Modell in den Speicher passt. Skalieren Sie, indem Sie die Anzahl der Instanzen erhöhen, im Gegensatz zur Erhöhung von
num_workers
in einem größeren GPU-Knoten. Wenn das Modell beispielsweise in den Instanztyp GPU_NV_S (GPU_NV_SM auf Azure) passt, verwenden Siegpu_requests=1
und skalieren Sie durch Erhöhen vonmax_instances
, anstatt eine Kombination ausgpu_requests
undnum_workers
auf einer größeren GPU-Instanz zu verwenden.- Wahl der Warehouse-Größe
Je größer das Warehouse ist, desto mehr parallele Anfragen werden an die Inferenzserver gesendet. Die Inferenz ist eine teure Operation, verwenden Sie daher nach Möglichkeit ein kleineres Warehouse. Die Verwendung einer Warehouse-Größe, die größer als mittel ist, beschleunigt die Leistung der Abfrage nicht und verursacht zusätzliche Kosten.
Problembehandlung¶
Überwachen der SPCS-Bereitstellungen¶
Sie können die Bereitstellung überwachen, indem Sie die Dienste, die gestartet werden, mit der folgenden SQL-Abfrage überprüfen.
SHOW SERVICES IN COMPUTE POOL my_compute_pool;
Zwei Jobs werden gestartet:
MODEL_BUILD_xxxxx: Die letzten Zeichen des Namens werden randomisiert, um Namenskonflikte zu vermeiden. Dieser Job erstellt das Image und endet, nachdem das Image erstellt wurde. Wenn bereits ein Image existiert, wird der Job übersprungen.
Die Protokolle sind nützlich, um Probleme wie Konflikte in Paketabhängigkeiten zu beheben. Um die Protokolle dieses Jobs zu sehen, führen Sie die folgende SQL aus. Achten Sie darauf, dass Sie die gleichen letzten Zeichen verwenden:
CALL SYSTEM$GET_SERVICE_LOGS('MODEL_BUILD_xxxxx', 0, 'model-build');MYSERVICE: Der Name des Dienstes, wie er im Aufruf von
create_service
angegeben ist. Dieser Job wird gestartet, wenn der MODEL_BUILD-Job erfolgreich ist oder übersprungen wird. Um die Protokolle dieses Jobs zu sehen, führen Sie die folgende SQL aus:CALL SYSTEM$GET_SERVICE_LOGS('MYSERVICE', 0, 'model-inference');Wenn die Protokolle nicht über
SYSTEM$GET_SERVICE_LOG
verfügbar sind, weil der Build Job oder Dienst gelöscht wurde, können Sie unter die Ereignistabelle (falls aktiviert) aufrufen, um die Protokolle anzuzeigen:SELECT RESOURCE_ATTRIBUTES, VALUE FROM <EVENT_TABLE_NAME> WHERE true AND timestamp > dateadd(day, -1, current_timestamp()) -- choose appropriate timestamp range AND RESOURCE_ATTRIBUTES:"snow.database.name" = '<db of the service>' AND RESOURCE_ATTRIBUTES:"snow.schema.name" = '<schema of the service>' AND RESOURCE_ATTRIBUTES:"snow.service.name" = '<Job or Service name>' AND RESOURCE_ATTRIBUTES:"snow.service.container.instance" = '0' -- choose all instances or one particular AND RESOURCE_ATTRIBUTES:"snow.service.container.name" != 'snowflake-ingress' --skip logs from internal sidecar ORDER BY timestamp ASC;
Paketkonflikte¶
Zwei Systeme bestimmen, welche Pakete im Service Container installiert werden: das Modell selbst und der Inferenzserver. Um Konflikte mit den Abhängigkeiten Ihres Modells zu minimieren, benötigt der Inferenzserver nur die folgenden Pakete:
gunicorn<24.0.0
starlette<1.0.0
uvicorn-standard<1.0.0
Vergewissern Sie sich, dass Ihre Modellabhängigkeiten, zusammen mit den oben genannten, von pip
oder conda
aufgelöst werden können.
Wenn ein Modell sowohl conda_dependencies
als auch pip_requirements
eingestellt hat, werden diese über conda wie folgt installiert:
Kanäle:
conda-forge
nodefaults
Abhängigkeiten:
all_conda_packages
- pip :
all_pip_packages
Snowflake bezieht Anacaonda-Pakete von conda-forge
, wenn es Container-Images erstellt, da der Snowflake-Conda-Kanal nur in Warehouses verfügbar ist und der defaults
-Kanal von den Benutzern verlangt, dass sie die Anaconda-Nutzungsbedingungen akzeptieren, was während eines automatisierten Builds nicht möglich ist. Um Pakete von einem anderen Kanal zu erhalten, wie z. B. defaults
, geben Sie jedes Paket mit dem Namen des Kanals an, wie in defaults::pkg_name
.
Bemerkung
Wenn Sie sowohl conda_dependencies
als auch pip_requirements
angeben, wird das Container-Image erfolgreich erstellt, auch wenn die beiden Sätze von Abhängigkeiten nicht kompatibel sind, was dazu führen kann, dass das resultierende Container-Image nicht so funktioniert, wie Sie es erwarten. Snowflake empfiehlt, nur conda_dependencies
oder nur pip_requirements
zu verwenden, nicht beides.
Dienst außerhalb des Speichers¶
Einige Modelle sind nicht Thread-sicher, so dass Snowflake für jeden Worker-Prozess eine eigene Kopie des Modells in den Speicher lädt. Dies kann bei großen Modellen mit einer größeren Anzahl von Workern dazu führen, dass der Speicher überlastet wird. Versuchen Sie, num_workers
zu reduzieren.
Unbefriedigende Leistung bei Abfragen¶
Normalerweise wird die Inferenz durch die Anzahl der Instanzen im Inferenzdienst behindert. Versuchen Sie, einen höheren Wert für max_instances
anzugeben, wenn Sie das Modell einsetzen.
Sie können die Dienstspezifikation nicht ändern¶
Die Dienstspezifikationen für die Modellerstellung und die Inferenz können nicht über ALTER SERVICE geändert werden. Sie können nur Attribute wie TAG, MIN_INSTANCES und so weiter ändern. Da das Image jedoch im Image Repository veröffentlicht ist, können Sie die Spezifikation kopieren, sie ändern und daraus einen neuen Dienst erstellen, den Sie manuell starten können.
Paket nicht gefunden¶
Die Modellbereitstellung ist während der Image-Erstellungsphase fehlgeschlagen. Die Protokolle von model-build
deuten darauf hin, dass ein angefordertes Paket nicht gefunden wurde. (Dieser Schritt verwendet standardmäßig conda-forge
, wenn das Paket in conda_dependencies
erwähnt wird)
Die Paketinstallation kann aus einem der folgenden Gründe fehlschlagen:
Der Paketname oder die Version ist ungültig. Überprüfen Sie die Schreibweise und die Version des Pakets.
Die angeforderte Version des Pakets existiert nicht in
conda-forge
. Sie können versuchen, die Versionsangabe zu entfernen, um die neueste Version zu erhalten, die inconda-forge
verfügbar ist, oder stattdessenpip_requirements
verwenden. Sie können alle verfügbaren Pakete hier einsehen.Manchmal benötigen Sie vielleicht ein Paket von einem speziellen Kanal (z. B.
pytorch
). Fügen Sie der Abhängigkeit einchannel_name::
Präfix hinzu, z. B.pytorch::torch
.
Huggingface Hub-Version stimmt nicht überein¶
Ein Hugging Face-Modellinferenzdienst kann mit der folgenden Fehlermeldung fehlschlagen:
ImportError: huggingface-hub>=0.30.0,<1.0 is required for a normal functioning of this module, but found huggingface-hub==0.25.2
Das liegt daran, dass das transformers
-Paket nicht die korrekten Abhängigkeiten von huggingface-hub
angibt, sondern stattdessen im Code überprüft. Um dieses Problem zu beheben, protokollieren Sie das Modell erneut, wobei Sie dieses Mal die erforderliche Version von huggingface-hub
in den conda_dependencies
oder pip_requirements
explizit angeben.
Torch kann nicht mit CUDA kompiliert werden¶
Die typische Ursache für diesen Fehler ist, dass Sie sowohl conda_dependencies
als auch pip_requirements
angegeben haben. Wie im Abschnitt Paketkonflikte erwähnt, ist conda
der Paketmanager, der für die Erstellung des Container-Images verwendet wird. Anaconda löst Pakete von conda_dependencies
und pip_requirements
nicht gemeinsam auf und gibt conda-Paketen den Vorrang. Dies kann dazu führen, dass die conda-Pakete nicht mit den pip-Paketen kompatibel sind. Möglicherweise haben Sie torch
in den pip_requirements
angegeben, nicht in den conda_dependencies
. Ziehen Sie in Erwägung, die Abhängigkeiten entweder in conda_dependencies
oder pip_requirements
zu konsolidieren. Wenn das nicht möglich ist, geben Sie lieber die wichtigsten Pakete in conda_dependencies
an.