Shadow Rollout with Seldon and Ambassador

This notebook shows how you can deploy “shadow” deployments to direct traffic not only to the main Seldon Deployment but also to a shadow deployment whose reponse will be dicarded. This allows you to test new models in a production setting and with production traffic and anlalyse how they perform before putting them live.

These are useful when you want to test a new model or higher latency inference piepline (e.g., with explanation components) with production traffic but without affecting the live deployment.

Setup Seldon Core

Use the setup notebook to Setup Cluster with Ambassador Ingress and Install Seldon Core. Instructions also online.

[1]:
!kubectl create namespace seldon
Error from server (AlreadyExists): namespaces "seldon" already exists
[2]:
!kubectl config set-context $(kubectl config current-context) --namespace=seldon
Context "kind-seldon" modified.
[3]:
from IPython.core.magic import register_line_cell_magic

@register_line_cell_magic
def writetemplate(line, cell):
    with open(line, 'w') as f:
        f.write(cell.format(**globals()))
[4]:
VERSION=!cat ../../../version.txt
VERSION=VERSION[0]
VERSION
[4]:
'1.6.0-dev'

Launch main model

We will create a very simple Seldon Deployment with a dummy model image seldonio/mock_classifier:1.0. This deployment is named example.

[5]:
%%writetemplate model.yaml
apiVersion: machinelearning.seldon.io/v1alpha2
kind: SeldonDeployment
metadata:
  labels:
    app: seldon
  name: example
spec:
  name: production-model
  predictors:
  - componentSpecs:
    - spec:
        containers:
        - image: seldonio/mock_classifier:{VERSION}
          imagePullPolicy: IfNotPresent
          name: classifier
        terminationGracePeriodSeconds: 1
    graph:
      children: []
      endpoint:
        type: REST
      name: classifier
      type: MODEL
    name: default
    replicas: 1

[6]:
!kubectl apply -f model.yaml
seldondeployment.machinelearning.seldon.io/example configured
[7]:
!kubectl rollout status deploy/$(kubectl get deploy -l seldon-deployment-id=example -o jsonpath='{.items[0].metadata.name}')
deployment "example-default-0-classifier" successfully rolled out

Get predictions

[8]:
from seldon_core.seldon_client import SeldonClient
sc = SeldonClient(deployment_name="example",namespace="seldon")

REST Request

[9]:
r = sc.predict(gateway="ambassador",transport="rest")
print(r)
Success:True message:
Request:
meta {
}
data {
  tensor {
    shape: 1
    shape: 1
    values: 0.9967112738898524
  }
}

Response:
{'data': {'names': ['proba'], 'tensor': {'shape': [1, 1], 'values': [0.12786654068631786]}}, 'meta': {'requestPath': {'classifier': 'seldonio/mock_classifier:1.6.0-dev'}}}

Launch Shadow

We will now create a new Seldon Deployment for our Shadow deployment with a new model.

[10]:
%%writetemplate shadow.yaml
apiVersion: machinelearning.seldon.io/v1alpha2
kind: SeldonDeployment
metadata:
  labels:
    app: seldon
  name: example
spec:
  name: shadow-model
  predictors:
  - componentSpecs:
    - spec:
        containers:
        - image: seldonio/mock_classifier:{VERSION}
          imagePullPolicy: IfNotPresent
          name: classifier
        terminationGracePeriodSeconds: 1
    graph:
      children: []
      endpoint:
        type: REST
      name: classifier
      type: MODEL
    name: default
    replicas: 1
  - componentSpecs:
    - spec:
        containers:
        - image: seldonio/mock_classifier:{VERSION}
          imagePullPolicy: IfNotPresent
          name: classifier
    graph:
      children: []
      endpoint:
        type: REST
      name: classifier
      type: MODEL
    name: shadow
    replicas: 1
    shadow: true

[11]:
!kubectl apply -f shadow.yaml
seldondeployment.machinelearning.seldon.io/example configured
[12]:
!kubectl rollout status deploy/$(kubectl get deploy -l seldon-deployment-id=example -o jsonpath='{.items[0].metadata.name}')
!kubectl rollout status deploy/$(kubectl get deploy -l seldon-deployment-id=example -o jsonpath='{.items[1].metadata.name}')
deployment "example-default-0-classifier" successfully rolled out
Waiting for deployment "example-shadow-0-classifier" rollout to finish: 0 of 1 updated replicas are available...
deployment "example-shadow-0-classifier" successfully rolled out

Let’s send a bunch of requests to the endpoint.

[13]:
for i in range(10):
    r = sc.predict(gateway="ambassador",transport="rest")
[14]:
default_count=!kubectl logs $(kubectl get pod -lseldon-app=example-default -o jsonpath='{.items[0].metadata.name}') classifier | grep "root.predict" | wc -l
[15]:
shadow_count=!kubectl logs $(kubectl get pod -lseldon-app=example-shadow -o jsonpath='{.items[0].metadata.name}') classifier | grep "root.predict" | wc -l
[16]:
print(shadow_count)
print(default_count)
assert(int(shadow_count[0])==10)
assert(int(default_count[0])==11)
['10']
['11']

TearDown

[17]:
!kubectl delete -f model.yaml
seldondeployment.machinelearning.seldon.io "example" deleted