Prepare and test your skills
Prepare and test your skills
Vertex AI custom serving is the pattern where inference preprocessing, prediction, and postprocessing all run inside a containerized HTTP server managed by Vertex AI (opens in a new tab). A custom prediction routine extends a prebuilt serving image with custom handler code, while a fully custom container (opens in a new tab) replaces the entire server. Both approaches let the same image deserialize diverse request payloads, apply business logic, and format prediction responses to prevent training-serving skew.
Custom prediction routines and fully custom containers both run on Vertex AI endpoints, but they divide ownership of the HTTP server differently. A custom prediction routine keeps the prebuilt server and adds a custom predictor handler for preprocessing and postprocessing, while a fully custom container requires the team to build and operate the entire HTTP server.
| Option | HTTP server ownership | Choose when |
|---|---|---|
| Custom prediction routine | Vertex AI prebuilt server handles liveness, health, and routing; custom handler handles deserialization and formatting | Input needs custom parsing or output needs custom business logic but the framework server is sufficient |
| Custom container | Team builds the server in any language or framework and implements the full serving contract | Model needs a nonstandard runtime, multi-model logic, or specialized preprocessing that prebuilt images cannot express |
Custom code in either option sits on the request path between Vertex AI and the model. Traffic flows from the Vertex AI endpoint to the container, the handler transforms the payload, the model produces raw outputs, and the handler transforms those outputs back into the client response.
The serving container contract requires the Docker image to run an HTTP server indefinitely when the container starts. The serving container contract applies to any language or framework, as long as the server listens and responds to liveness checks, health checks, and inference requests from Vertex AI. Common ways to meet the serving container contract include:
The start command for the server comes from the image Dockerfile ENTRYPOINT, the Dockerfile CMD, or both together. Vertex AI can override that startup behavior without rebuilding the image by setting containerSpec.command to replace ENTRYPOINT and containerSpec.args to replace CMD. However the command is set, the resulting process must run indefinitely so the container stays alive to accept checks and predictions.
Exam tip: Use containerSpec.command and containerSpec.args to fix an incompatible or missing ENTRYPOINT and CMD instead of rebuilding an otherwise working image.
Liveness checks, health checks, and inference requests define the serving lifecycle that the container HTTP server must support. Liveness indicates whether the container process is running, health indicates whether the model and dependencies are ready to serve, and inference carries the actual prediction workload. The interaction follows an ordered sequence:
This ordering protects latency and reliability because no prediction traffic flows to a container until its server, model, and custom logic have all reported readiness.
Image publishing, permissions, and model artifact access control whether Vertex AI can deploy and run the serving container. The serving container image must be published in a registry location that Vertex AI can reach, with permissions that allow the Vertex AI service to pull the image at deploy time. The Model resource references that image URI, so the deployment depends on both the image location and the grant that authorizes access. Model artifacts are separate from the container image and are accessed by the running container during startup and inference. The container loads those artifacts into memory during initialization, then applies them to every inference request without reloading them per request.
Environment variables available to the inference container configure ports, paths, and custom behavior without changing handler code. The inference container merges configuration from three distinct owners, which lets platform routing, image defaults, and per-model settings compose in one runtime.
Custom predictor handlers read these variables at startup to locate artifacts and at request time to control deserialization and response formatting, so the same image can serve different models with different preprocessing rules.
In-graph and exported artifact transformations embed preprocessing and postprocessing directly into the served model artifact so Vertex AI (opens in a new tab) receives raw inference payloads and returns finished predictions. The exported artifact flows from the training process to Cloud Storage (opens in a new tab) to a Vertex AI Model resource to an endpoint, and the serving container loads the artifact and executes the embedded logic on each request. This design eliminates training-serving skew because the same transformation code runs in training and serving, and it reduces latency by avoiding a separate preprocessing service hop.
A TensorFlow SavedModel artifact packages the computation graph, including any in-graph preprocessing and postprocessing ops, as saved_model.pb for serving by a TensorFlow prebuilt container. The TensorFlow SavedModel artifact lives in the Cloud Storage directory that the Model resource points to, and TensorFlow Serving loads that graph and applies the embedded transformations before and after the core model computation. To enable server-side request batching, include config/batching_parameters_config in the same Cloud Storage directory as saved_model.pb and configure it according to TensorFlow Serving batching configuration. Batching lets the server combine individual inference requests from clients into efficient graph executions, then split the results back to each request destination.
A PyTorch model served by the prebuilt container must be packaged as a model archive file named model.mar that contains model weights, supporting artifacts, and a handler script. The PyTorch handler script, either default or custom, defines how the model processes inference requests, with data flowing from the client payload to the handler preprocessing function to the PyTorch model forward pass to the handler postprocessing function and back to the client response. The archive must be created with model-name model so the prebuilt TorchServe image finds model.mar at load time. For advanced workflows that need custom libraries, multi-model logic, or non-standard raw formats, use custom containers instead of relying on the prebuilt PyTorch serving image.
XGBoost and scikit-learn artifacts embed transformations by exporting a single file whose filename must exactly match what the prebuilt inference container expects. An XGBoost model trained in a prebuilt container is exported either with xgboost.Booster save_model as model.bst or with the joblib library as model.joblib, while a scikit-learn model is exported with joblib as model.joblib. A scikit-learn Pipeline object is the in-artifact mechanism for skew prevention because the pipeline chains transformers and the final estimator into one object, so raw features flow from the request through each transformer step in order to the estimator without separate serving code. Export follows the same ordered lifecycle for both frameworks:
model.bst or model.joblib to the local filesystem, which does not persist beyond the training worker.AIP_MODEL_DIR environment variable using the Cloud Storage client, so the artifact flows from the ephemeral trainer to durable storage for deployment.To serve inferences, create a Model with the prebuilt container for inference matching the XGBoost or scikit-learn version used for training, because the serving container depends on that version to deserialize the artifact.
A custom container is a Docker image that runs an HTTP server and is used when preprocessing or postprocessing cannot be fully embedded in saved_model.pb, model.mar, model.bst, or model.joblib. The custom container must listen and respond to liveness checks, health checks, and inference requests after Vertex AI starts it, and the server can be implemented with Flask, TensorFlow Serving, TorchServe, or KServe Python Server. The container loads model artifacts from Cloud Storage at startup, then on each request data flows from the endpoint to the custom HTTP handler to the model and back through postprocessing to the response. Choose a custom container when raw payload parsing, external feature lookups, or complex output formatting must live in serving code outside the exported graph or pipeline.
Exported artifact requirements define the filename contract, the transformation carrier, and the serving dependency for each framework. The choice of artifact determines how transformations travel with the model and what the serving container expects at load time.
| Option | Artifact filename | Transformation carrier |
|---|---|---|
| TensorFlow | saved_model.pb plus optional config/batching_parameters_config in same directory | In-graph ops inside the SavedModel graph |
| PyTorch | model.mar created with model-name model | Handler script inside the archive |
| XGBoost | model.bst or model.joblib | Exported booster object with training-time feature handling |
| scikit-learn | model.joblib | Pipeline object chaining transformers to estimator |
The serving container depends on an exact filename match and, for XGBoost and scikit-learn, on a container version match with training, so a mismatched name or version prevents the Model from loading.
Exam tip: The prebuilt PyTorch image expects model.mar, XGBoost expects model.bst or model.joblib, and scikit-learn expects model.joblib — the filename must match exactly.
Architecting low-latency feature enrichment and stream transformations means combining a real-time event stream with precomputed features for inference without adding lookup delay. In this architecture, Cloud Pub/Sub (Pub/Sub) (opens in a new tab) carries the live transaction stream, Dataflow runs an Apache Beam (Beam) streaming pipeline, Vertex AI Feature Store (Feature Store) (opens in a new tab) supplies low-latency feature values, and Vertex AI endpoints return predictions. The pipeline enriches each event in flight and then scores it, so preprocessing, inference, and post-prediction handling stay in one scalable streaming path.
Vertex AI Feature Store is the central system for creating, maintaining, sharing, and serving machine learning features for both training and inference. Feature data lives in BigQuery as a table or view, which retains all data including historical feature values for offline work such as training and batch analysis. To serve online, you must first create an online store instance and then define feature views that map entity keys, such as user_id, to their precomputed features. Because the same BigQuery-backed definitions feed both offline training and the online store, the serving path reuses the same feature logic and reduces training-serving skew.
| Serving mode | Backing storage | Use when |
|---|---|---|
| Online serving | Online store instance with Bigtable online serving | Each streaming request needs a millisecond-scale key lookup before inference |
| Offline use | BigQuery table or view with historical values | Training, evaluation, or batch scoring needs point-in-time history |
Online serving is optimized for workloads that need low latency during streaming inference. As of Apache Beam SDK version 2.55.0, online feature serving is supported through Bigtable online serving and the Vertex AI Feature Store legacy method, with Bigtable online serving used for the enrichment pattern.
Cloud Pub/Sub is the ingestion layer that delivers the unbounded transaction stream into the Beam pipeline running on Dataflow. Each Pub/Sub message carries only the live event fields, for example product_id, user_id, and sale_price in an ecommerce recommendation case. The full model input requires additional context such as age, gender, state, and country, which are not in the event and must be joined at inference time. This split keeps the event small and fast while the pipeline fetches the remaining features by key during enrichment.
The Apache Beam enrichment transform is a turnkey element-wise transform that enriches each streaming element by key-value lookup against Vertex AI Feature Store. Data flows from the Pub/Sub source to the enrichment step, the enrichment step calls Feature Store with the entity key from the event, and the returned feature values flow forward joined to the original event. The enriched record then becomes the complete inference request, so preprocessing happens inline without a separate batch join. The enrichment transform provides three peer capabilities for production streaming:
Exam tip: Use Apache Beam SDK version 2.55.0 or later when the pipeline uses the enrichment transform with Bigtable online serving; earlier versions do not support that path.
Streaming inference is performed by the Beam RunInference transform using the VertexAIModelHandlerJSON interface to call a deployed Vertex AI model. The VertexAIModelHandlerJSON interface holds the connection from the pipeline to the Vertex AI endpoint, formats each enriched record as JSON, and routes the prediction request to the deployed model. The model returns a prediction, such as a product recommendation, and that prediction flows to downstream post-prediction steps such as writing to a sink, publishing to another Pub/Sub topic, or triggering an action. The end-to-end streaming flow runs in strict order:
product_id, user_id, and sale_price to Pub/Sub.user_id in Vertex AI Feature Store and joins age, gender, state, and country onto each event.RunInference transform sends the enriched JSON record through VertexAIModelHandlerJSON to the Vertex AI endpoint for online prediction.This order matters because inference depends on enrichment, and enrichment depends on both the live key from Pub/Sub and the pre-provisioned online store and feature views.
containerSpec.command replaces Dockerfile ENTRYPOINT while containerSpec.args replaces Dockerfile CMD.saved_model.pb with optional config/batching_parameters_config, PyTorch uses model.mar with model-name model, XGBoost uses model.bst or model.joblib, and scikit-learn uses model.joblib.RunInference through VertexAIModelHandlerJSON, and forwards predictions for post-processing.A custom prediction routine keeps the Vertex AI prebuilt server to handle liveness, health, and routing while adding a custom predictor handler for deserialization and formatting, whereas a fully custom container requires the team to build and operate the entire HTTP server. Choose a custom prediction routine when input needs custom parsing or output needs custom business logic but the framework server is sufficient, and choose a fully custom container when the model needs a nonstandard runtime, multi-model logic, or specialized preprocessing that prebuilt images cannot express.
TensorFlow expects saved_model.pb with optional config/batching_parameters_config in the same Cloud Storage directory, PyTorch expects model.mar created with model-name model, XGBoost expects model.bst or model.joblib, and scikit-learn expects model.joblib. The serving container depends on an exact filename match and, for XGBoost and scikit-learn, on a container version match with training, so a mismatched name or version prevents the Model from loading.
The Dataflow pipeline running Apache Beam (Beam) reads the unbounded Cloud Pub/Sub (Pub/Sub) stream, uses the enrichment transform to look up the entity key such as user_id in Vertex AI Feature Store (Feature Store) and join the returned features onto each event, then uses the RunInference transform with VertexAIModelHandlerJSON to send the enriched JSON record to the Vertex AI endpoint for online prediction. Inference depends on enrichment because the live event carries only fields like product_id, user_id, and sale_price while the remaining context must be joined at inference time.
Last updated