clipper
clipper copied to clipboard
Q: Examples of RClipper using complex R DataFrames?
Q: Would it be possible to get some more complex examples of RClipper using R DataFrames? The current example only uses "ints" which does not really show the needed complexity to implement a complex R DataFrame with multiple strings with label/value pairs. Actually, I am not even sure if Clipper supports label/value pairs as inputs, for example: {"Name":"Luke Skywalker", "Age":"34", "Height":"72", "Weight":"190"} You could try using the mtcars example.
Q: Is there some way to view the format of the REST API for the different deployed models?
I'll leave the first question to @Corey-Zumar. key-value pairs are potential use case such that Clipper will directly be exposed as part of the micro-service.
To answer the second question, do you mean the input format for each applications?
- You can use
clipper_conn.get_all_apps(verbose=True)
to get all applications'name, input_type, default_output, slo_micros
; orclipper_conn.get_all_model(verbose=True)
to get the info for models.
@csmithnm Great question regarding R dataframes. Rclipper accepts dataframes in json-serialized format using the jsonlite library. For example, to send the mtcars dataframe to clipper, you could proceed as follows:
In an R shell:
> library(jsonlite)
> json_mtcars = jsonlite::toJSON(mtcars)
You can the send the json_mtcars
string to a Clipper application in the body of a POST request. This application should accept inputs of type "strings." This string will automatically be converted into the mtcars
dataframe before it is passed to your model for evaluation.
Does that help? Let me know if you have any additional questions. If you have any ideas for a more efficient or intuitive way of representing dataframes in requests to Clipper, it would be great to get your input.
Thank you for that example of how to get the R dataframe into a format for the POST request - that helped to move me a little further forward.
My next question is about setting up the sample_input =
interface to the R model function during the build_model()
step.
Q: What format/syntax is used for the R build_model() sample_input for an R dataframe and the POST "input"?
Would it look like the one below?
Is the data type data.frame
or as.data.frame
?
Do you include the column names?
Why do I ask all this?
I ask because when I have tried a similar dataframe interface and call via the REST API I get an error indicating that I should be using Strings
not an Array
. And that an Array
is NOT a valid data type for RClipper interfaces.
Here is what I tried:
clipper_conn.register_application(name="app_mtcars", input_type="strings", default_output="-1.0", slo_micros=100000)
Rclipper::build_model("r-mtcars", 2, pred_mtcars_fn, sample_input = data.frame( mpg= c("21"), cyl= c("6"), disp= c("160"), hp= c("110"), drat= c("3.9"), wt= c("2.62"), qsec= c("16.46"), vs= c("0"), am= c("1"), gear= c("4"), carb= c("4"), carmodel= c("Mazda RX4") ) )
clipper_conn.deploy_model("r-mtcars", "1", "strings", "r-mtcars:1", num_replicas=1)
clipper_conn.link_model_to_app(app_name="app_mtcars", model_name="r-mtcars")
Copied the json_mtcars
string to the "input" in the POST request:
curl -X POST --header "Content-Type:application/json" -d '{"input": [[{"mpg":"21","cyl":"6","disp":"160","hp":"110","drat":"3.9","wt":"2.62","qsec":"16.46","vs":"0","am":"1","gear":"4","carb":"4","carmodel":"Mazda RX4"}]]}' 127.0.0.1:1337/app_mtcars/predict
Error Message:
{"error":"Json error","cause":"Error parsing JSON: Type mismatch! JSON key input expected type Stringbut found type Array. Expected JSON schema: \n {\n \"input\" := [double] | [int] | [string] | [byte] | [float],\n }\n"}
I also tried all sorts of other formats of the "input" by removing the [[]] brackets, removing the column names, etc., but with no success at calling the REST API.
@csmithnm Thank you for the very detailed description of the problem. The issue is that your dataframe is being interpreted as an array, rather than a string. You'll want to put quotation marks around the outer brackets, [[]], and escape the interior quotation marks (i.e. "mpg" becomes \"mpg\"). Please let me know if this works.
I realize that this isn't the cleanest interface. Perhaps it would be better to support the conversion of a raw JSON string dictionary into a dataframe at prediction time.
Thanks again for the tip on the input format. I am getting further. I believe I have gotten the inputs to work - now I think the next error is dealing with the format of the output. I tried sending the mtcars dataframe back in the return, but that failed so I tried to simplify things with just returning a string like in the example below. Each time I get the same output error dealing with encoding.mode == \"NULL"
.
R Function:
pred_mtcars_fn = function(mtcars) { output_string <- "Test Prediction Output = 1.0" return(output_string) }
I added the double quotes around the "[[]]" and then added the escape character \ before the double quotes:
curl -X POST --header \"Content-Type:application/json\" -d '{"input": "[[{\"mpg\":\"21\",\"cyl\":\"6\",\"disp\":\"160\",\"hp\":\"110\",\"drat\":\"3.9\",\"wt\":\"2.62\",\"qsec\":\"16.46\",\"vs\":\"0\",\"am\":\"1\",\"gear\":\"4\",\"carb\":\"4\",\"carmodel\":\"Mazda RX4\"}]]"}' 127.0.0.1:1337/app_mtcars/predict
Error Message:
{"query_id":5,"output":"{\"error\": Error in if (encoding.mode == \"NULL\") {: argument is of length zero\n\"}","default":false}
Any light you can shed on the output format, would be great.
It is still not working. I have been trying every combination and permutation for months, but have not been able to get a dataframe to work.
Q: Do you have an R Dataframe example yet?
If we can't get this to work, then we might have to look else where for a predictive model framework.