BYOM Model Upload Guide (SDK)

In this guide, you’ll learn how to upload your models to the Matrice.ai platform using the BYOM (Bring Your Own Model) SDK. This step outlines how to add newly created configuration files for any model to the Matrice platform using the Matrice SDK. The process involves three main steps: Setting up Matrice credentials, adding the model family and configuration files.

Steps for Uploading Your Model

1. Setting up Matrice credentials

Initialize the Matrice keys for authentication. These keys allow you to interact with the Matrice platform securely.

Ensure you have your Matrice Access Key ID and Secret Access Key. Set these keys in your environment or directly in your script.

import os
os.environ['ENV']="prod"
os.environ['MATRICE_ACCESS_KEY_ID'] = "YOUR_ACCESS_KEY_ID"
os.environ['MATRICE_SECRET_ACCESS_KEY'] = "YOUR_SECRET_ACCESS_KEY"
os.environ['MATRICE_ACCOUNT_NUMBER'] = "YOUR_ACCOUNT_NUMBER"

Add your project_id or name and create the Sessoin class and BYOM class.

from matrice.session import Session
from matrice.model_store import BYOM

project_id = "67***************ae7"

S = Session(os.environ['MATRICE_ACCOUNT_NUMBER'], os.environ['MATRICE_ACCESS_KEY_ID'], os.environ['MATRICE_SECRET_ACCESS_KEY'], project_id=project_id)

byom = BYOM(S)

2. Model Family Information

First, add the model family information. This includes specifying the model inputs, outputs, architecture, and any other custom training settings.

model_family_name = "TEST_ResNet"

model_family_info = {
    "modelFamily": "TEST_ResNet",
    "modelInputs": ["image"],
    "modelOutputs": ["classification"],
    "modelArchs": [
        {
            "modelKey": "resnet18",
            "modelName": "ResNet-18",
            "paramsInMillion": 11.7
        },
        {
            "modelKey": "resnet34",
            "modelName": "ResNet-34",
            "paramsInMillion": 21.8
        },
        {
            "modelKey": "resnet50",
            "modelName": "ResNet-50",
            "paramsInMillion": 25.6
        },
        {
            "modelKey": "resnet101",
            "modelName": "ResNet-101",
            "paramsInMillion": 44.5
        },
        {
            "modelKey": "resnet152",
            "modelName": "ResNet-152",
            "paramsInMillion": 60.2
        }
    ],
    "description": "ResNet (Residual Network) is a deep neural network architecture that introduces skip connections, or shortcuts, to jump over some layers. This helps in addressing the vanishing gradient problem and allows training of very deep networks.",
    "references": [
        "https://arxiv.org/abs/1512.03385"
    ],
    "trainingFramework": "PyTorch",
    "dataProcessing": {
        "inputFormat": "ImageNet",
        "input_size": {
            "all": 224,
            "resnet152": 448
        }
    },
    "exportFormats": [
        "TorchScript",
        "ONNX",
        "OpenVINO",
        "TensorRT"
    ],
    "supportedMetrics": [
        "acc@1",
        "acc@5",
        "f1_score",
        "recall",
        "precision",
        "specificity"
    ],
    "benchmarkResults": [
        {
            "dataset": "ImageNet",
            "splitType": "val",
            "metric": "acc@1",
            "values": {
                "resnet18": 69.8,
                "resnet34": 73.3,
                "resnet50": 76.1,
                "resnet101": 77.37,
                "resnet152": 78.31
            }
        }
    ]
}

byom.add_model_family(model_family_info)

3. Train Configuration

Next, add the training configuration details. This includes specifying the training dataset, hyperparameters, and any other custom training settings.

