Inference Server
Learn how to perform model inference in Seldon Core using REST and gRPC protocols, including request/response formats and client examples.
This section will discuss how to make inference calls against your Seldon models or pipelines.
You can make synchronous inference requests via REST or gRPC or asynchronous requests via Kafka topics. The content of your request should be an inference v2 protocol payload:
REST payloads will generally be in the JSON v2 protocol format.
gRPC and Kafka payloads must be in the Protobuf v2 protocol format.
Synchronous Requests
For making synchronous requests, the process will generally be:
Find the appropriate service endpoint (IP address and port) for accessing the installation of Seldon Core 2.
Determine the appropriate headers/metadata for the request.
Make requests via REST or gRPC.
Find the Seldon Service Endpoint
In the default Docker Compose setup, container ports are accessible from the host machine. This means you can use localhost or 0.0.0.0 as the hostname.
The default port for sending inference requests to the Seldon system is 9000. This is controlled by the ENVOY_DATA_PORT environment variable for Compose.
Putting this together, you can send inference requests to 0.0.0.0:9000.
In Kubernetes, Seldon creates a single Service called seldon-mesh in the namespace it is installed into. By default, this namespace is also called seldon-mesh.
If this Service is exposed via a load balancer, the appropriate address and port can be found via:
kubectl get svc seldon-mesh -n seldon-mesh -o jsonpath='{.status.loadBalancer.ingress[0].ip}'If you are not using a LoadBalancer for the seldon-mesh Service, you can still send inference requests.
For development and testing purposes, you can port-forward the Service locally using the below. Inference requests can then be sent to localhost:8080.
kubectl port-forward svc/seldon-mesh -n seldon-mesh 8080:80If you are using a service mesh like Istio or Ambassador, you will need to use the IP address of the service mesh ingress and determine the appropriate port.
Make Inference Requests
Let us imagine making inference requests to a model called iris.
This iris model has the following schema, which can be set in a model-settings.json file for MLServer:
Examples are given below for some common tools for making requests.
An example seldon request might look like this:
The default inference mode is REST, but you can also send gRPC requests like this:
An example curl request might look like this:
An example grpcurl request might look like this:
The above request was run from the project root folder allowing reference to the Protobuf manifests defined in the apis/ folder.
You can use the Python tritonclient package to send inference requests.
A short, self-contained example is:
Request Routing
Seldon Routes
Seldon needs to determine where to route requests to, as models and pipelines might have the same name. There are two ways of doing this: header-based routing (preferred) and path-based routing.
Seldon can route requests to the correct endpoint via headers in HTTP calls, both for REST (HTTP/1.1) and gRPC (HTTP/2).
Use the Seldon-Model header as follows:
For models, use the model name as the value. For example, to send requests to a model named
foouse the headerSeldon-Model: foo.For pipelines, use the pipeline name followed by
.pipelineas the value. For example, to send requests to a pipeline namedfoouse the headerSeldon-Model: foo.pipeline.
The seldon CLI is aware of these rules and can be used to easily send requests to your deployed resources. See the examples and the Seldon CLI docs for more information.
The inference v2 protocol is only aware of models, thus has no concept of pipelines. Seldon works around this limitation by introducing virtual endpoints for pipelines. Virtual means that Seldon understands them, but other v2 protocol-compatible components like inference servers do not.
Use the following rules for paths to route to models and pipelines:
For models, use the path prefix
/v2/models/{model name}. This is normal usage of the inference v2 protocol.For pipelines, you can use the path prefix
/v2/pipelines/{pipeline name}. Otherwise calling pipelines looks just like the inference v2 protocol for models. Do not use any suffix for the pipeline name as you would for routing headers.For pipelines, you can also use the path prefix
/v2/models/{pipeline name}.pipeline. Again, this form looks just like the inference v2 protocol for models.
Extending our examples from above, the requests may look like the below when using header-based routing.
No changes are required as the seldon CLI already understands how to set the appropriate gRPC and REST headers.
Note the rpc-header flag in the penultimate line:
Note the headers dictionary in the client.infer() call:
Ingress Routes
If you are using an ingress controller to make inference requests with Seldon, you will need to configure the routing rules correctly.
There are many ways to do this, but custom path prefixes will not work with gRPC. This is because gRPC determines the path based on the Protobuf definition. Some gRPC implementations permit manipulating paths when sending requests, but this is by no means universal.
If you want to expose your inference endpoints via gRPC and REST in a consistent way, you should use virtual hosts, subdomains, or headers.
The downside of using only paths is that you cannot differentiate between different installations of Seldon Core 2 or between traffic to Seldon and any other inference endpoints you may have exposed via the same ingress.
You might want to use a mixture of these methods; the choice is yours.
Virtual hosts are a way of differentiating between logical services accessed via the same physical machine(s).
Virtual hosts are defined by the Host header for HTTP/1 and the :authority pseudo-header for HTTP/2. These represent the same thing, and the HTTP/2 specification defines how to translate these when converting between protocol versions.
Many tools and libraries treat these headers as special and have particular ways of handling them. Some common ones are given below:
The
seldonCLI has an--authorityflag which applies to both REST and gRPC inference calls.curlacceptsHostas a normal header.grpcurlhas an-authorityflag.In Go, the standard library's
http.Requeststruct has aHostfield and ignores attempts to set this value via headers.In Python, the
requestslibrary accepts the host as a normal header.
Be sure to check the documentation for how to set this with your preferred tools and languages.
Subdomain names constitute a part of the overall host name. As such, specifying a subdomain name for requests will involve setting the appropriate host in the URI.
For example, you may expose inference services in the namespaces seldon-1 and seldon-2 as in the following snippets:
Many popular ingresses support subdomain-based routing, including Istio and Nginx. Please refer to the documentation for your ingress of choice for further information.
Many ingress controllers and service meshes support routing on headers. You can use whatever headers you prefer, so long as they do not conflict with any Seldon relies upon.
Many tools and libraries support adding custom headers to requests. Some common ones are given below:
The
seldonCLI accepts headers using the--headerflag, which can be specified multiple times.curlaccepts headers using the-Hor--headerflags.grpcurlaccepts headers using the-Hflag, which can be specified multiple times.
It is possible to route on paths by using well-known path prefixes defined by the inference v2 protocol. For gRPC, the full path (or "method") for an inference call is:
This corresponds to the package (inference), service (GRPCInferenceService), and RPC name (ModelInfer) in the Protobuf definition of the inference v2 protocol.
You could use an exact match or a regex like .*inference.* to match this path, for example.
Asynchronous Requests
The Seldon architecture uses Kafka and therefore asynchronous requests can be sent by pushing inference v2 protocol payloads to the appropriate topic. Topics have the following form:
Model Inference
For a local install if you have a model iris, you would be able to send a prediction request by pushing to the topic: seldon.default.model.iris.inputs. The response will appear on seldon.default.model.iris.outputs.
For a Kubernetes install in seldon-mesh if you have a model iris, you would be able to send a prediction request by pushing to the topic: seldon.seldon-mesh.model.iris.inputs. The response will appear on seldon.seldon-mesh.model.iris.outputs.
Pipeline Inference
For a local install if you have a pipeline mypipeline, you would be able to send a prediction request by pushing to the topic: seldon.default.pipeline.mypipeline.inputs. The response will appear on seldon.default.pipeline.mypipeline.outputs.
For a Kubernetes install in seldon-mesh if you have a pipeline mypipeline, you would be able to send a prediction request by pushing to the topic: seldon.seldon-mesh.pipeline.mypipeline.inputs. The response will appear on seldon.seldon-mesh.pipeline.mypipeline.outputs.
Pipeline Metadata
It may be useful to send metadata alongside your inference.
If using Kafka directly as described above, you can attach Kafka metadata to your request, which will be passed around the graph. When making synchronous requests to your pipeline with REST or gRPC you can also do this.
For REST requests add HTTP headers prefixed with
X-For gRPC requests add metadata with keys starting with
X-
You can also do this with the Seldon CLI by setting headers with the --header argument (and also showing response headers with the --show-headers argument)
For pipeline inference, the response also contains a x-pipeline-version header, indicating which version of pipeline it ran inference with.
Request IDs
For both model and pipeline requests the response will contain a x-request-id response header. For pipeline requests this can be used to inspect the pipeline steps via the CLI, e.g.:
The --offset parameter specifies how many messages (from the latest) you want to search to find your request. If not specified the last request will be shown.
x-request-id will also appear in tracing spans.
If x-request-id is passed in by the caller then this will be used. It is the caller's responsibility to ensure it is unique.
The IDs generated are XIDs.
Last updated
Was this helpful?

