CertSafari
    Snowflake SnowPro Specialty: Gen AI (GES-C02)· Lessons

    Domain 2 · Lesson 7/15

    Run Third-Party Models in Snowflake: SPCS and Model Registry

    Run third-party models in Snowflake.

    18 min read
    7.6% of exam
    8 sources
    Published 5 Oct 2026
    Docs as of 4 Oct 2026

    What you will be able to do

    • Set up the account objects Snowpark Container Services needs, including the role, warehouse, compute pool and image repository
    • Build a linux/amd64 Docker image, tag it with a Snowflake repository URL and know which privileges control the repository
    • Write a service specification file and know which fields are required and which ones override Dockerfile defaults
    • Log a model with the Snowflake Model Registry and call its methods from Python or SQL, including how versions are chosen

    Key concept

    Two routes for running your own model — A model you bring to Snowflake runs in one of two ways. You can log it in the Model Registry and call its methods, which run in a virtual warehouse with no container work from you. Or you can package it yourself as an OCI image and run it as a Snowpark Container Services service on a compute pool, which is also where the registry serves models that need GPUs.

    1.Snowpark Container Services: what it is and the environment it needs

    Snowpark Container Services (SPCS) is a managed container orchestration platform inside Snowflake. You package an application and its dependencies into an Open Container Initiative (OCI) image, which can contain any language, framework or library. The documentation names custom runtimes, specialized libraries and GPU workloads such as ML model serving and training as the use cases. Snowflake runs the infrastructure, and you control what goes in the container. Your container can still connect to Snowflake, run SQL in a virtual warehouse, read files from a stage, and use your existing network policies, external access integrations, role-based access control and event tables.

    On top of the usual databases and warehouses, SPCS adds three objects: an image repository that stores your images, a compute pool of VM nodes that runs them, and a service that defines what runs. A workload runs in one of two forms:

    The two ways to run a container workload in SPCS
    FormLifespanRestart behaviourCommand
    ServiceLong-running; you stop it explicitlySnowflake restarts a container that exitsCREATE SERVICE
    Job serviceFinite, like a stored procedure; done when all containers exitSnowflake doesn't restart job service containersEXECUTE JOB SERVICE

    Environment setup. The common tutorial setup lists these prerequisites: a Snowflake account (trial accounts are not supported), a SQL client such as SnowSQL or Snowsight, and Docker Desktop. Any OCI-compliant client, such as Podman or Nerdctl, also works for building images. The setup script runs as ACCOUNTADMIN. It creates a dedicated role, gives that role ownership of a database, creates an X-SMALL warehouse and grants USAGE on it, grants BIND SERVICE ENDPOINT on the account (needed for a service that exposes a public endpoint), creates a compute pool and grants USAGE and MONITOR on it, and then grants the role to the user who will do the work.

    The warehouse can look out of place, because containers run on the compute pool and not in a warehouse. It is there because services, including job services, can run SQL DML statements, and Snowflake runs those statements in a warehouse. SQL is the main interface in the documentation, but Python APIs, REST APIs and the Snowflake CLI cover most of the same operations.

    Checkpoint 1 of 9· Check yourself

    The SPCS common setup script creates a virtual warehouse even though containers run on a compute pool. Why?

    Sources12

    2.Image repositories and Docker images

    Snowflake runs an OCIv2-compliant image registry for each account. Inside it you create repositories, which are named storage units for images. The documentation compares the two to a DBMS and a table: the registry is the DBMS and each repository is a table. You create a repository with CREATE IMAGE REPOSITORY, which needs the CREATE IMAGE REPOSITORY privilege on the schema. You manage repositories with DROP IMAGE REPOSITORY and SHOW IMAGE REPOSITORIES, and list their contents with SHOW IMAGES IN IMAGE REPOSITORY. You might create separate DEV, TEST and PROD repositories, or give different repositories different permissions.

    The registry hostname follows the pattern <orgname>-<acctname>.registry.snowflakecomputing.com, and a repository URL is <registry-hostname>/<db_name>/<schema_name>/<repository_name>. URLs can't contain underscores, so an account name like my_account becomes my-account. SHOW IMAGE REPOSITORIES returns the repository URL for you.

    You have to authenticate before Docker can push. One option is the Snowflake CLI command snow spcs image-registry login. Another is docker login with a programmatic access token (PAT): the username is "USER" and the token is the password. Plain username/password login works only if an administrator enables it, because MFA is incompatible with docker login.

    Docker images. You build the image from a Dockerfile for the linux/amd64 platform. Then you tag it with the repository URL and push it. In the containers tutorial the build command looks like this:

    Building an SPCS-compatible image for the linux/amd64 platformbash
    docker build --rm --platform linux/amd64 -t my_echo_service_image:tutorial .

    Next you get the repository URL with snow spcs image-repository url or SHOW IMAGE REPOSITORIES, and tag the image with docker tag <image_name> <image_url>/<image_name> so that the push lands in your Snowflake repository. Access control applies to the whole repository. You can't set permissions on individual images. You also can't drop a single image: dropping the repository removes all of its images. The largest compressed layer allowed is 160 GiB on AWS and 195 GiB on Azure.

    Image repository privileges
    PrivilegeWhat it enables
    READList and download images
    WRITEList and download images, and push images
    OWNERSHIPList and download images, and push images
    SERVICE READA container service lists and downloads images (needed for the image building step of model serving)
    SERVICE WRITEA container service pushes images (needed for the image building step of model serving)

    Checkpoint 2 of 9· Put it in order

    Put these steps for getting an image into Snowflake in order

    1. 1.Build the image with docker build --platform linux/amd64
    2. 2.Look up the repository URL
    3. 3.Tag the image with the repository URL using docker tag
    4. 4.Create the repository with CREATE IMAGE REPOSITORY

    Sources3

    3.Creating a compute pool

    Services and job services run on a compute pool, a collection of one or more VM nodes. A compute pool is an account-level object, much like a virtual warehouse, so each pool name must be unique in the account. You create the pool first and then name it when you create a service or job service. You need three pieces of information to create one:

    - Instance family: the machine type. Choosing it is like choosing a warehouse size, and some families provide GPUs. SHOW COMPUTE POOL INSTANCE FAMILIES lists the available families. - Minimum nodes: how many nodes the pool launches with. - Maximum nodes: the upper limit for Snowflake's autoscaling.

    You can create a pool with SQL, or in Snowsight under Compute » Compute Pools using ACCOUNTADMIN or another role that is allowed to create pools.

    Creating a one-node CPU compute poolsql
    CREATE COMPUTE POOL tutorial_compute_pool MIN_NODES = 1 MAX_NODES = 1 INSTANCE_FAMILY = CPU_X64_XS;

    After creation, Snowflake launches the minimum number of nodes and adds more, up to the maximum, when the running nodes can't take any more work. It also removes nodes that have run no services for a while, but never goes below the minimum. Setting the minimum above 1 keeps spare capacity ready for bursts of load instead of waiting for autoscaling. Setting a maximum caps cost if a load spike or a bug would otherwise make Snowflake add many nodes.

    The placement_group setting is optional. Without it, Snowflake places nodes wherever capacity is available. With DISTRIBUTED, Snowflake tries to spread nodes across placement groups for fault tolerance. If a placement group fails, Snowflake doesn't automatically fail nodes over to a healthy group, so the documentation recommends overprovisioning service instances (N+1).

    Checkpoint 3 of 9· Check yourself

    Which of these is NOT part of the minimum information needed to create a compute pool?

    Checkpoint 4 of 9· Exam question

    A team wants to deploy a custom PyTorch model that requires GPU inference and needs full control over the runtime environment, including custom system libraries not available in Snowflake warehouses. Which Snowflake feature should they use to host this workload?

    Sources4

    4.Service specification files

    The pool supplies the machines and the repository holds the image. The specification file, written in YAML and supplied when you create the service, tells Snowflake how to run the image. It has two top-level fields: spec and serviceRoles. Service roles control privileges on the endpoints the service exposes. Under spec, only containers is required. A service must have at least one container, and each container needs only a name and an image, where the image is one you uploaded to a repository in your account. All containers of one service instance run on a single node and share its network interface. Container, endpoint and volume names can be up to 63 characters long, may contain only lowercase alphanumerics and -, must start with a letter and must end with an alphanumeric character.

    Main specification fields and what they control
    FieldRequired?Purpose
    spec.containersYesOne or more application containers (name and image required)
    spec.endpointsNoEndpoints the service exposes; an endpoint can be made public for ingress
    spec.volumesNoStorage volumes for the containers (local, stage, memory or block)
    spec.logExportersNoLevel of container logs exported to the event table
    spec.resourceManagementNoAutoscaling policies to scale service instances up, down, or suspend them
    serviceRolesNoService roles that manage privileges on endpoints

    The spec can override what you put in the Dockerfile, so changing a container's behaviour doesn't require rebuilding the image. containers.command overrides the Dockerfile ENTRYPOINT, and containers.args overrides CMD. containers.env sets environment variables for every process in the container. The example below sets two variables. Because one of them changes the listening port, the endpoint's port has to change to match:

    Overriding environment variables and updating the endpoint port to matchyaml
    spec:
      containers:
      - name: echo
        image: <image_name>
        env:
          CHARACTER_NAME: Bob
          SERVER_PORT: 8085
      endpoints:
      - name: echo-endpoint
        port: 8085

    Other container fields you'll see:

    - readinessProbe: Snowflake sends an HTTP GET to the given port and path, expects HTTP 200 OK, and stops routing traffic to the container while the probe fails. - resources: requests and limits for memory, CPU and nvidia.com/gpu. - secrets: points to a snowflakeSecret by objectName or objectReference, and delivers it to the container through an envVarName or a directoryPath. The credential then never has to appear in the image or the spec.

    Under the top-level capabilities.securityContext, executeAsCaller signals that the application intends to use caller's rights. Don't put personal, sensitive or regulated data in the specification as metadata.

    Checkpoint 5 of 9· Check yourself

    Your Dockerfile has ENTRYPOINT ["python3", "main.py"] and CMD ["Bob"]. You want the service to pass "Alice" instead of "Bob" without rebuilding the image. Which specification field do you set?

    Checkpoint 6 of 9· Exam question

    A developer runs `docker push` targeting their Snowflake account after tagging an image for their custom inference service. Which object must already exist in Snowflake to receive this pushed image?

    Sources5

    5.Model Registry: logging the model

    SPCS means building and running containers yourself. The Snowflake Model Registry is the shorter route for a trained Python model. It stores models as schema-level objects together with their versions, metrics and metadata, and runs inference from Python, SQL or REST endpoints. Its built-in types include scikit-learn, xgboost, LightGBM, Prophet, CatBoost, PyTorch, TensorFlow, Keras, Hugging Face pipelines, Sentence Transformer and MLFlow pyfunc models, and it also accepts custom models. Models trained with Snowflake ML Functions such as FORECAST don't appear in the registry. The API is generally available from snowflake-ml-python 1.5.0.

    Any schema can act as a registry without setup, though Snowflake recommends a dedicated schema such as ML.REGISTRY. You start by opening the registry:

    Opening a registry in a schemapython
    from snowflake.ml.registry import Registry
    
    reg = Registry(session=session, database_name="ML", schema_name="REGISTRY")

    Adding a model is called logging it. log_model serializes the Python model object, creates a Snowflake model object from it, and records metadata such as a comment and metrics. It has two required arguments: model, which must be picklable, and model_name, which can't be changed later. The model name and version name together must be unique in the schema. To add a version, call log_model again with the same model_name and a new version_name. conda_dependencies lists packages to deploy with the model. You can't add tags in the log_model call, because the model object is only created when its first version is logged. Add tags afterwards.

    To create a model you must own the schema or hold CREATE MODEL on it. The limits are up to 1000 versions per model, 10 methods per version, and 15 GB total model size for warehouse-deployed models. You can also import models from an external provider.

    Checkpoint 7 of 9· Fill the gap

    Which registry method completes this sample that adds a model version?

    mv = reg. ? (clf,
                       model_name="my_model",
                       version_name="v1",
                       conda_dependencies=["scikit-learn"],
                       comment="My awesome ML model",
                       metrics={"score": 96},
                       sample_input_data=train_features,
                       task=task.Task.TABULAR_BINARY_CLASSIFICATION)

    Sources6

    6.Model Registry: calling the model

    A logged model version has methods, such as predict, which are functions attached to the model. Different versions of a model can have different methods with different signatures. In Python, you call a method with mv.run, where mv is a ModelVersion. You pass a Snowpark or pandas DataFrame and the function_name, and you get back a DataFrame of the same type. The method runs in the warehouse of your current session. Snowpark DataFrames are evaluated lazily, so nothing runs until you call collect, show or to_pandas.

    Running a model version's predict method from Pythonpython
    remote_prediction = mv.run(test_features, function_name="predict")

    In SQL, the syntax is MODEL(<model_name>)!<method_name>(...), with the inference table in the FROM clause. If you don't name a version, the call goes to the model's default version, not automatically to the newest one. To target a specific version, pass a version name or alias as the second argument. The built-in LAST alias selects the latest version. SHOW FUNCTION IN MODEL ... VERSION ... lists a version's methods and their signatures.

    Calling the latest version through the LAST alias in SQLsql
    SELECT MODEL(my_model,LAST)!predict(...) FROM my_table;

    Calling a model also needs privileges. USAGE allows warehouse inference without exposing the model's internals. READ allows SPCS inference and also shows metadata such as comments, tags and metrics. Both can be granted on all current or future models in a schema, for example with GRANT USAGE ON FUTURE MODELS IN SCHEMA.

    Checkpoint 8 of 9· Check yourself

    A model has versions v1, v2 and v3. A query runs SELECT MODEL(my_model)!predict(...) FROM t without naming a version. Which version executes?

    Checkpoint 9 of 9· Exam question

    Which SQL commands are part of the standard workflow for preparing the environment to run a custom Docker-based service in Snowpark Container Services? (Select all that apply.)(Select 3)

    Sources67

    Exam traps

    Each one states something that sounds right. Open it to see what is actually true.

    1. 1.SPCS accepts images built for any platform, including ARM images built on a laptop.Why is that wrong?

      SPCS currently requires linux/amd64 images, so you build with --platform linux/amd64.

      Covered in Image repositories and Docker images

    2. 2.You can delete one outdated image from a repository, or restrict access to individual images.Why is that wrong?

      Dropping individual images isn't supported, and access control applies to the whole repository. Dropping the repository removes all of its images.

      Covered in Image repositories and Docker images

    3. 3.Compute pools are schema-level objects, so two schemas can each have a pool with the same name.Why is that wrong?

      A compute pool is an account-level object, like a warehouse, so its name must be unique in the account.

      Covered in Creating a compute pool

    4. 4.You can attach tags to a model in the log_model call.Why is that wrong?

      log_model adds a version and creates the model only when its first version is logged. Tags are attributes of the model, so you add them afterwards.

      Covered in Model Registry: logging the model

    5. 5.USAGE on a model is enough for every kind of inference, including models served in SPCS.Why is that wrong?

      USAGE covers warehouse inference only. SPCS inference requires READ, which also shows the model's metadata.

      Covered in Model Registry: calling the model

    Sources

    Every claim above is drawn from one of these pages, quoted as it was written on the date shown.

    1. 2.
      “Note that you can use any OCI-compliant clients to create images, such as Docker, Podman, or Nerdctl.”
      ↩︎ Snowpark Container Services: what it is and the environment it needs
      “You create a warehouse because the services (including job services) can run SQL DML statements (such as SELECT and INSERT).”
      ↩︎ Checkpoint
    2. 3.
      “Access control is supported at the repository level; individual image-level access control is not supported.”
      ↩︎ Image repositories and Docker images
      “Enables a container service to list and download images from a repository. This is needed for the image building step of model serving.”
      ↩︎ Image repositories and Docker images
      “Dropping images from a repository is currently not supported.”
      ↩︎ Exam trap 2
    3. 4.
      “The machine type (referred to as the instance family) to provision for the compute pool nodes”
      ↩︎ Creating a compute pool
      “Setting a maximum node limit prevents an unexpectedly large number of nodes from being added to your compute pool by Snowflake autoscaling.”
      ↩︎ Creating a compute pool
      “A compute pool is an account-level construct, analogous to a Snowflake virtual warehouse.”
      ↩︎ Exam trap 3
      “You can optionally specify which placement group to provision compute pool nodes in”
      ↩︎ Checkpoint
    4. 5.
      “For each container, only name and image are required fields.”
      ↩︎ Service specification files
      “containers.command overrides the Dockerfile ENTRYPOINT.”
      ↩︎ Service specification files
      “Currently, Snowpark Container Services requires linux/amd64 platform images.”
      ↩︎ Exam trap 1
      “Currently, Snowpark Container Services requires linux/amd64 platform images.”
      ↩︎ Prediction
      “containers.args overrides the Dockerfile CMD.”
      ↩︎ Checkpoint
    5. 6.
      “Adding a model to the registry is called logging the model.”
      ↩︎ Model Registry: logging the model
      “To log additional versions of the model, call log_model again with the same model_name but a different version_name.”
      ↩︎ Model Registry: logging the model
      “To call a method of a model version, use mv.run, where mv is a ModelVersion object.”
      ↩︎ Model Registry: calling the model
      “perform model operations, such as inference, in a Snowflake virtual warehouse, or serve the model in Snowpark Container Services for GPU-based inference”
      ↩︎ Key concept
      “You cannot add tags to a model when it is added to the registry”
      ↩︎ Exam trap 4
      “The READ privilege allows grantees to use the model for SPCS inference and also see its metadata”
      ↩︎ Exam trap 5
    6. 7.
      “The following example uses the LAST alias to call the latest version of a model.”
      ↩︎ Model Registry: calling the model
      “To call a method of the default model, use the following syntax.”
      ↩︎ Checkpoint

    Also cited

    Ready to test yourself?

    Practise the 27 questions on this subdomain.

    Spotted a mistake, or was something unclear? Tell us.