model_train_config = {
    "actionType": "train_model",
    "actionConfig": [
        {
            "keyName": "batch_size",
            "valueType": "int32",
            "defaultValue": 4,
            "predefinedValues": [
                1,
                4,
                16,
                32,
                64
            ],
            "minValue": 1,
            "maxValue": 1024,
            "anyValue": True,
            "modelKeys": [
                "all"
            ]
        },
        {
            "keyName": "epochs",
            "valueType": "int32",
            "defaultValue": 50,
            "predefinedValues": [
                10,
                50,
                100,
                150,
                200
            ],
            "minValue": 5,
            "maxValue": 300,
            "anyValue": True,
            "modelKeys": [
                "all"
            ]
        },
        {
            "keyName": "learning_rate",
            "valueType": "float32",
            "defaultValue": 0.001,
            "predefinedValues": [
                1e-05,
                0.0001,
                0.001,
                0.01,
                0.05,
                0.1
            ],
            "minValue": 1e-05,
            "maxValue": 0.5,
            "anyValue": True,
            "modelKeys": [
                "all"
            ]
        },
        {
            "keyName": "momentum",
            "valueType": "float32",
            "defaultValue": 0.95,
            "predefinedValues": [
                0.9,
                0.95,
                0.99,
                0.995
            ],
            "minValue": 0.8,
            "maxValue": 0.995,
            "anyValue": True,
            "modelKeys": [
                "all"
            ]
        },
        {
            "keyName": "weight_decay",
            "valueType": "float64",
            "defaultValue": 0.0001,
            "predefinedValues": [
                0.0001,
                0.001,
                0.0002
            ],
            "minValue": 0,
            "maxValue": 0.1,
            "anyValue": True,
            "modelKeys": [
                "all"
            ]
        },
        {
            "keyName": "optimizer",
            "valueType": "string",
            "defaultValue": "AdamW",
            "predefinedValues": [
                "AdamW",
                "SGD",
                "RMSprop"
            ],
            "minValue": 0,
            "maxValue": 0,
            "anyValue": False,
            "modelKeys": [
                "all"
            ]
        },
        {
            "keyName": "lr_scheduler",
            "valueType": "string",
            "defaultValue": "StepLR",
            "predefinedValues": [
                "StepLR",
                "CosineAnnealingLR",
                "ExponentialLR"
            ],
            "minValue": 0,
            "maxValue": 0,
            "anyValue": False,
            "modelKeys": [
                "all"
            ]
        },
        {
            "keyName": "lr_step_size",
            "valueType": "int32",
            "defaultValue": 10,
            "predefinedValues": [
                5,
                10,
                15,
                20,
                25
            ],
            "minValue": 1,
            "maxValue": 50,
            "anyValue": True,
            "modelKeys": [
                "all"
            ]
        },
        {
            "keyName": "lr_min",
            "valueType": "float32",
            "defaultValue": 1e-05,
            "predefinedValues": [
                1e-05,
                0.0001,
                0.001,
                0.01,
                0.1
            ],
            "minValue": 1e-05,
            "maxValue": 1.0,
            "anyValue": True,
            "modelKeys": [
                "all"
            ]
        },
        {
            "keyName": "lr_gamma",
            "valueType": "float32",
            "defaultValue": 0.1,
            "predefinedValues": [
                0.1,
                0.2,
                0.5,
                0.9,
                0.95
            ],
            "minValue": 0.01,
            "maxValue": 1.0,
            "anyValue": True,
            "modelKeys": [
                "all"
            ]
        },
        {
            "keyName": "patience",
            "valueType": "int32",
            "defaultValue": 5,
            "predefinedValues": [
                5,
                10,
                15,
                20,
                25
            ],
            "minValue": 1,
            "maxValue": 50,
            "anyValue": True,
            "modelKeys": [
                "all"
            ]
        },
        {
            "keyName": "min_delta",
            "valueType": "float32",
            "defaultValue": 0.0001,
            "predefinedValues": [
                1e-05,
                0.0001,
                0.001,
                0.01,
                0.1
            ],
            "minValue": 1e-05,
            "maxValue": 1.0,
            "anyValue": True,
            "modelKeys": [
                "all"
            ]
        }
    ]
}

byom.add_train_action_config(model_family_name, model_train_config)

3. Export Configuration

