Main Content

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 of x and y.

  • getParameters — Return the definition of the parameters in a batch of evaluations. In this example, this method returns the names and types of A and B.

  • getOutputs — Return the definition of the output variables. In this example, this method returns z.

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 field name with a value listed in mwtype.

  • 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 size N x M x .... Use NaN 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.