Model Implementation for Modelscape Deploy
This example shows how to use the Modelscape™ Deploy™ software.
Modelscape Deploy supports a generic interface for specifying model inputs, model outputs, and a single method to execute models. This example explains the interface and shows how to implement it as a model developer.
This example uses a model that takes inputs x
and y
and calculates the weighted sum z = A*x + B*y
, where A
and B
are scalar weights. If x
and y
are vectors, the evaluation of the model is a batch evaluation for each pair of elements in x
and y
. The scalars A
and B
are configurable, but constant across a batch of evaluations, so you treat them as parameters.
Realistic examples of inputs that vary within a batch are the contract details for a book of derivative transactions and the data corresponding to a group of credit card applicants. Examples of parameters corresponding to these inputs are the number of Monte Carlo paths for pricing the derivatives and macro-economic data for credit-scoring the loan applicants, respectively. The batch parameters are fixed for all inputs in a batch.
Work with Modelscape Deploy
You must implement models for execution in Modelscape Deploy as subclasses of mrm.execution.Model
.
classdef WeightedSum < mrm.execution.Model
The inputs and outputs of the model execution must be tables. Each model class defines how to query the input table and populate the output table.
Methods for Inputs and Outputs
Each model must implement three methods for specifying the inputs and outputs of the model.
getInputs
— Return the definition of the variables required for each evaluation in a batch. In this example, this method returns the names and types ofx
andy
.getParameters
— Return the definition of the parameters in a batch of evaluations. In this example, this method returns the names and types ofA
and B.getOutputs
— Return the definition of the output variables. In this example, this method returnsz.
Each output is an array of structures with these fields:
name
— Name of the input, parameter, or output, specified as a string.dataType
— Information about the type of the input, parameter, or output, in a struct that must contain a fieldname
with a value listed inmwtype
.sizes
— Optional array of doubles indicating the size of the input, parameter, or output. For scalar inputs, omit the struct or use empty vector[]
. Otherwise use[N,M,...]
to indicate sizeN x M x ...
. UseNaN
to indicate unrestricted size in any dimension. For example, for a single column with arbitrary height, specify the corresponding vector as[1,NaN]
.
Define the toy model.
function parameters = getInputs(~) doubleDatatype = struct( ... name="double"); parameters = struct( ... name={"X","Y"}, ... dataType={doubleDatatype,doubleDatatype}); end function parameters = getParameters(~) doubleDatatype = struct( ... name="double"); parameters = struct( ... name={"A","B"}, ... dataType={doubleDatatype,doubleDatatype}); end function parameters = getOutputs(~) doubleDatatype = struct( ... name="double"); parameters = struct( ... name={"Z"}, ... dataType={doubleDatatype}); end
Evaluation Method
Define the evaluate
method.
[outputs,diagnostics,batchDiagnostics] = evaluate(this,inputs,parameters)
In this definition, inputs
is a table with a row for each evaluation in the batch. parameters
is a structure that contains the variables that apply to all evaluations in the batch.
The outputs
variable must be a table containing a row for each row of the inputs
table. The diagnostics
output must be an array of structures, one for each row of the input table. The batchDiagnostic
output is a single diagnostic for the whole batch and must be a scalar structure.
Define the model evaluation function. In this case the diagnostics
structures are empty. You can define these structures to contain information about the Monte Carlo noise in the valuation, for example.
function [outputs, diagnostics, batchDiagnostics] = evaluate(~,inputs,parameters) outputs = table( ... parameters.A * inputs.X + parameters.B * inputs.Y, ... VariableNames={'Z'}, ... RowNames=inputs.Properties.RowNames); rawDiagnostics = [inputs.Properties.RowNames,repmat({struct()},numel(inputs.Properties.RowNames),1)]'; diagnostics = struct(rawDiagnostics{:}); batchDiagnostics = struct(); end
Create Image for Deployment
To deploy a model that implements the mrm.execution.Model
interface, package the executable model code into a Docker® image that is suitable for deployment using MATLAB® Compiler SDK software. Use the mrm.execution.packageModel
helper function to perform this operation.
modelInstance = WeightedSum; outputFolder = tempname; imageName = mrm.execution.compiler.packageModel(modelInstance, ... OutputFolder=outputFolder, ... Name="weighted-sum", ... Tag="v1")
Runtime Image Already Exists Sending build context to Docker daemon 278kB Step 1/6 : FROM matlabruntime/r2023a/prerelease/update0/308000000000000000 ---> 9578d4e15248 Step 2/6 : COPY ./applicationFilesForMATLABCompiler /usr/bin/mlrtapp ---> ff0709fcec70 Step 3/6 : RUN chmod -R a+rX /usr/bin/mlrtapp/* ---> Running in c83375557f83 Removing intermediate container c83375557f83 ---> da1d6f8978b3 Step 4/6 : RUN useradd -ms /bin/bash appuser ---> Running in aab934c26070 Removing intermediate container aab934c26070 ---> 5e5490e6e58e Step 5/6 : USER appuser ---> Running in fd6d76d6d108 Removing intermediate container fd6d76d6d108 ---> 54efdb411a1b Step 6/6 : ENTRYPOINT ["/opt/matlabruntime/R2023a/bin/glnxa64/muserve", "-a", "/usr/bin/mlrtapp/weightedsum.ctf"] ---> Running in 4c6771bc9751 Removing intermediate container 4c6771bc9751 ---> 0da443f8e974 Successfully built 0da443f8e974 Successfully tagged weighted-sum:v1 DOCKER CONTEXT LOCATION: /tmp/tp984f0556_95f6_46b1_a428_473bcc9e54dc/docker FOR HELP GETTING STARTED WITH MICROSERVICE IMAGES, PLEASE READ: /tmp/tp984f0556_95f6_46b1_a428_473bcc9e54dc/docker/GettingStarted.txt Sending build context to Docker daemon 4.608kB Step 1/7 : FROM weighted-sum:v1 ---> 0da443f8e974 Step 2/7 : COPY ./routes.json /usr/bin/mlrtapp/routes.json ---> e97e7b05ec7e Step 3/7 : USER root ---> Running in 01c65af653f1 Removing intermediate container 01c65af653f1 ---> 276549f8c441 Step 4/7 : RUN useradd -u 2000 -ms /bin/bash modeluser ---> Running in e5d62f47d4fa Removing intermediate container e5d62f47d4fa ---> 206c7ad88b83 Step 5/7 : USER 2000 ---> Running in 98307802e3cb Removing intermediate container 98307802e3cb ---> 0ac44031eb4a Step 6/7 : EXPOSE 8080 ---> Running in 75b018a3bd8d Removing intermediate container 75b018a3bd8d ---> 314e6255d91e Step 7/7 : CMD ["--http", "8080","--routes-file", "/usr/bin/mlrtapp/routes.json"] ---> Running in 1549e1f467cc Removing intermediate container 1549e1f467cc ---> f703f5e9bd1b Successfully built f703f5e9bd1b Successfully tagged weighted-sum:v1
imageName = "weighted-sum:v1"
Deploy Model
You must push the image to a Docker registry that is visible to the Modelscape API. For next steps, choose the model version for which you want to create a model version build. Use the Modelscape API to create the build and deployment environment, then deploy your build. For more information about the API, see Using the Modelscape API.
Create Archive for Deployment to MATLAB Production Server
To deploy a model that implements the mrm.execution.Model
interface to MATLAB Production Server, use the mrm.execution.compiler.buildDeployableArchive
function.
modelInstance = WeightedSum; mrm.execution.compiler.buildDeployableArchive(modelInstance)
Register the archive as a Model Version Build using the CreateBuild
endpoint of the Modelscape API. Specify the build type as deployable_archive
. For more information about the API, see Using the Modelscape API.
Copy the archive to the MATLAB Production Server auto_deploy
folder, and register the deployment using the CreateDeployment
endpoint of the Modelscape API.