The final configuration step is to upload or specify the model export settings. Exporting involves defining how the trained model will be serialized, including the export format (e.g., ONNX, OpenVINO, TorchScript, etc.) and any runtime-specific parameters.

model_export_config = {
    "actionType": "export_model",
    "actionConfig": [
        {
            "keyName": "dynamic",
            "valueType": "bool",
            "defaultValue": False,
            "predefinedValues": [
                True,
                False
            ],
            "anyValue": False,
            "hyperparameter": True,
            "minValue": 0,
            "maxValue": 0,
            "exportFormats": [
                "ONNX",
                "TensorRT"
            ],
            "modelKeys": [
                "all"
            ]
        },
        {
            "keyName": "simplify",
            "valueType": "bool",
            "defaultValue": False,
            "predefinedValues": [
                True,
                False
            ],
            "anyValue": False,
            "hyperparameter": True,
            "minValue": 0,
            "maxValue": 0,
            "exportFormats": [
                "ONNX"
            ],
            "modelKeys": [
                "all"
            ]
        },
        {
            "keyName": "int8",
            "valueType": "bool",
            "defaultValue": False,
            "predefinedValues": [
                True,
                False
            ],
            "anyValue": False,
            "hyperparameter": True,
            "minValue": 0,
            "maxValue": 0,
            "exportFormats": [
                "OpenVINO"
            ],
            "modelKeys": [
                "all"
            ]
        },
        {
            "keyName": "optimize",
            "valueType": "bool",
            "defaultValue": False,
            "predefinedValues": [
                True,
                False
            ],
            "anyValue": False,
            "hyperparameter": True,
            "minValue": 0,
            "maxValue": 0,
            "exportFormats": [
                "TorchScript"
            ],
            "modelKeys": [
                "all"
            ]
        }
    ]
}
byom.add_export_action_config(model_family_name, model_export_config)

4. Upload the Requirement file, dockerfile and Codebase and Logs

Once all configurations have been added, upload your codebase. This step involves:

code_zip_path = "my_code.zip"
matrice_sdk_version = "1.0.96"
cuda_version = "12.1"
project_type = "classification"
requirement_txt_path="my_requirement.txt"
docker_file_path="my_dockerfile"

byom.add_family_requirement_file(
        model_family_name, 
        requirement_txt_path)

byom.add_family_docker_file(
        model_family_name, 
        docker_file_path)


byom.upload_model_family_codebase(
        model_family_name,
        code_zip_path,
        matrice_sdk_version,
        cuda_version,
        project_type,
    )

5. Actions Integration and Running Test Cases

Once everything is uploaded and validated, the model will be added to the platform and you need start the test cases and integrate the model actions to start training, optimization, and deployment.

For getting the model family test cases, you can use the following code:

test_cases, error, message= byom.get_test_cases(model_family_name)

For starting the test cases, you can use either start test cases by type or start a specific test cases of the following codes:

test_cases_type = "default" # or "all" or "failed"
byom.start_test_cases_by_type(model_family_name, test_cases_type, project_type)

Or with a specific test case:

test_cases = [
    {"actionType": "model_train", "batch_size": 4},
    {"actionType": "model_export", "exportFormat": "TorchScript"},
    {"actionType": "model_export", "exportFormat": "ONNX"},
    {"actionType": "model_eval", "exportFormat": "ONNX"},
    {"actionType": "model_deploy", "exportFormat": "ONNX"}
]
byom.start_selected_test_cases(model_family_name, model_key, test_cases)

For getting the model family actions, you can use the following code:

get_allowed_actions, error, message= byom.get_allowed_actions(model_family_name)

For integrating the model actions, you can use the following code:

actions = [
    {"actionType": "train_model", "batch_size": 4},
    {"actionType": "export_model", "exportFormat": "TorchScript"},
]
byom.integrate_model_actions(model_family_name, model_key, actions)

With this step-by-step process, you can successfully upload your models to the BYOM platform and ensure they are ready for integration.