Skip to content

Commit 9e7ce2b

Browse files
committed
example edit + changes .py instances to inputs
1 parent faab23e commit 9e7ce2b

File tree

2 files changed

+120
-90
lines changed

2 files changed

+120
-90
lines changed

churn_server/churn_server.ipynb

+119-89
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,21 @@
1515
"cell_type": "markdown",
1616
"metadata": {},
1717
"source": [
18-
"<a id=\"deploy\"></a>\n",
19-
"### Deploy our serving class using as a serverless function\n",
20-
"in the following section we create a new model serving function which wraps our class , and specify model and other resources."
18+
"in the following section we create a new model serving function which wraps our class , and specify model and other resources.\n",
19+
"Deploying the serving function will provide us an http endpoint that can handle requests in real time.\n",
20+
"This function is part of the [customer-churn-prediction demo](https://github.com/mlrun/demos/tree/master/customer-churn-prediction).<br>\n",
21+
"To see how the model is trained or how the data-set is generated, check out `coxph_trainer` and `xgb_trainer` functions from the function marketplace repository."
22+
]
23+
},
24+
{
25+
"cell_type": "markdown",
26+
"metadata": {},
27+
"source": [
28+
"### **Steps**\n",
29+
"1. [Setup function parameters](#Setup-function-parameters)\n",
30+
"2. [Importing the function](#Importing-the-function)\n",
31+
"3. [Testing the function locally](#Testing-the-function-locally)\n",
32+
"4. [Testing the function remotely](#Testing-the-function-remotely)"
2133
]
2234
},
2335
{
@@ -26,91 +38,124 @@
2638
"metadata": {},
2739
"outputs": [],
2840
"source": [
29-
"import mlrun\n",
30-
"import pandas as pd\n",
31-
"import os"
41+
"import warnings\n",
42+
"warnings.filterwarnings(\"ignore\")"
3243
]
3344
},
3445
{
3546
"cell_type": "code",
3647
"execution_count": 2,
3748
"metadata": {},
49+
"outputs": [],
50+
"source": [
51+
"# Following packages are required, make sure to install\n",
52+
"# !pip install xgboost==1.3.1"
53+
]
54+
},
55+
{
56+
"cell_type": "markdown",
57+
"metadata": {},
58+
"source": [
59+
"### **Setup function parameters**"
60+
]
61+
},
62+
{
63+
"cell_type": "code",
64+
"execution_count": 3,
65+
"metadata": {},
66+
"outputs": [],
67+
"source": [
68+
"# Setting up models path\n",
69+
"xgb_model_path = 'https://s3.wasabisys.com/iguazio/models/function-marketplace-models/churn_server/xgb_model.pkl'"
70+
]
71+
},
72+
{
73+
"cell_type": "markdown",
74+
"metadata": {},
75+
"source": [
76+
"### **Importing the function**"
77+
]
78+
},
79+
{
80+
"cell_type": "code",
81+
"execution_count": 4,
82+
"metadata": {},
3883
"outputs": [
3984
{
4085
"name": "stdout",
4186
"output_type": "stream",
4287
"text": [
43-
"> 2021-10-12 07:29:57,497 [info] loaded project function-marketplace from MLRun DB\n"
88+
"> 2021-10-14 06:10:16,104 [info] loaded project function-marketplace from MLRun DB\n"
4489
]
4590
},
4691
{
4792
"data": {
4893
"text/plain": [
49-
"('function-marketplace', 'v3io:///projects/{{run.project}}/artifacts')"
94+
"<mlrun.serving.states.TaskStep at 0x7f8f2306ca90>"
5095
]
5196
},
52-
"execution_count": 2,
97+
"execution_count": 4,
5398
"metadata": {},
5499
"output_type": "execute_result"
55100
}
56101
],
57102
"source": [
58-
"# setting environment \n",
59-
"mlrun.set_environment(project='function-marketplace')"
103+
"import mlrun\n",
104+
"mlrun.set_environment(project='function-marketplace')\n",
105+
"\n",
106+
"# Importing the function from the hub\n",
107+
"fn = mlrun.import_function(\"hub://churn_server:development\")\n",
108+
"fn.apply(mlrun.auto_mount())\n",
109+
"\n",
110+
"# Manually specifying needed packages \n",
111+
"fn.spec.build.commands = ['pip install lifelines==0.22.8', 'pip install xgboost==1.3.1']\n",
112+
"\n",
113+
"# Adding the model \n",
114+
"fn.add_model(key='xgb_model', model_path=xgb_model_path ,class_name='ChurnModel')"
60115
]
61116
},
62117
{
63-
"cell_type": "code",
64-
"execution_count": 3,
118+
"cell_type": "markdown",
65119
"metadata": {},
66-
"outputs": [
67-
{
68-
"name": "stdout",
69-
"output_type": "stream",
70-
"text": [
71-
"File ‘/User/functions/churn_server/models/xgb_model.pkl’ already there; not retrieving.\n",
72-
"\n"
73-
]
74-
}
75-
],
76120
"source": [
77-
"# Stored artifacts path (S3)\n",
78-
"data_path = 'https://s3.wasabisys.com/iguazio/data/churn/test_set.csv'\n",
79-
"model_url = 'https://s3.wasabisys.com/iguazio/models/churn/xgb_model.pkl'\n",
80-
"model_path = os.getcwd() + '/models'\n",
121+
"### **Testing the function locally**"
122+
]
123+
},
124+
{
125+
"cell_type": "markdown",
126+
"metadata": {},
127+
"source": [
128+
"> Note that this function is a serving function, hence not needs to run, but deployed.<br>\n",
81129
"\n",
82-
"# Downloading the model\n",
83-
"! wget -nc -P {model_path} {model_url}"
130+
"in order to test locally without deploying to server, mlrun provides mocking api that simulate the action."
84131
]
85132
},
86133
{
87134
"cell_type": "code",
88-
"execution_count": 4,
135+
"execution_count": 5,
89136
"metadata": {},
90137
"outputs": [
91138
{
92-
"data": {
93-
"text/plain": [
94-
"<mlrun.serving.states.TaskStep at 0x7f559bdabb90>"
95-
]
96-
},
97-
"execution_count": 4,
98-
"metadata": {},
99-
"output_type": "execute_result"
139+
"name": "stdout",
140+
"output_type": "stream",
141+
"text": [
142+
"> 2021-10-14 06:10:19,145 [info] model xgb_model was loaded\n",
143+
"> 2021-10-14 06:10:19,145 [info] Initializing endpoint records\n",
144+
"> 2021-10-14 06:10:19,164 [info] Loaded ['xgb_model']\n"
145+
]
100146
}
101147
],
102148
"source": [
103-
"# importing the function from the function marketplace\n",
104-
"fn = mlrun.import_function(\"hub://churn_server\").apply(mlrun.auto_mount())\n",
105-
"fn.spec.build.commands = ['pip install lifelines==0.22.8', 'pip install xgboost==1.3.1']\n",
149+
"# When mocking, class has to be present\n",
150+
"from churn_server import *\n",
106151
"\n",
107-
"# Adding the model \n",
108-
"fn.add_model(key='xgb_model', model_path=model_path ,class_name='ChurnModel')"
152+
"# Mocking function\n",
153+
"server = fn.to_mock_server()"
109154
]
110155
},
111156
{
112157
"cell_type": "code",
113-
"execution_count": 5,
158+
"execution_count": 6,
114159
"metadata": {},
115160
"outputs": [
116161
{
@@ -315,106 +360,94 @@
315360
"[5 rows x 23 columns]"
316361
]
317362
},
318-
"execution_count": 5,
363+
"execution_count": 6,
319364
"metadata": {},
320365
"output_type": "execute_result"
321366
}
322367
],
323368
"source": [
369+
"import pandas as pd\n",
370+
"\n",
371+
"#declaring test_set path\n",
372+
"test_set_path = \"https://s3.wasabisys.com/iguazio/data/function-marketplace-data/churn_server/test_set.csv\"\n",
373+
"\n",
324374
"# Getting the data\n",
325-
"x_test = pd.read_csv(data_path)\n",
375+
"x_test = pd.read_csv(test_set_path)\n",
326376
"y_test = x_test['labels']\n",
327377
"x_test.drop(['labels'],axis=1,inplace=True)\n",
328378
"x_test.head()"
329379
]
330380
},
331381
{
332-
"cell_type": "markdown",
382+
"cell_type": "code",
383+
"execution_count": 12,
333384
"metadata": {},
385+
"outputs": [],
334386
"source": [
335-
"### **Testing the model locally**"
387+
"# KFServing protocol event\n",
388+
"event_data = {\"inputs\": x_test.values.tolist()}"
336389
]
337390
},
338391
{
339392
"cell_type": "code",
340-
"execution_count": 6,
393+
"execution_count": 13,
341394
"metadata": {},
342395
"outputs": [],
343396
"source": [
344-
"# an old version of lifelines and xgboost is required when running locally, uncomment to install\n",
345-
"# !pip install lifelines==0.22.8\n",
346-
"# !pip install xgboost==1.3.1"
397+
"response = server.test(path='/v2/models/xgb_model/predict',body=event_data)"
347398
]
348399
},
349400
{
350401
"cell_type": "code",
351-
"execution_count": 7,
402+
"execution_count": 14,
352403
"metadata": {},
353404
"outputs": [
354405
{
355406
"name": "stdout",
356407
"output_type": "stream",
357408
"text": [
358-
"> 2021-10-12 07:30:00,756 [info] model xgb_model was loaded\n",
359-
"> 2021-10-12 07:30:00,757 [info] Initializing endpoint records\n",
360-
"> 2021-10-12 07:30:00,768 [info] Loaded ['xgb_model']\n",
361-
"model's accuracy : 0.7913907284768212\n"
409+
"When mocking to server, returned dict has the following fields : id, model_name, outputs\n"
362410
]
363411
}
364412
],
365413
"source": [
366-
"# importing the class (a must when using mock_to_server)\n",
367-
"from churn_server import *\n",
368-
"\n",
369-
"server = fn.to_mock_server()\n",
370-
"response = server.test(\"/v2/models/xgb_model/predict\",body={'inputs' : x_test.values.tolist()})\n",
371-
"\n",
372-
"# Calculating model's accuracy\n",
373-
"accuracy = sum(1 for x,y in zip(response['outputs'],y_test) if x == y) / len(y_test)\n",
374-
"print(f\"model's accuracy : {accuracy}\")"
414+
"print(f'When mocking to server, returned dict has the following fields : {\", \".join([x for x in response.keys()])}')"
375415
]
376416
},
377417
{
378418
"cell_type": "markdown",
379419
"metadata": {},
380420
"source": [
381-
"### **Deploying and testing our model server using HTTP request**"
421+
"### **Testing the function remotely**"
382422
]
383423
},
384424
{
385425
"cell_type": "code",
386-
"execution_count": 9,
426+
"execution_count": 10,
387427
"metadata": {},
388428
"outputs": [
389429
{
390430
"name": "stdout",
391431
"output_type": "stream",
392432
"text": [
393-
"> 2021-10-12 07:33:32,143 [info] Starting remote function deploy\n",
394-
"2021-10-12 07:33:32 (info) Deploying function\n",
395-
"2021-10-12 07:33:32 (info) Building\n",
396-
"2021-10-12 07:33:32 (info) Staging files and preparing base images\n",
397-
"2021-10-12 07:33:32 (info) Building processor image\n",
398-
"2021-10-12 07:33:33 (info) Build complete\n",
399-
"2021-10-12 07:33:41 (info) Function deploy complete\n",
400-
"> 2021-10-12 07:33:42,050 [info] successfully deployed function: {'internal_invocation_urls': ['nuclio-default-churn-server.default-tenant.svc.cluster.local:8080'], 'external_invocation_urls': ['default-tenant.app.app-lab-eks-testing.iguazio-cd1.com:31334']}\n"
433+
"> 2021-10-14 06:10:20,163 [info] Starting remote function deploy\n",
434+
"2021-10-14 06:10:20 (info) Deploying function\n",
435+
"2021-10-14 06:10:20 (info) Building\n",
436+
"2021-10-14 06:10:20 (info) Staging files and preparing base images\n",
437+
"2021-10-14 06:10:20 (info) Building processor image\n",
438+
"2021-10-14 06:10:21 (info) Build complete\n",
439+
"2021-10-14 06:10:29 (info) Function deploy complete\n",
440+
"> 2021-10-14 06:10:30,408 [info] successfully deployed function: {'internal_invocation_urls': ['nuclio-function-marketplace-churn-server.default-tenant.svc.cluster.local:8080'], 'external_invocation_urls': ['default-tenant.app.dev39.lab.iguazeng.com:31984']}\n"
401441
]
402442
}
403443
],
404444
"source": [
405445
"address = fn.deploy()"
406446
]
407447
},
408-
{
409-
"cell_type": "markdown",
410-
"metadata": {},
411-
"source": [
412-
"We invoke our model serving function using test data, the data vector is specified in the `inputs` attribute."
413-
]
414-
},
415448
{
416449
"cell_type": "code",
417-
"execution_count": 19,
450+
"execution_count": 11,
418451
"metadata": {},
419452
"outputs": [
420453
{
@@ -429,10 +462,7 @@
429462
"import json\n",
430463
"import requests\n",
431464
"\n",
432-
"# KFServing protocol event\n",
433-
"event_data = {\"inputs\": x_test.values.tolist()}\n",
434-
"\n",
435-
"# sending data in a json format\n",
465+
"# using requests to predict\n",
436466
"response = requests.put(address + \"/v2/models/xgb_model/predict\", json=json.dumps(event_data))\n",
437467
"\n",
438468
"# returned data is a string \n",
@@ -445,7 +475,7 @@
445475
"cell_type": "markdown",
446476
"metadata": {},
447477
"source": [
448-
"**[back to top](#top)**"
478+
"[Back to the top](#Churn-Server)"
449479
]
450480
}
451481
],

churn_server/churn_server.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ def load(self):
2323

2424
def predict(self, body):
2525
try:
26-
feats = np.asarray(body["instances"], dtype=np.float32).reshape(-1, 23)
26+
feats = np.asarray(body["inputs"], dtype=np.float32).reshape(-1, 23)
2727
result = self.model.predict(feats, validate_features=False)
2828
return result.tolist()
2929
except Exception as e:

0 commit comments

Comments
 (0)