forked from kubeflow/pipelines
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add text explainer notebook (kubeflow#355)
* Add text explainer notebook example * Fix formatting
- Loading branch information
1 parent
fcf1a13
commit 4c647d9
Showing
2 changed files
with
255 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
252 changes: 252 additions & 0 deletions
252
docs/samples/explanation/alibi/moviesentiment/kfserving_text_explainer.ipynb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,252 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"# Sample for KFService Explainer" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"The notebook shows how to use KFServing SDK to create KFService with explainer, predictor." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 59, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"from kubernetes import client\n", | ||
"\n", | ||
"from kfserving import KFServingClient\n", | ||
"from kfserving import constants\n", | ||
"from kfserving import V1alpha2EndpointSpec\n", | ||
"from kfserving import V1alpha2PredictorSpec\n", | ||
"from kfserving import V1alpha2ExplainerSpec\n", | ||
"from kfserving import V1alpha2AlibiExplainerSpec\n", | ||
"from kfserving import V1alpha2SKLearnSpec\n", | ||
"from kfserving import V1alpha2KFServiceSpec\n", | ||
"from kfserving import V1alpha2KFService\n", | ||
"from kubernetes.client import V1ResourceRequirements\n", | ||
"from kubernetes import client, config\n", | ||
"import kubernetes.client\n", | ||
"import os\n", | ||
"import requests \n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Define KFService with Explainer" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"Add predictor and explainer on the endpoint spec" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"api_version = constants.KFSERVING_GROUP + '/' + constants.KFSERVING_VERSION\n", | ||
"default_endpoint_spec = V1alpha2EndpointSpec(\n", | ||
" predictor=V1alpha2PredictorSpec(\n", | ||
" min_replicas=1,\n", | ||
" sklearn=V1alpha2SKLearnSpec(\n", | ||
" storage_uri='gs://seldon-models/sklearn/moviesentiment',\n", | ||
" resources=V1ResourceRequirements(\n", | ||
" requests={'cpu': '100m', 'memory': '1Gi'},\n", | ||
" limits={'cpu': '100m', 'memory': '1Gi'}))),\n", | ||
" explainer=V1alpha2ExplainerSpec(\n", | ||
" min_replicas=1, \n", | ||
" alibi=V1alpha2AlibiExplainerSpec(\n", | ||
" type='AnchorText',\n", | ||
" resources=V1ResourceRequirements(\n", | ||
" requests={'cpu': '100m', 'memory': '2Gi'},\n", | ||
" limits={'cpu': '100m', 'memory': '2Gi'}))))\n", | ||
" \n", | ||
"kfsvc = V1alpha2KFService(api_version=api_version,\n", | ||
" kind=constants.KFSERVING_KIND,\n", | ||
" metadata=client.V1ObjectMeta(\n", | ||
" name='moviesentiment', namespace='kubeflow'),\n", | ||
" spec=V1alpha2KFServiceSpec(default=default_endpoint_spec))\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Create KFService" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"Call KFServingClient to create KFService." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"KFServing = KFServingClient()\n", | ||
"KFServing.create(kfsvc)\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Check the KFService" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 60, | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"NAME READY DEFAULT_TRAFFIC CANARY_TRAFFIC URL \n", | ||
"moviesentiment True 100 http://moviesentiment-predict.kubeflow.example.com\n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"KFServing.get('moviesentiment', namespace='kubeflow', watch=True, timeout_seconds=120)\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Predict the sentiment for the sentence" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 61, | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"34.67.11.82\n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"api_instance = kubernetes.client.CoreV1Api(kubernetes.client.ApiClient())\n", | ||
"service = api_instance.read_namespaced_service(\"istio-ingressgateway\", \"istio-system\", exact='true')\n", | ||
"cluster_ip = service.status.load_balancer.ingress[0].ip\n", | ||
"print(cluster_ip)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 62, | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"b'{\"predictions\": [0]}'\n", | ||
"b'{\"predictions\": [1]}'\n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"url = \"http://\" + cluster_ip + \"/v1/models/moviesentiment:predict\"\n", | ||
"headers = {'Host': 'moviesentiment-predict.kubeflow.example.com'}\n", | ||
"response = requests.post(url, '{\"instances\":[\"This is a bad book .\"]}', headers=headers)\n", | ||
"print(response.content)\n", | ||
"response = requests.post(url, '{\"instances\":[\"This is a good book .\"]}', headers=headers)\n", | ||
"print(response.content)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Explain the Prediction" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 58, | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"b'{\"names\": [\"bad\"], \"precision\": 1.0, \"coverage\": 0.5007, \"raw\": {\"feature\": [3], \"mean\": [1.0], \"precision\": [1.0], \"coverage\": [0.5007], \"examples\": [{\"covered\": [[\"This is a bad book UNK\"], [\"UNK is UNK bad book UNK\"], [\"UNK is UNK bad book .\"], [\"This UNK UNK bad book UNK\"], [\"This is UNK bad UNK .\"], [\"UNK UNK UNK bad book .\"], [\"UNK is a bad UNK UNK\"], [\"UNK UNK a bad UNK .\"], [\"UNK UNK a bad book UNK\"], [\"UNK is UNK bad book .\"]], \"covered_true\": [[\"UNK is UNK bad UNK UNK\"], [\"UNK is UNK bad UNK UNK\"], [\"UNK is UNK bad book UNK\"], [\"This UNK UNK bad book UNK\"], [\"UNK UNK a bad book .\"], [\"This is UNK bad UNK UNK\"], [\"UNK UNK UNK bad UNK UNK\"], [\"This is UNK bad UNK .\"], [\"This is UNK bad UNK .\"], [\"This UNK a bad UNK .\"]], \"covered_false\": [], \"uncovered_true\": [], \"uncovered_false\": []}], \"all_precision\": 0, \"num_preds\": 1000101, \"names\": [\"bad\"], \"positions\": [10], \"instance\": \"This is a bad book .\", \"prediction\": 0}}'\n", | ||
"b'{\"names\": [\"good\"], \"precision\": 1.0, \"coverage\": 0.5007, \"raw\": {\"feature\": [3], \"mean\": [1.0], \"precision\": [1.0], \"coverage\": [0.5007], \"examples\": [{\"covered\": [[\"This is a good book .\"], [\"This is a good book UNK\"], [\"UNK is UNK good book UNK\"], [\"This UNK UNK good UNK UNK\"], [\"UNK UNK a good book UNK\"], [\"This UNK a good UNK UNK\"], [\"UNK is a good book UNK\"], [\"UNK is a good UNK UNK\"], [\"This is UNK good book .\"], [\"UNK UNK UNK good UNK UNK\"]], \"covered_true\": [[\"UNK UNK UNK good book UNK\"], [\"UNK is a good book .\"], [\"UNK is a good book UNK\"], [\"UNK is UNK good book .\"], [\"UNK UNK UNK good book .\"], [\"UNK is a good book .\"], [\"UNK is UNK good UNK UNK\"], [\"UNK UNK UNK good UNK .\"], [\"This UNK a good UNK UNK\"], [\"This is a good UNK .\"]], \"covered_false\": [], \"uncovered_true\": [], \"uncovered_false\": []}], \"all_precision\": 0, \"num_preds\": 1000001, \"names\": [\"good\"], \"positions\": [10], \"instance\": \"This is a good book .\", \"prediction\": 1}}'\n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"url = \"http://\" + cluster_ip + \"/v1/models/moviesentiment:explain\"\n", | ||
"headers = {'Host': 'moviesentiment-explain.kubeflow.example.com'}\n", | ||
"response = requests.post(url, '{\"instances\":[\"This is a bad book .\"]}', headers=headers)\n", | ||
"print(response.content)\n", | ||
"response = requests.post(url, '{\"instances\":[\"This is a good book .\"]}', headers=headers)\n", | ||
"print(response.content)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Delete the KFService" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"KFServing.delete('moviesentiment', namespace='kubeflow')\n" | ||
] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": "Python 3", | ||
"language": "python", | ||
"name": "python3" | ||
}, | ||
"language_info": { | ||
"codemirror_mode": { | ||
"name": "ipython", | ||
"version": 3 | ||
}, | ||
"file_extension": ".py", | ||
"mimetype": "text/x-python", | ||
"name": "python", | ||
"nbconvert_exporter": "python", | ||
"pygments_lexer": "ipython3", | ||
"version": "3.6.5" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 2 | ||
} |