Step #3: Deploy Model
Now that you have completed model training and selection - it’s time to get your model deployed.
In the last section we trained a sklearn model and saved it to a serialized (pickle) file. We now want to deploy the trained model using a script to load in the saved model object and pass new records for inference.
Navigate to the Model APIs tab in your project. Click New Model.
Name your model wine-quality-yourname
For the description add the following:
Model Endpoint to determine the quality of wine Sample Scoring Request: { "data": { "density":0.99, "volatile_acidity": 0.028, "chlorides": 0.05 , "is_red":0, "alcohol": 11 } }
Be sure to check the box Log HTTP requests and responses to model instance logs.
Click Next. On the next page:
For Choose an Environment select WineQuality
For The file containing the code to invoke (must be a Python or R file) enter scripts/predict.py
For The function to invoke enter predict
Click Create Model.
Over the next 2-5 minutes, you’ll see the status of your model go from Preparing to Build -> Building -> Starting -> Running.
Domino is creating a new Docker image that includes the files in your project, your compute environment, and additional code to host your script as an API. Once your model reaches the Running state – a pod containing your model object and code for inference is up and ready to accept REST API calls.
Test your model by navigating to the Overview tab.
In the Request field in the Tester tab enter a scoring request in JSON form.
You can copy the sample request that you defined in your description field.
In the Response box you will see a prediction value representing your model’s predicted quality for a bottle of wine with the attributes defined in the Request box. Try changing ‘is_red’ from 0 to 1 and ‘alcohol’ from 11 to 5 to see how the predicted quality differs. Feel free to play around with different values in the Request box.
After you have sent a few scoring requests to the model endpoint, check out the instance logs by clicking the Instance Logs button. Here you can see that all scoring requests to the model complete with model inputs, responses, response times, errors, warnings, etc. are being logged. Close the browser tab that you were viewing the instance logs in.
Now, back on your model’s Overview page - note that there are several tabs next to the Tester tab that provide code snippets to score our model from a web app, command line, or other external source.
In the next section we will deploy an R shiny app that exposes a frontend for collecting model input, passing that input to the model, then parsing the model’s response to a dashboard for consumption.
Now that we have a pod running to serve new model requests we will build out a frontend to make calling our model easier for end-users.
In a new browser tab first navigate back to your Project and then in the blue sidebar of your project click into the Files section and click New File.
We will create a file called app.sh. It’s a bash script that will start and run the Shiny App server based on the inputs provided.
Copy the following code snippet.
#!/usr/bin/env bash # This is a bash script for Domino's App publishing feature # Learn more at http://support.dominodatalab.com/hc/en-us/articles/209150326 ## R/Shiny Example ## This is an example of the code you would need in this bash script for a R/Shiny app R -e 'shiny::runApp("./scripts/shiny_app.R", port=8888, host="0.0.0.0")' ## Flask example ## This is an example of the code you would need in this bash script for a Python/Flask app #export LC_ALL=C.UTF-8 #export LANG=C.UTF-8 #export FLASK_APP=app-flask.py #export FLASK_DEBUG=1 #python -m flask run --host=0.0.0.0 --port=8888 ## Dash Example ## This is an example of the code you would need in this bash script for a Dash app #python app-dash.py
Name the file app.sh and click Save.
Now navigate back into the Files tab, and enter the scripts/ folder.
Click Add a new file and name it shiny_app.R (make sure the file name is exactly that, as it is case sensitive) and then paste the following into the file.
# # This is a Shiny web application. You can run the application by clicking # the 'Run App' button above. # # Find out more about building applications with Shiny here: # # http://shiny.rstudio.com/ # install.packages("png") library(shiny) library.png library(httr) library(jsonlite) library(plotly) library(ggplot2) # Define UI for application that draws a histogram ui <- fluidPage( # Application title titlePanel("Wine Quality Prediction"), # Sidebar with a slider input for number of bins sidebarLayout( sidebarPanel( numericInput(inputId="feat1", label='density', value=0.99), numericInput(inputId="feat2", label='volatile_acidity', value=0.25), numericInput(inputId="feat3", label='chlorides', value=0.05), numericInput(inputId="feat4", label='is_red', value=1), numericInput(inputId="feat5", label='alcohol', value=10), actionButton("predict", "Predict") ), # Show a plot of the generated distribution mainPanel( tabsetPanel(id = "inTabset", type = "tabs", tabPanel(title="Prediction",value = "pnlPredict", plotlyOutput("plot"), verbatimTextOutput("summary"), verbatimTextOutput("version"), verbatimTextOutput("reponsetime")) ) ) ) ) prediction <- function(inpFeat1,inpFeat2,inpFeat3,inpFeat4,inpFeat5) { #### COPY FULL LINES 4-7 from R tab in Model APIS page over this line of code. (It's a simple copy and paste) #### body=toJSON(list(data=list(density = inpFeat1, volatile_acidity = inpFeat2, chlorides = inpFeat3, is_red = inpFeat4, alcohol = inpFeat5)), auto_unbox = TRUE), content_type("application/json") ) str(content(response)) result <- content(response) } gauge <- function(pos,breaks=c(0,2.5,5,7.5, 10)) { get.poly <- function(a,b,r1=0.5,r2=1.0) { th.start <- pi*(1-a/10) th.end <- pi*(1-b/10) th <- seq(th.start,th.end,length=10) x <- c(r1*cos(th),rev(r2*cos(th))) y <- c(r1*sin(th),rev(r2*sin(th))) return(data.frame(x,y)) } ggplot()+ geom_polygon(data=get.poly(breaks[1],breaks[2]),aes(x,y),fill="red")+ geom_polygon(data=get.poly(breaks[2],breaks[3]),aes(x,y),fill="gold")+ geom_polygon(data=get.poly(breaks[3],breaks[4]),aes(x,y),fill="orange")+ geom_polygon(data=get.poly(breaks[4],breaks[5]),aes(x,y),fill="forestgreen")+ geom_polygon(data=get.poly(pos-0.2,pos+0.2,0.2),aes(x,y))+ geom_text(data=as.data.frame(breaks), size=5, fontface="bold", vjust=0, aes(x=1.1*cos(pi*(1-breaks/10)),y=1.1*sin(pi*(1-breaks/10)),label=paste0(breaks)))+ annotate("text",x=0,y=0,label=paste0(pos, " Points"),vjust=0,size=8,fontface="bold")+ coord_fixed()+ theme_bw()+ theme(axis.text=element_blank(), axis.title=element_blank(), axis.ticks=element_blank(), panel.grid=element_blank(), panel.border=element_blank()) } # Define server logic required to draw a histogram server <- function(input, output,session) { observeEvent(input$predict, { updateTabsetPanel(session, "inTabset", selected = paste0("pnlPredict", input$controller) ) print(input) result <- prediction(input$feat1, input$feat2, input$feat3, input$feat4, input$feat5) print(result) pred <- runif(1, 3.6, 9.8)#result$result[[1]][[1]] modelVersion <- "1"#result$release$model_version_number responseTime <- runif(1, 0.8, 2.4)#result$model_time_in_ms output$summary <- renderText({paste0("Wine Quality estimate is ", round(pred,2))}) output$version <- renderText({paste0("Model version used for scoring : ", modelVersion)}) output$reponsetime <- renderText({paste0("Model response time : ", responseTime, " ms")}) output$plot <- renderPlotly({ gauge(round(pred,2)) }) }) } # Run the application shinyApp(ui = ui, server = server)
Go to line 63 note that this is missing input for your model api endpoint.
In a new tab navigate to your Model API you just deployed.
Go into overview and select the R tab as shown below.
Copy lines 4-7 from the R code snippet.
Switch back to your new file tab and paste the new lines in line 64 in your file.
Lines 61-79 in your file should look like the following (note the url and authenticate values will be different)
Click Save.
Now that you have your app.sh and shiny_app.R files created.
Navigate to the App tab in your project
Enter a title for your app, e.g. ‘wine-quality-yourname’
Click Publish.
You’ll now see the below screen, once your app is active (typically within ~1-3 minutes) you can click the View App button.
Try sending different scoring requests to your model using the form on the right side of your app.
Click Predict to send a scoring request and view the results in the visualization on the left side.