Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Model container testing function to clipper admin (Vanilla python) #394

Merged
merged 35 commits into from
Mar 13, 2018

Conversation

rohsuresh
Copy link
Contributor

@rohsuresh rohsuresh commented Feb 1, 2018

Closes #360
Added a function test_predict_function in clipper_admin/clipper_admin/clipper_admin.py that verifies input type and function serialization/reloading for vanilla python models. Will resolve PyTorch and TensorFlow after this has been approved.

@AmplabJenkins
Copy link

Can one of the admins verify this patch?

@dcrankshaw
Copy link
Contributor

jenkins ok to test

Copy link
Contributor

@dcrankshaw dcrankshaw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you delete all the extra Python files that got committed?

This implementation looks good! The only thing missing now is an integration test. Add a test to [clipper_admin_tests.py] that deploys a predict function (using deploy python closure) that sums the elements in an input and check to make sure that your newly added test function returns the same result as the deployed model.

Parameters
----------
query: JSON or list of dicts
Input that the user sends to the query frontend
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Inputs to test the prediction function on."

query: JSON or list of dicts
Input that the user sends to the query frontend
func: function
Predict function that the user's model is using
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Predict function to test."

if input_type == "strings":
for x in flattened_data:
if type(x) != str:
return "Invalid input type"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add checks for the other two accepted input types: (floats and bytes)

try:
assert reloaded_func
except AssertionError as e:
return 'Function does not properly serialize and reload'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's log this error as well logger.error("Function ...")

except AssertionError as e:
return 'Function does not properly serialize and reload'

numpy_data = list(np.array(x) for x in query_data)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only tricky thing here is to ensure that the numpy array as the right dtype. The mapping is defined here.

@AmplabJenkins
Copy link

Test FAILed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/Clipper-PRB/940/
Test FAILed.

@dcrankshaw
Copy link
Contributor

jenkins add to whitelist

@AmplabJenkins
Copy link

Test FAILed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/Clipper-PRB/971/
Test FAILed.

@AmplabJenkins
Copy link

Test FAILed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/Clipper-PRB/981/
Test FAILed.

@AmplabJenkins
Copy link

Test FAILed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/Clipper-PRB/982/
Test FAILed.

@dcrankshaw
Copy link
Contributor

Jenkins is failing because of the format checker. Run ./bin/format_code.sh to format.

Copy link
Contributor

@dcrankshaw dcrankshaw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. Just a few minor changes.

@@ -4,6 +4,8 @@
import os
import posixpath
import shutil
import pickle
import numpy as np
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revert the changes to this file

Predict function to test.
input_type: str
The input_type to be associated with the registered app and deployed model.
One of "integers", "floats", "doubles", "bytes", or "strings".
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add an example in the method comment?

query_data = list(x for x in list(query.values()))

if type(query_data[0][0]) == list:
query_data = query_data[0]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are you checking for here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm checking the nesting of the query data, whether it is a list or a list of lists.

The input_type to be associated with the registered app and deployed model.
One of "integers", "floats", "doubles", "bytes", or "strings".
"""
query_data = list(x for x in list(query.values()))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's going on here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should be checking the JSON key as well, to ensure that their input is properly formatted

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assuming that the query is in a JSON/dict structure, I'm getting the values of each key. I'm then checking to make sure the values are of the right input_type before then converting it into the respective numpy array of right dtype. What formatting of the key input needs to be checked?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the user wants to provide a single input, the key should be "input". If they want to provide a list of inputs, the key should be "input_batch". See the website for details.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it. Thanks for the clarification.

headers = {"Content-type": "application/json"}
test_input = list(np.random.random(10))
pred = requests.post("http://localhost:1337/hello-world/predict", headers=headers, data=json.dumps({"input": test_input})).json()
test_predict_result = test_predict_function(self.clipper_conn, query={"input": test_input}, func=predict_func, input_type="doubles")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should call the function like this self.clipper_conn.test_predict_function(query=...), not by passing in self.clipper_conn as an argument.

Can you add a second test prediction that uses the batch_predict interface? e.g.

batch_input = [list(np.random.random(10)) for _ in range(4)]
batch_pred = requests.post("http://localhost:1337/hello-world/predict", headers=headers, data=json.dumps({"input_batch": batch_input})).json()
test_batch_predict_result = self.clipper_conn.test_predict_function(query={"input_batch": test_input}, func=predict_func, input_type="doubles")

@AmplabJenkins
Copy link

Test FAILed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/Clipper-PRB/1024/
Test FAILed.

@AmplabJenkins
Copy link

Test FAILed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/Clipper-PRB/1070/
Test FAILed.

@AmplabJenkins
Copy link

Test FAILed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/Clipper-PRB/1074/
Test FAILed.

@AmplabJenkins
Copy link

Test FAILed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/Clipper-PRB/1075/
Test FAILed.

@AmplabJenkins
Copy link

Test FAILed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/Clipper-PRB/1086/
Test FAILed.

@AmplabJenkins
Copy link

Test FAILed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/Clipper-PRB/1088/
Test FAILed.

@dcrankshaw
Copy link
Contributor

jenkins test this please

@AmplabJenkins
Copy link

Test FAILed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/Clipper-PRB/1089/
Test FAILed.

@AmplabJenkins
Copy link

Test FAILed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/Clipper-PRB/1091/
Test FAILed.

@AmplabJenkins
Copy link

Test FAILed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/Clipper-PRB/1092/
Test FAILed.

@AmplabJenkins
Copy link

Test FAILed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/Clipper-PRB/1093/
Test FAILed.

@AmplabJenkins
Copy link

Test FAILed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/Clipper-PRB/1097/
Test FAILed.

@AmplabJenkins
Copy link

Test FAILed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/Clipper-PRB/1101/
Test FAILed.

@AmplabJenkins
Copy link

Test FAILed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/Clipper-PRB/1103/
Test FAILed.

@dcrankshaw
Copy link
Contributor

jenkins test this please

@AmplabJenkins
Copy link

Test PASSed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/Clipper-PRB/1104/
Test PASSed.

Copy link
Contributor

@dcrankshaw dcrankshaw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@dcrankshaw dcrankshaw merged commit bd57920 into develop Mar 13, 2018
@dcrankshaw dcrankshaw deleted the modelTest branch March 17, 2018 06:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Adding model container testing function to clipper admin
3 participants