From 8fb12afe706c3408618e92fffcb65a9a894d9fd0 Mon Sep 17 00:00:00 2001 From: Stephanie Visser <42637613+zoekdestep@users.noreply.github.com> Date: Tue, 5 May 2020 20:16:56 +0200 Subject: [PATCH 01/29] Add Terraform option to environment_setup (#268) * setup basic folder and file structure * add tf backend file and bash script to create state storage * basic pipeline for infrastructure with tf - yaml, tf, bash * naming and deleting unnecessary bash script * updated documentation * added to the get_started.md guide * added terraform plan step --- docs/code_description.md | 9 ++- docs/getting_started.md | 6 +- ...> iac-create-environment-pipeline-arm.yml} | 0 .../iac-create-environment-pipeline-tf.yml | 72 +++++++++++++++++++ environment_setup/tf-templates/backend.tf | 4 ++ environment_setup/tf-templates/main.tf | 71 ++++++++++++++++++ 6 files changed, 158 insertions(+), 4 deletions(-) rename environment_setup/{iac-create-environment-pipeline.yml => iac-create-environment-pipeline-arm.yml} (100%) create mode 100644 environment_setup/iac-create-environment-pipeline-tf.yml create mode 100644 environment_setup/tf-templates/backend.tf create mode 100644 environment_setup/tf-templates/main.tf diff --git a/docs/code_description.md b/docs/code_description.md index 351b4c34..8dc3c756 100644 --- a/docs/code_description.md +++ b/docs/code_description.md @@ -18,7 +18,8 @@ High level directory structure for this repository: │ ├── util <- Python script for various utility operations specific to this ML project. ├── docs <- Extensive markdown documentation for entire project. ├── environment_setup <- The top-level folder for everything related to infrastructure. -│ ├── arm-templates <- Azure Resource Manager(ARM) templates to build infrastructure needed for this project. +│ ├── arm-templates <- Azure Resource Manager(ARM) templates to build infrastructure needed for this project. +│ ├── tf-templates <- Terraform templates to build infrastructure needed for this project. ├── experimentation <- Jupyter notebooks with ML experimentation code. ├── ml_service <- The top-level folder for all Azure Machine Learning resources. │ ├── pipelines <- Python script that builds Azure Machine Learning pipelines. @@ -35,7 +36,11 @@ The repository provides a template with folders structure suitable for maintaini - `environment_setup/install_requirements.sh` : This script prepares a local conda environment i.e. install the Azure ML SDK and the packages specified in environment definitions. -- `environment_setup/iac-*.yml, arm-templates` : Infrastructure as Code piplines to create and delete required resources along with corresponding arm-templates. +- `environment_setup/iac-*-arm.yml, arm-templates` : Infrastructure as Code piplines to create required resources using ARM, along with corresponding arm-templates. Infrastructure as Code can be deployed with this template or with the Terraform template. + +- `environment_setup/iac-*-tf.yml, tf-templates` : Infrastructure as Code piplines to create required resources using Terraform, along with corresponding tf-templates. Infrastructure as Code can be deployed with this template or with the ARM template. + +- `environment_setup/iac-remove-environment.yml` : Infrastructure as Code piplines to delete the created required resources. - `environment_setup/Dockerfile` : Dockerfile of a build agent containing Python 3.6 and all required packages. diff --git a/docs/getting_started.md b/docs/getting_started.md index 86eb73df..2c63fa94 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -81,7 +81,7 @@ More variables are available for further tweaking, but the above variables are a ## Provisioning resources using Azure Pipelines -The easiest way to create all required Azure resources (Resource Group, Azure ML Workspace, Container Registry, and others) is to use the **Infrastructure as Code (IaC)** [pipeline in this repository](../environment_setup/iac-create-environment-pipeline.yml). The pipeline takes care of setting up all required resources based on these [Azure Resource Manager templates](../environment_setup/arm-templates/cloud-environment.json). +The easiest way to create all required Azure resources (Resource Group, Azure ML Workspace, Container Registry, and others) is to use the **Infrastructure as Code (IaC)** [pipeline with ARM templates](../environment_setup/iac-create-environment-pipeline-arm.yml) or the [pipeline with Terraform templates](../environment_setup/iac-create-environment-pipeline-tf.yml). The pipeline takes care of setting up all required resources based on these [Azure Resource Manager templates](../environment_setup/arm-templates/cloud-environment.json), or based on these [Terraform templates](../environment_setup/tf-templates). ### Create an Azure DevOps Service Connection for the Azure Resource Manager @@ -100,10 +100,12 @@ In your Azure DevOps project, create a build pipeline from your forked repositor ![Build connect step](./images/build-connect.png) -Select the **Existing Azure Pipelines YAML file** option and set the path to [/environment_setup/iac-create-environment-pipeline.yml](../environment_setup/iac-create-environment-pipeline.yml): +Select the **Existing Azure Pipelines YAML file** option and set the path to [/environment_setup/iac-create-environment-pipeline-arm.yml](../environment_setup/iac-create-environment-pipeline-arm.yml) or to [/environment_setup/iac-create-environment-pipeline-tf.yml](../environment_setup/iac-create-environment-pipeline-tf.yml), depending on if you want to deploy your infrastructure using ARM templates or Terraform: ![Configure step](./images/select-iac-pipeline.png) +If you decide to use Terraform, make sure the ['Terraform Build & Release Tasks' from Charles Zipp](https://marketplace.visualstudio.com/items?itemName=charleszipp.azure-pipelines-tasks-terraform) is installed. + Having done that, run the pipeline: ![IaC run](./images/run-iac-pipeline.png) diff --git a/environment_setup/iac-create-environment-pipeline.yml b/environment_setup/iac-create-environment-pipeline-arm.yml similarity index 100% rename from environment_setup/iac-create-environment-pipeline.yml rename to environment_setup/iac-create-environment-pipeline-arm.yml diff --git a/environment_setup/iac-create-environment-pipeline-tf.yml b/environment_setup/iac-create-environment-pipeline-tf.yml new file mode 100644 index 00000000..3e94677e --- /dev/null +++ b/environment_setup/iac-create-environment-pipeline-tf.yml @@ -0,0 +1,72 @@ +# CI/PR Pipeline that deploys an TF template to create or update the resources needed by the other pipelines. +trigger: + branches: + include: + - master + paths: + include: + - environment_setup/tf-templates/* +pr: + branches: + include: + - master + paths: + include: + - environment_setup/tf-templates/* + +pool: + vmImage: 'ubuntu-latest' + +variables: +- group: devopsforai-aml-vg + +steps: +- task: charleszipp.azure-pipelines-tasks-terraform.azure-pipelines-tasks-terraform-installer.TerraformInstaller@0 + displayName: 'Use Terraform 0.12.24' + inputs: + terraformVersion: 0.12.24 + +- task: charleszipp.azure-pipelines-tasks-terraform.azure-pipelines-tasks-terraform-cli.TerraformCLI@0 + displayName: 'TF init - Deploy MLOps resources to Azure' + inputs: + command: init + commandOptions: '-backend=true -backend-config=$(Build.SourcesDirectory)/environment_setup/tf-templates/backend.tf' + workingDirectory: '$(Build.SourcesDirectory)/environment_setup/tf-templates' + backendType: azurerm + backendServiceArm: $(AZURE_RM_SVC_CONNECTION) + ensureBackend: true + backendAzureRmResourceGroupLocation: $(LOCATION) + backendAzureRmResourceGroupName: $(RESOURCE_GROUP) + backendAzureRmStorageAccountName: 'statestor' + backendAzureRmStorageAccountSku: 'Standard_LRS' + backendAzureRmContainerName: 'tfstate-cont' + backendAzureRmKey: 'mlopsinfra.tfstate' + +- task: charleszipp.azure-pipelines-tasks-terraform.azure-pipelines-tasks-terraform-cli.TerraformCLI@0 + displayName: 'TF validate - Deploy MLOps resources to Azure' + inputs: + command: validate + workingDirectory: '$(Build.SourcesDirectory)/environment_setup/tf-templates' + +- task: charleszipp.azure-pipelines-tasks-terraform.azure-pipelines-tasks-terraform-cli.TerraformCLI@0 + displayName: 'TF plan - Deploy MLOps resources to Azure' + inputs: + command: plan + workingDirectory: '$(Build.SourcesDirectory)/environment_setup/tf-templates' + environmentServiceName: $(AZURE_RM_SVC_CONNECTION) + env: + TF_VAR_BASE_NAME: $(BASE_NAME) + TF_VAR_RESOURCE_GROUP: $(RESOURCE_GROUP) + TF_VAR_WORKSPACE_NAME: $(WORKSPACE_NAME) + +- task: charleszipp.azure-pipelines-tasks-terraform.azure-pipelines-tasks-terraform-cli.TerraformCLI@0 + displayName: 'TF apply - Deploy MLOps resources to Azure' + inputs: + command: apply + workingDirectory: '$(Build.SourcesDirectory)/environment_setup/tf-templates' + environmentServiceName: $(AZURE_RM_SVC_CONNECTION) + env: + TF_VAR_BASE_NAME: $(BASE_NAME) + TF_VAR_RESOURCE_GROUP: $(RESOURCE_GROUP) + TF_VAR_WORKSPACE_NAME: $(WORKSPACE_NAME) + diff --git a/environment_setup/tf-templates/backend.tf b/environment_setup/tf-templates/backend.tf new file mode 100644 index 00000000..0aec0499 --- /dev/null +++ b/environment_setup/tf-templates/backend.tf @@ -0,0 +1,4 @@ +terraform { + backend "azurerm" { + } +} diff --git a/environment_setup/tf-templates/main.tf b/environment_setup/tf-templates/main.tf new file mode 100644 index 00000000..c57a5a84 --- /dev/null +++ b/environment_setup/tf-templates/main.tf @@ -0,0 +1,71 @@ +provider "azurerm" { + version = "=2.3.0" + features {} +} + +variable BASE_NAME {} +variable RESOURCE_GROUP {} +variable WORKSPACE_NAME {} + +#-------------------------------------------------------------------------------- + +#Set the already-existing resource group +data "azurerm_resource_group" "amlrg" { + name = var.RESOURCE_GROUP +} + +#Set client config for a.o. tenant id +data "azurerm_client_config" "currentconfig" { +} + +#-------------------------------------------------------------------------------- + +# Storage account for AML Service +resource "azurerm_storage_account" "amlstor" { + name = "${var.BASE_NAME}amlsa" + location = data.azurerm_resource_group.amlrg.location + resource_group_name = data.azurerm_resource_group.amlrg.name + account_tier = "Standard" + account_replication_type = "LRS" +} + +# Keyvault for AML Service +resource "azurerm_key_vault" "amlkv" { + name = "${var.BASE_NAME}-AML-KV" + location = data.azurerm_resource_group.amlrg.location + resource_group_name = data.azurerm_resource_group.amlrg.name + tenant_id = data.azurerm_client_config.currentconfig.tenant_id + sku_name = "standard" +} + +# App Insights for AML Service +resource "azurerm_application_insights" "amlai" { + name = "${var.BASE_NAME}-AML-AI" + location = data.azurerm_resource_group.amlrg.location + resource_group_name = data.azurerm_resource_group.amlrg.name + application_type = "web" +} + +# Container registry for AML Service +resource "azurerm_container_registry" "amlacr" { + name = "${var.BASE_NAME}amlcr" + resource_group_name = data.azurerm_resource_group.amlrg.name + location = data.azurerm_resource_group.amlrg.location + sku = "Standard" + admin_enabled = true +} + +# ML Workspace for AML Service, depending on the storage account, Keyvault, App Insights and ACR. +resource "azurerm_machine_learning_workspace" "amlws" { + name = var.WORKSPACE_NAME + location = data.azurerm_resource_group.amlrg.location + resource_group_name = data.azurerm_resource_group.amlrg.name + application_insights_id = azurerm_application_insights.amlai.id + key_vault_id = azurerm_key_vault.amlkv.id + storage_account_id = azurerm_storage_account.amlstor.id + container_registry_id = azurerm_container_registry.amlacr.id + + identity { + type = "SystemAssigned" + } +} From f8cd70f3b1e573bb859c5d49526032e412357bfc Mon Sep 17 00:00:00 2001 From: Kosuke Fujimoto Date: Thu, 21 May 2020 05:51:13 +0900 Subject: [PATCH 02/29] Replaced Env class with dataclass (#277) --- ml_service/util/env_variables.py | 218 +++++++------------------------ 1 file changed, 48 insertions(+), 170 deletions(-) diff --git a/ml_service/util/env_variables.py b/ml_service/util/env_variables.py index c734e098..747df5ec 100644 --- a/ml_service/util/env_variables.py +++ b/ml_service/util/env_variables.py @@ -1,174 +1,52 @@ +"""Env dataclass to load and hold all environment variables +""" +from dataclasses import dataclass import os -from dotenv import load_dotenv - - -class Singleton(object): - _instances = {} - - def __new__(class_, *args, **kwargs): - if class_ not in class_._instances: - class_._instances[class_] = super(Singleton, class_).__new__(class_, *args, **kwargs) # noqa E501 - return class_._instances[class_] - - -class Env(Singleton): - - def __init__(self): - load_dotenv() - self._workspace_name = os.environ.get("WORKSPACE_NAME") - self._resource_group = os.environ.get("RESOURCE_GROUP") - self._subscription_id = os.environ.get("SUBSCRIPTION_ID") - self._tenant_id = os.environ.get("TENANT_ID") - self._app_id = os.environ.get("SP_APP_ID") - self._app_secret = os.environ.get("SP_APP_SECRET") - self._vm_size = os.environ.get("AML_COMPUTE_CLUSTER_CPU_SKU") - self._compute_name = os.environ.get("AML_COMPUTE_CLUSTER_NAME") - self._vm_priority = os.environ.get("AML_CLUSTER_PRIORITY", 'lowpriority') # noqa E501 - self._min_nodes = int(os.environ.get("AML_CLUSTER_MIN_NODES", 0)) - self._max_nodes = int(os.environ.get("AML_CLUSTER_MAX_NODES", 4)) - self._build_id = os.environ.get("BUILD_BUILDID") - self._pipeline_name = os.environ.get("TRAINING_PIPELINE_NAME") - self._sources_directory_train = os.environ.get("SOURCES_DIR_TRAIN") - self._train_script_path = os.environ.get("TRAIN_SCRIPT_PATH") - self._evaluate_script_path = os.environ.get("EVALUATE_SCRIPT_PATH") - self._register_script_path = os.environ.get("REGISTER_SCRIPT_PATH") - self._model_name = os.environ.get("MODEL_NAME") - self._experiment_name = os.environ.get("EXPERIMENT_NAME") - self._model_version = os.environ.get('MODEL_VERSION') - self._image_name = os.environ.get('IMAGE_NAME') - self._db_cluster_id = os.environ.get("DB_CLUSTER_ID") - self._score_script = os.environ.get("SCORE_SCRIPT") - self._build_uri = os.environ.get("BUILD_URI") - self._dataset_name = os.environ.get("DATASET_NAME") - self._datastore_name = os.environ.get("DATASTORE_NAME") - self._dataset_version = os.environ.get("DATASET_VERSION") - self._run_evaluation = os.environ.get("RUN_EVALUATION", "true") - self._allow_run_cancel = os.environ.get( - "ALLOW_RUN_CANCEL", "true") - self._aml_env_name = os.environ.get("AML_ENV_NAME") - self._rebuild_env = os.environ.get("AML_REBUILD_ENVIRONMENT", - "false").lower().strip() == "true" - - @property - def workspace_name(self): - return self._workspace_name - - @property - def resource_group(self): - return self._resource_group - - @property - def subscription_id(self): - return self._subscription_id - - @property - def tenant_id(self): - return self._tenant_id - - @property - def app_id(self): - return self._app_id - - @property - def app_secret(self): - return self._app_secret - - @property - def vm_size(self): - return self._vm_size - - @property - def compute_name(self): - return self._compute_name - - @property - def db_cluster_id(self): - return self._db_cluster_id - - @property - def build_id(self): - return self._build_id - - @property - def pipeline_name(self): - return self._pipeline_name +from typing import Optional - @property - def sources_directory_train(self): - return self._sources_directory_train - - @property - def train_script_path(self): - return self._train_script_path - - @property - def evaluate_script_path(self): - return self._evaluate_script_path - - @property - def register_script_path(self): - return self._register_script_path - - @property - def model_name(self): - return self._model_name - - @property - def experiment_name(self): - return self._experiment_name - - @property - def vm_priority(self): - return self._vm_priority - - @property - def min_nodes(self): - return self._min_nodes - - @property - def max_nodes(self): - return self._max_nodes - - @property - def model_version(self): - return self._model_version - - @property - def image_name(self): - return self._image_name - - @property - def score_script(self): - return self._score_script - - @property - def build_uri(self): - return self._build_uri - - @property - def dataset_name(self): - return self._dataset_name - - @property - def datastore_name(self): - return self._datastore_name - - @property - def dataset_version(self): - return self._dataset_version - - @property - def run_evaluation(self): - return self._run_evaluation - - @property - def allow_run_cancel(self): - return self._allow_run_cancel +from dotenv import load_dotenv - @property - def aml_env_name(self): - return self._aml_env_name - @property - def rebuild_env(self): - return self._rebuild_env +@dataclass(frozen=True) +class Env: + """Loads all environment variables into a predefined set of properties + """ + # to load .env file into environment variables for local execution + load_dotenv() + workspace_name: Optional[str] = os.environ.get("WORKSPACE_NAME") + resource_group: Optional[str] = os.environ.get("RESOURCE_GROUP") + subscription_id: Optional[str] = os.environ.get("SUBSCRIPTION_ID") + tenant_id: Optional[str] = os.environ.get("TENANT_ID") + app_id: Optional[str] = os.environ.get("SP_APP_ID") + app_secret: Optional[str] = os.environ.get("SP_APP_SECRET") + vm_size: Optional[str] = os.environ.get("AML_COMPUTE_CLUSTER_CPU_SKU") + compute_name: Optional[str] = os.environ.get("AML_COMPUTE_CLUSTER_NAME") + vm_priority: Optional[str] = os.environ.get("AML_CLUSTER_PRIORITY", + 'lowpriority') + min_nodes: int = int(os.environ.get("AML_CLUSTER_MIN_NODES", 0)) + max_nodes: int = int(os.environ.get("AML_CLUSTER_MAX_NODES", 4)) + build_id: Optional[str] = os.environ.get("BUILD_BUILDID") + pipeline_name: Optional[str] = os.environ.get("TRAINING_PIPELINE_NAME") + sources_directory_train: Optional[str] = os.environ.get( + "SOURCES_DIR_TRAIN") + train_script_path: Optional[str] = os.environ.get("TRAIN_SCRIPT_PATH") + evaluate_script_path: Optional[str] = os.environ.get( + "EVALUATE_SCRIPT_PATH") + register_script_path: Optional[str] = os.environ.get( + "REGISTER_SCRIPT_PATH") + model_name: Optional[str] = os.environ.get("MODEL_NAME") + experiment_name: Optional[str] = os.environ.get("EXPERIMENT_NAME") + model_version: Optional[str] = os.environ.get('MODEL_VERSION') + image_name: Optional[str] = os.environ.get('IMAGE_NAME') + db_cluster_id: Optional[str] = os.environ.get("DB_CLUSTER_ID") + score_script: Optional[str] = os.environ.get("SCORE_SCRIPT") + build_uri: Optional[str] = os.environ.get("BUILD_URI") + dataset_name: Optional[str] = os.environ.get("DATASET_NAME") + datastore_name: Optional[str] = os.environ.get("DATASTORE_NAME") + dataset_version: Optional[str] = os.environ.get("DATASET_VERSION") + run_evaluation: Optional[str] = os.environ.get("RUN_EVALUATION", "true") + allow_run_cancel: Optional[str] = os.environ.get("ALLOW_RUN_CANCEL", + "true") + aml_env_name: Optional[str] = os.environ.get("AML_ENV_NAME") + rebuild_env: Optional[bool] = os.environ.get( + "AML_REBUILD_ENVIRONMENT", "false").lower().strip() == "true" From cbeadae5b53409f71ff69a34c27ed4aa1e6606da Mon Sep 17 00:00:00 2001 From: Jenny So Date: Tue, 2 Jun 2020 14:30:15 -0700 Subject: [PATCH 03/29] update azureml sdk (#287) --- diabetes_regression/ci_dependencies.yml | 2 +- diabetes_regression/conda_dependencies.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/diabetes_regression/ci_dependencies.yml b/diabetes_regression/ci_dependencies.yml index 72c91cd3..52bdeb44 100644 --- a/diabetes_regression/ci_dependencies.yml +++ b/diabetes_regression/ci_dependencies.yml @@ -16,7 +16,7 @@ dependencies: - pip: # dependencies with versions aligned with conda_dependencies.yml. - - azureml-sdk==1.3.* + - azureml-sdk==1.6.* # Additional pip dependencies for the CI environment. - pytest==5.4.* diff --git a/diabetes_regression/conda_dependencies.yml b/diabetes_regression/conda_dependencies.yml index 277efbec..57f2b999 100644 --- a/diabetes_regression/conda_dependencies.yml +++ b/diabetes_regression/conda_dependencies.yml @@ -23,11 +23,11 @@ dependencies: - pip: # Base AzureML SDK - - azureml-sdk==1.3.* + - azureml-sdk==1.6.* # Minimum required for the scoring environment. Must match AzureML SDK version. # https://docs.microsoft.com/en-us/azure/machine-learning/concept-environments - - azureml-defaults==1.3.* + - azureml-defaults==1.6.* # Training deps - scikit-learn From cd762ecaa9dd1914d4e72dc514d0ce7dad66a58d Mon Sep 17 00:00:00 2001 From: jotaylo Date: Mon, 15 Jun 2020 12:28:23 -0700 Subject: [PATCH 04/29] Move instruction to install AML extension to Azure Devops setup instructions (#298) --- docs/getting_started.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/getting_started.md b/docs/getting_started.md index 2c63fa94..11bfb20f 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -6,6 +6,7 @@ This guide shows how to get MLOpsPython working with a sample ML project ***diab We recommend working through this guide completely to ensure everything is working in your environment. After the sample is working, follow the [bootstrap instructions](../bootstrap/README.md) to convert the ***diabetes_regression*** sample into a starting point for your project. - [Setting up Azure DevOps](#setting-up-azure-devops) + - [Install the Azure Machine Learning extension](#install-the-azure-machine-learning-extension) - [Get the code](#get-the-code) - [Create a Variable Group for your Pipeline](#create-a-variable-group-for-your-pipeline) - [Variable Descriptions](#variable-descriptions) @@ -33,6 +34,12 @@ You'll use Azure DevOps for running the multi-stage pipeline with build, model t If you already have an Azure DevOps organization, create a new project using the guide at [Create a project in Azure DevOps and TFS](https://docs.microsoft.com/en-us/azure/devops/organizations/projects/create-project?view=azure-devops). +### Install the Azure Machine Learning extension + +Install the **Azure Machine Learning** extension to your Azure DevOps organization from the [Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=ms-air-aiagility.vss-services-azureml). + +This extension contains the Azure ML pipeline tasks and adds the ability to create Azure ML Workspace service connections. + ## Get the code We recommend using the [repository template](https://github.com/microsoft/MLOpsPython/generate), which effectively forks the repository to your own GitHub location and squashes the history. You can use the resulting repository for this guide and for your own experimentation. @@ -118,8 +125,6 @@ Check that the newly created resources appear in the [Azure Portal](https://port At this point, you should have an Azure ML Workspace created. Similar to the Azure Resource Manager service connection, you need to create an additional one for the Azure ML Workspace. -Install the **Azure Machine Learning** extension to your Azure DevOps organization from the [Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=ms-air-aiagility.vss-services-azureml). The extension is required for the service connection. - Create a new service connection to your Azure ML Workspace using the [Machine Learning Extension](https://marketplace.visualstudio.com/items?itemName=ms-air-aiagility.vss-services-azureml) instructions to enable executing the Azure ML training pipeline. The connection name needs to match `WORKSPACE_SVC_CONNECTION` that you set in the variable group above. ![Created resources](./images/ml-ws-svc-connection.png) From 08bb6f4a26d3db7ee998a45da62825c47411aec1 Mon Sep 17 00:00:00 2001 From: David Tesar Date: Mon, 15 Jun 2020 14:09:12 -0700 Subject: [PATCH 05/29] Simplify docs flow (#297) --- bootstrap/README.md | 17 +---------------- docs/custom_model.md | 24 ++++++++++++++++++------ docs/getting_started.md | 4 ++-- 3 files changed, 21 insertions(+), 24 deletions(-) diff --git a/bootstrap/README.md b/bootstrap/README.md index 27051f2b..0841cc30 100644 --- a/bootstrap/README.md +++ b/bootstrap/README.md @@ -1,18 +1,3 @@ # Bootstrap from MLOpsPython repository -To use this existing project structure and scripts for your new ML project, you can quickly get started from the existing repository, bootstrap and create a template that works for your ML project. - -Bootstrapping will prepare a directory structure for your project which includes: - -* renaming files and folders from the base project name `diabetes_regression` to your project name -* fixing imports and absolute path based on your project name -* deleting and cleaning up some directories - -To bootstrap from the existing MLOpsPython repository: - -1. Ensure Python 3 is installed locally -1. Clone this repository locally -1. Run bootstrap.py script -`python bootstrap.py -d [dirpath] -n [projectname]` - * `[dirpath]` is the absolute path to the root of the directory where MLOpsPython is cloned - * `[projectname]` is the name of your ML project +For steps on how to use the bootstrap script, please see the "Bootstrap the project" section of the [custom model guide](../docs/custom_model.md#bootstrap-the-project). diff --git a/docs/custom_model.md b/docs/custom_model.md index bce1fb8a..d21c8b8d 100644 --- a/docs/custom_model.md +++ b/docs/custom_model.md @@ -3,11 +3,11 @@ This document provides steps to follow when using this repository as a template to train models and deploy the models with real-time inference in Azure ML with your own scripts and data. 1. Follow the MLOpsPython [Getting Started](getting_started.md) guide -1. Follow the MLOpsPython [bootstrap instructions](../bootstrap/README.md) to create your project starting point +1. Bootstrap the project 1. Configure training data 1. [If necessary] Convert your ML experimental code into production ready code 1. Replace the training code -1. Update the evaluation code +1. [Optional] Update the evaluation code 1. Customize the build agent environment 1. [If appropriate] Replace the score code @@ -17,24 +17,36 @@ Follow the [Getting Started](getting_started.md) guide to set up the infrastruct Take a look at the [Repo Details](code_description.md) document for a description of the structure of this repository. -## Follow the Bootstrap instructions +## Bootstrap the project -The [Bootstrap from MLOpsPython repository](../bootstrap/README.md) guide will help you to quickly prepare the repository for your project. +Bootstrapping will prepare the directory structure to be used for your project name which includes: + +* renaming files and folders from the base project name `diabetes_regression` to your project name +* fixing imports and absolute path based on your project name +* deleting and cleaning up some directories **Note:** Since the bootstrap script will rename the `diabetes_regression` folder to the project name of your choice, we'll refer to your project as `[project name]` when paths are involved. +To bootstrap from the existing MLOpsPython repository: + +1. Ensure Python 3 is installed locally +1. From a local copy of the code, run the `bootstrap.py` script in the `bootstrap` folder +`python bootstrap.py -d [dirpath] -n [projectname]` + * `[dirpath]` is the absolute path to the root of the directory where MLOpsPython is cloned + * `[projectname]` is the name of your ML project + ## Configure training data The training ML pipeline uses a [sample diabetes dataset](https://scikit-learn.org/stable/modules/generated/sklearn.datasets.load_diabetes.html) as training data. -To use your own data: +**Important** Convert the template to use your own Azure ML Dataset for model training via these steps: 1. [Create a Dataset](https://docs.microsoft.com/azure/machine-learning/how-to-create-register-datasets) in your Azure ML workspace 1. Update the `DATASET_NAME` and `DATASTORE_NAME` variables in `.pipelines/[project name]-variables-template.yml` ## Convert your ML experimental code into production ready code -The MLOpsPython template creates an Azure Machine Learning (ML) pipeline that invokes a set of [Azure ML pipeline steps](https://docs.microsoft.com/python/api/azureml-pipeline-steps/azureml.pipeline.steps) (see `ml_service/pipelines/[project name]_build_train_pipeline.py`). If your experiment is currently in a Jupyter notebook, it will need to be refactored into scripts that can be run independantly and dropped into the template which the existing Azure ML pipeline steps utilize. +The MLOpsPython template creates an Azure Machine Learning (ML) pipeline that invokes a set of [Azure ML pipeline steps](https://docs.microsoft.com/python/api/azureml-pipeline-steps/azureml.pipeline.steps) (see `ml_service/pipelines/[project name]_build_train_pipeline.py`). If your experiment is currently in a Jupyter notebook, it will need to be refactored into scripts that can be run independently and dropped into the template which the existing Azure ML pipeline steps utilize. 1. Refactor your experiment code into scripts 1. [Recommended] Prepare unit tests diff --git a/docs/getting_started.md b/docs/getting_started.md index 11bfb20f..3dc67ab3 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -1,9 +1,9 @@ # Getting Started with MLOpsPython -This guide shows how to get MLOpsPython working with a sample ML project ***diabetes_regression***. The project creates a linear regression model to predict diabetes. You can adapt this example to use with your own project. +This guide shows how to get MLOpsPython working with a sample ML project ***diabetes_regression***. The project creates a linear regression model to predict diabetes and has CI/CD DevOps practices enabled for model training and serving when these steps are completed in this getting started guide. -We recommend working through this guide completely to ensure everything is working in your environment. After the sample is working, follow the [bootstrap instructions](../bootstrap/README.md) to convert the ***diabetes_regression*** sample into a starting point for your project. +If you would like to bring your own model code to use this template structure, follow the [custom model](custom_model.md) guide. We recommend completing this getting started guide with the diabetes model through ACI deployment first to ensure everything is working in your environment before converting the template to use your own model code. - [Setting up Azure DevOps](#setting-up-azure-devops) - [Install the Azure Machine Learning extension](#install-the-azure-machine-learning-extension) From 90562854f37a24e199118d7b9dc667cf7b12ce81 Mon Sep 17 00:00:00 2001 From: My Date: Thu, 18 Jun 2020 09:48:01 -0700 Subject: [PATCH 06/29] update arm template to make workspace sku configurable (#283) --- ...diabetes_regression-variables-template.yml | 17 +++--- docs/getting_started.md | 55 ++++++++++--------- .../arm-templates/cloud-environment.json | 20 ++++++- .../iac-create-environment-pipeline-arm.yml | 39 +++++++------ 4 files changed, 72 insertions(+), 59 deletions(-) diff --git a/.pipelines/diabetes_regression-variables-template.yml b/.pipelines/diabetes_regression-variables-template.yml index def14549..159f76af 100644 --- a/.pipelines/diabetes_regression-variables-template.yml +++ b/.pipelines/diabetes_regression-variables-template.yml @@ -1,8 +1,7 @@ # Pipeline template that defines common runtime environment variables. variables: - # Source Config - # The directory containing the scripts for training, evaluating, and registering the model + # The directory containing the scripts for training, evaluating, and registering the model - name: SOURCES_DIR_TRAIN value: diabetes_regression # The path to the model training script under SOURCES_DIR_TRAIN @@ -23,7 +22,7 @@ variables: value: mlopspython - name: DATASET_NAME value: diabetes_ds - # Uncomment DATASTORE_NAME if you have configured non default datastore to point to your data + # Uncomment DATASTORE_NAME if you have configured non default datastore to point to your data # - name: DATASTORE_NAME # value: datablobstore - name: DATASET_VERSION @@ -50,25 +49,23 @@ variables: # The name for the (docker/webapp) scoring image - name: IMAGE_NAME value: "diabetestrained" - + # Optional. Used by a training pipeline with R on Databricks - name: DB_CLUSTER_ID value: "" # These are the default values set in ml_service\util\env_variables.py. Uncomment and override if desired. - # Set to false to disable the evaluation step in the ML pipeline and register the newly trained model unconditionally. + # Set to false to disable the evaluation step in the ML pipeline and register the newly trained model unconditionally. # - name: RUN_EVALUATION # value: "true" - # Set to false to register the model regardless of the outcome of the evaluation step in the ML pipeline. + # Set to false to register the model regardless of the outcome of the evaluation step in the ML pipeline. # - name: ALLOW_RUN_CANCEL # value: "true" - # For debugging deployment issues. Specify a build id with the MODEL_BUILD_ID pipeline variable at queue time - # to skip training and deploy a model registered by a previous build. + # For debugging deployment issues. Specify a build id with the MODEL_BUILD_ID pipeline variable at queue time + # to skip training and deploy a model registered by a previous build. - name: modelbuildid value: $[coalesce(variables['MODEL_BUILD_ID'], variables['Build.BuildId'])] - - # Flag to allow rebuilding the AML Environment after it was built for the first time. This enables dependency updates from conda_dependencies.yaml. # - name: AML_REBUILD_ENVIRONMENT # value: "false" diff --git a/docs/getting_started.md b/docs/getting_started.md index 3dc67ab3..89981fa3 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -1,9 +1,8 @@ - # Getting Started with MLOpsPython -This guide shows how to get MLOpsPython working with a sample ML project ***diabetes_regression***. The project creates a linear regression model to predict diabetes and has CI/CD DevOps practices enabled for model training and serving when these steps are completed in this getting started guide. +This guide shows how to get MLOpsPython working with a sample ML project **_diabetes_regression_**. The project creates a linear regression model to predict diabetes and has CI/CD DevOps practices enabled for model training and serving when these steps are completed in this getting started guide. -If you would like to bring your own model code to use this template structure, follow the [custom model](custom_model.md) guide. We recommend completing this getting started guide with the diabetes model through ACI deployment first to ensure everything is working in your environment before converting the template to use your own model code. +If you would like to bring your own model code to use this template structure, follow the [custom model](custom_model.md) guide. We recommend completing this getting started guide with the diabetes model through ACI deployment first to ensure everything is working in your environment before converting the template to use your own model code. - [Setting up Azure DevOps](#setting-up-azure-devops) - [Install the Azure Machine Learning extension](#install-the-azure-machine-learning-extension) @@ -46,13 +45,13 @@ We recommend using the [repository template](https://github.com/microsoft/MLOpsP ## Create a Variable Group for your Pipeline -MLOpsPython requires some variables to be set before you can run any pipelines. You'll need to create a *variable group* in Azure DevOps to store values that are reused across multiple pipelines or pipeline stages. Either store the values directly in [Azure DevOps](https://docs.microsoft.com/en-us/azure/devops/pipelines/library/variable-groups?view=azure-devops&tabs=designer#create-a-variable-group) or connect to an Azure Key Vault in your subscription. Check out the [Add & use variable groups](https://docs.microsoft.com/en-us/azure/devops/pipelines/library/variable-groups?view=azure-devops&tabs=yaml#use-a-variable-group) documentation to learn more about how to create a variable group and link it to your pipeline. +MLOpsPython requires some variables to be set before you can run any pipelines. You'll need to create a _variable group_ in Azure DevOps to store values that are reused across multiple pipelines or pipeline stages. Either store the values directly in [Azure DevOps](https://docs.microsoft.com/en-us/azure/devops/pipelines/library/variable-groups?view=azure-devops&tabs=designer#create-a-variable-group) or connect to an Azure Key Vault in your subscription. Check out the [Add & use variable groups](https://docs.microsoft.com/en-us/azure/devops/pipelines/library/variable-groups?view=azure-devops&tabs=yaml#use-a-variable-group) documentation to learn more about how to create a variable group and link it to your pipeline. Navigate to **Library** in the **Pipelines** section as indicated below: ![Library Variable Groups](./images/library_variable_groups.png) -Create a variable group named **``devopsforai-aml-vg``**. The YAML pipeline definitions in this repository refer to this variable group by name. +Create a variable group named **`devopsforai-aml-vg`**. The YAML pipeline definitions in this repository refer to this variable group by name. The variable group should contain the following required variables. **Azure resources that don't exist yet will be created in the [Provisioning resources using Azure Pipelines](#provisioning-resources-using-azure-pipelines) step below.** @@ -80,7 +79,7 @@ More variables are available for further tweaking, but the above variables are a **WORKSPACE_NAME** is used for creating the Azure Machine Learning Workspace. You can provide an existing Azure ML Workspace here if you've got one. -**AZURE_RM_SVC_CONNECTION** is used by the [Azure Pipeline]((../environment_setup/iac-create-environment-pipeline.yml)) in Azure DevOps that creates the Azure ML workspace and associated resources through Azure Resource Manager. You'll create the connection in a [step below](#create-an-azure-devops-service-connection-for-the-azure-resource-manager). +**AZURE_RM_SVC_CONNECTION** is used by the [Azure Pipeline](../environment_setup/iac-create-environment-pipeline.yml) in Azure DevOps that creates the Azure ML workspace and associated resources through Azure Resource Manager. You'll create the connection in a [step below](#create-an-azure-devops-service-connection-for-the-azure-resource-manager). **WORKSPACE_SVC_CONNECTION** is used to reference a [service connection for the Azure ML workspace](#create-an-azure-devops-azure-ml-workspace-service-connection). You'll create the connection after [provisioning the workspace](#provisioning-resources-using-azure-pipelines) in the [Create an Azure DevOps Service Connection for the Azure ML Workspace](#create-an-azure-devops-service-connection-for-the-azure-ml-workspace) section below. @@ -92,11 +91,11 @@ The easiest way to create all required Azure resources (Resource Group, Azure ML ### Create an Azure DevOps Service Connection for the Azure Resource Manager -The [IaC provisioning pipeline]((../environment_setup/iac-create-environment-pipeline.yml)) requires an **Azure Resource Manager** [service connection](https://docs.microsoft.com/en-us/azure/devops/pipelines/library/service-endpoints?view=azure-devops&tabs=yaml#create-a-service-connection). +The [IaC provisioning pipeline](../environment_setup/iac-create-environment-pipeline.yml) requires an **Azure Resource Manager** [service connection](https://docs.microsoft.com/en-us/azure/devops/pipelines/library/service-endpoints?view=azure-devops&tabs=yaml#create-a-service-connection). ![Create service connection](./images/create-rm-service-connection.png) -Leave the **``Resource Group``** field empty. +Leave the **`Resource Group`** field empty. **Note:** Creating the Azure Resource Manager service connection scope requires 'Owner' or 'User Access Administrator' permissions on the subscription. You'll also need sufficient permissions to register an application with your Azure AD tenant, or you can get the ID and secret of a service principal from your Azure AD Administrator. That principal must have 'Contributor' permissions on the subscription. @@ -143,7 +142,7 @@ Now that you've provisioned all the required Azure resources and service connect ### Set up the Pipeline -In your Azure DevOps project, create and run a new build pipeline based on the [diabetes_regression-ci.yml](../.pipelines/diabetes_regression-ci.yml) +In your Azure DevOps project, create and run a new build pipeline based on the [diabetes_regression-ci.yml](../.pipelines/diabetes_regression-ci.yml) pipeline definition in your forked repository. ![Configure CI build pipeline](./images/ci-build-pipeline-configure.png) @@ -164,15 +163,15 @@ The pipeline stages are summarized below: - Linting (code quality analysis) - Unit tests and code coverage analysis -- Build and publish *ML Training Pipeline* in an *ML Workspace* +- Build and publish _ML Training Pipeline_ in an _ML Workspace_ #### Train model -- Determine the ID of the *ML Training Pipeline* published in the previous stage. -- Trigger the *ML Training Pipeline* and waits for it to complete. +- Determine the ID of the _ML Training Pipeline_ published in the previous stage. +- Trigger the _ML Training Pipeline_ and waits for it to complete. - This is an **agentless** job. The CI pipeline can wait for ML pipeline completion for hours or even days without using agent resources. -- Determine if a new model was registered by the *ML Training Pipeline*. - - If the model evaluation determines that the new model doesn't perform any better than the previous one, the new model won't register and the *ML Training Pipeline* will be **canceled**. In this case, you'll see a message in the 'Train Model' job under the 'Determine if evaluation succeeded and new model is registered' step saying '**Model was not registered for this run.**' +- Determine if a new model was registered by the _ML Training Pipeline_. + - If the model evaluation determines that the new model doesn't perform any better than the previous one, the new model won't register and the _ML Training Pipeline_ will be **canceled**. In this case, you'll see a message in the 'Train Model' job under the 'Determine if evaluation succeeded and new model is registered' step saying '**Model was not registered for this run.**' - See [evaluate_model.py](../diabetes_regression/evaluate/evaluate_model.py#L118) for the evaluation logic and [diabetes_regression_verify_train_pipeline.py](../ml_service/pipelines/diabetes_regression_verify_train_pipeline.py#L54) for the ML pipeline reporting logic. - [Additional Variables and Configuration](#additional-variables-and-configuration) for configuring this and other behavior. @@ -182,13 +181,13 @@ The pipeline stages are summarized below: - Smoke test - The test sends a sample query to the scoring web service and verifies that it returns the expected response. Have a look at the [smoke test code](../ml_service/util/smoke_test_scoring_service.py) for an example. -The pipeline uses a Docker container on the Azure Pipelines agents to accomplish the pipeline steps. The container image ***mcr.microsoft.com/mlops/python:latest*** is built with [this Dockerfile](../environment_setup/Dockerfile) and has all the necessary dependencies installed for MLOpsPython and ***diabetes_regression***. This image is an example of a custom Docker image with a pre-baked environment. The environment is guaranteed to be the same on any building agent, VM, or local machine. In your project, you'll want to build your own Docker image that only contains the dependencies and tools required for your use case. Your image will probably be smaller and faster, and it will be maintained by your team. +The pipeline uses a Docker container on the Azure Pipelines agents to accomplish the pipeline steps. The container image **_mcr.microsoft.com/mlops/python:latest_** is built with [this Dockerfile](../environment_setup/Dockerfile) and has all the necessary dependencies installed for MLOpsPython and **_diabetes_regression_**. This image is an example of a custom Docker image with a pre-baked environment. The environment is guaranteed to be the same on any building agent, VM, or local machine. In your project, you'll want to build your own Docker image that only contains the dependencies and tools required for your use case. Your image will probably be smaller and faster, and it will be maintained by your team. After the pipeline is finished, you'll see a new model in the **ML Workspace**: ![Trained model](./images/trained-model.png) -To disable the automatic trigger of the training pipeline, change the `auto-trigger-training` variable as listed in the `.pipelines\diabetes_regression-ci.yml` pipeline to `false`. You can also override the variable at runtime execution of the pipeline. +To disable the automatic trigger of the training pipeline, change the `auto-trigger-training` variable as listed in the `.pipelines\diabetes_regression-ci.yml` pipeline to `false`. You can also override the variable at runtime execution of the pipeline. To skip model training and registration, and deploy a model successfully registered by a previous build (for testing changes to the score file or inference configuration), add the variable `MODEL_BUILD_ID` when the pipeline is queued, and set the value to the ID of the previous build. @@ -202,7 +201,9 @@ MLOpsPython also can deploy to [Azure Kubernetes Service](https://azure.microsof Creating a cluster on Azure Kubernetes Service is out of scope of this tutorial, but you can find set up information on the [Quickstart: Deploy an Azure Kubernetes Service (AKS) cluster using the Azure portal](https://docs.microsoft.com/en-us/azure/aks/kubernetes-walkthrough-portal#create-an-aks-cluster) page. -**Note:** If your target deployment environment is a Kubernetes cluster and you want to implement Canary and/or A/B testing deployment strategies, check out this [tutorial](./canary_ab_deployment.md). +> **_Note_** +> +> If your target deployment environment is a Kubernetes cluster and you want to implement Canary and/or A/B testing deployment strategies, check out this [tutorial](./canary_ab_deployment.md). Keep the Azure Container Instances deployment active because it's a lightweight way to validate changes before deploying to Azure Kubernetes Service. @@ -213,7 +214,7 @@ In the Variables tab, edit your variable group (`devopsforai-aml-vg`). In the va | AKS_COMPUTE_NAME | aks | | AKS_DEPLOYMENT_NAME | mlops-aks | -Set **AKS_COMPUTE_NAME** to the *Compute name* of the Inference Cluster that references the Azure Kubernetes Service cluster in your Azure ML Workspace. +Set **AKS_COMPUTE_NAME** to the _Compute name_ of the Inference Cluster that references the Azure Kubernetes Service cluster in your Azure ML Workspace. After successfully deploying to Azure Container Instances, the next stage will deploy the model to Kubernetes and run a smoke test. @@ -249,8 +250,8 @@ Make sure your webapp has the credentials to pull the image from the Azure Conta The build pipeline also supports building and publishing Azure ML pipelines using R to train a model. You can enable it by changing the `build-train-script` pipeline variable to either of the following values: -* `diabetes_regression_build_train_pipeline_with_r.py` to train a model with R on Azure ML Compute. You'll also need to uncomment (include) the `r-essentials` Conda packages in the environment definition YAML `diabetes_regression/conda_dependencies.yml`. -* `diabetes_regression_build_train_pipeline_with_r_on_dbricks.py` to train a model with R on Databricks. You'll need to manually create a Databricks cluster and attach it to the Azure ML Workspace as a compute resource. Set the DB_CLUSTER_ID and DATABRICKS_COMPUTE_NAME variables in your variable group. +- `diabetes_regression_build_train_pipeline_with_r.py` to train a model with R on Azure ML Compute. You'll also need to uncomment (include) the `r-essentials` Conda packages in the environment definition YAML `diabetes_regression/conda_dependencies.yml`. +- `diabetes_regression_build_train_pipeline_with_r_on_dbricks.py` to train a model with R on Databricks. You'll need to manually create a Databricks cluster and attach it to the Azure ML Workspace as a compute resource. Set the DB_CLUSTER_ID and DATABRICKS_COMPUTE_NAME variables in your variable group. Example ML pipelines using R have a single step to train a model. They don't demonstrate how to evaluate and register a model. The evaluation and registering techniques are shown only in the Python implementation. @@ -258,9 +259,9 @@ Example ML pipelines using R have a single step to train a model. They don't dem You can explore aspects of model observability in the solution, such as: -* **Logging**: Navigate to the Application Insights instance linked to the Azure ML Portal, then go to the Logs (Analytics) pane. The following sample query correlates HTTP requests with custom logs generated in `score.py`. This can be used, for example, to analyze query duration vs. scoring batch size: +- **Logging**: Navigate to the Application Insights instance linked to the Azure ML Portal, then go to the Logs (Analytics) pane. The following sample query correlates HTTP requests with custom logs generated in `score.py`. This can be used, for example, to analyze query duration vs. scoring batch size: - ``` + ```sql let Traceinfo=traces | extend d=parse_json(tostring(customDimensions.Content)) | project workspace=customDimensions.["Workspace Name"], @@ -274,8 +275,8 @@ You can explore aspects of model observability in the solution, such as: | project-away id1 ``` -* **Distributed tracing**: The smoke test client code sets an HTTP `traceparent` header (per the [W3C Trace Context proposed specification](https://www.w3.org/TR/trace-context-1)), and the `score.py` code logs the header. The query above shows how to surface this value. You can adapt it to your tracing framework. -* **Monitoring**: You can use [Azure Monitor for containers](https://docs.microsoft.com/en-us/azure/azure-monitor/insights/container-insights-overview) to monitor the Azure ML scoring containers' performance. +- **Distributed tracing**: The smoke test client code sets an HTTP `traceparent` header (per the [W3C Trace Context proposed specification](https://www.w3.org/TR/trace-context-1)), and the `score.py` code logs the header. The query above shows how to surface this value. You can adapt it to your tracing framework. +- **Monitoring**: You can use [Azure Monitor for containers](https://docs.microsoft.com/en-us/azure/azure-monitor/insights/container-insights-overview) to monitor the Azure ML scoring containers' performance. ### Clean up the example resources @@ -283,8 +284,8 @@ To remove the resources created for this project, use the [/environment_setup/ia ## Next Steps: Integrating your project -* The [custom model](custom_model.md) guide includes information on bringing your own code to this repository template. -* Consider using [Azure Pipelines self-hosted agents](https://docs.microsoft.com/en-us/azure/devops/pipelines/agents/agents?view=azure-devops&tabs=browser#install) to speed up your Azure ML pipeline execution. The Docker container image for the Azure ML pipeline is sizable, and having it cached on the agent between runs can trim several minutes from your runs. +- The [custom model](custom_model.md) guide includes information on bringing your own code to this repository template. +- Consider using [Azure Pipelines self-hosted agents](https://docs.microsoft.com/en-us/azure/devops/pipelines/agents/agents?view=azure-devops&tabs=browser#install) to speed up your Azure ML pipeline execution. The Docker container image for the Azure ML pipeline is sizable, and having it cached on the agent between runs can trim several minutes from your runs. ### Additional Variables and Configuration @@ -294,7 +295,7 @@ There are more variables used in the project. They're defined in two places: one For using Azure Pipelines, all other variables are stored in the file `.pipelines/diabetes_regression-variables-template.yml`. Using the default values as a starting point, adjust the variables to suit your requirements. -In that folder, you'll also find the `parameters.json` file that we recommend using to provide parameters for training, evaluation, and scoring scripts. The sample parameter that `diabetes_regression` uses is the ridge regression [*alpha* hyperparameter](https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.Ridge.html). We don't provide any serializers for this config file. +In that folder, you'll also find the `parameters.json` file that we recommend using to provide parameters for training, evaluation, and scoring scripts. The sample parameter that `diabetes_regression` uses is the ridge regression [_alpha_ hyperparameter](https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.Ridge.html). We don't provide any serializers for this config file. #### Local configuration diff --git a/environment_setup/arm-templates/cloud-environment.json b/environment_setup/arm-templates/cloud-environment.json index f2b2ac2f..6d1114f6 100644 --- a/environment_setup/arm-templates/cloud-environment.json +++ b/environment_setup/arm-templates/cloud-environment.json @@ -45,6 +45,17 @@ "acr": { "type": "string", "defaultValue": "[concat(toLower(parameters('baseName')),'amlcr')]" + }, + "sku": { + "type": "string", + "defaultValue": "basic", + "allowedValues": [ + "basic", + "enterprise" + ], + "metadata": { + "description": "Specifies the sku, also referred as 'edition' of the Azure Machine Learning workspace." + } } }, "variables": { @@ -92,7 +103,8 @@ "name": "standard", "family": "A" }, - "accessPolicies": [] + "accessPolicies": [ + ] } }, { @@ -131,6 +143,10 @@ "identity": { "type": "systemAssigned" }, + "sku": { + "tier": "[parameters('sku')]", + "name": "[parameters('sku')]" + }, "properties": { "friendlyName": "[variables('amlWorkspaceName')]", "keyVault": "[resourceId('Microsoft.KeyVault/vaults',variables('keyVaultName'))]", @@ -138,6 +154,6 @@ "containerRegistry": "[resourceId('Microsoft.ContainerRegistry/registries',variables('containerRegistryName'))]", "storageAccount": "[resourceId('Microsoft.Storage/storageAccounts/',variables('storageAccountName'))]" } - } + } ] } \ No newline at end of file diff --git a/environment_setup/iac-create-environment-pipeline-arm.yml b/environment_setup/iac-create-environment-pipeline-arm.yml index f21c6eab..0b9f474c 100644 --- a/environment_setup/iac-create-environment-pipeline-arm.yml +++ b/environment_setup/iac-create-environment-pipeline-arm.yml @@ -2,36 +2,35 @@ trigger: branches: include: - - master + - master paths: include: - - environment_setup/arm-templates/* + - environment_setup/arm-templates/* pr: branches: include: - - master + - master paths: include: - - environment_setup/arm-templates/* + - environment_setup/arm-templates/* pool: - vmImage: 'ubuntu-latest' + vmImage: "ubuntu-latest" variables: -- group: devopsforai-aml-vg - + - group: devopsforai-aml-vg + - name: WORKSPACE_SKU # https://docs.microsoft.com/en-us/azure/machine-learning/overview-what-is-azure-ml#sku + value: basic steps: -- task: AzureResourceGroupDeployment@2 - inputs: - azureSubscription: '$(AZURE_RM_SVC_CONNECTION)' - action: 'Create Or Update Resource Group' - resourceGroupName: '$(RESOURCE_GROUP)' - location: $(LOCATION) - templateLocation: 'Linked artifact' - csmFile: '$(Build.SourcesDirectory)/environment_setup/arm-templates/cloud-environment.json' - overrideParameters: '-baseName $(BASE_NAME) -location $(LOCATION) -workspace $(WORKSPACE_NAME)' - deploymentMode: 'Incremental' - displayName: 'Deploy MLOps resources to Azure' - - \ No newline at end of file + - task: AzureResourceGroupDeployment@2 + inputs: + azureSubscription: "$(AZURE_RM_SVC_CONNECTION)" + action: "Create Or Update Resource Group" + resourceGroupName: "$(RESOURCE_GROUP)" + location: $(LOCATION) + templateLocation: "Linked artifact" + csmFile: "$(Build.SourcesDirectory)/environment_setup/arm-templates/cloud-environment.json" + overrideParameters: "-baseName $(BASE_NAME) -location $(LOCATION) -workspace $(WORKSPACE_NAME) -sku $(WORKSPACE_SKU)" + deploymentMode: "Incremental" + displayName: "Deploy MLOps resources to Azure" From bcdac5c3ae7a494162f6c54a6a700964770beaf9 Mon Sep 17 00:00:00 2001 From: jitghosh Date: Mon, 22 Jun 2020 11:02:30 -0400 Subject: [PATCH 07/29] Jitghosh/parallelbatchscore (#289) * Batch Scoring First Draft: Added pipeline creation and run scripts, scoring script, new environment variables, changes to env loading script, compute creation and AML environment creation scripts, and new Azure pipeline for batch scoring CI * Score copy step added * Modified bootstrap.py, updated getting started doc * Addressed PR comments * Addressed PR comments * Doc fix * Doc fix --- .env.example | 38 +- .../diabetes_regression-batchscoring-ci.yml | 64 +++ ...diabetes_regression-variables-template.yml | 62 +++ bootstrap/bootstrap.py | 2 + .../conda_dependencies_scorecopy.yml | 31 ++ .../conda_dependencies_scoring.yml | 32 ++ .../scoring/parallel_batchscore.py | 139 +++++ .../scoring/parallel_batchscore_copyoutput.py | 91 ++++ docs/getting_started.md | 60 ++- docs/images/batchscoring-ci-result.png | Bin 0 -> 19207 bytes docs/images/batchscoring-pipeline.png | Bin 0 -> 17956 bytes ...sion_build_parallel_batchscore_pipeline.py | 482 ++++++++++++++++++ ...iabetes_regression_build_train_pipeline.py | 100 ++-- ..._regression_build_train_pipeline_with_r.py | 21 +- ml_service/pipelines/load_sample_data.py | 8 +- .../run_parallel_batchscore_pipeline.py | 133 +++++ ml_service/util/attach_compute.py | 32 +- ml_service/util/env_variables.py | 94 +++- ml_service/util/manage_environment.py | 17 +- 19 files changed, 1311 insertions(+), 95 deletions(-) create mode 100644 .pipelines/diabetes_regression-batchscoring-ci.yml create mode 100644 diabetes_regression/conda_dependencies_scorecopy.yml create mode 100644 diabetes_regression/conda_dependencies_scoring.yml create mode 100644 diabetes_regression/scoring/parallel_batchscore.py create mode 100644 diabetes_regression/scoring/parallel_batchscore_copyoutput.py create mode 100644 docs/images/batchscoring-ci-result.png create mode 100644 docs/images/batchscoring-pipeline.png create mode 100644 ml_service/pipelines/diabetes_regression_build_parallel_batchscore_pipeline.py create mode 100644 ml_service/pipelines/run_parallel_batchscore_pipeline.py diff --git a/.env.example b/.env.example index 01dc40e8..3c63d969 100644 --- a/.env.example +++ b/.env.example @@ -1,30 +1,33 @@ # Azure Subscription Variables SUBSCRIPTION_ID = '' -LOCATION = 'westeurope' +LOCATION = '' TENANT_ID = '' BASE_NAME = '' SP_APP_ID = '' SP_APP_SECRET = '' -RESOUCE_GROUP = 'mlops-rg' +RESOURCE_GROUP = 'mlops-RG' # Mock build/release ID for local testing BUILD_BUILDID = '001' # Azure ML Workspace Variables -WORKSPACE_NAME = 'aml-workspace' -EXPERIMENT_NAME = '' +WORKSPACE_NAME = 'mlops-aml-ws' +EXPERIMENT_NAME = 'mlopspython' # AML Compute Cluster Config AML_ENV_NAME='diabetes_regression_training_env' +AML_ENV_TRAIN_CONDA_DEP_FILE="conda_dependencies.yml" AML_COMPUTE_CLUSTER_NAME = 'train-cluster' AML_COMPUTE_CLUSTER_CPU_SKU = 'STANDARD_DS2_V2' AML_CLUSTER_MAX_NODES = '4' AML_CLUSTER_MIN_NODES = '0' AML_CLUSTER_PRIORITY = 'lowpriority' # Training Config -MODEL_NAME = 'sklearn_regression_model.pkl' +MODEL_NAME = 'diabetes_regression_model.pkl' MODEL_VERSION = '1' TRAIN_SCRIPT_PATH = 'training/train.py' + + # AML Pipeline Config TRAINING_PIPELINE_NAME = 'Training Pipeline' MODEL_PATH = '' @@ -51,3 +54,28 @@ ALLOW_RUN_CANCEL = 'true' # Flag to allow rebuilding the AML Environment after it was built for the first time. This enables dependency updates from conda_dependencies.yaml. AML_REBUILD_ENVIRONMENT = 'false' + + + +USE_GPU_FOR_SCORING = "false" +AML_ENV_SCORE_CONDA_DEP_FILE="conda_dependencies_scoring.yml" +AML_ENV_SCORECOPY_CONDA_DEP_FILE="conda_dependencies_scorecopy.yml" +# AML Compute Cluster Config for parallel batch scoring +AML_ENV_NAME_SCORING='diabetes_regression_scoring_env' +AML_ENV_NAME_SCORE_COPY='diabetes_regression_score_copy_env' +AML_COMPUTE_CLUSTER_NAME_SCORING = 'score-cluster' +AML_COMPUTE_CLUSTER_CPU_SKU_SCORING = 'STANDARD_DS2_V2' +AML_CLUSTER_MAX_NODES_SCORING = '4' +AML_CLUSTER_MIN_NODES_SCORING = '0' +AML_CLUSTER_PRIORITY_SCORING = 'lowpriority' +AML_REBUILD_ENVIRONMENT_SCORING = 'true' +BATCHSCORE_SCRIPT_PATH = 'scoring/parallel_batchscore.py' +BATCHSCORE_COPY_SCRIPT_PATH = 'scoring/parallel_batchscore_copyoutput.py' + + +SCORING_DATASTORE_INPUT_CONTAINER = 'input' +SCORING_DATASTORE_INPUT_FILENAME = 'diabetes_scoring_input.csv' +SCORING_DATASTORE_OUTPUT_CONTAINER = 'output' +SCORING_DATASTORE_OUTPUT_FILENAME = 'diabetes_scoring_output.csv' +SCORING_DATASET_NAME = 'diabetes_scoring_ds' +SCORING_PIPELINE_NAME = 'diabetes-scoring-pipeline' \ No newline at end of file diff --git a/.pipelines/diabetes_regression-batchscoring-ci.yml b/.pipelines/diabetes_regression-batchscoring-ci.yml new file mode 100644 index 00000000..79a7f46f --- /dev/null +++ b/.pipelines/diabetes_regression-batchscoring-ci.yml @@ -0,0 +1,64 @@ +# Continuous Integration (CI) pipeline that orchestrates the batch scoring of the diabetes_regression model. + +resources: + containers: + - container: mlops + image: mcr.microsoft.com/mlops/python:latest + + +pr: none +trigger: + branches: + include: + - master + paths: + include: + - diabetes_regression/scoring/parallel_batchscore.py + - ml_service/pipelines/diabetes_regression_build_parallel_batchscore_pipeline.py + - ml_service/pipelines/run_parallel_batchscore_pipeline.py + +variables: +- template: diabetes_regression-variables-template.yml +- group: devopsforai-aml-vg + +pool: + vmImage: ubuntu-latest + +stages: +- stage: 'Batch_Scoring_Pipeline_CI' + displayName: 'Batch Scoring Pipeline CI' + jobs: + - job: "Build_Batch_Scoring_Pipeline" + displayName: "Build Batch Scoring Pipeline" + container: mlops + timeoutInMinutes: 0 + steps: + - template: code-quality-template.yml + - task: AzureCLI@1 + name: publish_batchscore + inputs: + azureSubscription: '$(WORKSPACE_SVC_CONNECTION)' + scriptLocation: inlineScript + workingDirectory: $(Build.SourcesDirectory) + inlineScript: | + set -e # fail on error + export SUBSCRIPTION_ID=$(az account show --query id -o tsv) + # Invoke the Python building and publishing a training pipeline + python -m ml_service.pipelines.diabetes_regression_build_parallel_batchscore_pipeline + + - job: "Run_Batch_Score_Pipeline" + displayName: "Run Batch Scoring Pipeline" + dependsOn: "Build_Batch_Scoring_Pipeline" + timeoutInMinutes: 240 + pool: server + variables: + pipeline_id: $[ dependencies.Build_Batch_Scoring_Pipeline.outputs['publish_batchscore.pipeline_id']] + steps: + - task: ms-air-aiagility.vss-services-azureml.azureml-restApi-task.MLPublishedPipelineRestAPITask@0 + displayName: 'Invoke Batch Scoring pipeline' + inputs: + azureSubscription: '$(WORKSPACE_SVC_CONNECTION)' + PipelineId: '$(pipeline_id)' + ExperimentName: '$(EXPERIMENT_NAME)' + PipelineParameters: '"ParameterAssignments": {"model_name": "$(MODEL_NAME)"}' + \ No newline at end of file diff --git a/.pipelines/diabetes_regression-variables-template.yml b/.pipelines/diabetes_regression-variables-template.yml index 159f76af..cf4ef9cf 100644 --- a/.pipelines/diabetes_regression-variables-template.yml +++ b/.pipelines/diabetes_regression-variables-template.yml @@ -16,6 +16,7 @@ variables: # The path to the model scoring script relative to SOURCES_DIR_TRAIN - name: SCORE_SCRIPT value: scoring/score.py + # Azure ML Variables - name: EXPERIMENT_NAME @@ -35,6 +36,8 @@ variables: # AML Compute Cluster Config - name: AML_ENV_NAME value: diabetes_regression_training_env + - name: AML_ENV_TRAIN_CONDA_DEP_FILE + value: "conda_dependencies.yml" - name: AML_COMPUTE_CLUSTER_CPU_SKU value: STANDARD_DS2_V2 - name: AML_COMPUTE_CLUSTER_NAME @@ -69,3 +72,62 @@ variables: # Flag to allow rebuilding the AML Environment after it was built for the first time. This enables dependency updates from conda_dependencies.yaml. # - name: AML_REBUILD_ENVIRONMENT # value: "false" + + # Variables below are used for controlling various aspects of batch scoring + - name: USE_GPU_FOR_SCORING + value: False + # Conda dependencies for the batch scoring step + - name: AML_ENV_SCORE_CONDA_DEP_FILE + value: "conda_dependencies_scoring.yml" + # Conda dependencies for the score copying step + - name: AML_ENV_SCORECOPY_CONDA_DEP_FILE + value: "conda_dependencies_scorecopy.yml" + # AML Compute Cluster Config for parallel batch scoring + - name: AML_ENV_NAME_SCORING + value: diabetes_regression_scoring_env + - name: AML_ENV_NAME_SCORE_COPY + value: diabetes_regression_score_copy_env + - name: AML_COMPUTE_CLUSTER_CPU_SKU_SCORING + value: STANDARD_DS2_V2 + - name: AML_COMPUTE_CLUSTER_NAME_SCORING + value: score-cluster + - name: AML_CLUSTER_MIN_NODES_SCORING + value: 0 + - name: AML_CLUSTER_MAX_NODES_SCORING + value: 4 + - name: AML_CLUSTER_PRIORITY_SCORING + value: lowpriority + # The path to the batch scoring script relative to SOURCES_DIR_TRAIN + - name: BATCHSCORE_SCRIPT_PATH + value: scoring/parallel_batchscore.py + - name: BATCHSCORE_COPY_SCRIPT_PATH + value: scoring/parallel_batchscore_copyoutput.py + # Flag to allow rebuilding the AML Environment after it was built for the first time. + # This enables dependency updates from the conda dependencies yaml for scoring activities. + - name: AML_REBUILD_ENVIRONMENT_SCORING + value: "true" + + # Datastore config for scoring + # The storage account name and key are supplied as variables in a variable group + # in the Azure Pipelines library for this project. Please refer to repo docs for + # more details + + # Blob container where the input data for scoring can be found + - name: SCORING_DATASTORE_INPUT_CONTAINER + value: "input" + # Blobname for the input data - include any applicable path in the string + - name: SCORING_DATASTORE_INPUT_FILENAME + value: "diabetes_scoring_input.csv" + # Blob container where the output data for scoring can be found + - name: SCORING_DATASTORE_OUTPUT_CONTAINER + value: "output" + # Blobname for the output data - include any applicable path in the string + - name: SCORING_DATASTORE_OUTPUT_FILENAME + value: "diabetes_scoring_output.csv" + # Dataset name for input data for scoring + - name: SCORING_DATASET_NAME + value: "diabetes_scoring_ds" + # Scoring pipeline name + - name: SCORING_PIPELINE_NAME + value: "diabetes-scoring-pipeline" + \ No newline at end of file diff --git a/bootstrap/bootstrap.py b/bootstrap/bootstrap.py index 6e51b503..cbc49e18 100644 --- a/bootstrap/bootstrap.py +++ b/bootstrap/bootstrap.py @@ -87,10 +87,12 @@ def replace_project_name(project_dir, project_name, rename_name): r".pipelines/diabetes_regression-ci.yml", r".pipelines/abtest.yml", r".pipelines/diabetes_regression-ci-image.yml", + r".pipelines/diabetes_regression-batchscoring-ci.yml", r".pipelines/diabetes_regression-get-model-version-template.yml", # NOQA: E501 r".pipelines/diabetes_regression-variables-template.yml", r"environment_setup/Dockerfile", r"environment_setup/install_requirements.sh", + r"ml_service/pipelines/diabetes_regression_build_parallel_batchscore_pipeline.py", # NOQA: E501 r"ml_service/pipelines/diabetes_regression_build_train_pipeline_with_r_on_dbricks.py", # NOQA: E501 r"ml_service/pipelines/diabetes_regression_build_train_pipeline_with_r.py", # NOQA: E501 r"ml_service/pipelines/diabetes_regression_build_train_pipeline.py", # NOQA: E501 diff --git a/diabetes_regression/conda_dependencies_scorecopy.yml b/diabetes_regression/conda_dependencies_scorecopy.yml new file mode 100644 index 00000000..dffafd08 --- /dev/null +++ b/diabetes_regression/conda_dependencies_scorecopy.yml @@ -0,0 +1,31 @@ +# Conda environment specification. The dependencies defined in this file will +# be automatically provisioned for managed runs. These include runs against +# the localdocker, remotedocker, and cluster compute targets. + +# Note that this file is NOT used to automatically manage dependencies for the +# local compute target. To provision these dependencies locally, run: +# conda env update --file conda_dependencies.yml + +# Details about the Conda environment file format: +# https://conda.io/docs/using/envs.html#create-environment-file-by-hand + +# For managing Spark packages and configuration, see spark_dependencies.yml. +# Version of this configuration file's structure and semantics in AzureML. +# This directive is stored in a comment to preserve the Conda file structure. +# [AzureMlVersion] = 2 + +# These dependencies are used to create the environment used by the batch score +# copy pipeline step +name: diabetes_regression_score_copy_env +dependencies: + # The python interpreter version. + # Currently Azure ML Workbench only supports 3.5.2 and later. + - python=3.7.* + - pip + + - pip: + # Base AzureML SDK + - azureml-sdk==1.6.* + + # Score copying deps + - azure-storage-blob diff --git a/diabetes_regression/conda_dependencies_scoring.yml b/diabetes_regression/conda_dependencies_scoring.yml new file mode 100644 index 00000000..60c45c44 --- /dev/null +++ b/diabetes_regression/conda_dependencies_scoring.yml @@ -0,0 +1,32 @@ +# Conda environment specification. The dependencies defined in this file will +# be automatically provisioned for managed runs. These include runs against +# the localdocker, remotedocker, and cluster compute targets. + +# Note that this file is NOT used to automatically manage dependencies for the +# local compute target. To provision these dependencies locally, run: +# conda env update --file conda_dependencies.yml + +# Details about the Conda environment file format: +# https://conda.io/docs/using/envs.html#create-environment-file-by-hand + +# For managing Spark packages and configuration, see spark_dependencies.yml. +# Version of this configuration file's structure and semantics in AzureML. +# This directive is stored in a comment to preserve the Conda file structure. +# [AzureMlVersion] = 2 + +# These dependencies are used to create the environment used by the batch score +# pipeline step +name: diabetes_regression_scoring_env +dependencies: + # The python interpreter version. + # Currently Azure ML Workbench only supports 3.5.2 and later. + - python=3.7.* + - pip + + - pip: + # Base AzureML SDK + - azureml-sdk==1.6.* + + # Scoring deps + - scikit-learn + - pandas diff --git a/diabetes_regression/scoring/parallel_batchscore.py b/diabetes_regression/scoring/parallel_batchscore.py new file mode 100644 index 00000000..aef6f3fb --- /dev/null +++ b/diabetes_regression/scoring/parallel_batchscore.py @@ -0,0 +1,139 @@ +""" +Copyright (C) Microsoft Corporation. All rights reserved.​ + ​ +Microsoft Corporation (“Microsoft”) grants you a nonexclusive, perpetual, +royalty-free right to use, copy, and modify the software code provided by us +("Software Code"). You may not sublicense the Software Code or any use of it +(except to your affiliates and to vendors to perform work on your behalf) +through distribution, network access, service agreement, lease, rental, or +otherwise. This license does not purport to express any claim of ownership over +data you may have shared with Microsoft in the creation of the Software Code. +Unless applicable law gives you more rights, Microsoft reserves all other +rights not expressly granted herein, whether by implication, estoppel or +otherwise. ​ + ​ +THE SOFTWARE CODE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +MICROSOFT OR ITS LICENSORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THE SOFTWARE CODE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +""" + +import numpy as np +import pandas as pd +import joblib +import sys +from typing import List +from util.model_helper import get_latest_model + +model = None + + +def parse_args() -> List[str]: + """ + The AML pipeline calls this file with a set of additional command + line arguments whose names are not documented. As such using the + ArgumentParser which necessitates that we supply the names of the + arguments is risky should those undocumented names change. Hence + we parse the arguments manually. + + :returns: List of model filters + + :raises: ValueError + """ + model_name_param = [ + (sys.argv[idx], sys.argv[idx + 1]) + for idx, itm in enumerate(sys.argv) + if itm == "--model_name" + ] + + if len(model_name_param) == 0: + raise ValueError( + "Model name is required but no model name parameter was passed to the script" # NOQA: E501 + ) + + model_name = model_name_param[0][1] + + model_tag_name_param = [ + (sys.argv[idx], sys.argv[idx + 1]) + for idx, itm in enumerate(sys.argv) + if itm == "--model_tag_name" + ] + model_tag_name = ( + None + if len(model_tag_name_param) < 1 + or len(model_tag_name_param[0][1].strip()) == 0 # NOQA: E501 + else model_tag_name_param[0][1] + ) + + model_tag_value_param = [ + (sys.argv[idx], sys.argv[idx + 1]) + for idx, itm in enumerate(sys.argv) + if itm == "--model_tag_value" + ] + model_tag_value = ( + None + if len(model_tag_value_param) < 1 + or len(model_tag_name_param[0][1].strip()) == 0 + else model_tag_value_param[0][1] + ) + + return [model_name, model_tag_name, model_tag_value] + + +def init(): + """ + Initializer called once per node that runs the scoring job. Parse command + line arguments and get the right model to use for scoring. + """ + try: + print("Initializing batch scoring script...") + + model_filter = parse_args() + amlmodel = get_latest_model( + model_filter[0], model_filter[1], model_filter[2] + ) # NOQA: E501 + + global model + modelpath = amlmodel.get_model_path(model_name=model_filter[0]) + model = joblib.load(modelpath) + print("Loaded model {}".format(model_filter[0])) + except Exception as ex: + print("Error: {}".format(ex)) + + +def run(mini_batch: pd.DataFrame) -> pd.DataFrame: + """ + The run method is called multiple times by the runtime. Each time + a mini-batch consisting of a portion of the input data is passed + in as a pandas DataFrame. The run method should return the scoring + results as a List or a pandas DataFrame. + + :param mini_batch: Dataframe containing a portion of the scoring data + + :returns: array containing the scores. + """ + + try: + result = None + + for _, sample in mini_batch.iterrows(): + # prediction + pred = model.predict(sample.values.reshape(1, -1)) + result = ( + np.array(pred) if result is None else np.vstack((result, pred)) + ) # NOQA: E501 + + return ( + [] + if result is None + else mini_batch.join(pd.DataFrame(result, columns=["score"])) + ) + + except Exception as ex: + print(ex) diff --git a/diabetes_regression/scoring/parallel_batchscore_copyoutput.py b/diabetes_regression/scoring/parallel_batchscore_copyoutput.py new file mode 100644 index 00000000..cc4af42c --- /dev/null +++ b/diabetes_regression/scoring/parallel_batchscore_copyoutput.py @@ -0,0 +1,91 @@ +""" +Copyright (C) Microsoft Corporation. All rights reserved.​ + ​ +Microsoft Corporation (“Microsoft”) grants you a nonexclusive, perpetual, +royalty-free right to use, copy, and modify the software code provided by us +("Software Code"). You may not sublicense the Software Code or any use of it +(except to your affiliates and to vendors to perform work on your behalf) +through distribution, network access, service agreement, lease, rental, or +otherwise. This license does not purport to express any claim of ownership over +data you may have shared with Microsoft in the creation of the Software Code. +Unless applicable law gives you more rights, Microsoft reserves all other +rights not expressly granted herein, whether by implication, estoppel or +otherwise. ​ + ​ +THE SOFTWARE CODE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +MICROSOFT OR ITS LICENSORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THE SOFTWARE CODE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +""" + +from azure.storage.blob import ContainerClient +from datetime import datetime, date, timezone +import argparse +import os + + +def parse_args(): + parser = argparse.ArgumentParser() + parser.add_argument("--output_path", type=str, default=None) + parser.add_argument("--scoring_datastore", type=str, default=None) + parser.add_argument("--score_container", type=str, default=None) + parser.add_argument("--scoring_datastore_key", type=str, default=None) + parser.add_argument("--scoring_output_filename", type=str, default=None) + + return parser.parse_args() + + +def copy_output(args): + print("Output : {}".format(args.output_path)) + + accounturl = "https://{}.blob.core.windows.net".format( + args.scoring_datastore + ) # NOQA E501 + + containerclient = ContainerClient( + accounturl, args.score_container, args.scoring_datastore_key + ) + + destfolder = date.today().isoformat() + filetime = ( + datetime.now(timezone.utc) + .time() + .isoformat("milliseconds") + .replace(":", "_") + .replace(".", "_") + ) # noqa E501 + destfilenameparts = args.scoring_output_filename.split(".") + destblobname = "{}/{}_{}.{}".format( + destfolder, destfilenameparts[0], filetime, destfilenameparts[1] + ) + + destblobclient = containerclient.get_blob_client(destblobname) + with open( + os.path.join(args.output_path, "parallel_run_step.txt"), "rb" + ) as scorefile: # noqa E501 + destblobclient.upload_blob(scorefile, blob_type="BlockBlob") + + +if __name__ == "__main__": + args = parse_args() + if ( + args.scoring_datastore is None + or args.scoring_datastore.strip() == "" + or args.score_container is None + or args.score_container.strip() == "" + or args.scoring_datastore_key is None + or args.scoring_datastore_key.strip() == "" + or args.scoring_output_filename is None + or args.scoring_output_filename.strip() == "" + or args.output_path is None + or args.output_path.strip() == "" + ): + print("Missing parameters") + else: + copy_output(args) diff --git a/docs/getting_started.md b/docs/getting_started.md index 89981fa3..cba7e424 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -64,6 +64,8 @@ The variable group should contain the following required variables. **Azure reso | AZURE_RM_SVC_CONNECTION | azure-resource-connection | [Azure Resource Manager Service Connection](#create-an-azure-devops-service-connection-for-the-azure-resource-manager) name | | WORKSPACE_SVC_CONNECTION | aml-workspace-connection | [Azure ML Workspace Service Connection](#create-an-azure-devops-azure-ml-workspace-service-connection) name | | ACI_DEPLOYMENT_NAME | mlops-aci | [Azure Container Instances](https://azure.microsoft.com/en-us/services/container-instances/) name | +| SCORING_DATASTORE_STORAGE_NAME | [your project name]scoredata | [Azure Blob Storage Account](https://docs.microsoft.com/en-us/azure/storage/blobs/) name (optional) | +| SCORING_DATASTORE_ACCESS_KEY | | [Azure Storage Account Key](https://docs.microsoft.com/en-us/rest/api/storageservices/authorize-requests-to-azure-storage) (optional) | Make sure you select the **Allow access to all pipelines** checkbox in the variable group configuration. @@ -85,10 +87,17 @@ More variables are available for further tweaking, but the above variables are a **ACI_DEPLOYMENT_NAME** is used for naming the scoring service during deployment to [Azure Container Instances](https://azure.microsoft.com/en-us/services/container-instances/). +**SCORING_DATASTORE_STORAGE_NAME** is the name for an Azure Blob Storage account that will contain both data used as input to batch scoring, as well as the batch scoring outputs. This variable is optional and only needed if you intend to use the batch scoring facility. Note that since this resource is optional, the resource provisioning pipelines mentioned below do not create this resource automatically, and manual creation is required before use. + +**SCORING_DATASTORE_ACCESS_KEY** is the access key for the scoring data Azure storage account mentioned above. You may want to consider linking this variable to Azure KeyVault to avoid storing the access key in plain text. This variable is optional and only needed if you intend to use the batch scoring facility. + + ## Provisioning resources using Azure Pipelines The easiest way to create all required Azure resources (Resource Group, Azure ML Workspace, Container Registry, and others) is to use the **Infrastructure as Code (IaC)** [pipeline with ARM templates](../environment_setup/iac-create-environment-pipeline-arm.yml) or the [pipeline with Terraform templates](../environment_setup/iac-create-environment-pipeline-tf.yml). The pipeline takes care of setting up all required resources based on these [Azure Resource Manager templates](../environment_setup/arm-templates/cloud-environment.json), or based on these [Terraform templates](../environment_setup/tf-templates). +**Note:** Since Azure Blob storage account required for batch scoring is optional, the resource provisioning pipelines mentioned above do not create this resource automatically, and manual creation is required before use. + ### Create an Azure DevOps Service Connection for the Azure Resource Manager The [IaC provisioning pipeline](../environment_setup/iac-create-environment-pipeline.yml) requires an **Azure Resource Manager** [service connection](https://docs.microsoft.com/en-us/azure/devops/pipelines/library/service-endpoints?view=azure-devops&tabs=yaml#create-a-service-connection). @@ -133,14 +142,19 @@ You'll need sufficient permissions to register an application with your Azure AD ## Set up Build, Release Trigger, and Release Multi-Stage Pipeline -Now that you've provisioned all the required Azure resources and service connections, you can set up the pipeline for deploying your machine learning model to production. The pipeline has a sequence of stages for: +Now that you've provisioned all the required Azure resources and service connections, you can set up the pipelines for deploying your machine learning model to production. + +**There are two main Azure pipelines - one to handle model training and another to handle batch scoring of the model.** + +### **Azure [pipeline](../.pipelines/diabetes_regression-ci.yml) for model training and deployment** +This pipeline has a sequence of stages for: 1. **Model Code Continuous Integration:** triggered on code changes to master branch on GitHub. Runs linting, unit tests, code coverage and publishes a training pipeline. 1. **Train Model**: invokes the Azure ML service to trigger the published training pipeline to train, evaluate, and register a model. 1. **Release Deployment:** deploys a model to either [Azure Container Instances (ACI)](https://azure.microsoft.com/en-us/services/container-instances/), [Azure Kubernetes Service (AKS)](https://azure.microsoft.com/en-us/services/kubernetes-service), or [Azure App Service](https://docs.microsoft.com/en-us/azure/machine-learning/service/how-to-deploy-app-service) environments. For simplicity, you're going to initially focus on Azure Container Instances. See [Further Exploration](#further-exploration) for other deployment types. 1. **Note:** Edit the pipeline definition to remove unused stages. For example, if you're deploying to Azure Container Instances and Azure Kubernetes Service only, delete the unused `Deploy_Webapp` stage. -### Set up the Pipeline +### Set up the Training Pipeline In your Azure DevOps project, create and run a new build pipeline based on the [diabetes_regression-ci.yml](../.pipelines/diabetes_regression-ci.yml) pipeline definition in your forked repository. @@ -155,7 +169,7 @@ Also check the published training pipeline in the **mlops-AML-WS** workspace in ![Training pipeline](./images/training-pipeline.png) -Great, you now have the build pipeline set up which automatically triggers every time there's a change in the master branch! +Great, you now have the build pipeline for training set up which automatically triggers every time there's a change in the master branch! The pipeline stages are summarized below: @@ -191,6 +205,46 @@ To disable the automatic trigger of the training pipeline, change the `auto-trig To skip model training and registration, and deploy a model successfully registered by a previous build (for testing changes to the score file or inference configuration), add the variable `MODEL_BUILD_ID` when the pipeline is queued, and set the value to the ID of the previous build. + +### **Azure [pipeline](../.pipelines/diabetes_regression-batchscoring-ci.yml) for batch scoring** +This pipeline has a sequence of stages for: +1. **Batch Scoring Code Continuous Integration:** triggered on code changes to master branch on GitHub. Runs linting, unit tests, code coverage and publishes a batch scoring pipeline. +1. **Run Batch Scoring**: invokes the published batch scoring pipeline to score a model. + +### Set up the Batch Scoring Pipeline + +In your Azure DevOps project, create and run a new build pipeline based on the [diabetes_regression-batchscoring-ci.yml](../.pipelines/diabetes_regression-batchscoring-ci.yml) +pipeline definition in your forked repository. + +Once the pipeline is finished, check the execution result: + +![Build](./images/batchscoring-ci-result.png) + +Also check the published batch scoring pipeline in the **mlops-AML-WS** workspace in [Azure Portal](https://portal.azure.com/): + +![Batch scoring pipeline](./images/batchscoring-pipeline.png) + +Great, you now have the build pipeline set up for batch scoring which automatically triggers every time there's a change in the master branch! + +The pipeline stages are summarized below: + +#### Batch Scoring CI + +- Linting (code quality analysis) +- Unit tests and code coverage analysis +- Build and publish *ML Batch Scoring Pipeline* in an *ML Workspace* + +#### Batch Score model + +- Determine the model to be used based on the model name, model tag name and model tag value bound pipeline parameters. +- Trigger the *ML Batch Scoring Pipeline* and waits for it to complete. + - This is an **agentless** job. The CI pipeline can wait for ML pipeline completion for hours or even days without using agent resources. +- Use the scoring input data supplied via the SCORING_DATASTORE_INPUT_* configuration variables. +- Once scoring is completed, the scores are made available in the same blob storage at the locations specified via the SCORING_DATASTORE_OUTPUT_* configuration variables. + +**Note** In the event a scoring data store is not yet configured, you can still try out batch scoring by supplying a scoring input data file within the data folder. Do make sure to set the SCORING_DATASTORE_INPUT_FILENAME variable to the name of the file. This approach will cause the score output to be written to the ML workspace's default datastore. + + ## Further Exploration You should now have a working pipeline that can get you started with MLOpsPython. Below are some additional features offered that might suit your scenario. diff --git a/docs/images/batchscoring-ci-result.png b/docs/images/batchscoring-ci-result.png new file mode 100644 index 0000000000000000000000000000000000000000..d07d41a86d2832684115e46ee6d738d5113c6b3d GIT binary patch literal 19207 zcmeFZ2T)Ycw=O!0fTDl_M6!xXk{~%FAVG2-GLpkc&J0PBAQF_EbA}lthXF=FL2{lU z=R5=nGvwh7{*V5D=T@Ct=heNh>fWl?RfOGZ@7~?3d-q!XeXIMUst03d!X z_evcAAb5!Tf8{y>?ze%T5*_Z(6&H0`NdUBuW*v8N%}PQ^0sttFx_M@TkGsC%D5vWJ z0Fbm@{#@yBC^QEEIlqD9uq4me!F@jbq1dpy z&B69>eXUk{-nCs>4j?=mMjd;GTdgF6Rt#2CcUyXVRvN@;ZEbCv6ShuwP?ppJ8iKe= z{!T~pYXez1 z1H9V_=ldBKRobrGQ@UwFZjX=t+zAjdZ71s)drxV`X+~_>(<0aqO&;Kg@%byaX69~x z(@xcs7&y+_dP~wkTVEd}{p_z;uREMK@dY9G(Hs1SJ=Wis6O8T4F8l3wvKHh<%+b8> zBzl>6@h1Km#xXB4`Woe(0|{MYVhz%Xj!!{7P8^1@E*Gu*hh7K z!G>6%pg`@u02a-~8M8DTLcF)nHQcA$o4qdtBj|W!g@vOKu4b?wF0u;rPf!ULLUK23 zLN@hk+8mfn2GA$tVQCxW+#S1OPIw2ph#S%|03`&er*l88CorCoq2)bWPqfMRL<^ns% z*u8$3gJ3;yp%Bv(y$<=F-Bbdb0B~lOa0}rdRW>f45k4d#W7<#T@t*Ju8kgP{n&na+ zjzIQ^QxrN0g=T=J*dki*$8VeD@XmND&A?{WGL48%k^14tr{1P&`H^W}nv8!6b0p~l z0~SzwQY@TCgy@DYwSm}eU{UR{cX3f@3wpy)JXu3Z3{&z+f?FLu8$+;G#xa#Q(=3iK z9FC6Dbq+Qk{Zmk;)@4B>MP-}y7_OI##;320xBO*4F`|dCK))i`dqUoXwKIp! zDTo@9m6+_j!I31-Ys45;U+olaYu1Z_^U=OzI@L?~_C9^$9Z$3q z>iAo#brI&~OB$oRA2%akAF3b>CESyW_N~u1%k^^)SFKOD{k3x5-U{Kj?K4wweY;ed zOgF4qv2NyVkG*?7YS&igk}-VHK@@(NlJnt_dsg|Ol(f=^2hCXd3`&ls_h9{|7k||F zt$tlqTN~s1@?}8NnqkL~f6)gZhT4T!s0v*sG=f@{KL-{2&CHfJ&pfj8d7>w-?L2xE{dDwnHlpG5hS(on%(2-`;Qh4_XO30I zqIZVE`l9e;AYh|ABu_`2X9r6hI$3kxVr@u@3-L@%}NL;(+Q9 zY%WEHk9xn|L>U$A79gNzB&)P^^E4m;04|5bv4H!WEht^i+k1y{a!$KC%3HM|@7+{b z-HZ$Grl%HuW!*CU-J26b9-}Pd^-5m&r&>CCHso$wN zZIfyNOMabP3yX{H}syb1J)*``)npcx*vi z0hq;9vD9>@*^nO-TdX`8IGXxgExp|Dq9~r!NMpBF)52G^>np$b^*}PGTCcP3EVhXm zn)UjE4$z@}j{G$h!pYixiI@(| zi`u}e?_!BNiF`d`=JJenJCaFy+Pz?bPJZM=irx_N%34`gZBmCytSPq826UI4)FA$tZd2%!Nq8aFbdO&iE!gK6z8-=5yBWM}c&=|5TMO5r`w zvl9RAzcwZ-$RaYM!7oFsw$mpw*r~qUbS{39ap7f1&1W|lFM3f@1_G~loWn|Tsw2jG zcXc6S&h>tGo$4`mM=Fr>GS_9FgL)wh+~}Pl9D%K!9Z0U?k4>*s$v8bgqTfw#FmM#G zY96gBos=Oj6xJOsv`)p&vs&f3TKg|>_1gsK=GJn2b~4O4 z2|noi7<~!M(00RB>GS)t=SX9*nX(FY@j*MJ8_=yqPqcZ-t)pBOIKGSxt|m=bE>u3z zpYUH>R=OA{~?E|q^3L1wpR5i*)^0-LGrs;a^Yy3UcK>Hxx13H(BLncjnW>K%aitcrqo0nr;{F)&clOXuYuQLOI zQjv~}h~9VKqAnR5G}!>LAKVz;TDdL!$PaOw&#KAt{7VJ_r5l4}4{@GEtx)jF`tXnP zsnQ9CE~DdY^?kS&eC?yWVrpTbQCzWzO<9L@+fIWjK4sZxNMx<)lTe2$ad6(yA*H@H zbx4rfLhmB9;-MDDvjWx~IsTyJ4oo8TGVn{m!BXCd#>dm9FDmGnlj@0!oQKlkl+euK z)3})AuG^D<0B)hEE4Jc6KNJTZlH2aXf>ve+o*f4(4xELAi>I0dl9AobU)wFGvX9;2 z5L~EH$~%cl&%WXDYQ682(e{ipr%*^`vN?RDjdZH0aMCo6Q>^Q`rcph5DvU*Jth97U z^{I%E+8_qIPvO|f{Z0|+i8jAu^?4eOG;^L8XcS6~yy^AyiOy*Zea6XnK z*$MQGxW}zA79rsrIkrB$ueV5AIIokpO9)pF5$Ee)B8ofdq3KOBQ@Ocyo*`m^{XLY9 zuKa?DX@86o&Hpe-(7E$T(gNb8#?c&~!%(nAWHoop3u1L$FHT><-@-i4^HT@QEnWqmJR()^N#s1PH;=#|oPhd9*^Rb~w2y;JGF+Z;#u$eN&)PQ9iI#@li+oIo z1am|?lwq~|BN_V4w*Y`T!JPs&U)c!YTe$7A-B^CK45Rxfiy~O9zu>L*{3`9Jhfb_1 zR#c*P5=7k~No$CG;87*6TefW_|3DkE5x9bK{PFY|%b;&V@7cXeU;=Q|@(T?dn~veV zNa~2aJ+3lJZ)LqKd`eB+saf_ESqhoEmpe(Xq^hZ!w>P6W_~~YbcGrremY-Ew$B)Gl zB3eGx&109vf^@td@l&sf zW3@Ii)oSvmLPL8Jl)t|pimZ)j$+$XWJnbaBL#ps@86;sdwLk($+l-o<@nz>c16uUC zGCi^&V{AWvnAZ*Eb56*-k^TUrGtb~|BxP`|xkPO}vRbba9oi7gxQ1zo#9kFkYtSuw zDjTI=7S9nW?ERXj({yBh?(>#iEUtTNA#Y(a9-kS*eFyRj?_YwR=l)ch6d6Ak)7XbIw%sE<$d_)rryh zzb!CQ)GbSWf6l_ptT~h69KrWGP;zs#wGKdwpj&*v<==nc*6wuB6QkGc1$Xr=%?~Fn zq4w*nH4c3oK6~$<`tMm)j&RZ_(GV<46b)Kq6-7TKH*E)h;<6|>!(5AGUoK->= zizjyYi~k6xoCtfA0{|3yyu0@BR@%ur29`tRD$R3oyB+&jCa{49xvfNvE*NSK^PO`? z*8(#tS*7BBrM&tFn%Yoa<~ zVKK?hmJ}*BNAfit&L?bu9p2lcOdzgn3uV+1zN>jqb@?v6Wz7T4p0+5PY$xJRH%I-J zDLYi#CnsY)mh|0-KMsBP9^`%Yg$eDZv^Qn(dE4iSvPo03);yT9i}gz|GR{<(SN0vs5*j&|1E6lfBRAeSAqYGe*G`K!9xQ7Ve=_g82m3dcWy{cUn7TV zRTD&U72x<0^>=AM)@%ze8AUA6_^KLZ!u`E;cxMqmYjet=um*TA{s$XH$5(6UklITO*$QY@kCOMA%vwa1Ku#vuY=GAuKj8e zok&Y5I4=lv1)sf|792p9-vtDGn(`uj*?0=~M--D9)g~nKdyNG)EHa8$C$PWLVwv3k zB6bK88nzC=qYL%FG$Uyv0zn)BA6w*DI=U~T8Kor7Az$=)?-XyrHP`ZUM zMt620u9_(kTV=WU52f|{bIkoR?)0Yq$gHA8FBm56BzW$dLtNW^1{Oy*Q&kMI1z=!%f*0_`!?RW%ellVt1f%xGzB(@>s!9ll+qAo{U}kPVpey>R7Rh{M z-pqyULw+b9*7si&eUlo$L_2z_&{5R-r3_` zlpx^Q;OnxGVN{0pcU2VhqD=M*RMYtajexP|&j;Eg%8cFpB5yUpS#=kC7S5hn7?Vli z^J-S3wUqq3kFe*9v5otmBdOq@(5IWC#ZA;Jofpoq1yY0Qa@ZqTFsZq9dQ!%@YVt~1 zr>M$123$+$)IXP5crd`V5X9i zn&_SdU!?G6>~|`oMmuA+^h*^22(V)>CMy-JI>Ng@^KT0hv+yZ7xwfSx+mBRKGtIWy zkXx}0Z;pLI_yvcjLu02Qbo@m|FEb?}Ni7>oCv#qQL3{j^J0AYA!8&%EIbX^vsT&Ix zxqoyCO!JxBdVAi>m>yHv21TK=2Bk{fd{4qPH%EBLCreOi>Z8p(qS!axV#ed|JZQLY zL@`1A+Zb2R87x__&%iC6F&Is9R+sg+N{)yZAuh>rL!NbP$k`q9F9=0$c*!F@%QPB6 z*c%l!Z$l2ego-^D@+O-qhE@Z*>_QvnE{E*e_Vs8*wn_}jy5oTSxOl=&%*5h3j81`V zkj>zu%RR_=82>&>46Jc1V9>3ckP8}YbJu@NH?-(*zo^K#a3f%FMYnJMYxquW(GK*6 zmH!1-euohRKHp=6xrGt3n9x!Nykg8v}tcmVSI(%*|79X0=ac>znpv?dJ%$xMc@E*%n zNh~VQW*s3IY4WAi=pMR_eiR++NG)F^-S&8TiBUz09eI-W^ige$KJ{vkZpr)m#0vO; zy3bW0z(ThJ)lAaXUJfhOtxEI0lqR|!XYQk~I70%C2t38CmSU>9YRV8G$`z$;{4n~_ zl^Zmg2NO~a{?5@udn&q8OvDEq!^z-#2P5t!j_8&_pBhN-p%yHTx*cc*9FVxobeP)LIWf}Q+tpV zb&ryNeYdp$8rhJZk}=KZFj7t5hEAmCe)!1D0wvZo4~4Uk0?Y2BTwmtCKWEi!wE1Eh(Lej}d~a6Wb+(XMo(ofQJBRj>s8&2x z$p@>NadN$~VYtD1;)`UI8fmCucX-W{^*{|#Ue3ol*pP~9Z-ma%vn-R=wTkd@D&Yz1 z{q60r^y-(~j07l`eHgW{;rgVh0s`N0{X%r31~Uk724=>iN>l zEp-Cf1(zOlBge~kIU`gVotc#g|0qg*+~SY>3c zhOPqZm>iw{lUMn)m3L>$uxosdMr?g`V|<}<>Li`Wm*9i-=G0?pc$Kt%d}IvVux){& z2o0VEwwLtV%v8N%(@kd4Uie8+fA2u#Rv&st-%F^pzuD2P?cuwp(%snj zLN-Dg#>HNb%04Zl1X&a&BW9k40F>j5vM)?v-U^aNNWUA8H*}v4Pd!BMi?Lw`shL@^ z1267TTN`lka&V(Sq7~f&bUiy}QjzX&6PZ!go-9h^ePu8%{W7tne6EXEkZ!$#)s<(q zGdEFHSc}DBN_hWpS*>4P!4&N@dJS{3$S_{_liNQk!V3+TQQOdv?MX&pEMk@Q(PbP0y9qW7+$EBsqFzb?#$V!y&{BU}foY~f&Iz%d&73S- zqI}|^$HQC^pr3JJC_4z(NG(5dd~u;tq$%c6Z^}kPhGTE4g>f}+E!}FNc7gIlrPcm% zM;DkwR?ux2OCU;~TC9wmaADIbo-PU+qLr|n5`3(A<8Wlva*c}5=m!65-5tLTZNC&# z&B7?LUB}yu++XL1%;w)7GxnU3p+%`HsEK*Cyg3ybm?hc_sb+bf>zQCGJ#b#A3XI?( zv^m?Pps_73GG%Dk-Yb{=NcBYPm@<%bd$LwL@X1Jf5)iW&;@ThhDb|-n#T}e&>QGbB zn`E;eyOx~E|IjF^uVPgc!Fj_iGc1nJqqJSwFy}EcCLKE;<|_J0i;TOUfjTZ&AfHkM4z<8NHJ#i%TJgy5EP9qrh4n*_+&49+x`ksa9}ikP1UYN0 zqO$a*c!thIpib9SCiZn}_?m6{p4iS*Io4x9H+<&Qdb#0I1QJ&ZTJ(NRz9PodF(~Fb z?TJDCF0R~Z=x)d|%H7Lx&tVOV1)=Sos`9phhc`6OmXa`%tcgt?d-3bL6g>=G#xdKU z-0MRHDudxsBW#b2Vq}tBO3?FHO616ehpHxy!U$EU%d8W29&;|Rvwm9;n$l2^?n^6n za=VD=U2G#7FI*dNf*r~?R{#?!z%d7o24A&IabDFVqXE8VCt7@q zn|xlO+~`3%lW{%A>qXPYea_GspR_Q;9VU%^vUO~Lrb7o>Ry}gMeJ0Yx3l%^8dq|X= zCBv9dO9h$!MTq&p(`vYVv8IMEt+%^_l6aUcd8t11IXCk`Vm_C!F)N&ae=maXkju!v zK}~|V>wL*0M)OE|KS%X|T4PqDCE4=3P7}+@Teq8RI5YPVioVaG*{YzMSVgzYfRNTKnPwJicgieakpxHNyrZI zOUbVkFYveTBDK&fTa>(ta(E?tJXS{Mq9Ez}P*!1kAE?{zBYNcA#yC2EXK;MJV0EYMK!kei9~ho`hK-s0kvqme?o9QiScNu{f1Al5qF15 zx^s_@Ua9Lo?=#JJ+it$8g0dpW%)`F(*Im$Gz$FKuP0NG+W~;;5j$2o6RndF0h;7uB z?}#XWN~c13a;%bxP46~Qjp|L}W$PQJlk>-ERW!d?tabTLp^eJAop8vPud~?N1d8ln*`@esukqnz0>u`$qAD%1_e4t)PkZJ=L0kie z4EKFm{=w6hf%gW)5Cq2rk>uL+VKQZFQAsNuSK#d+`DsJ?Qb$a)oNxQ)BZ+N7Kph#* z7cupGx%k4aXNDw+ux5R6@dAWTuZ&%!1}m8<+4=YRoRQOBxajt;JM?RPId^mmeAPFD z2&3-r-MC-6dl*q`iONtFw{u%1rsS0v1~%nX^vzS955E$rC$|f1!Za0>Jc^k#=S=5AX@@TgiDt)R~>k@+KcU;#UG}Stp5EF)~v~F`A zH79Aae{LUsgZ_%DO0!n7-D@&*j=?DtVE6N4CQc~XfwX&MBL%%kro;bsD9KZ`gC@I( z-63#tiR(l3sAW!1HAM(Wee=>9AK~9ppUoC!Ic{aQ4(fvMsF~24i6h7G=?d9(K+8%@ zjb_33GnkJC(i={hM{*veZqhy2iLbl$V?<@plJq0vy;5JDch|YSYMSl?9CvMSYvflK z^BW#oi%Sxg73(YSNmpkqYkpK}*U5oDpUc|yRN8D(ZHdPdu3sdcMvx(k2EGfdle!;@nl zWwHZ{v5y38G^N$Qz8tXb1H#Ht$^0nNI%4CL!K1V0FEcA{uk*W7o9a^*B+>$|w2wwG z?yR;BeljbIb75QGZWk3u){oNOxK|wd`Mj%}L#xD|HkEyJ8@`Fm^e46(V_kSIU)wi0 zToe@cB8HD&aC7L`1yV3Aki3yJPgBvksZ`FPMcp3_#KAWvpu;C4H%tyEe=qivwe+(# zkw8{tDm^X4@wD^as?t~w~fxHkfZFJ*qSjYp$t~g^nz58vOOqZVv z5NiF9S8%%pSrTWMavFvW9lc!vk@~xpb;qgZ_tf%D>?<+jut#k6IRly1(`X~eEIbty zHN2x5A2+>W0N4&gu&Ym`hXps$*mlR(PAgYzB6|k|zr|p#ePEp^j>*m?KPE;sqLbrh zU*;^54bG||^6ekw!+K^$$X~ZRY~FP&>_Tpk+h8P5JAHVS>e-Fu#`A%(rYo&=CXJ7` z<_oSeERfkXYM1&dt=j_ywFrk|>-&wYZ>9y?9NgN!**yaCe|t2kdjXv7u@`f=45=G1 zJ?=XE${0X?Th$~dQ$kudOVr9`#oCkiyl3?*-N-Jz$%-jAl##FcKyhrguO3kcA?bz4 zb|2fU(Z1LlZ_pLYVgpU~q2=2}O#uY^AGB>?SxCER-2pNQ_=YJ6%pe@*F# zzk`gL_Z2CGiL0+EyLzs65tY8_KJ!7V-F2FK0xIlYA=Wr_C($~Nx*dgF`7GHrvU!Jr z98}ZN)A{SC1U?mG8ry!B-$ltu{~cZy`TgEq@is=A&cH8`kG$R!fTEAx{q=L1NyVVK zE0%7NK1aZU4Kn{hdD>|#Ch_P_q}x4HS=*(h z>|p-T{+9JFvfgHJD8WI|g;DUe$dQBEaK57sW-q;}w9WAtOx=hVvv$trY=7}S>*DvB zso9&mZg96rBH$UfleT1ik8b;EhtR}bUfT*1Jqq?MkmIVsIoC7o$_%BUMN--IbeokR z<+_!pO3v3HisuoFuJ(0K_;Jwn6(^xl5qBE2Y(zR_fv>k^;Pn?$_P4(#d;R#Nnfv?P z&y1(HAqmt(-jn8a zxzp1X@l0-fxs%LkWWpZEk=XXig8!$&v}^0;5X9b#US1(wC`(?zpZ+euF>*o_U~-95 zj&7{hBh31!8uF^}{HjGh#oClvMM_ zI|JI%wOkXGw+NTRwC-OVSgJ!aI3_< zIPhGZkXuE^1TIi;4|7XY{Doc%V}x7#X`Id1yTI@gxQ%Zl!ECLvLjDg{E`#<%Q=j}s zQ#X>RD*qJoAA;gBIH)7h&3%cWw0!XnB& zzGjECQ+G)0;lQB?%sqi)j|onXM3#zp8+81=2ItKuY@PC>Jy}rQCpaJtq2Hy;+b@8P zm}M}lju%bIpNioJ4HeTU*#>GpC$2kd25PUc*!_6S)+JP!o|BIB7EZi`t382rmUO)X zB3AD$!Bkvqnv}9pRIA>3R53AG&$Wy#qhfcq&q_bFYo+(B`M!wtBx} z;&e$-DtX_v5sdkkgK6L!0>IqD(0>FXxi?ayvN13{JGQ<-!e#uE(}WPMeY*%B;ggMq zl2ee*%f$9;vYo3H_p!V9>~~j&H4z%>!wA&CJ@>LWzG!$=6nY6!M-HyuGqRt*)W%Ew z62aIUw1Z{gubbk;4Q_>!gan=aetl&tC3oXCCvzI{;`U(7I3zkk{c{NOJskc#5cfB5 zbd?`)YL}_R@(JRcoX~#Gnx?VmUXEa}yMD1>4^h!UN{$J6{-;ULCx}xz|&ej;V zE|$K^Mo3*^i&rR@q(|8An*{xhh_)uhVVe8Vcvp`eQPRNFZ$6tTwU^y8AoD69zb*W_AC7HS zpM3N;ihLDM^dYXvzf%Bk;NPKpRm}hAabFE278Vw>#=huLA+Nn$!@q%^bM@?o4QpYn zP}RSb%Hs8x*REX~)B4jkfL;eLpyjsWpX>jt=)CRsL@#{~&pj|SzpMW(FQ+D7hPST> z!F~-ecNh8Zcs$=xKVS*uhu}$O<4gaGy|1>-kS`9h#)ckl{=_%04=2ts9UH8eA^#QT zUl*#GP&{{TU^l6oxj5>c1Ob(CO3TRF9x0uV#O*TULJ&Uh?KvNxoOE?`te)XNbdOsG z^@iA-?4^`#Mz=$o7g$7nTpDGr1y4TxmsTknsN(GXr9fPVC1!FTvSmoL9L4?Jsx!(< zA<%*OKyZ~Xzsji!;X3B%V}na(nHlaeiu!%J0MA4Ji&8E6Mtcrk2b?qD)}i8O%W-8! zHLpUHe%%F5O+EupF?4@d!lZ6r&g1y~&2dIlq{Qm!`6W|1XX@A>3FB|hM(3TAgJ(UZ z@!hI{Jo7NyxXrObv;)01{FHtakKydc@_pRBt5gBjhsu87sQcASM{l@LDU(^}%N$!d zV!kKVUHL??r6JY-Oi>yA52Vx0e~?ZBTK{XLQ@-uLNvCtHcXNDwZEqqDZqFQ7;MSVj zNLkWinTXBqpihVN^lxUn1M?Q1=MZa{@eUo22fwmu9qEYk8iNk?H3Yq4@(Un4dimjf zzdm7TepF|^|Na|d7^6BC`=tT3@&;BanznOz2}Mpw4I?eOF=Hj~EH!t!hgJe5yp}yM2KrYzz0zab% zxH55^%<0}R)V)Qt8V7&Rkh*mfxQbUV54H)*z8hb(R%Mtc9Tq2Q_eI-5FiYFcudgc> zTcQ@0{I=>5gRuo(EA1?75IPk;$|7b=>TxZ6IJz;%+kahPl-^=hW%>o>o#%r7`wx(r zYK%esI%Q2@Bxq$o*&wo1Waa)^E83TiQH{&@KJ(DJ9YJ`vZ_v9A{%jjwzU_7m+I19cRJ8*LzE~ zXVAIV(PrmX5(FP$(12sv%3)KL9WwSXcFCI^B9@9STXzXnY8{ku`;4lwQIX7y9J2k? ztBJ*O$l_{OAhNKKjS4QyU#^4 zdpeUd0W(QIOow7v%x0coKL)*4cXm}_1rz8dHAKcLnfq^ zrL6ea@sicOU+&P-LgxeZ@A!T_Vs>3}r0o>UL>%5I)NYAJ%r3U%v_bL+UpMz=`yV7*|Cpc`j|lyLn_;)nIX5g$E9r1#n`dXxK)%?r>QOPv@t z#8aI`(^CDjVu7>z4R0bn6?o#bT>@o6Hgp5F)ZpF*q34DxYMl-p90f8!mLKI5uv#1n zKB2sRU9*svTPMwcUZjjg0|SZz$(Jtro*YnS7lu$UH|1j8-EbbPj8|#+u(ecveu(ho z8rO`bU66Ccxd@MUXj8_Qu(afSQ?Of;2IR!Rf^f#E=ZQ#m9hNvF^)M>2=qP0qpHXE( zL#wnWuadV#w}Yn7Mq7T-q)JQyNd}^Cckrx`1LaHGgzk#6O|I7TsZGwE*%dG~HOfmn zP;G^BCPeJG>xJ#5tU;U_o@jKJo(oO9@Re>ZcAxC%8*#0+H7~QDmrqTx?$vHgGCmwn z>FSu*b8mQJ_=&D&^6u_uI{!*JrE^Iw!f?KRXOa*LAGngQhmyeQDcExgcHS%{Bc3ar z5|;Aza(BhROgr)Qud97MLWK4k2D8n$1fp^to7jDURw74sZ#g60BTE)C4}8R)c=gDb=Ch*I-dSVCKd>d_5G`+2F)g z@JlAEhb`$9`eau=4u&_RQ&>3$yYqHJB3wisAZ`F0=WTIVT*53*W8mbnERg4cWoIfs zSTu3j@|Ov2&c{#@9&R-)$8rn+jRkzR1G4W}=HO>t&>eJF15Mc8(&3_iLUAn-=oa{I2uo1kqPV>O7 zH03{2NZ44${p#oTq0dCh^~U3X6K!JnU59HQW%xg&U=4=j5Q-!r-#)`=xZ79dga>-; zEOA|&UNrtfEqPBpnZ!0TNBNu0a&x`hz2NUujHgOy3V|#;4)Ma{l(2|J2YJT+(3gc%}FWo(+&NasBhiy~yO22ORBR8#L$SvqnH;en#!v~W@ zxt&m)s*&f^)1d>#s(Y*zqQwM8HSieTFZ(m;msmw;wbD~P3uo_6gp}t*@a=3v*K}|4 zxR`zwFd(1AyNypENu)MfXw|7#WiKmntIO9_BOd@UGk3 zmVCM@jNH+x$Op*<5*E`4u25|=N}=)OE)m>(87*U)FVOX8301>v$m$gD^-vZ#wEU)C zcG3*#sXF?=(xy@LY_Ro%DtW#bWD_!;T-l~_)3B>D9_%>`H?AsIs!G1e8cWAB;WivW zWLse^>nX3zKr>d0)3 zED=a=bL43kCp?N+aH8BKpMZM#SS62n^4JY%i5g`b)?CRbbkjv0OijJ&1)HQH;BS2z zE{99ZVlxw(`RTG2(@79*f!0=csm{(ASVev6-#bta=5Z)S z`L*)8#QVA-r@T{h^wNZE`qO(?=~;K0XqHEmPDe*_;}ddN)9-KJD5QNCcCFs;1Jq=2i#wGJ zkg0UZR&TIUMFx7-4LR+5Pq0Oe;M2>)S;WnLwfLSQw1Uw?2{}x(1UU6%pmfx3u3+9bd~&Yk7T)2PBYj4Kk-1up^RI{ z&-JNid93d8I_P-@zEPXQi?U7kxA6z64M&yamQCC;+wdZXIrU9!va4}b_m7q&-ZS6uMTY+t z5yb01waN+(^18$SnzRF7|7kq?e8Y5cGGt0}|F>V)7c=9e=XFrX)uZ`=i9WApSv zNVk#Lh9Y$(wAA2U*yF*^W(LOJ+kl zvG&ysj|Ac1;0n}{p&3oyshIi=DfTPhp5_?h-NpkOSoI4wy1W4yrW0EInlFNI=yfYO z%{Ete?YYFk+EVwl@~zo^PGmnNy@s59B}O>ikZN+fpo=A~!m7WI?FRZC4O@M`u?6Km zdafI)QkbFrW0otf=JD$&m9)$oIVQ9rp#k1YHpZ)9a9vJ=u2{1unQ#~{U#%>9dK1Pu}oTMdhG=k z#?xbQRJ`J*vC2(zt3zc1zEJQ(p5NF^l6=hwS+I=f^>o_q(EA2W=9fc8W>~B77r0>_ zzM05r`m{ei_jS$zzt2TSg^TTe$B$5x8iN{Us17i1!LRkmozX(X1l{dky2Eyd)liO7 zgw!MU9XrMHcKn2O*Geg~%g@=4!zVsx^EgZSC`)_h*_kT|AsE?aR z5ojP$W^qTKUez*7`fj1)yX1X~A0AipU>&nx(Qk3Hs}ZJKaOS3*Ev0n`>31C|hu4sA z!?d}l?y07DF<|m+Yp3tDj-Nh8Q#y+SzU5`(y08t8D$3UkEjFdx}UrtXcf9_igef*;WQb`d$G~AFX5k@!2tcrvBIVS^k-1h`(f$;yRov>ycSL z(>lZ_jpzYn&}lzbq|0EO=cRZ#~^dt0&%;XC?hfYaMi2T3ev+_~w@{H^ks!L_y1j3DQP*FnMGN3|o43 zsY-SL_7FNU=mXZt*Pbn)sO{{Me(dmQJ`gZnTs%S>~q5-?L?3*DuvO(L|ZBtpZVHu;`tHbhE z^r3!Xd|+9Tq&KmX@2)4%T}EAA^4*V5NP+MYDn?SS7$trRAI@6t+QWQ%se9FX%dd`s zODyYOo-8*+BG>4xSCy@&99k;VZ`pnGlRS4dN>2Cd)_KtMDy6mz8O?Y%?no}R^;DqP z>wCYkcHQGeDROTvD4JbDKwspyvX;f`!w1Sh2Nx`#et}X@|J6kIOFTFd~)%GpV-*N3bmm0|| zq5@>RQ;-}Mo~bE^;f{7ou8MwA6`VH#w&kW z-INBC#BDCvPt7Omar}l?Nwkjjnz9X}ZY!*m*mSuaOLp-!Ws`AJv=c9q+mMQrKe$t1 zy;yC!1(NrGc^3(N&hPQXNb0ZgDCStG5|EbxXD zYWoxX&aolXF%tl=RWOZrTk7N%V#$PbLLvPH4n(Prun$Xzy^861@O@%je!_N^3Ia3H z%e6R^VMZwG`TEChdzEx;(2co^jqLa@D@Kb-sO4ny%+esaeWK$<9@r3fF4Es+E{WMn z*(Vpa`=V~-Z9p2~D^DH>!CtX{Pkt6~td}bd53R-=d&YY$P!%3gM3YF`2r4^& z70WbZO2*9=WnCw z{Ko{83z8@}=aUn7ItMk{M*JK7M3Dl{EJM7$A9lgGpx@V)BzJPKg@ct^Q~81qgqZhQ zf{6WK&prqP3>;ov&r1oM%kjUn)SrK^(Dq^wc=V19iROCQZbQ9b$> zQAPk$1RR#*j4ai}WaSSj@aM_oO#*Fu`y#`d_~m_lH%&=(+c=nIBq)}CDb)D2#W`xk z$HPbpT(e(-60DecOneL%{!laKBdV=If;D7-Z+KgD0i4sjF&Va)LYsz@u#(N_{3KMb zx8*tCG6f_F(Yr(hNl(dr%ldWZ^%oa@&~lYE{%HcUzig5%G%XhiJe#0PE`n$l3iKyE z5e71b*Zh-s`5;m{qI8pt;xV~{{9rO|0a-bZmImZW&vt{&lmmj<>Fw7u(q-1eZ%%F- z=26x3w+oiGD82o%cPUk`BvytN_)%tx%~+JS<8=G z!sw_jV7>Bwb#_vkN;gu^gzXZA70GqGtGv5!7z(;a$D8NbuBalP-%TSEL$NKFCKq__ zAO6&VSoG&JA1?JKSFy;(G{%@N_Zaxiva-6w)tG*{Z$YcsuhtK0qV2gfQ+-j6y&}n3 zUVYbkF+ApagJ+a>QNPB9|jrcXE*Z`>L##bfvmy$Yurc@d(> z6=TYnByl%EXy^NPVLD|O=l{3di?zu?i|VoTyq6;9RuPm4Y+Y`7AU`_n(sOON{Xnr8 znpTdZU<|u#x;zfm`^PQ{KfK%Dew13W zZ+VNK3ud-Pi49>@NJ^Fx1p#V6^sSAu%+J*1LISTOkVitrm%Be60$T&`N^h z)n%C$@hH@rbOs5}BL-B}#`qc^y>{rIBWD6`e#9+t8kYh9?D&CZK--q@DWhA3X`deN zR9!V?Tt7z60&Rt_{oYA|>-RZHnSY;*Fh_n6fXn+=vJ3lDA^`CJ(IGbZxMOAzD2o+E zJ3C1ApZDT6)LE9|La;cEIk*cO8YWo&3ap8_5pUXQQrTf=d);me-*1eLjEqVD6{mBX z-NHQ?E;vHmVlKlV%iKBU-cGeFB`Fo=PHFy4-_WL~#0x3b9W+W@-1doJ# zj+YZ=Q^_(m9F0Id-!4WUUo&r9+-RV4FRnIBlo~us^YcF!>4|yqj_gyF#$$yz`T%PAgMM- zXm<8vR={q*KX!Nn{l*#N_Ym-IC2{aMcf}|~pC9&zRdQsuWx*ZNM5Sms&_e0?^*t%A d(AvcnU{|a2qv#2p%aUJ9E5G`Gw$3S`2>^4CuqXfk literal 0 HcmV?d00001 diff --git a/docs/images/batchscoring-pipeline.png b/docs/images/batchscoring-pipeline.png new file mode 100644 index 0000000000000000000000000000000000000000..2b79fe03cd0a04abb1406873b3db5c808d794b52 GIT binary patch literal 17956 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 PAKyUN_;$I@!|?wFon4u8 literal 0 HcmV?d00001 diff --git a/ml_service/pipelines/diabetes_regression_build_parallel_batchscore_pipeline.py b/ml_service/pipelines/diabetes_regression_build_parallel_batchscore_pipeline.py new file mode 100644 index 00000000..d7acbf46 --- /dev/null +++ b/ml_service/pipelines/diabetes_regression_build_parallel_batchscore_pipeline.py @@ -0,0 +1,482 @@ +""" +Copyright (C) Microsoft Corporation. All rights reserved.​ + ​ +Microsoft Corporation (“Microsoft”) grants you a nonexclusive, perpetual, +royalty-free right to use, copy, and modify the software code provided by us +("Software Code"). You may not sublicense the Software Code or any use of it +(except to your affiliates and to vendors to perform work on your behalf) +through distribution, network access, service agreement, lease, rental, or +otherwise. This license does not purport to express any claim of ownership over +data you may have shared with Microsoft in the creation of the Software Code. +Unless applicable law gives you more rights, Microsoft reserves all other +rights not expressly granted herein, whether by implication, estoppel or +otherwise. ​ + ​ +THE SOFTWARE CODE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +MICROSOFT OR ITS LICENSORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THE SOFTWARE CODE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +""" +import os +from azureml.pipeline.steps import ParallelRunConfig, ParallelRunStep +from ml_service.util.manage_environment import get_environment +from ml_service.pipelines.load_sample_data import create_sample_data_csv +from ml_service.util.env_variables import Env +from ml_service.util.attach_compute import get_compute +from azureml.core import ( + Workspace, + Dataset, + Datastore, + Model, + RunConfiguration, +) +from azureml.pipeline.core import Pipeline, PipelineData, PipelineParameter +from azureml.core.compute import ComputeTarget +from azureml.data.datapath import DataPath +from azureml.pipeline.steps import PythonScriptStep +from argparse import ArgumentParser, Namespace +from typing import Tuple + + +def parse_args() -> Namespace: + """ + Parse arguments supplied to the pipeline creation script. + The only allowed arguments are model_tag_name and model_tag_value + specifying a custom tag/value pair to help locate a specific model. + + + :returns: Namespace with two attributes model_tag_name and model_tag_value + and corresponding values + + """ + parser = ArgumentParser() + parser.add_argument("--model_tag_name", default=None, type=str) + parser.add_argument("--model_tag_value", default=None, type=str) + args = parser.parse_args() + return args + + +def get_model( + ws: Workspace, env: Env, tagname: str = None, tagvalue: str = None +) -> Model: + """ + Gets a model from the models registered with the AML workspace. + If a tag/value pair is supplied, uses it to filter. + + :param ws: Current AML workspace + :param env: Environment variables + :param tagname: Optional tag name, default is None + :param tagvalue: Optional tag value, default is None + + :returns: Model + + :raises: ValueError + """ + if tagname is not None and tagvalue is not None: + model = Model(ws, name=env.model_name, tags=[[tagname, tagvalue]]) + elif (tagname is None and tagvalue is not None) or ( + tagvalue is None and tagname is not None + ): + raise ValueError( + "model_tag_name and model_tag_value should both be supplied" + + "or excluded" # NOQA: E501 + ) + else: + model = Model(ws, name=env.model_name) + return model + + +def get_or_create_datastore( + datastorename: str, ws: Workspace, env: Env, input: bool = True +) -> Datastore: + """ + Obtains a datastore with matching name. Creates it if none exists. + + :param datastorename: Name of the datastore + :param ws: Current AML Workspace + :param env: Environment variables + :param input: Datastore points to the input container if + this is True(default) or the output storage container otherwise + + :returns: Datastore + + :raises: ValueError + """ + if datastorename is None: + raise ValueError("Datastore name is required.") + + containername = ( + env.scoring_datastore_input_container + if input + else env.scoring_datastore_output_container + ) + + if datastorename in ws.datastores: + + datastore = ws.datastores[datastorename] + + # the datastore is not registered but we have all details to register it + elif ( + env.scoring_datastore_access_key is not None + and containername is not None # NOQA: E501 + ): # NOQA:E501 + + datastore = Datastore.register_azure_blob_container( + workspace=ws, + datastore_name=datastorename, + account_name=env.scoring_datastore_storage_name, + account_key=env.scoring_datastore_access_key, + container_name=containername, + ) + else: + raise ValueError( + "No existing datastore named {} nor was enough information supplied to create one.".format( # NOQA: E501 + datastorename + ) + ) + + return datastore + + +def get_input_dataset(ws: Workspace, ds: Datastore, env: Env) -> Dataset: + """ + Gets an input dataset wrapped around an input data file. The input + data file is assumed to exist in the supplied datastore. + + + :param ws: AML Workspace + :param ds: Datastore containing the data file + :param env: Environment variables + + :returns: Input Dataset + """ + + scoringinputds = Dataset.Tabular.from_delimited_files( + path=DataPath(ds, env.scoring_datastore_input_filename) + ) + + scoringinputds = scoringinputds.register( + ws, + name=env.scoring_dataset_name, + tags={"purpose": "scoring input", "format": "csv"}, + create_new_version=True, + ).as_named_input(env.scoring_dataset_name) + + return scoringinputds + + +def get_fallback_input_dataset(ws: Workspace, env: Env) -> Dataset: + """ + Called when an input datastore does not exist or no input data file exists + at that location. Create a sample dataset using the diabetes dataset from + scikit-learn. Useful when debugging this code in the absence of the input + data location Azure blob. + + + :param ws: AML Workspace + :param env: Environment Variables + + :returns: Fallback input dataset + + :raises: FileNotFoundError + """ + # This call creates an example CSV from sklearn sample data. If you + # have already bootstrapped your project, you can comment this line + # out and use your own CSV. + create_sample_data_csv( + file_name=env.scoring_datastore_input_filename, for_scoring=True + ) + + if not os.path.exists(env.scoring_datastore_input_filename): + error_message = ( + "Could not find CSV dataset for scoring at {}. " + + "No alternate data store location was provided either.".format( + env.scoring_datastore_input_filename + ) # NOQA: E501 + ) + + raise FileNotFoundError(error_message) + + # upload the input data to the workspace default datastore + default_datastore = ws.get_default_datastore() + scoreinputdataref = default_datastore.upload_files( + [env.scoring_datastore_input_filename], + target_path="scoringinput", + overwrite=False, + ) + + scoringinputds = ( + Dataset.Tabular.from_delimited_files(scoreinputdataref) + .register(ws, env.scoring_dataset_name, create_new_version=True) + .as_named_input(env.scoring_dataset_name) + ) + + return scoringinputds + + +def get_output_location( + ws: Workspace, env: Env, outputdatastore: Datastore = None +) -> PipelineData: + """ + Returns a Datastore wrapped as a PipelineData instance suitable + for passing into a pipeline step. Represents the location where + the scoring output should be written. Uses the default workspace + blob store if no output datastore is supplied. + + + :param ws: AML Workspace + :param env: Environment Variables + :param outputdatastore: AML Datastore, optional, default is None + + :returns: PipelineData wrapping the output datastore + """ + + if outputdatastore is None: + output_loc = PipelineData( + name="defaultoutput", datastore=ws.get_default_datastore() + ) + else: + output_loc = PipelineData( + name=outputdatastore.name, datastore=outputdatastore + ) # NOQA: E501 + + return output_loc + + +def get_inputds_outputloc( + ws: Workspace, env: Env +) -> Tuple[Dataset, PipelineData]: # NOQA: E501 + """ + Prepare the input and output for the scoring step. Input is a tabular + dataset wrapped around the scoring data. Output is PipelineData + representing a location to write the scores down. + + :param ws: AML Workspace + :param env: Environment Variables + + :returns: Input dataset and output location + """ + + if env.scoring_datastore_storage_name is None: + # fall back to default + scoringinputds = get_fallback_input_dataset(ws, env) + output_loc = get_output_location(ws, env) + else: + inputdatastore = get_or_create_datastore( + "{}_in".format(env.scoring_datastore_storage_name), ws, env + ) + outputdatastore = get_or_create_datastore( + "{}_out".format(env.scoring_datastore_storage_name), + ws, + env, + input=False, # NOQA: E501 + ) + scoringinputds = get_input_dataset(ws, inputdatastore, env) + output_loc = get_output_location(ws, env, outputdatastore) + + return (scoringinputds, output_loc) + + +def get_run_configs( + ws: Workspace, computetarget: ComputeTarget, env: Env +) -> Tuple[ParallelRunConfig, RunConfiguration]: + """ + Creates the necessary run configurations required by the + pipeline to enable parallelized scoring. + + :param ws: AML Workspace + :param computetarget: AML Compute target + :param env: Environment Variables + + :returns: Tuple[Scoring Run configuration, Score copy run configuration] + """ + + # get a conda environment for scoring + environment = get_environment( + ws, + env.aml_env_name_scoring, + conda_dependencies_file=env.aml_env_score_conda_dep_file, + enable_docker=True, + use_gpu=env.use_gpu_for_scoring, + create_new=env.rebuild_env_scoring, + ) + + score_run_config = ParallelRunConfig( + entry_script=env.batchscore_script_path, + source_directory=env.sources_directory_train, + error_threshold=10, + output_action="append_row", + compute_target=computetarget, + node_count=env.max_nodes_scoring, + environment=environment, + run_invocation_timeout=300, + ) + + copy_run_config = RunConfiguration() + copy_run_config.environment = get_environment( + ws, + env.aml_env_name_score_copy, + conda_dependencies_file=env.aml_env_scorecopy_conda_dep_file, + enable_docker=True, + use_gpu=env.use_gpu_for_scoring, + create_new=env.rebuild_env_scoring, + ) + return (score_run_config, copy_run_config) + + +def get_scoring_pipeline( + model: Model, + scoring_dataset: Dataset, + output_loc: PipelineData, + score_run_config: ParallelRunConfig, + copy_run_config: RunConfiguration, + computetarget: ComputeTarget, + ws: Workspace, + env: Env, +) -> Pipeline: + """ + Creates the scoring pipeline. + + :param model: The model to use for scoring + :param scoring_dataset: Data to score + :param output_loc: Location to save the scoring results + :param score_run_config: Parallel Run configuration to support + parallelized scoring + :param copy_run_config: Script Run configuration to support + score copying + :param computetarget: AML Compute target + :param ws: AML Workspace + :param env: Environment Variables + + :returns: Scoring pipeline instance + """ + # To help filter the model make the model name, model version and a + # tag/value pair bindable parameters so that they can be passed to + # the pipeline when invoked either over REST or via the AML SDK. + model_name_param = PipelineParameter( + "model_name", default_value=env.model_name + ) # NOQA: E501 + model_tag_name_param = PipelineParameter( + "model_tag_name", default_value=" " + ) # NOQA: E501 + model_tag_value_param = PipelineParameter( + "model_tag_value", default_value=" " + ) # NOQA: E501 + + scoring_step = ParallelRunStep( + name="scoringstep", + inputs=[scoring_dataset], + output=output_loc, + arguments=[ + "--model_name", + model_name_param, + "--model_tag_name", + model_tag_name_param, + "--model_tag_value", + model_tag_value_param, + ], + parallel_run_config=score_run_config, + allow_reuse=False, + ) + + copying_step = PythonScriptStep( + name="scorecopystep", + script_name=env.batchscore_copy_script_path, + source_directory=env.sources_directory_train, + arguments=[ + "--output_path", + output_loc, + "--scoring_output_filename", + env.scoring_datastore_output_filename + if env.scoring_datastore_output_filename is not None + else "", + "--scoring_datastore", + env.scoring_datastore_storage_name + if env.scoring_datastore_storage_name is not None + else "", + "--score_container", + env.scoring_datastore_output_container + if env.scoring_datastore_output_container is not None + else "", + "--scoring_datastore_key", + env.scoring_datastore_access_key + if env.scoring_datastore_access_key is not None + else "", + ], + inputs=[output_loc], + allow_reuse=False, + compute_target=computetarget, + runconfig=copy_run_config, + ) + return Pipeline(workspace=ws, steps=[scoring_step, copying_step]) + + +def build_batchscore_pipeline(): + """ + Main method that builds and publishes a scoring pipeline. + """ + + try: + env = Env() + + args = parse_args() + + # Get Azure machine learning workspace + aml_workspace = Workspace.get( + name=env.workspace_name, + subscription_id=env.subscription_id, + resource_group=env.resource_group, + ) + + # Get Azure machine learning cluster + aml_compute_score = get_compute( + aml_workspace, + env.compute_name_scoring, + env.vm_size_scoring, + for_batch_scoring=True, + ) + + input_dataset, output_location = get_inputds_outputloc( + aml_workspace, env + ) # NOQA: E501 + + scoring_runconfig, score_copy_runconfig = get_run_configs( + aml_workspace, aml_compute_score, env + ) + + trained_model = get_model( + aml_workspace, env, args.model_tag_name, args.model_tag_value + ) + + scoring_pipeline = get_scoring_pipeline( + trained_model, + input_dataset, + output_location, + scoring_runconfig, + score_copy_runconfig, + aml_compute_score, + aml_workspace, + env, + ) + + published_pipeline = scoring_pipeline.publish( + name=env.scoring_pipeline_name, + description="Diabetes Batch Scoring Pipeline", + ) + pipeline_id_string = "##vso[task.setvariable variable=pipeline_id;isOutput=true]{}".format( # NOQA: E501 + published_pipeline.id + ) + print(pipeline_id_string) + except Exception as e: + print(e) + exit(1) + + +if __name__ == "__main__": + build_batchscore_pipeline() diff --git a/ml_service/pipelines/diabetes_regression_build_train_pipeline.py b/ml_service/pipelines/diabetes_regression_build_train_pipeline.py index dfe3f5b3..03937186 100644 --- a/ml_service/pipelines/diabetes_regression_build_train_pipeline.py +++ b/ml_service/pipelines/diabetes_regression_build_train_pipeline.py @@ -16,81 +16,90 @@ def main(): aml_workspace = Workspace.get( name=e.workspace_name, subscription_id=e.subscription_id, - resource_group=e.resource_group + resource_group=e.resource_group, ) print("get_workspace:") print(aml_workspace) # Get Azure machine learning cluster - aml_compute = get_compute( - aml_workspace, - e.compute_name, - e.vm_size) + aml_compute = get_compute(aml_workspace, e.compute_name, e.vm_size) if aml_compute is not None: print("aml_compute:") print(aml_compute) # Create a reusable Azure ML environment environment = get_environment( - aml_workspace, e.aml_env_name, create_new=e.rebuild_env) # + aml_workspace, + e.aml_env_name, + conda_dependencies_file=e.aml_env_train_conda_dep_file, + create_new=e.rebuild_env, + ) # run_config = RunConfiguration() run_config.environment = environment - if (e.datastore_name): + if e.datastore_name: datastore_name = e.datastore_name else: datastore_name = aml_workspace.get_default_datastore().name - run_config.environment.environment_variables["DATASTORE_NAME"] = datastore_name # NOQA: E501 + run_config.environment.environment_variables[ + "DATASTORE_NAME" + ] = datastore_name # NOQA: E501 - model_name_param = PipelineParameter( - name="model_name", default_value=e.model_name) + model_name_param = PipelineParameter(name="model_name", default_value=e.model_name) # NOQA: E501 dataset_version_param = PipelineParameter( - name="dataset_version", default_value=e.dataset_version) + name="dataset_version", default_value=e.dataset_version + ) data_file_path_param = PipelineParameter( - name="data_file_path", default_value="none") - caller_run_id_param = PipelineParameter( - name="caller_run_id", default_value="none") + name="data_file_path", default_value="none" + ) + caller_run_id_param = PipelineParameter(name="caller_run_id", default_value="none") # NOQA: E501 # Get dataset name dataset_name = e.dataset_name # Check to see if dataset exists - if (dataset_name not in aml_workspace.datasets): + if dataset_name not in aml_workspace.datasets: # This call creates an example CSV from sklearn sample data. If you # have already bootstrapped your project, you can comment this line # out and use your own CSV. create_sample_data_csv() # Use a CSV to read in the data set. - file_name = 'diabetes.csv' + file_name = "diabetes.csv" - if (not os.path.exists(file_name)): - raise Exception("Could not find CSV dataset at \"%s\". If you have bootstrapped your project, you will need to provide a CSV." % file_name) # NOQA: E501 + if not os.path.exists(file_name): + raise Exception( + 'Could not find CSV dataset at "%s". If you have bootstrapped your project, you will need to provide a CSV.' # NOQA: E501 + % file_name + ) # NOQA: E501 # Upload file to default datastore in workspace datatstore = Datastore.get(aml_workspace, datastore_name) - target_path = 'training-data/' + target_path = "training-data/" datatstore.upload_files( files=[file_name], target_path=target_path, overwrite=True, - show_progress=False) + show_progress=False, + ) # Register dataset path_on_datastore = os.path.join(target_path, file_name) dataset = Dataset.Tabular.from_delimited_files( - path=(datatstore, path_on_datastore)) + path=(datatstore, path_on_datastore) + ) dataset = dataset.register( workspace=aml_workspace, name=dataset_name, - description='diabetes training data', - tags={'format': 'CSV'}, - create_new_version=True) + description="diabetes training data", + tags={"format": "CSV"}, + create_new_version=True, + ) # Create a PipelineData to pass data between steps pipeline_data = PipelineData( - 'pipeline_data', - datastore=aml_workspace.get_default_datastore()) + "pipeline_data", datastore=aml_workspace.get_default_datastore() + ) train_step = PythonScriptStep( name="Train Model", @@ -99,12 +108,18 @@ def main(): source_directory=e.sources_directory_train, outputs=[pipeline_data], arguments=[ - "--model_name", model_name_param, - "--step_output", pipeline_data, - "--dataset_version", dataset_version_param, - "--data_file_path", data_file_path_param, - "--caller_run_id", caller_run_id_param, - "--dataset_name", dataset_name, + "--model_name", + model_name_param, + "--step_output", + pipeline_data, + "--dataset_version", + dataset_version_param, + "--data_file_path", + data_file_path_param, + "--caller_run_id", + caller_run_id_param, + "--dataset_name", + dataset_name, ], runconfig=run_config, allow_reuse=True, @@ -117,8 +132,10 @@ def main(): compute_target=aml_compute, source_directory=e.sources_directory_train, arguments=[ - "--model_name", model_name_param, - "--allow_run_cancel", e.allow_run_cancel, + "--model_name", + model_name_param, + "--allow_run_cancel", + e.allow_run_cancel, ], runconfig=run_config, allow_reuse=False, @@ -131,16 +148,13 @@ def main(): compute_target=aml_compute, source_directory=e.sources_directory_train, inputs=[pipeline_data], - arguments=[ - "--model_name", model_name_param, - "--step_input", pipeline_data, - ], + arguments=["--model_name", model_name_param, "--step_input", pipeline_data, ], # NOQA: E501 runconfig=run_config, allow_reuse=False, ) print("Step Register created") # Check run_evaluation flag to include or exclude evaluation step. - if ((e.run_evaluation).lower() == 'true'): + if (e.run_evaluation).lower() == "true": print("Include evaluation step before register step.") evaluate_step.run_after(train_step) register_step.run_after(evaluate_step) @@ -156,11 +170,11 @@ def main(): published_pipeline = train_pipeline.publish( name=e.pipeline_name, description="Model training/retraining pipeline", - version=e.build_id + version=e.build_id, ) - print(f'Published pipeline: {published_pipeline.name}') - print(f'for build {published_pipeline.version}') + print(f"Published pipeline: {published_pipeline.name}") + print(f"for build {published_pipeline.version}") -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/ml_service/pipelines/diabetes_regression_build_train_pipeline_with_r.py b/ml_service/pipelines/diabetes_regression_build_train_pipeline_with_r.py index b49ae53d..254f22eb 100644 --- a/ml_service/pipelines/diabetes_regression_build_train_pipeline_with_r.py +++ b/ml_service/pipelines/diabetes_regression_build_train_pipeline_with_r.py @@ -13,16 +13,13 @@ def main(): aml_workspace = Workspace.get( name=e.workspace_name, subscription_id=e.subscription_id, - resource_group=e.resource_group + resource_group=e.resource_group, ) print("get_workspace:") print(aml_workspace) # Get Azure machine learning cluster - aml_compute = get_compute( - aml_workspace, - e.compute_name, - e.vm_size) + aml_compute = get_compute(aml_workspace, e.compute_name, e.vm_size) if aml_compute is not None: print("aml_compute:") print(aml_compute) @@ -31,7 +28,11 @@ def main(): # Make sure to include `r-essentials' # in diabetes_regression/conda_dependencies.yml environment = get_environment( - aml_workspace, e.aml_env_name, create_new=e.rebuild_env) # NOQA: E501 + aml_workspace, + e.aml_env_name, + conda_dependencies_file=e.aml_env_train_conda_dep_file, + create_new=e.rebuild_env, + ) # NOQA: E501 run_config = RunConfiguration() run_config.environment = environment @@ -52,11 +53,11 @@ def main(): published_pipeline = train_pipeline.publish( name=e.pipeline_name, description="Model training/retraining pipeline", - version=e.build_id + version=e.build_id, ) - print(f'Published pipeline: {published_pipeline.name}') - print(f'for build {published_pipeline.version}') + print(f"Published pipeline: {published_pipeline.name}") + print(f"for build {published_pipeline.version}") -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/ml_service/pipelines/load_sample_data.py b/ml_service/pipelines/load_sample_data.py index 717fc7ab..304a8e7b 100644 --- a/ml_service/pipelines/load_sample_data.py +++ b/ml_service/pipelines/load_sample_data.py @@ -5,12 +5,14 @@ # Loads the diabetes sample data from sklearn and produces a csv file that can # be used by the build/train pipeline script. -def create_sample_data_csv(): +def create_sample_data_csv(file_name: str = "diabetes.csv", + for_scoring: bool = False): sample_data = load_diabetes() df = pd.DataFrame( data=sample_data.data, columns=sample_data.feature_names) - df['Y'] = sample_data.target + if not for_scoring: + df['Y'] = sample_data.target # Hard code to diabetes so we fail fast if the project has been # bootstrapped. - df.to_csv('diabetes.csv', index=False) + df.to_csv(file_name, index=False) diff --git a/ml_service/pipelines/run_parallel_batchscore_pipeline.py b/ml_service/pipelines/run_parallel_batchscore_pipeline.py new file mode 100644 index 00000000..ec6cebae --- /dev/null +++ b/ml_service/pipelines/run_parallel_batchscore_pipeline.py @@ -0,0 +1,133 @@ +""" +Copyright (C) Microsoft Corporation. All rights reserved.​ + ​ +Microsoft Corporation (“Microsoft”) grants you a nonexclusive, perpetual, +royalty-free right to use, copy, and modify the software code provided by us +("Software Code"). You may not sublicense the Software Code or any use of it +(except to your affiliates and to vendors to perform work on your behalf) +through distribution, network access, service agreement, lease, rental, or +otherwise. This license does not purport to express any claim of ownership over +data you may have shared with Microsoft in the creation of the Software Code. +Unless applicable law gives you more rights, Microsoft reserves all other +rights not expressly granted herein, whether by implication, estoppel or +otherwise. ​ + ​ +THE SOFTWARE CODE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +MICROSOFT OR ITS LICENSORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THE SOFTWARE CODE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +""" + +from azure.storage.blob import ContainerClient +from ml_service.util.env_variables import Env +from azureml.core import Experiment, Workspace +from azureml.pipeline.core import PublishedPipeline +import argparse + + +def parse_args(): + parser = argparse.ArgumentParser() + parser.add_argument("--pipeline_id", type=str, default=None) + return parser.parse_args() + + +def get_pipeline(pipeline_id, ws: Workspace, env: Env): + if pipeline_id is not None: + scoringpipeline = PublishedPipeline.get(ws, pipeline_id) + else: + pipelines = PublishedPipeline.list(ws) + scoringpipelinelist = [ + pl for pl in pipelines if pl.name == env.scoring_pipeline_name + ] # noqa E501 + + if scoringpipelinelist.count == 0: + raise Exception( + "No pipeline found matching name:{}".format(env.scoring_pipeline_name) # NOQA: E501 + ) + else: + # latest published + scoringpipeline = scoringpipelinelist[0] + + return scoringpipeline + + +def copy_output(step_id: str, env: Env): + accounturl = "https://{}.blob.core.windows.net".format( + env.scoring_datastore_storage_name + ) + + srcblobname = "azureml/{}/{}_out/parallel_run_step.txt".format( + step_id, env.scoring_datastore_storage_name + ) + + srcbloburl = "{}/{}/{}".format( + accounturl, env.scoring_datastore_output_container, srcblobname + ) + + containerclient = ContainerClient( + accounturl, + env.scoring_datastore_output_container, + env.scoring_datastore_access_key, + ) + srcblobproperties = containerclient.get_blob_client( + srcblobname + ).get_blob_properties() # noqa E501 + + destfolder = srcblobproperties.last_modified.date().isoformat() + filetime = ( + srcblobproperties.last_modified.time() + .isoformat("milliseconds") + .replace(":", "_") + .replace(".", "_") + ) # noqa E501 + destfilenameparts = env.scoring_datastore_output_filename.split(".") + destblobname = "{}/{}_{}.{}".format( + destfolder, destfilenameparts[0], filetime, destfilenameparts[1] + ) + + destblobclient = containerclient.get_blob_client(destblobname) + destblobclient.start_copy_from_url(srcbloburl) + + +def run_batchscore_pipeline(): + try: + env = Env() + + args = parse_args() + + aml_workspace = Workspace.get( + name=env.workspace_name, + subscription_id=env.subscription_id, + resource_group=env.resource_group, + ) + + scoringpipeline = get_pipeline(args.pipeline_id, aml_workspace, env) + + experiment = Experiment(workspace=aml_workspace, name=env.experiment_name) # NOQA: E501 + + run = experiment.submit( + scoringpipeline, + pipeline_parameters={ + "model_name": env.model_name, + "model_tag_name": " ", + "model_tag_value": " ", + }, + ) + + run.wait_for_completion(show_output=True) + + if run.get_status() == "Finished": + copy_output(list(run.get_steps())[0].id, env) + + except Exception as ex: + print("Error: {}".format(ex)) + + +if __name__ == "__main__": + run_batchscore_pipeline() diff --git a/ml_service/util/attach_compute.py b/ml_service/util/attach_compute.py index bcff58da..ad9668db 100644 --- a/ml_service/util/attach_compute.py +++ b/ml_service/util/attach_compute.py @@ -1,3 +1,4 @@ + from azureml.core import Workspace from azureml.core.compute import AmlCompute from azureml.core.compute import ComputeTarget @@ -5,38 +6,33 @@ from ml_service.util.env_variables import Env -def get_compute( - workspace: Workspace, - compute_name: str, - vm_size: str -): +def get_compute(workspace: Workspace, compute_name: str, vm_size: str, for_batch_scoring: bool = False): # NOQA E501 try: if compute_name in workspace.compute_targets: compute_target = workspace.compute_targets[compute_name] if compute_target and type(compute_target) is AmlCompute: - print('Found existing compute target ' + compute_name - + ' so using it.') + print("Found existing compute target " + compute_name + " so using it.") # NOQA else: e = Env() compute_config = AmlCompute.provisioning_configuration( vm_size=vm_size, - vm_priority=e.vm_priority, - min_nodes=e.min_nodes, - max_nodes=e.max_nodes, + vm_priority=e.vm_priority if not for_batch_scoring else e.vm_priority_scoring, # NOQA E501 + min_nodes=e.min_nodes if not for_batch_scoring else e.min_nodes_scoring, # NOQA E501 + max_nodes=e.max_nodes if not for_batch_scoring else e.max_nodes_scoring, # NOQA E501 idle_seconds_before_scaledown="300" # #Uncomment the below lines for VNet support # vnet_resourcegroup_name=vnet_resourcegroup_name, # vnet_name=vnet_name, # subnet_name=subnet_name ) - compute_target = ComputeTarget.create(workspace, compute_name, - compute_config) + compute_target = ComputeTarget.create( + workspace, compute_name, compute_config + ) compute_target.wait_for_completion( - show_output=True, - min_node_count=None, - timeout_in_minutes=10) + show_output=True, min_node_count=None, timeout_in_minutes=10 + ) return compute_target - except ComputeTargetException as e: - print(e) - print('An error occurred trying to provision compute.') + except ComputeTargetException as ex: + print(ex) + print("An error occurred trying to provision compute.") exit(1) diff --git a/ml_service/util/env_variables.py b/ml_service/util/env_variables.py index 747df5ec..753c152d 100644 --- a/ml_service/util/env_variables.py +++ b/ml_service/util/env_variables.py @@ -11,6 +11,7 @@ class Env: """Loads all environment variables into a predefined set of properties """ + # to load .env file into environment variables for local execution load_dotenv() workspace_name: Optional[str] = os.environ.get("WORKSPACE_NAME") @@ -21,23 +22,27 @@ class Env: app_secret: Optional[str] = os.environ.get("SP_APP_SECRET") vm_size: Optional[str] = os.environ.get("AML_COMPUTE_CLUSTER_CPU_SKU") compute_name: Optional[str] = os.environ.get("AML_COMPUTE_CLUSTER_NAME") - vm_priority: Optional[str] = os.environ.get("AML_CLUSTER_PRIORITY", - 'lowpriority') + vm_priority: Optional[str] = os.environ.get( + "AML_CLUSTER_PRIORITY", "lowpriority" + ) # NOQA: E501 min_nodes: int = int(os.environ.get("AML_CLUSTER_MIN_NODES", 0)) max_nodes: int = int(os.environ.get("AML_CLUSTER_MAX_NODES", 4)) build_id: Optional[str] = os.environ.get("BUILD_BUILDID") pipeline_name: Optional[str] = os.environ.get("TRAINING_PIPELINE_NAME") sources_directory_train: Optional[str] = os.environ.get( - "SOURCES_DIR_TRAIN") + "SOURCES_DIR_TRAIN" + ) # NOQA: E501 train_script_path: Optional[str] = os.environ.get("TRAIN_SCRIPT_PATH") evaluate_script_path: Optional[str] = os.environ.get( - "EVALUATE_SCRIPT_PATH") + "EVALUATE_SCRIPT_PATH" + ) # NOQA: E501 register_script_path: Optional[str] = os.environ.get( - "REGISTER_SCRIPT_PATH") + "REGISTER_SCRIPT_PATH" + ) # NOQA: E501 model_name: Optional[str] = os.environ.get("MODEL_NAME") experiment_name: Optional[str] = os.environ.get("EXPERIMENT_NAME") - model_version: Optional[str] = os.environ.get('MODEL_VERSION') - image_name: Optional[str] = os.environ.get('IMAGE_NAME') + model_version: Optional[str] = os.environ.get("MODEL_VERSION") + image_name: Optional[str] = os.environ.get("IMAGE_NAME") db_cluster_id: Optional[str] = os.environ.get("DB_CLUSTER_ID") score_script: Optional[str] = os.environ.get("SCORE_SCRIPT") build_uri: Optional[str] = os.environ.get("BUILD_URI") @@ -45,8 +50,77 @@ class Env: datastore_name: Optional[str] = os.environ.get("DATASTORE_NAME") dataset_version: Optional[str] = os.environ.get("DATASET_VERSION") run_evaluation: Optional[str] = os.environ.get("RUN_EVALUATION", "true") - allow_run_cancel: Optional[str] = os.environ.get("ALLOW_RUN_CANCEL", - "true") + allow_run_cancel: Optional[str] = os.environ.get( + "ALLOW_RUN_CANCEL", "true" + ) # NOQA: E501 aml_env_name: Optional[str] = os.environ.get("AML_ENV_NAME") + aml_env_train_conda_dep_file: Optional[str] = os.environ.get( + "AML_ENV_TRAIN_CONDA_DEP_FILE", "conda_dependencies.yml" + ) rebuild_env: Optional[bool] = os.environ.get( - "AML_REBUILD_ENVIRONMENT", "false").lower().strip() == "true" + "AML_REBUILD_ENVIRONMENT", "false" + ).lower().strip() == "true" + + use_gpu_for_scoring: Optional[bool] = os.environ.get( + "USE_GPU_FOR_SCORING", "false" + ).lower().strip() == "true" + aml_env_score_conda_dep_file: Optional[str] = os.environ.get( + "AML_ENV_SCORE_CONDA_DEP_FILE", "conda_dependencies_scoring.yml" + ) + aml_env_scorecopy_conda_dep_file: Optional[str] = os.environ.get( + "AML_ENV_SCORECOPY_CONDA_DEP_FILE", "conda_dependencies_scorecopy.yml" + ) + vm_size_scoring: Optional[str] = os.environ.get( + "AML_COMPUTE_CLUSTER_CPU_SKU_SCORING" + ) + compute_name_scoring: Optional[str] = os.environ.get( + "AML_COMPUTE_CLUSTER_NAME_SCORING" + ) + vm_priority_scoring: Optional[str] = os.environ.get( + "AML_CLUSTER_PRIORITY_SCORING", "lowpriority" + ) + min_nodes_scoring: int = int( + os.environ.get("AML_CLUSTER_MIN_NODES_SCORING", 0) + ) # NOQA: E501 + max_nodes_scoring: int = int( + os.environ.get("AML_CLUSTER_MAX_NODES_SCORING", 4) + ) # NOQA: E501 + rebuild_env_scoring: Optional[bool] = os.environ.get( + "AML_REBUILD_ENVIRONMENT_SCORING", "false" + ).lower().strip() == "true" + scoring_datastore_storage_name: Optional[str] = os.environ.get( + "SCORING_DATASTORE_STORAGE_NAME" + ) + scoring_datastore_access_key: Optional[str] = os.environ.get( + "SCORING_DATASTORE_ACCESS_KEY" + ) + scoring_datastore_input_container: Optional[str] = os.environ.get( + "SCORING_DATASTORE_INPUT_CONTAINER" + ) + scoring_datastore_input_filename: Optional[str] = os.environ.get( + "SCORING_DATASTORE_INPUT_FILENAME" + ) + scoring_datastore_output_container: Optional[str] = os.environ.get( + "SCORING_DATASTORE_OUTPUT_CONTAINER" + ) + scoring_datastore_output_filename: Optional[str] = os.environ.get( + "SCORING_DATASTORE_OUTPUT_FILENAME" + ) + scoring_dataset_name: Optional[str] = os.environ.get( + "SCORING_DATASET_NAME" + ) # NOQA: E501 + scoring_pipeline_name: Optional[str] = os.environ.get( + "SCORING_PIPELINE_NAME" + ) # NOQA: E501 + aml_env_name_scoring: Optional[str] = os.environ.get( + "AML_ENV_NAME_SCORING" + ) # NOQA: E501 + aml_env_name_score_copy: Optional[str] = os.environ.get( + "AML_ENV_NAME_SCORE_COPY" + ) # NOQA: E501 + batchscore_script_path: Optional[str] = os.environ.get( + "BATCHSCORE_SCRIPT_PATH" + ) # NOQA: E501 + batchscore_copy_script_path: Optional[str] = os.environ.get( + "BATCHSCORE_COPY_SCRIPT_PATH" + ) # NOQA: E501 diff --git a/ml_service/util/manage_environment.py b/ml_service/util/manage_environment.py index 43749f3f..54c5a72f 100644 --- a/ml_service/util/manage_environment.py +++ b/ml_service/util/manage_environment.py @@ -1,12 +1,17 @@ + +import os from azureml.core import Workspace, Environment from ml_service.util.env_variables import Env -import os +from azureml.core.runconfig import DEFAULT_CPU_IMAGE, DEFAULT_GPU_IMAGE def get_environment( workspace: Workspace, environment_name: str, - create_new: bool = False + conda_dependencies_file: str, + create_new: bool = False, + enable_docker: bool = None, + use_gpu: bool = False ): try: e = Env() @@ -17,8 +22,14 @@ def get_environment( restored_environment = environments[environment_name] if restored_environment is None or create_new: - new_env = Environment.from_conda_specification(environment_name, os.path.join(e.sources_directory_train, "conda_dependencies.yml")) # NOQA: E501 + new_env = Environment.from_conda_specification( + environment_name, + os.path.join(e.sources_directory_train, conda_dependencies_file), # NOQA: E501 + ) # NOQA: E501 restored_environment = new_env + if enable_docker is not None: + restored_environment.docker.enabled = enable_docker + restored_environment.docker.base_image = DEFAULT_GPU_IMAGE if use_gpu else DEFAULT_CPU_IMAGE # NOQA: E501 restored_environment.register(workspace) if restored_environment is not None: From b21a46e02560db8d306cdfa8efa204d2b0106c11 Mon Sep 17 00:00:00 2001 From: Jenny So Date: Fri, 26 Jun 2020 11:24:46 -0700 Subject: [PATCH 08/29] Convert to new split pipeline approach for CI/CD (#278) * new split pipelines * specify channel * fix pip jq install * fixes and cleanup * add new lines * add docs and clean up naming * use shared image * rename * strip quotes from location * fix env var * remove succeeded condition * remove extra deploy yml * no pr trigger * remove unused template * remove unused pipeline * add more docs and add to bootstrap * linting * fix model package to show logs * Squashed commit of the following: commit 01af8da39c77787a3a533c3cb506cb9b83ec6e43 Author: j-so Date: Fri Jun 12 14:15:35 2020 -0700 fixed failure handling commit 1e6f9068451f24927e4624b22ec9da8b1e9c6191 Author: j-so Date: Fri Jun 12 14:03:09 2020 -0700 test failed conda dep commit a8030d75ec0f2822116554e08eb29a1f6be2da67 Author: j-so Date: Fri Jun 12 13:55:00 2020 -0700 test package fail commit c7845aaca16d98e0b560619b1cf13a11bc7e8eb0 Author: j-so Date: Fri Jun 12 13:46:27 2020 -0700 fail on deploy error' * Squashed commit of the following: commit 5af6eeb242dfbbeeb1782fdabbe3d3eec1c7dd02 Author: j-so Date: Mon Jun 15 18:31:15 2020 -0700 fix bootstrap commit f61e103ed08cdfbaf1dca555f14b286ea28bc003 Merge: 2796b40 08bb6f4 Author: j-so Date: Mon Jun 15 18:30:21 2020 -0700 Merge branch 'master' into jenns/splitpipeline_docfix commit 2796b4002487e058a92f68ce09fbb068b5c8e114 Author: j-so Date: Mon Jun 15 18:30:00 2020 -0700 remove old pipeline commit 08bb6f4a26d3db7ee998a45da62825c47411aec1 Author: David Tesar Date: Mon Jun 15 14:09:12 2020 -0700 Simplify docs flow (#297) commit cd762ecaa9dd1914d4e72dc514d0ce7dad66a58d Author: jotaylo Date: Mon Jun 15 12:28:23 2020 -0700 Move instruction to install AML extension to Azure Devops setup instructions (#298) * remove need for model build id * fix batch scoring * use model version for batch scoring * linting * Squashed commit of the following: commit 493ed3e64f89483005eade0b553db21a98f6f1bb Author: j-so Date: Mon Jun 22 16:42:07 2020 -0700 mark as output commit 1ca7a592ad24ee0fe1e7ba28b41f97431f07039d Author: j-so Date: Mon Jun 22 16:12:10 2020 -0700 fix import commit 743e301081a439472b3bc778b22df3764b16d945 Author: j-so Date: Mon Jun 22 15:59:43 2020 -0700 more fixes commit 44abcac49d1b593da0f87bf8553638887d98f63c Author: j-so Date: Mon Jun 22 15:50:49 2020 -0700 fix batch scoring * improve the docs * fix secret access * pass to cli task and impove naming --- .../diabetes_regression-batchscoring-ci.yml | 35 +++- .pipelines/diabetes_regression-cd.yml | 161 ++++++++++++++++++ .pipelines/diabetes_regression-ci-image.yml | 15 +- .pipelines/diabetes_regression-ci.yml | 119 +------------ ...ression-get-model-id-artifact-template.yml | 48 ++++++ ..._regression-get-model-version-template.yml | 15 -- ...etes_regression-package-model-template.yml | 42 +++++ ...ession-publish-model-artifact-template.yml | 29 ++++ ...diabetes_regression-variables-template.yml | 4 - bootstrap/bootstrap.py | 4 +- diabetes_regression/ci_dependencies.yml | 1 + .../evaluate/evaluate_model.py | 11 +- .../scoring/parallel_batchscore.py | 30 +++- diabetes_regression/util/model_helper.py | 67 +++----- docs/getting_started.md | 95 +++++++---- docs/images/model-deploy-artifact-logs.PNG | Bin 0 -> 104171 bytes docs/images/model-deploy-configure.png | Bin 0 -> 39099 bytes docs/images/model-deploy-result.png | Bin 0 -> 19960 bytes .../images/model-train-register-artifacts.png | Bin 0 -> 8827 bytes docs/images/model-train-register.png | Bin 0 -> 15690 bytes ...sion_build_parallel_batchscore_pipeline.py | 64 +------ ...abetes_regression_verify_train_pipeline.py | 10 +- .../run_parallel_batchscore_pipeline.py | 1 + 23 files changed, 456 insertions(+), 295 deletions(-) create mode 100644 .pipelines/diabetes_regression-cd.yml create mode 100644 .pipelines/diabetes_regression-get-model-id-artifact-template.yml delete mode 100644 .pipelines/diabetes_regression-get-model-version-template.yml create mode 100644 .pipelines/diabetes_regression-package-model-template.yml create mode 100644 .pipelines/diabetes_regression-publish-model-artifact-template.yml create mode 100644 docs/images/model-deploy-artifact-logs.PNG create mode 100644 docs/images/model-deploy-configure.png create mode 100644 docs/images/model-deploy-result.png create mode 100644 docs/images/model-train-register-artifacts.png create mode 100644 docs/images/model-train-register.png diff --git a/.pipelines/diabetes_regression-batchscoring-ci.yml b/.pipelines/diabetes_regression-batchscoring-ci.yml index 79a7f46f..1392fddb 100644 --- a/.pipelines/diabetes_regression-batchscoring-ci.yml +++ b/.pipelines/diabetes_regression-batchscoring-ci.yml @@ -1,12 +1,27 @@ # Continuous Integration (CI) pipeline that orchestrates the batch scoring of the diabetes_regression model. +# Runtime parameters to select artifacts +parameters: +- name : artifactBuildId + displayName: Model Train CI Build ID. Default is 'latest'. + type: string + default: latest + +pr: none + +# Trigger this pipeline on model-train pipeline completion resources: containers: - container: mlops image: mcr.microsoft.com/mlops/python:latest - + pipelines: + - pipeline: model-train-ci + source: Model-Train-Register-CI # Name of the triggering pipeline + trigger: + branches: + include: + - master -pr: none trigger: branches: include: @@ -34,7 +49,13 @@ stages: timeoutInMinutes: 0 steps: - template: code-quality-template.yml + - template: diabetes_regression-get-model-id-artifact-template.yml + parameters: + projectId: '$(resources.pipeline.model-train-ci.projectID)' + pipelineId: '$(resources.pipeline.model-train-ci.pipelineID)' + artifactBuildId: ${{ parameters.artifactBuildId }} - task: AzureCLI@1 + displayName: "Publish Batch Scoring Pipeline" name: publish_batchscore inputs: azureSubscription: '$(WORKSPACE_SVC_CONNECTION)' @@ -45,14 +66,18 @@ stages: export SUBSCRIPTION_ID=$(az account show --query id -o tsv) # Invoke the Python building and publishing a training pipeline python -m ml_service.pipelines.diabetes_regression_build_parallel_batchscore_pipeline - + env: + SCORING_DATASTORE_ACCESS_KEY: $(SCORING_DATASTORE_ACCESS_KEY) + - job: "Run_Batch_Score_Pipeline" displayName: "Run Batch Scoring Pipeline" - dependsOn: "Build_Batch_Scoring_Pipeline" + dependsOn: ["Build_Batch_Scoring_Pipeline"] timeoutInMinutes: 240 pool: server variables: pipeline_id: $[ dependencies.Build_Batch_Scoring_Pipeline.outputs['publish_batchscore.pipeline_id']] + model_name: $[ dependencies.Build_Batch_Scoring_Pipeline.outputs['get_model.MODEL_NAME']] + model_version: $[ dependencies.Build_Batch_Scoring_Pipeline.outputs['get_model.MODEL_VERSION']] steps: - task: ms-air-aiagility.vss-services-azureml.azureml-restApi-task.MLPublishedPipelineRestAPITask@0 displayName: 'Invoke Batch Scoring pipeline' @@ -60,5 +85,5 @@ stages: azureSubscription: '$(WORKSPACE_SVC_CONNECTION)' PipelineId: '$(pipeline_id)' ExperimentName: '$(EXPERIMENT_NAME)' - PipelineParameters: '"ParameterAssignments": {"model_name": "$(MODEL_NAME)"}' + PipelineParameters: '"ParameterAssignments": {"model_name": "$(model_name)", "model_version": "$(model_version)"}' \ No newline at end of file diff --git a/.pipelines/diabetes_regression-cd.yml b/.pipelines/diabetes_regression-cd.yml new file mode 100644 index 00000000..16bc4724 --- /dev/null +++ b/.pipelines/diabetes_regression-cd.yml @@ -0,0 +1,161 @@ +# Continuous Integration (CI) pipeline that orchestrates the deployment of the diabetes_regression model. + +# Runtime parameters to select artifacts +parameters: +- name : artifactBuildId + displayName: Model Train CI Build ID. Default is 'latest'. + type: string + default: latest + +pr: none + +# Trigger this pipeline on model-train pipeline completion +trigger: none +resources: + containers: + - container: mlops + image: mcr.microsoft.com/mlops/python:latest + pipelines: + - pipeline: model-train-ci + source: Model-Train-Register-CI # Name of the triggering pipeline + trigger: + branches: + include: + - master + +variables: +- template: diabetes_regression-variables-template.yml +- group: devopsforai-aml-vg + +stages: +- stage: 'Deploy_ACI' + displayName: 'Deploy to ACI' + condition: variables['ACI_DEPLOYMENT_NAME'] + jobs: + - job: "Deploy_ACI" + displayName: "Deploy to ACI" + container: mlops + timeoutInMinutes: 0 + steps: + - download: none + - template: diabetes_regression-get-model-id-artifact-template.yml + parameters: + projectId: '$(resources.pipeline.model-train-ci.projectID)' + pipelineId: '$(resources.pipeline.model-train-ci.pipelineID)' + artifactBuildId: ${{ parameters.artifactBuildId }} + - task: AzureCLI@1 + displayName: 'Install AzureML CLI' + inputs: + azureSubscription: '$(WORKSPACE_SVC_CONNECTION)' + scriptLocation: inlineScript + workingDirectory: $(Build.SourcesDirectory) + inlineScript: 'az extension add -n azure-cli-ml' + - task: AzureCLI@1 + displayName: "Deploy to ACI (CLI)" + inputs: + azureSubscription: '$(WORKSPACE_SVC_CONNECTION)' + scriptLocation: inlineScript + workingDirectory: $(Build.SourcesDirectory)/$(SOURCES_DIR_TRAIN)/scoring + inlineScript: | + set -e # fail on error + + az ml model deploy --name $(ACI_DEPLOYMENT_NAME) --model '$(MODEL_NAME):$(MODEL_VERSION)' \ + --ic inference_config.yml \ + --dc deployment_config_aci.yml \ + -g $(RESOURCE_GROUP) --workspace-name $(WORKSPACE_NAME) \ + --overwrite -v + - task: AzureCLI@1 + displayName: 'Smoke test' + inputs: + azureSubscription: '$(WORKSPACE_SVC_CONNECTION)' + scriptLocation: inlineScript + inlineScript: | + set -e # fail on error + export SUBSCRIPTION_ID=$(az account show --query id -o tsv) + python -m ml_service.util.smoke_test_scoring_service --type ACI --service "$(ACI_DEPLOYMENT_NAME)" + +- stage: 'Deploy_AKS' + displayName: 'Deploy to AKS' + dependsOn: Deploy_ACI + condition: and(succeeded(), variables['AKS_DEPLOYMENT_NAME']) + jobs: + - job: "Deploy_AKS" + displayName: "Deploy to AKS" + container: mlops + timeoutInMinutes: 0 + steps: + - template: diabetes_regression-get-model-id-artifact-template.yml + parameters: + projectId: '$(resources.pipeline.model-train-ci.projectID)' + pipelineId: '$(resources.pipeline.model-train-ci.pipelineID)' + artifactBuildId: ${{ parameters.artifactBuildId }} + - task: AzureCLI@1 + displayName: 'Install AzureML CLI' + inputs: + azureSubscription: '$(WORKSPACE_SVC_CONNECTION)' + scriptLocation: inlineScript + workingDirectory: $(Build.SourcesDirectory) + inlineScript: 'az extension add -n azure-cli-ml' + - task: AzureCLI@1 + displayName: "Deploy to AKS (CLI)" + inputs: + azureSubscription: '$(WORKSPACE_SVC_CONNECTION)' + scriptLocation: inlineScript + workingDirectory: $(Build.SourcesDirectory)/$(SOURCES_DIR_TRAIN)/scoring + inlineScript: | + set -e # fail on error + + az ml model deploy --name $(AKS_DEPLOYMENT_NAME) --model '$(MODEL_NAME):$(MODEL_VERSION)' \ + --compute-target $(AKS_COMPUTE_NAME) \ + --ic inference_config.yml \ + --dc deployment_config_aks.yml \ + -g $(RESOURCE_GROUP) --workspace-name $(WORKSPACE_NAME) \ + --overwrite -v + - task: AzureCLI@1 + displayName: 'Smoke test' + inputs: + azureSubscription: '$(WORKSPACE_SVC_CONNECTION)' + scriptLocation: inlineScript + inlineScript: | + set -e # fail on error + export SUBSCRIPTION_ID=$(az account show --query id -o tsv) + python -m ml_service.util.smoke_test_scoring_service --type AKS --service "$(AKS_DEPLOYMENT_NAME)" + +- stage: 'Deploy_Webapp' + displayName: 'Deploy to Webapp' + condition: variables['WEBAPP_DEPLOYMENT_NAME'] + jobs: + - job: "Deploy_Webapp" + displayName: "Package and deploy model" + container: mlops + timeoutInMinutes: 0 + steps: + - template: diabetes_regression-get-model-id-artifact-template.yml + parameters: + projectId: '$(resources.pipeline.model-train-ci.projectID)' + pipelineId: '$(resources.pipeline.model-train-ci.pipelineID)' + artifactBuildId: ${{ parameters.artifactBuildId }} + - template: diabetes_regression-package-model-template.yml + parameters: + modelId: $(MODEL_NAME):$(MODEL_VERSION) + scoringScriptPath: '$(Build.SourcesDirectory)/$(SOURCES_DIR_TRAIN)/scoring/score.py' + condaFilePath: '$(Build.SourcesDirectory)/$(SOURCES_DIR_TRAIN)/conda_dependencies.yml' + - script: echo $(IMAGE_LOCATION) >image_location.txt + displayName: "Write image location file" + - task: AzureWebAppContainer@1 + name: WebAppDeploy + displayName: 'Azure Web App on Container Deploy' + inputs: + azureSubscription: '$(AZURE_RM_SVC_CONNECTION)' + appName: '$(WEBAPP_DEPLOYMENT_NAME)' + resourceGroupName: '$(RESOURCE_GROUP)' + imageName: '$(IMAGE_LOCATION)' + - task: AzureCLI@1 + displayName: 'Smoke test' + inputs: + azureSubscription: '$(WORKSPACE_SVC_CONNECTION)' + scriptLocation: inlineScript + inlineScript: | + set -e # fail on error + export SUBSCRIPTION_ID=$(az account show --query id -o tsv) + python -m ml_service.util.smoke_test_scoring_service --type Webapp --service "$(WebAppDeploy.AppServiceApplicationUrl)/score" diff --git a/.pipelines/diabetes_regression-ci-image.yml b/.pipelines/diabetes_regression-ci-image.yml index 6282fd31..d7c925bf 100644 --- a/.pipelines/diabetes_regression-ci-image.yml +++ b/.pipelines/diabetes_regression-ci-image.yml @@ -30,14 +30,9 @@ variables: value: 'scoring/scoreB.py' steps: -- task: AzureCLI@1 - inputs: - azureSubscription: '$(WORKSPACE_SVC_CONNECTION)' - scriptLocation: inlineScript - workingDirectory: $(Build.SourcesDirectory) - inlineScript: | - set -e - export SUBSCRIPTION_ID=$(az account show --query id -o tsv) - python3 -m ml_service.util.create_scoring_image - displayName: 'Create Scoring Image' +- template: diabetes_regression-package-model-template.yml + parameters: + modelId: $(MODEL_NAME):$(MODEL_VERSION) + scoringScriptPath: '$(Build.SourcesDirectory)/$(SOURCES_DIR_TRAIN)/$(SCORE_SCRIPT)' + condaFilePath: '$(Build.SourcesDirectory)/$(SOURCES_DIR_TRAIN)/conda_dependencies.yml' diff --git a/.pipelines/diabetes_regression-ci.yml b/.pipelines/diabetes_regression-ci.yml index 56258d50..5a539af0 100644 --- a/.pipelines/diabetes_regression-ci.yml +++ b/.pipelines/diabetes_regression-ci.yml @@ -1,4 +1,4 @@ -# Continuous Integration (CI) pipeline that orchestrates the training, evaluation, registration, deployment, and testing of the diabetes_regression model. +# Continuous Integration (CI) pipeline that orchestrates the training, evaluation, and registration of the diabetes_regression model. resources: containers: @@ -27,7 +27,6 @@ pool: stages: - stage: 'Model_CI' displayName: 'Model CI' - condition: not(variables['MODEL_BUILD_ID']) jobs: - job: "Model_CI_Pipeline" displayName: "Model CI Pipeline" @@ -48,8 +47,8 @@ stages: displayName: 'Publish Azure Machine Learning Pipeline' - stage: 'Trigger_AML_Pipeline' - displayName: 'Train model' - condition: and(succeeded(), not(variables['MODEL_BUILD_ID'])) + displayName: 'Train and evaluate model' + condition: succeeded() variables: BUILD_URI: '$(SYSTEM.COLLECTIONURI)$(SYSTEM.TEAMPROJECT)/_build/results?buildId=$(BUILD.BUILDID)' jobs: @@ -91,116 +90,8 @@ stages: - job: "Training_Run_Report" dependsOn: "Run_ML_Pipeline" condition: always() - displayName: "Determine if evaluation succeeded and new model is registered" + displayName: "Publish artifact if new model was registered" container: mlops timeoutInMinutes: 0 steps: - - template: diabetes_regression-get-model-version-template.yml - -- stage: 'Deploy_ACI' - displayName: 'Deploy to ACI' - dependsOn: Trigger_AML_Pipeline - condition: and(or(succeeded(), variables['MODEL_BUILD_ID']), variables['ACI_DEPLOYMENT_NAME']) - jobs: - - job: "Deploy_ACI" - displayName: "Deploy to ACI" - container: mlops - timeoutInMinutes: 0 - steps: - - template: diabetes_regression-get-model-version-template.yml - - task: ms-air-aiagility.vss-services-azureml.azureml-model-deploy-task.AMLModelDeploy@0 - displayName: 'Azure ML Model Deploy' - inputs: - azureSubscription: $(WORKSPACE_SVC_CONNECTION) - modelSourceType: manualSpec - modelName: '$(MODEL_NAME)' - modelVersion: $(MODEL_VERSION) - inferencePath: '$(Build.SourcesDirectory)/$(SOURCES_DIR_TRAIN)/scoring/inference_config.yml' - deploymentTarget: ACI - deploymentName: $(ACI_DEPLOYMENT_NAME) - deployConfig: '$(Build.SourcesDirectory)/$(SOURCES_DIR_TRAIN)/scoring/deployment_config_aci.yml' - overwriteExistingDeployment: true - - task: AzureCLI@1 - displayName: 'Smoke test' - inputs: - azureSubscription: '$(WORKSPACE_SVC_CONNECTION)' - scriptLocation: inlineScript - inlineScript: | - set -e # fail on error - export SUBSCRIPTION_ID=$(az account show --query id -o tsv) - python -m ml_service.util.smoke_test_scoring_service --type ACI --service "$(ACI_DEPLOYMENT_NAME)" - -- stage: 'Deploy_AKS' - displayName: 'Deploy to AKS' - dependsOn: Deploy_ACI - condition: and(succeeded(), variables['AKS_DEPLOYMENT_NAME']) - jobs: - - job: "Deploy_AKS" - displayName: "Deploy to AKS" - container: mlops - timeoutInMinutes: 0 - steps: - - template: diabetes_regression-get-model-version-template.yml - - task: ms-air-aiagility.vss-services-azureml.azureml-model-deploy-task.AMLModelDeploy@0 - displayName: 'Azure ML Model Deploy' - inputs: - azureSubscription: $(WORKSPACE_SVC_CONNECTION) - modelSourceType: manualSpec - modelName: '$(MODEL_NAME)' - modelVersion: $(MODEL_VERSION) - inferencePath: '$(Build.SourcesDirectory)/$(SOURCES_DIR_TRAIN)/scoring/inference_config.yml' - deploymentTarget: AKS - aksCluster: $(AKS_COMPUTE_NAME) - deploymentName: $(AKS_DEPLOYMENT_NAME) - deployConfig: '$(Build.SourcesDirectory)/$(SOURCES_DIR_TRAIN)/scoring/deployment_config_aks.yml' - overwriteExistingDeployment: true - - task: AzureCLI@1 - displayName: 'Smoke test' - inputs: - azureSubscription: '$(WORKSPACE_SVC_CONNECTION)' - scriptLocation: inlineScript - inlineScript: | - set -e # fail on error - export SUBSCRIPTION_ID=$(az account show --query id -o tsv) - python -m ml_service.util.smoke_test_scoring_service --type AKS --service "$(AKS_DEPLOYMENT_NAME)" - -- stage: 'Deploy_Webapp' - displayName: 'Deploy to Webapp' - dependsOn: Trigger_AML_Pipeline - condition: and(or(succeeded(), variables['MODEL_BUILD_ID']), variables['WEBAPP_DEPLOYMENT_NAME']) - jobs: - - job: "Deploy_Webapp" - displayName: "Deploy to Webapp" - container: mlops - timeoutInMinutes: 0 - steps: - - template: diabetes_regression-get-model-version-template.yml - - task: AzureCLI@1 - displayName: 'Create scoring image and set IMAGE_LOCATION variable' - inputs: - azureSubscription: '$(WORKSPACE_SVC_CONNECTION)' - scriptLocation: inlineScript - inlineScript: | - set -e # fail on error - export SUBSCRIPTION_ID=$(az account show --query id -o tsv) - python -m ml_service.util.create_scoring_image --output_image_location_file image_location.txt - # Output image location to Azure DevOps job - IMAGE_LOCATION="$(cat image_location.txt)" - echo "##vso[task.setvariable variable=IMAGE_LOCATION]$IMAGE_LOCATION" - - task: AzureWebAppContainer@1 - name: WebAppDeploy - displayName: 'Azure Web App on Container Deploy' - inputs: - azureSubscription: '$(AZURE_RM_SVC_CONNECTION)' - appName: '$(WEBAPP_DEPLOYMENT_NAME)' - resourceGroupName: '$(RESOURCE_GROUP)' - imageName: '$(IMAGE_LOCATION)' - - task: AzureCLI@1 - displayName: 'Smoke test' - inputs: - azureSubscription: '$(WORKSPACE_SVC_CONNECTION)' - scriptLocation: inlineScript - inlineScript: | - set -e # fail on error - export SUBSCRIPTION_ID=$(az account show --query id -o tsv) - python -m ml_service.util.smoke_test_scoring_service --type Webapp --service "$(WebAppDeploy.AppServiceApplicationUrl)/score" + - template: diabetes_regression-publish-model-artifact-template.yml diff --git a/.pipelines/diabetes_regression-get-model-id-artifact-template.yml b/.pipelines/diabetes_regression-get-model-id-artifact-template.yml new file mode 100644 index 00000000..b9e61306 --- /dev/null +++ b/.pipelines/diabetes_regression-get-model-id-artifact-template.yml @@ -0,0 +1,48 @@ +# Pipeline template that gets the model name and version from a previous build's artifact + +parameters: +- name: projectId + type: string + default: '' +- name: pipelineId + type: string + default: '' +- name: artifactBuildId + type: string + default: latest + +steps: + - download: none + - task: DownloadPipelineArtifact@2 + displayName: Download Pipeline Artifacts + inputs: + source: 'specific' + project: '${{ parameters.projectId }}' + pipeline: '${{ parameters.pipelineId }}' + preferTriggeringPipeline: true + ${{ if eq(parameters.artifactBuildId, 'latest') }}: + buildVersionToDownload: 'latestFromBranch' + ${{ if ne(parameters.artifactBuildId, 'latest') }}: + buildVersionToDownload: 'specific' + runId: '${{ parameters.artifactBuildId }}' + runBranch: '$(Build.SourceBranch)' + path: $(Build.SourcesDirectory)/bin + - task: Bash@3 + name: get_model + displayName: Parse Json for Model Name and Version + inputs: + targetType: 'inline' + script: | + # Print JSON + cat $(Build.SourcesDirectory)/bin/model/model.json | jq '.' + + # Set model name and version variables + MODEL_NAME=$(jq -r '.name' <$(Build.SourcesDirectory)/bin/model/model.json) + MODEL_VERSION=$(jq -r '.version' <$(Build.SourcesDirectory)/bin/model/model.json) + + echo "Model Name: $MODEL_NAME" + echo "Model Version: $MODEL_VERSION" + + # Set environment variables + echo "##vso[task.setvariable variable=MODEL_VERSION;isOutput=true]$MODEL_VERSION" + echo "##vso[task.setvariable variable=MODEL_NAME;isOutput=true]$MODEL_NAME" diff --git a/.pipelines/diabetes_regression-get-model-version-template.yml b/.pipelines/diabetes_regression-get-model-version-template.yml deleted file mode 100644 index 870985a6..00000000 --- a/.pipelines/diabetes_regression-get-model-version-template.yml +++ /dev/null @@ -1,15 +0,0 @@ -# Pipeline template that attempts to get the latest model version and adds it to the environment for subsequent tasks to use. -steps: -- task: AzureCLI@1 - inputs: - azureSubscription: '$(WORKSPACE_SVC_CONNECTION)' - scriptLocation: inlineScript - inlineScript: | - set -e # fail on error - export SUBSCRIPTION_ID=$(az account show --query id -o tsv) - python -m ml_service.pipelines.diabetes_regression_verify_train_pipeline --build_id $(modelbuildid) --output_model_version_file "model_version.txt" - # Output model version to Azure DevOps job - MODEL_VERSION="$(cat model_version.txt)" - echo "##vso[task.setvariable variable=MODEL_VERSION]$MODEL_VERSION" - name: 'getversion' - displayName: "Determine if evaluation succeeded and new model is registered" diff --git a/.pipelines/diabetes_regression-package-model-template.yml b/.pipelines/diabetes_regression-package-model-template.yml new file mode 100644 index 00000000..7725b19c --- /dev/null +++ b/.pipelines/diabetes_regression-package-model-template.yml @@ -0,0 +1,42 @@ +# Pipeline template that creates a model package and adds the package location to the environment for subsequent tasks to use. +parameters: +- name: modelId + type: string + default: '' +- name: scoringScriptPath + type: string + default: '' +- name: condaFilePath + type: string + default: '' + +steps: + - task: AzureCLI@1 + displayName: 'Install AzureML CLI' + inputs: + azureSubscription: '$(WORKSPACE_SVC_CONNECTION)' + scriptLocation: inlineScript + workingDirectory: $(Build.SourcesDirectory) + inlineScript: 'az extension add -n azure-cli-ml' + - task: AzureCLI@1 + displayName: 'Create model package and set IMAGE_LOCATION variable' + inputs: + azureSubscription: '$(WORKSPACE_SVC_CONNECTION)' + scriptLocation: inlineScript + inlineScript: | + set -e # fail on error + + # Create model package using CLI + az ml model package --workspace-name $(WORKSPACE_NAME) -g $(RESOURCE_GROUP) \ + --model '${{ parameters.modelId }}' \ + --entry-script '${{ parameters.scoringScriptPath }}' \ + --cf '${{ parameters.condaFilePath }}' \ + -v \ + --rt python --query 'location' -o tsv > image_logs.txt + + # Show logs + cat image_logs.txt + + # Set environment variable using the last line of logs that has the package location + IMAGE_LOCATION=$(tail -n 1 image_logs.txt) + echo "##vso[task.setvariable variable=IMAGE_LOCATION]$IMAGE_LOCATION" diff --git a/.pipelines/diabetes_regression-publish-model-artifact-template.yml b/.pipelines/diabetes_regression-publish-model-artifact-template.yml new file mode 100644 index 00000000..00e45105 --- /dev/null +++ b/.pipelines/diabetes_regression-publish-model-artifact-template.yml @@ -0,0 +1,29 @@ +# Pipeline template to check if a model was registered for the build and publishes an artifact with the model JSON +steps: +- task: AzureCLI@1 + displayName: 'Install AzureML CLI' + inputs: + azureSubscription: '$(WORKSPACE_SVC_CONNECTION)' + scriptLocation: inlineScript + workingDirectory: $(Build.SourcesDirectory) + inlineScript: 'az extension add -n azure-cli-ml' +- task: AzureCLI@1 + inputs: + azureSubscription: '$(WORKSPACE_SVC_CONNECTION)' + scriptLocation: inlineScript + workingDirectory: $(Build.SourcesDirectory) + inlineScript: | + set -e # fail on error + + # Get the model using the build ID tag + FOUND_MODEL=$(az ml model list -g $(RESOURCE_GROUP) --workspace-name $(WORKSPACE_NAME) --tag BuildId=$(Build.BuildId) --query '[0]') + + # If the variable is empty, print and fail + [[ -z "$FOUND_MODEL" ]] && { echo "Model was not registered for this run." ; exit 1; } + + # Write to a file + echo $FOUND_MODEL >model.json + name: 'getversion' + displayName: "Determine if evaluation succeeded and new model is registered (CLI)" +- publish: model.json + artifact: model diff --git a/.pipelines/diabetes_regression-variables-template.yml b/.pipelines/diabetes_regression-variables-template.yml index cf4ef9cf..502753fb 100644 --- a/.pipelines/diabetes_regression-variables-template.yml +++ b/.pipelines/diabetes_regression-variables-template.yml @@ -65,10 +65,6 @@ variables: # - name: ALLOW_RUN_CANCEL # value: "true" - # For debugging deployment issues. Specify a build id with the MODEL_BUILD_ID pipeline variable at queue time - # to skip training and deploy a model registered by a previous build. - - name: modelbuildid - value: $[coalesce(variables['MODEL_BUILD_ID'], variables['Build.BuildId'])] # Flag to allow rebuilding the AML Environment after it was built for the first time. This enables dependency updates from conda_dependencies.yaml. # - name: AML_REBUILD_ENVIRONMENT # value: "false" diff --git a/bootstrap/bootstrap.py b/bootstrap/bootstrap.py index cbc49e18..9e52af55 100644 --- a/bootstrap/bootstrap.py +++ b/bootstrap/bootstrap.py @@ -84,11 +84,13 @@ def replace_project_name(project_dir, project_name, rename_name): files = [r".env.example", r".pipelines/code-quality-template.yml", r".pipelines/pr.yml", + r".pipelines/diabetes_regression-cd.yml", r".pipelines/diabetes_regression-ci.yml", r".pipelines/abtest.yml", r".pipelines/diabetes_regression-ci-image.yml", + r".pipelines/diabetes_regression-publish-model-artifact-template.yml", # NOQA: E501 + r".pipelines/diabetes_regression-get-model-id-artifact-template.yml", # NOQA: E501 r".pipelines/diabetes_regression-batchscoring-ci.yml", - r".pipelines/diabetes_regression-get-model-version-template.yml", # NOQA: E501 r".pipelines/diabetes_regression-variables-template.yml", r"environment_setup/Dockerfile", r"environment_setup/install_requirements.sh", diff --git a/diabetes_regression/ci_dependencies.yml b/diabetes_regression/ci_dependencies.yml index 52bdeb44..c54f3e32 100644 --- a/diabetes_regression/ci_dependencies.yml +++ b/diabetes_regression/ci_dependencies.yml @@ -12,6 +12,7 @@ dependencies: - r=3.6.0 - r-essentials=3.6.0 + - conda-forge::jq - pip=20.0.* - pip: diff --git a/diabetes_regression/evaluate/evaluate_model.py b/diabetes_regression/evaluate/evaluate_model.py index 125a16a5..5a69addb 100644 --- a/diabetes_regression/evaluate/evaluate_model.py +++ b/diabetes_regression/evaluate/evaluate_model.py @@ -26,7 +26,7 @@ from azureml.core import Run import argparse import traceback -from util.model_helper import get_latest_model +from util.model_helper import get_model run = Run.get_context() @@ -45,7 +45,7 @@ # sources_dir = 'diabetes_regression' # path_to_util = os.path.join(".", sources_dir, "util") # sys.path.append(os.path.abspath(path_to_util)) # NOQA: E402 -# from model_helper import get_latest_model +# from model_helper import get_model # workspace_name = os.environ.get("WORKSPACE_NAME") # experiment_name = os.environ.get("EXPERIMENT_NAME") # resource_group = os.environ.get("RESOURCE_GROUP") @@ -108,8 +108,11 @@ firstRegistration = False tag_name = 'experiment_name' - model = get_latest_model( - model_name, tag_name, exp.name, ws) + model = get_model( + model_name=model_name, + tag_name=tag_name, + tag_value=exp.name, + aml_workspace=ws) if (model is not None): production_model_mse = 10000 diff --git a/diabetes_regression/scoring/parallel_batchscore.py b/diabetes_regression/scoring/parallel_batchscore.py index aef6f3fb..cd42c79c 100644 --- a/diabetes_regression/scoring/parallel_batchscore.py +++ b/diabetes_regression/scoring/parallel_batchscore.py @@ -29,7 +29,8 @@ import joblib import sys from typing import List -from util.model_helper import get_latest_model +from util.model_helper import get_model +from azureml.core import Model model = None @@ -59,6 +60,18 @@ def parse_args() -> List[str]: model_name = model_name_param[0][1] + model_version_param = [ + (sys.argv[idx], sys.argv[idx + 1]) + for idx, itm in enumerate(sys.argv) + if itm == "--model_version" + ] + model_version = ( + None + if len(model_version_param) < 1 + or len(model_version_param[0][1].strip()) == 0 # NOQA: E501 + else model_version_param[0][1] + ) + model_tag_name_param = [ (sys.argv[idx], sys.argv[idx + 1]) for idx, itm in enumerate(sys.argv) @@ -83,7 +96,7 @@ def parse_args() -> List[str]: else model_tag_value_param[0][1] ) - return [model_name, model_tag_name, model_tag_value] + return [model_name, model_version, model_tag_name, model_tag_value] def init(): @@ -94,13 +107,18 @@ def init(): try: print("Initializing batch scoring script...") + # Get the model using name/version/tags filter model_filter = parse_args() - amlmodel = get_latest_model( - model_filter[0], model_filter[1], model_filter[2] - ) # NOQA: E501 + amlmodel = get_model( + model_name=model_filter[0], + model_version=model_filter[1], + tag_name=model_filter[2], + tag_value=model_filter[3]) + # Load the model using name/version found global model - modelpath = amlmodel.get_model_path(model_name=model_filter[0]) + modelpath = Model.get_model_path( + model_name=amlmodel.name, version=amlmodel.version) model = joblib.load(modelpath) print("Loaded model {}".format(model_filter[0])) except Exception as ex: diff --git a/diabetes_regression/util/model_helper.py b/diabetes_regression/util/model_helper.py index ceceff41..f90237e5 100644 --- a/diabetes_regression/util/model_helper.py +++ b/diabetes_regression/util/model_helper.py @@ -22,8 +22,9 @@ def get_current_workspace() -> Workspace: return experiment.workspace -def get_latest_model( +def get_model( model_name: str, + model_version: int = None, # If none, return latest model tag_name: str = None, tag_value: str = None, aml_workspace: Workspace = None @@ -35,53 +36,29 @@ def get_latest_model( Parameters: aml_workspace (Workspace): aml.core Workspace that the model lives. model_name (str): name of the model we are looking for + (optional) model_version (str): model version. Latest if not provided. (optional) tag (str): the tag value & name the model was registered under. Return: A single aml model from the workspace that matches the name and tag. """ - try: - # Validate params. cannot be None. - if model_name is None: - raise ValueError("model_name[:str] is required") + if aml_workspace is None: + print("No workspace defined - using current experiment workspace.") + aml_workspace = get_current_workspace() - if aml_workspace is None: - print("No workspace defined - using current experiment workspace.") - aml_workspace = get_current_workspace() - - model_list = None - tag_ext = "" - - # Get lastest model - # True: by name and tags - if tag_name is not None and tag_value is not None: - model_list = AMLModel.list( - aml_workspace, name=model_name, - tags=[[tag_name, tag_value]], latest=True - ) - tag_ext = f"tag_name: {tag_name}, tag_value: {tag_value}." - # False: Only by name - else: - model_list = AMLModel.list( - aml_workspace, name=model_name, latest=True) - - # latest should only return 1 model, but if it does, - # then maybe sdk or source code changed. - - # define the error messages - too_many_model_message = ("Found more than one latest model. " - f"Models found: {model_list}. " - f"{tag_ext}") - - no_model_found_message = (f"No Model found with name: {model_name}. " - f"{tag_ext}") - - if len(model_list) > 1: - raise ValueError(too_many_model_message) - if len(model_list) == 1: - return model_list[0] - else: - print(no_model_found_message) - return None - except Exception: - raise + if tag_name is not None and tag_value is not None: + model = AMLModel( + aml_workspace, + name=model_name, + version=model_version, + tags=[[tag_name, tag_value]]) + elif (tag_name is None and tag_value is not None) or ( + tag_value is None and tag_name is not None + ): + raise ValueError( + "model_tag_name and model_tag_value should both be supplied" + + "or excluded" # NOQA: E501 + ) + else: + model = AMLModel(aml_workspace, name=model_name, version=model_version) # NOQA: E501 + return model diff --git a/docs/getting_started.md b/docs/getting_started.md index cba7e424..c3abed02 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -140,30 +140,31 @@ Create a new service connection to your Azure ML Workspace using the [Machine Le **Note:** Similar to the Azure Resource Manager service connection you created earlier, creating a service connection with Azure Machine Learning workspace scope requires 'Owner' or 'User Access Administrator' permissions on the Workspace. You'll need sufficient permissions to register an application with your Azure AD tenant, or you can get the ID and secret of a service principal from your Azure AD Administrator. That principal must have Contributor permissions on the Azure ML Workspace. -## Set up Build, Release Trigger, and Release Multi-Stage Pipeline +## Set up Build, Release Trigger, and Release Multi-Stage Pipelines -Now that you've provisioned all the required Azure resources and service connections, you can set up the pipelines for deploying your machine learning model to production. +Now that you've provisioned all the required Azure resources and service connections, you can set up the pipelines for training (CI) and deploying (CD) your machine learning model to production. Additionally, you can set up a pipeline for batch scoring. -**There are two main Azure pipelines - one to handle model training and another to handle batch scoring of the model.** - -### **Azure [pipeline](../.pipelines/diabetes_regression-ci.yml) for model training and deployment** -This pipeline has a sequence of stages for: - -1. **Model Code Continuous Integration:** triggered on code changes to master branch on GitHub. Runs linting, unit tests, code coverage and publishes a training pipeline. -1. **Train Model**: invokes the Azure ML service to trigger the published training pipeline to train, evaluate, and register a model. -1. **Release Deployment:** deploys a model to either [Azure Container Instances (ACI)](https://azure.microsoft.com/en-us/services/container-instances/), [Azure Kubernetes Service (AKS)](https://azure.microsoft.com/en-us/services/kubernetes-service), or [Azure App Service](https://docs.microsoft.com/en-us/azure/machine-learning/service/how-to-deploy-app-service) environments. For simplicity, you're going to initially focus on Azure Container Instances. See [Further Exploration](#further-exploration) for other deployment types. +1. **Model CI, training, evaluation, and registration** - triggered on code changes to master branch on GitHub. Runs linting, unit tests, code coverage, and publishes and runs the training pipeline. If a new model is registered after evaluation, it creates a build artifact containing the JSON metadata of the model. Definition: [diabetes_regression-ci.yml](../.pipelines/diabetes_regression-ci.yml). +1. **Release deployment** - consumes the artifact of the previous pipeline and deploys a model to either [Azure Container Instances (ACI)](https://azure.microsoft.com/en-us/services/container-instances/), [Azure Kubernetes Service (AKS)](https://azure.microsoft.com/en-us/services/kubernetes-service), or [Azure App Service](https://docs.microsoft.com/en-us/azure/machine-learning/service/how-to-deploy-app-service) environments. See [Further Exploration](#further-exploration) for other deployment types. Definition: [diabetes_regression-cd.yml](../.pipelines/diabetes_regression-cd.yml). 1. **Note:** Edit the pipeline definition to remove unused stages. For example, if you're deploying to Azure Container Instances and Azure Kubernetes Service only, delete the unused `Deploy_Webapp` stage. +1. **Batch Scoring Code Continuous Integration** - consumes the artifact of the model training pipeline. Runs linting, unit tests, code coverage, publishes a batch scoring pipeline, and invokes the published batch scoring pipeline to score a model. + +These pipelines use a Docker container on the Azure Pipelines agents to accomplish the pipeline steps. The container image ***mcr.microsoft.com/mlops/python:latest*** is built with [this Dockerfile](../environment_setup/Dockerfile) and has all the necessary dependencies installed for MLOpsPython and ***diabetes_regression***. This image is an example of a custom Docker image with a pre-baked environment. The environment is guaranteed to be the same on any building agent, VM, or local machine. In your project, you'll want to build your own Docker image that only contains the dependencies and tools required for your use case. Your image will probably be smaller and faster, and it will be maintained by your team. -### Set up the Training Pipeline +### Set up the Model CI, training, evaluation, and registration pipeline In your Azure DevOps project, create and run a new build pipeline based on the [diabetes_regression-ci.yml](../.pipelines/diabetes_regression-ci.yml) pipeline definition in your forked repository. -![Configure CI build pipeline](./images/ci-build-pipeline-configure.png) +If you plan to use the release deployment pipeline (in the next section), you will need to rename this pipeline to `Model-Train-Register-CI`. Once the pipeline is finished, check the execution result: -![Build](./images/multi-stage-aci.png) +![Build](./images/model-train-register.png) + +And the pipeline artifacts: + +![Build](./images/model-train-register-artifacts.png) Also check the published training pipeline in the **mlops-AML-WS** workspace in [Azure Portal](https://portal.azure.com/): @@ -171,6 +172,12 @@ Also check the published training pipeline in the **mlops-AML-WS** workspace in Great, you now have the build pipeline for training set up which automatically triggers every time there's a change in the master branch! +After the pipeline is finished, you'll see a new model in the **ML Workspace**: + +![Trained model](./images/trained-model.png) + +To disable the automatic trigger of the training pipeline, change the `auto-trigger-training` variable as listed in the `.pipelines\diabetes_regression-ci.yml` pipeline to `false`. You can also override the variable at runtime execution of the pipeline. + The pipeline stages are summarized below: #### Model CI @@ -186,32 +193,62 @@ The pipeline stages are summarized below: - This is an **agentless** job. The CI pipeline can wait for ML pipeline completion for hours or even days without using agent resources. - Determine if a new model was registered by the _ML Training Pipeline_. - If the model evaluation determines that the new model doesn't perform any better than the previous one, the new model won't register and the _ML Training Pipeline_ will be **canceled**. In this case, you'll see a message in the 'Train Model' job under the 'Determine if evaluation succeeded and new model is registered' step saying '**Model was not registered for this run.**' - - See [evaluate_model.py](../diabetes_regression/evaluate/evaluate_model.py#L118) for the evaluation logic and [diabetes_regression_verify_train_pipeline.py](../ml_service/pipelines/diabetes_regression_verify_train_pipeline.py#L54) for the ML pipeline reporting logic. + - See [evaluate_model.py](../diabetes_regression/evaluate/evaluate_model.py#L118) for the evaluation logic. - [Additional Variables and Configuration](#additional-variables-and-configuration) for configuring this and other behavior. -#### Deploy to ACI +#### Create pipeline artifact -- Deploy the model to the QA environment in [Azure Container Instances](https://azure.microsoft.com/en-us/services/container-instances/). -- Smoke test - - The test sends a sample query to the scoring web service and verifies that it returns the expected response. Have a look at the [smoke test code](../ml_service/util/smoke_test_scoring_service.py) for an example. +- Get the info about the registered model +- Create a pipeline artifact called `model` that contains a `model.json` file containing the model information. -The pipeline uses a Docker container on the Azure Pipelines agents to accomplish the pipeline steps. The container image **_mcr.microsoft.com/mlops/python:latest_** is built with [this Dockerfile](../environment_setup/Dockerfile) and has all the necessary dependencies installed for MLOpsPython and **_diabetes_regression_**. This image is an example of a custom Docker image with a pre-baked environment. The environment is guaranteed to be the same on any building agent, VM, or local machine. In your project, you'll want to build your own Docker image that only contains the dependencies and tools required for your use case. Your image will probably be smaller and faster, and it will be maintained by your team. +### Set up the Release Deployment and/or Batch Scoring pipelines -After the pipeline is finished, you'll see a new model in the **ML Workspace**: +--- +**PREREQUISITE** -![Trained model](./images/trained-model.png) +In order to use these pipelines: + +1. Follow the steps to set up the Model CI, training, evaluation, and registration pipeline. +1. You **must** rename your model CI/train/eval/register pipeline to `Model-Train-Register-CI`. + +These pipelines rely on the model CI pipeline and reference it by name. -To disable the automatic trigger of the training pipeline, change the `auto-trigger-training` variable as listed in the `.pipelines\diabetes_regression-ci.yml` pipeline to `false`. You can also override the variable at runtime execution of the pipeline. +--- -To skip model training and registration, and deploy a model successfully registered by a previous build (for testing changes to the score file or inference configuration), add the variable `MODEL_BUILD_ID` when the pipeline is queued, and set the value to the ID of the previous build. +These pipelines have the following behaviors: +- The pipeline will **automatically trigger** on completion of the Model-Train-Register-CI pipeline for the master branch. +- The pipeline will default to using the latest successful build of the Model-Train-Register-CI pipeline. It will deploy the model produced by that build. +- You can specify a `Model-Train-Register-CI` build ID when running the pipeline manually. You can find this in the url of the build, and the model registered from that build will also be tagged with the build ID. This is useful to skip model training and registration, and deploy/score a model successfully registered by a `Model-Train-Register-CI` build. -### **Azure [pipeline](../.pipelines/diabetes_regression-batchscoring-ci.yml) for batch scoring** -This pipeline has a sequence of stages for: -1. **Batch Scoring Code Continuous Integration:** triggered on code changes to master branch on GitHub. Runs linting, unit tests, code coverage and publishes a batch scoring pipeline. -1. **Run Batch Scoring**: invokes the published batch scoring pipeline to score a model. +### Set up the Release Deployment pipeline + +In your Azure DevOps project, create and run a new build pipeline based on the [diabetes_regression-cd.yml](../.pipelines/diabetes_regression-cd.yml) +pipeline definition in your forked repository. + +Your first run will use the latest model created by the `Model-Train-Register-CI` pipeline. + +Once the pipeline is finished, check the execution result: + +![Build](./images/model-deploy-result.png) + +To specify a particular build's model, set the `Model Train CI Build Id` parameter to the build Id you would like to use. + +![Build](./images/model-deploy-configure.png) + +Once your pipeline run begins, you can see the model name and version downloaded from the `Model-Train-Register-CI` pipeline. + +![Build](./images/model-deploy-artifact-logs.png) + +The pipeline has the following stage: + +#### Deploy to ACI + +- Deploy the model to the QA environment in [Azure Container Instances](https://azure.microsoft.com/en-us/services/container-instances/). +- Smoke test + - The test sends a sample query to the scoring web service and verifies that it returns the expected response. Have a look at the [smoke test code](../ml_service/util/smoke_test_scoring_service.py) for an example. -### Set up the Batch Scoring Pipeline +### Set up the Batch Scoring pipeline In your Azure DevOps project, create and run a new build pipeline based on the [diabetes_regression-batchscoring-ci.yml](../.pipelines/diabetes_regression-batchscoring-ci.yml) pipeline definition in your forked repository. @@ -247,7 +284,7 @@ The pipeline stages are summarized below: ## Further Exploration -You should now have a working pipeline that can get you started with MLOpsPython. Below are some additional features offered that might suit your scenario. +You should now have a working set of pipelines that can get you started with MLOpsPython. Below are some additional features offered that might suit your scenario. ### Deploy the model to Azure Kubernetes Service diff --git a/docs/images/model-deploy-artifact-logs.PNG b/docs/images/model-deploy-artifact-logs.PNG new file mode 100644 index 0000000000000000000000000000000000000000..2dfee3057bb122de04b0ceea2a7bb1247a623781 GIT binary patch literal 104171 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 IjV)sAT+2qSh$xE@6H> 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
LMjdY!oQB+ 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 literal 0 HcmV?d00001 diff --git a/docs/images/model-deploy-configure.png b/docs/images/model-deploy-configure.png new file mode 100644 index 0000000000000000000000000000000000000000..fcd8775012c39f58da4bf456bcf5fa093f851a53 GIT binary patch literal 39099 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 b+&g^4Cqf|L;P{&Z@ZWV+tt%gtO&|YX^MA8c literal 0 HcmV?d00001 diff --git a/docs/images/model-deploy-result.png b/docs/images/model-deploy-result.png new file mode 100644 index 0000000000000000000000000000000000000000..cd3d166e289f31b68b231bae8c4ecf96285003da GIT binary patch literal 19960 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 literal 0 HcmV?d00001 diff --git a/docs/images/model-train-register-artifacts.png b/docs/images/model-train-register-artifacts.png new file mode 100644 index 0000000000000000000000000000000000000000..0d3eed26b63f5988289b64772d1491adeff808cf GIT binary patch literal 8827 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 literal 0 HcmV?d00001 diff --git a/docs/images/model-train-register.png b/docs/images/model-train-register.png new file mode 100644 index 0000000000000000000000000000000000000000..5ce4ef417fa3dbf55e83418dabfe8feea9186ff5 GIT binary patch literal 15690 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 literal 0 HcmV?d00001 diff --git a/ml_service/pipelines/diabetes_regression_build_parallel_batchscore_pipeline.py b/ml_service/pipelines/diabetes_regression_build_parallel_batchscore_pipeline.py index d7acbf46..ac3d3407 100644 --- a/ml_service/pipelines/diabetes_regression_build_parallel_batchscore_pipeline.py +++ b/ml_service/pipelines/diabetes_regression_build_parallel_batchscore_pipeline.py @@ -33,65 +33,15 @@ Workspace, Dataset, Datastore, - Model, RunConfiguration, ) from azureml.pipeline.core import Pipeline, PipelineData, PipelineParameter from azureml.core.compute import ComputeTarget from azureml.data.datapath import DataPath from azureml.pipeline.steps import PythonScriptStep -from argparse import ArgumentParser, Namespace from typing import Tuple -def parse_args() -> Namespace: - """ - Parse arguments supplied to the pipeline creation script. - The only allowed arguments are model_tag_name and model_tag_value - specifying a custom tag/value pair to help locate a specific model. - - - :returns: Namespace with two attributes model_tag_name and model_tag_value - and corresponding values - - """ - parser = ArgumentParser() - parser.add_argument("--model_tag_name", default=None, type=str) - parser.add_argument("--model_tag_value", default=None, type=str) - args = parser.parse_args() - return args - - -def get_model( - ws: Workspace, env: Env, tagname: str = None, tagvalue: str = None -) -> Model: - """ - Gets a model from the models registered with the AML workspace. - If a tag/value pair is supplied, uses it to filter. - - :param ws: Current AML workspace - :param env: Environment variables - :param tagname: Optional tag name, default is None - :param tagvalue: Optional tag value, default is None - - :returns: Model - - :raises: ValueError - """ - if tagname is not None and tagvalue is not None: - model = Model(ws, name=env.model_name, tags=[[tagname, tagvalue]]) - elif (tagname is None and tagvalue is not None) or ( - tagvalue is None and tagname is not None - ): - raise ValueError( - "model_tag_name and model_tag_value should both be supplied" - + "or excluded" # NOQA: E501 - ) - else: - model = Model(ws, name=env.model_name) - return model - - def get_or_create_datastore( datastorename: str, ws: Workspace, env: Env, input: bool = True ) -> Datastore: @@ -331,7 +281,6 @@ def get_run_configs( def get_scoring_pipeline( - model: Model, scoring_dataset: Dataset, output_loc: PipelineData, score_run_config: ParallelRunConfig, @@ -343,7 +292,6 @@ def get_scoring_pipeline( """ Creates the scoring pipeline. - :param model: The model to use for scoring :param scoring_dataset: Data to score :param output_loc: Location to save the scoring results :param score_run_config: Parallel Run configuration to support @@ -362,6 +310,9 @@ def get_scoring_pipeline( model_name_param = PipelineParameter( "model_name", default_value=env.model_name ) # NOQA: E501 + model_version_param = PipelineParameter( + "model_version", default_value=env.model_version + ) # NOQA: E501 model_tag_name_param = PipelineParameter( "model_tag_name", default_value=" " ) # NOQA: E501 @@ -376,6 +327,8 @@ def get_scoring_pipeline( arguments=[ "--model_name", model_name_param, + "--model_version", + model_version_param, "--model_tag_name", model_tag_name_param, "--model_tag_value", @@ -425,8 +378,6 @@ def build_batchscore_pipeline(): try: env = Env() - args = parse_args() - # Get Azure machine learning workspace aml_workspace = Workspace.get( name=env.workspace_name, @@ -450,12 +401,7 @@ def build_batchscore_pipeline(): aml_workspace, aml_compute_score, env ) - trained_model = get_model( - aml_workspace, env, args.model_tag_name, args.model_tag_value - ) - scoring_pipeline = get_scoring_pipeline( - trained_model, input_dataset, output_location, scoring_runconfig, diff --git a/ml_service/pipelines/diabetes_regression_verify_train_pipeline.py b/ml_service/pipelines/diabetes_regression_verify_train_pipeline.py index 306f2259..28511f9b 100644 --- a/ml_service/pipelines/diabetes_regression_verify_train_pipeline.py +++ b/ml_service/pipelines/diabetes_regression_verify_train_pipeline.py @@ -3,7 +3,7 @@ import os from azureml.core import Run, Experiment, Workspace from ml_service.util.env_variables import Env -from diabetes_regression.util.model_helper import get_latest_model +from diabetes_regression.util.model_helper import get_model def main(): @@ -53,8 +53,12 @@ def main(): try: tag_name = 'BuildId' - model = get_latest_model( - model_name, tag_name, build_id, exp.workspace) + model = get_model( + model_name=model_name, + tag_name=tag_name, + tag_value=build_id, + aml_workspace=exp.workspace) + if (model is not None): print("Model was registered for this build.") if (model is None): diff --git a/ml_service/pipelines/run_parallel_batchscore_pipeline.py b/ml_service/pipelines/run_parallel_batchscore_pipeline.py index ec6cebae..c046eb9c 100644 --- a/ml_service/pipelines/run_parallel_batchscore_pipeline.py +++ b/ml_service/pipelines/run_parallel_batchscore_pipeline.py @@ -115,6 +115,7 @@ def run_batchscore_pipeline(): scoringpipeline, pipeline_parameters={ "model_name": env.model_name, + "model_version": env.model_version, "model_tag_name": " ", "model_tag_value": " ", }, From 090698692697114d6fb322f28ad8b8a7f843c76d Mon Sep 17 00:00:00 2001 From: Tom Care Date: Fri, 3 Jul 2020 16:16:10 -0700 Subject: [PATCH 09/29] Restore call convention compatibility in get_model (#304) A bug surfaced where first time evaluation of a model fails due to the Model constructor throwing if the model does not exist. Looking deeper, we see that most calls to get_model expect a possible None response and check at the call site. Unfortunately we get the same WebserviceException class for a model not being found as we do a REST error or similar. This change is a stopgap mitigation to restore compatibility with the existing callers, and compromises by allowing the model version dependent behavior to continue passing on exceptions. In a future follow up we should settle on a convention and allow version checks to propagate failure while still giving the possibility for handling a service exception in the caller. --- diabetes_regression/util/model_helper.py | 45 ++++++++++++++++-------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/diabetes_regression/util/model_helper.py b/diabetes_regression/util/model_helper.py index f90237e5..0fd20ef0 100644 --- a/diabetes_regression/util/model_helper.py +++ b/diabetes_regression/util/model_helper.py @@ -8,8 +8,8 @@ def get_current_workspace() -> Workspace: """ - Retrieves and returns the latest model from the workspace - by its name and tag. Will not work when ran locally. + Retrieves and returns the current workspace. + Will not work when ran locally. Parameters: None @@ -30,8 +30,8 @@ def get_model( aml_workspace: Workspace = None ) -> AMLModel: """ - Retrieves and returns the latest model from the workspace - by its name and (optional) tag. + Retrieves and returns a model from the workspace by its name + and (optional) tag. Parameters: aml_workspace (Workspace): aml.core Workspace that the model lives. @@ -40,25 +40,40 @@ def get_model( (optional) tag (str): the tag value & name the model was registered under. Return: - A single aml model from the workspace that matches the name and tag. + A single aml model from the workspace that matches the name and tag, or + None. """ if aml_workspace is None: print("No workspace defined - using current experiment workspace.") aml_workspace = get_current_workspace() - if tag_name is not None and tag_value is not None: + tags = None + if tag_name is not None or tag_value is not None: + # Both a name and value must be specified to use tags. + if tag_name is None or tag_value is None: + raise ValueError( + "model_tag_name and model_tag_value should both be supplied" + + "or excluded" # NOQA: E501 + ) + tags = [[tag_name, tag_value]] + + model = None + if model_version is not None: + # TODO(tcare): Finding a specific version currently expects exceptions + # to propagate in the case we can't find the model. This call may + # result in a WebserviceException that may or may not be due to the + # model not existing. model = AMLModel( aml_workspace, name=model_name, version=model_version, - tags=[[tag_name, tag_value]]) - elif (tag_name is None and tag_value is not None) or ( - tag_value is None and tag_name is not None - ): - raise ValueError( - "model_tag_name and model_tag_value should both be supplied" - + "or excluded" # NOQA: E501 - ) + tags=tags) else: - model = AMLModel(aml_workspace, name=model_name, version=model_version) # NOQA: E501 + models = AMLModel.list( + aml_workspace, name=model_name, tags=tags, latest=True) + if len(models) == 1: + model = models[0] + elif len(models) > 1: + raise Exception("Expected only one model") + return model From 6d02555358ed6943b1c13cf1dccd758ad357681e Mon Sep 17 00:00:00 2001 From: Tom Care Date: Fri, 3 Jul 2020 16:26:50 -0700 Subject: [PATCH 10/29] Fix CD deployment break (#305) Recently the step to get the model version had a name associated with the step. We need to also update the references in future step to use the step name as a prefix. This resulted in the MODEL_VERSION variable causing failures in each CD deployment step. This did not show up in CI because the MODEL_VERSION var is hard coded in the variable group. We should also remove that. --- .pipelines/diabetes_regression-cd.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pipelines/diabetes_regression-cd.yml b/.pipelines/diabetes_regression-cd.yml index 16bc4724..8dd35e47 100644 --- a/.pipelines/diabetes_regression-cd.yml +++ b/.pipelines/diabetes_regression-cd.yml @@ -59,7 +59,7 @@ stages: inlineScript: | set -e # fail on error - az ml model deploy --name $(ACI_DEPLOYMENT_NAME) --model '$(MODEL_NAME):$(MODEL_VERSION)' \ + az ml model deploy --name $(ACI_DEPLOYMENT_NAME) --model '$(MODEL_NAME):$(get_model.MODEL_VERSION)' \ --ic inference_config.yml \ --dc deployment_config_aci.yml \ -g $(RESOURCE_GROUP) --workspace-name $(WORKSPACE_NAME) \ @@ -105,7 +105,7 @@ stages: inlineScript: | set -e # fail on error - az ml model deploy --name $(AKS_DEPLOYMENT_NAME) --model '$(MODEL_NAME):$(MODEL_VERSION)' \ + az ml model deploy --name $(AKS_DEPLOYMENT_NAME) --model '$(MODEL_NAME):$(get_model.MODEL_VERSION)' \ --compute-target $(AKS_COMPUTE_NAME) \ --ic inference_config.yml \ --dc deployment_config_aks.yml \ @@ -137,7 +137,7 @@ stages: artifactBuildId: ${{ parameters.artifactBuildId }} - template: diabetes_regression-package-model-template.yml parameters: - modelId: $(MODEL_NAME):$(MODEL_VERSION) + modelId: $(MODEL_NAME):$(get_model.MODEL_VERSION) scoringScriptPath: '$(Build.SourcesDirectory)/$(SOURCES_DIR_TRAIN)/scoring/score.py' condaFilePath: '$(Build.SourcesDirectory)/$(SOURCES_DIR_TRAIN)/conda_dependencies.yml' - script: echo $(IMAGE_LOCATION) >image_location.txt From 27b7d2a7bbf0cd2cc73a549cd7fb3d5e3a8e6f95 Mon Sep 17 00:00:00 2001 From: Jenny So Date: Mon, 6 Jul 2020 18:50:33 -0700 Subject: [PATCH 11/29] Update docs and pipeline status badge (#303) * docs * fix pipeline status badge and tf naming uniqueness * add a note about how to change the name of the pipeline * extra clarification on workspace connection --- README.md | 4 +- bootstrap/bootstrap.py | 1 - data/README.md | 3 + docs/code_description.md | 8 +- docs/custom_container.md | 6 +- docs/getting_started.md | 22 ++++- docs/images/custom-container-variables.png | Bin 0 -> 16148 bytes .../iac-create-environment-pipeline-tf.yml | 2 +- ...abetes_regression_verify_train_pipeline.py | 79 ------------------ 9 files changed, 36 insertions(+), 89 deletions(-) create mode 100644 data/README.md create mode 100644 docs/images/custom-container-variables.png delete mode 100644 ml_service/pipelines/diabetes_regression_verify_train_pipeline.py diff --git a/README.md b/README.md index 0f9ab4a6..434be0df 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,9 @@ description: "Code which demonstrates how to set up and operationalize an MLOps # MLOps with Azure ML -[![Build Status](https://aidemos.visualstudio.com/MLOps/_apis/build/status/microsoft.MLOpsPython?branchName=master)](https://aidemos.visualstudio.com/MLOps/_build/latest?definitionId=151&branchName=master) +CI: [![Build Status](https://aidemos.visualstudio.com/MLOps/_apis/build/status/Model-Train-Register-CI?branchName=master)](https://aidemos.visualstudio.com/MLOps/_build/latest?definitionId=160&branchName=master) + +CD: [![Build Status](https://aidemos.visualstudio.com/MLOps/_apis/build/status/microsoft.MLOpsPython-CD?branchName=master)](https://aidemos.visualstudio.com/MLOps/_build/latest?definitionId=161&branchName=master) MLOps will help you to understand how to build a Continuous Integration and Continuous Delivery pipeline for an ML/AI project. We will be using the Azure DevOps Project for build and release/deployment pipelines along with Azure ML services for model retraining pipeline, model management and operationalization. diff --git a/bootstrap/bootstrap.py b/bootstrap/bootstrap.py index 9e52af55..02f51bbc 100644 --- a/bootstrap/bootstrap.py +++ b/bootstrap/bootstrap.py @@ -98,7 +98,6 @@ def replace_project_name(project_dir, project_name, rename_name): r"ml_service/pipelines/diabetes_regression_build_train_pipeline_with_r_on_dbricks.py", # NOQA: E501 r"ml_service/pipelines/diabetes_regression_build_train_pipeline_with_r.py", # NOQA: E501 r"ml_service/pipelines/diabetes_regression_build_train_pipeline.py", # NOQA: E501 - r"ml_service/pipelines/diabetes_regression_verify_train_pipeline.py", # NOQA: E501 r"ml_service/util/create_scoring_image.py", r"diabetes_regression/conda_dependencies.yml", r"diabetes_regression/evaluate/evaluate_model.py", diff --git a/data/README.md b/data/README.md new file mode 100644 index 00000000..a25aa451 --- /dev/null +++ b/data/README.md @@ -0,0 +1,3 @@ +This folder is used for example data, and it is not meant to be used for storing training data. + +Follow steps to [Configure Training Data]('docs/custom_model.md#configure-training-data.md') to use your own data for training. \ No newline at end of file diff --git a/docs/code_description.md b/docs/code_description.md index 8dc3c756..d30295e9 100644 --- a/docs/code_description.md +++ b/docs/code_description.md @@ -8,7 +8,7 @@ High level directory structure for this repository: ├── .pipelines <- Azure DevOps YAML pipelines for CI, PR and model training and deployment. ├── bootstrap <- Python script to initialize this repository with a custom project name. ├── charts <- Helm charts to deploy resources on Azure Kubernetes Service(AKS). -├── data <- Initial set of data to train and evaluate model. +├── data <- Initial set of data to train and evaluate model. Not for use to store data. ├── diabetes_regression <- The top-level folder for the ML project. │ ├── evaluate <- Python script to evaluate trained ML model. │ ├── register <- Python script to register trained ML model with Azure Machine Learning Service. @@ -52,7 +52,10 @@ The repository provides a template with folders structure suitable for maintaini - `.pipelines/code-quality-template.yml` : a pipeline template used by the CI and PR pipelines. It contains steps performing linting, data and unit testing. - `.pipelines/diabetes_regression-ci-image.yml` : a pipeline building a scoring image for the diabetes regression model. - `.pipelines/diabetes_regression-ci.yml` : a pipeline triggered when the code is merged into **master**. It performs linting, data integrity testing, unit testing, building and publishing an ML pipeline. -- `.pipelines/diabetes_regression-get-model-version-template.yml` : a pipeline template used by the `.pipelines/diabetes_regression-ci.yml` pipeline. It finds out if a new model was registered and retrieves a version of the new model. +- `.pipelines/diabetes_regression-cd.yml` : a pipeline triggered when the code is merged into **master** and the `.pipelines/diabetes_regression-ci.yml` completes. It performs linting, data integrity testing, unit testing, building and publishing an ML pipeline. +- `.pipelines/diabetes_regression-package-model-template.yml` : a pipeline triggered when the code is merged into **master**. It deploys the registered model to a target. +- `.pipelines/diabetes_regression-get-model-id-artifact-template.yml` : a pipeline template used by the `.pipelines/diabetes_regression-cd.yml` pipeline. It takes the model metadata artifact published by the previous pipeline and gets the model ID. +- `.pipelines/diabetes_regression-publish-model-artifact-template.yml` : a pipeline template used by the `.pipelines/diabetes_regression-ci.yml` pipeline. It finds out if a new model was registered and publishes a pipeline artifact containing the model metadata. - `.pipelines/helm-*.yml` : pipeline templates used by the `.pipelines/abtest.yml` pipeline. - `.pipelines/pr.yml` : a pipeline triggered when a **pull request** to the **master** branch is created. It performs linting, data integrity testing and unit testing only. @@ -62,7 +65,6 @@ The repository provides a template with folders structure suitable for maintaini - `ml_service/pipelines/diabetes_regression_build_train_pipeline_with_r.py` : builds and publishes an ML training pipeline. It uses R on ML Compute. - `ml_service/pipelines/diabetes_regression_build_train_pipeline_with_r_on_dbricks.py` : builds and publishes an ML training pipeline. It uses R on Databricks Compute. - `ml_service/pipelines/run_train_pipeline.py` : invokes a published ML training pipeline (Python on ML Compute) via REST API. -- `ml_service/pipelines/diabetes_regression_verify_train_pipeline.py` : determines whether the evaluate_model.py step of the training pipeline registered a new model. - `ml_service/util` : contains common utility functions used to build and publish an ML training pipeline. ### Environment Definitions diff --git a/docs/custom_container.md b/docs/custom_container.md index 8c031d15..46e692f9 100644 --- a/docs/custom_container.md +++ b/docs/custom_container.md @@ -61,7 +61,11 @@ Edit the [environment_setup/docker-image-pipeline.yml](../environment_setup/dock and modify the string `'public/mlops/python'` with an name suitable to describe your environment, e.g. `'mlops/diabetes_regression'`. -Save and run the pipeline. This will build and push a container image to your Azure Container Registry with +Save and run the pipeline, making sure to set the these runtime variables: `amlsdkversion` and `githubrelease`. The values are up to you to set depending on your environment. These will show as tags on your image. + +![Custom Container Vars](./images/custom-container-variables.png) + +This will build and push a container image to your Azure Container Registry with the name you have just edited. The next step is to modify the build pipeline to run the CI job on a container run from that image. diff --git a/docs/getting_started.md b/docs/getting_started.md index c3abed02..629e0dc2 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -73,7 +73,7 @@ More variables are available for further tweaking, but the above variables are a ### Variable Descriptions -**BASE_NAME** is used as a prefix for naming Azure resources. When sharing an Azure subscription, the prefix allows you to avoid naming collisions for resources that require unique names, for example, Azure Blob Storage and Registry DNS. Make sure to set BASE_NAME to a unique name so that created resources will have unique names, for example, MyUniqueMLamlcr, MyUniqueML-AML-KV, and so on. The length of the BASE_NAME value shouldn't exceed 10 characters and must contain letters and numbers only. +**BASE_NAME** is used as a prefix for naming Azure resources and should be unique. When sharing an Azure subscription, the prefix allows you to avoid naming collisions for resources that require unique names, for example, Azure Blob Storage and Registry DNS. Make sure to set BASE_NAME to a unique name so that created resources will have unique names, for example, MyUniqueMLamlcr, MyUniqueML-AML-KV, and so on. The length of the BASE_NAME value shouldn't exceed 10 characters and must contain letters and numbers only. **LOCATION** is the name of the [Azure location](https://azure.microsoft.com/en-us/global-infrastructure/locations/) for your resources. There should be no spaces in the name. For example, central, westus, westus2. @@ -133,7 +133,7 @@ Check that the newly created resources appear in the [Azure Portal](https://port At this point, you should have an Azure ML Workspace created. Similar to the Azure Resource Manager service connection, you need to create an additional one for the Azure ML Workspace. -Create a new service connection to your Azure ML Workspace using the [Machine Learning Extension](https://marketplace.visualstudio.com/items?itemName=ms-air-aiagility.vss-services-azureml) instructions to enable executing the Azure ML training pipeline. The connection name needs to match `WORKSPACE_SVC_CONNECTION` that you set in the variable group above. +Create a new service connection to your Azure ML Workspace using the [Machine Learning Extension](https://marketplace.visualstudio.com/items?itemName=ms-air-aiagility.vss-services-azureml) instructions to enable executing the Azure ML training pipeline. The connection name needs to match `WORKSPACE_SVC_CONNECTION` that you set in the variable group above (eg. 'aml-workspace-connection'). ![Created resources](./images/ml-ws-svc-connection.png) @@ -213,9 +213,25 @@ In order to use these pipelines: These pipelines rely on the model CI pipeline and reference it by name. +If you would like to change the name of your model CI pipeline, you must edit this section of yml for the CD and batch scoring pipeline, where it says `source: Model-Train-Register-CI` to use your own name. +``` +trigger: none +resources: + containers: + - container: mlops + image: mcr.microsoft.com/mlops/python:latest + pipelines: + - pipeline: model-train-ci + source: Model-Train-Register-CI # Name of the triggering pipeline + trigger: + branches: + include: + - master +``` + --- -These pipelines have the following behaviors: +The release deployment and batch scoring pipelines have the following behaviors: - The pipeline will **automatically trigger** on completion of the Model-Train-Register-CI pipeline for the master branch. - The pipeline will default to using the latest successful build of the Model-Train-Register-CI pipeline. It will deploy the model produced by that build. diff --git a/docs/images/custom-container-variables.png b/docs/images/custom-container-variables.png new file mode 100644 index 0000000000000000000000000000000000000000..24a6a92a473c1ce8fdb60fd1dc13cb6e614005db GIT binary patch literal 16148 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 Date: Fri, 10 Jul 2020 16:09:30 -0700 Subject: [PATCH 12/29] Fix default parameters to batch scoring pipeline + doc fixes (#310) * fix default params in build batch score * docs * fix image * fix images * update to azure ml studio pics --- docs/getting_started.md | 15 +++++++++------ docs/images/model-deploy-artifact-logs.PNG | Bin 104171 -> 0 bytes .../images/model-deploy-get-artifact-logs.png | Bin 0 -> 53016 bytes docs/images/trained-model.png | Bin 61705 -> 28871 bytes docs/images/training-pipeline.png | Bin 69220 -> 37895 bytes ...sion_build_parallel_batchscore_pipeline.py | 4 ++-- 6 files changed, 11 insertions(+), 8 deletions(-) delete mode 100644 docs/images/model-deploy-artifact-logs.PNG create mode 100644 docs/images/model-deploy-get-artifact-logs.png diff --git a/docs/getting_started.md b/docs/getting_started.md index 629e0dc2..430ae0a6 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -13,8 +13,9 @@ If you would like to bring your own model code to use this template structure, f - [Create an Azure DevOps Service Connection for the Azure Resource Manager](#create-an-azure-devops-service-connection-for-the-azure-resource-manager) - [Create the IaC Pipeline](#create-the-iac-pipeline) - [Create an Azure DevOps Service Connection for the Azure ML Workspace](#create-an-azure-devops-service-connection-for-the-azure-ml-workspace) -- [Set up Build, Release Trigger, and Release Multi-Stage Pipeline](#set-up-build-release-trigger-and-release-multi-stage-pipeline) - - [Set up the Pipeline](#set-up-the-pipeline) +- [Set up Build, Release Trigger, and Release Multi-Stage Pipeline](#set-up-build-release-trigger-and-release-multi-stage-pipelines) + - [Set up the Model CI Training, Evaluation, and Registration Pipeline](##set-up-the-model-ci-training-evaluation-and-registration-pipeline) + - [Set up the Release Deployment and/or Batch Scoring Pipelines](#set-up-the-release-deployment-andor-batch-scoring-pipelines) - [Further Exploration](#further-exploration) - [Deploy the model to Azure Kubernetes Service](#deploy-the-model-to-azure-kubernetes-service) - [Web Service Authentication on Azure Kubernetes Service](#web-service-authentication-on-azure-kubernetes-service) @@ -166,7 +167,7 @@ And the pipeline artifacts: ![Build](./images/model-train-register-artifacts.png) -Also check the published training pipeline in the **mlops-AML-WS** workspace in [Azure Portal](https://portal.azure.com/): +Also check the published training pipeline in the **mlops-AML-WS** workspace in [Azure Machine Learning Studio](https://ml.azure.com/): ![Training pipeline](./images/training-pipeline.png) @@ -254,7 +255,7 @@ To specify a particular build's model, set the `Model Train CI Build Id` paramet Once your pipeline run begins, you can see the model name and version downloaded from the `Model-Train-Register-CI` pipeline. -![Build](./images/model-deploy-artifact-logs.png) +![Build](./images/model-deploy-get-artifact-logs.png) The pipeline has the following stage: @@ -289,7 +290,9 @@ The pipeline stages are summarized below: #### Batch Score model -- Determine the model to be used based on the model name, model tag name and model tag value bound pipeline parameters. +- Determine the model to be used based on the model name (required), model version, model tag name and model tag value bound pipeline parameters. + - If run via Azure DevOps pipeline, the batch scoring pipeline will take the model name and version from the `Model-Train-Register-CI` build used as input. + - If run locally without the model version, the batch scoring pipeline will use the model's latest version. - Trigger the *ML Batch Scoring Pipeline* and waits for it to complete. - This is an **agentless** job. The CI pipeline can wait for ML pipeline completion for hours or even days without using agent resources. - Use the scoring input data supplied via the SCORING_DATASTORE_INPUT_* configuration variables. @@ -347,7 +350,7 @@ Set **WEBAPP_DEPLOYMENT_NAME** to the name of your Azure Web App. This app must Delete the **ACI_DEPLOYMENT_NAME** variable. -The pipeline uses the [Create Image Script](../ml_service/util/create_scoring_image.py) to create a scoring image. The image will be registered under an Azure Container Registry instance that belongs to the Azure Machine Learning Service. Any dependencies that the scoring file depends on can also be packaged with the container with an image config. Learn more about how to create a container using the Azure ML SDK with the [Image class](https://docs.microsoft.com/en-us/python/api/azureml-core/azureml.core.image.image.image?view=azure-ml-py#create-workspace--name--models--image-config-) API documentation. +The pipeline uses the [Azure ML CLI](../.pipelines/diabetes_regression-package-model-template.yml) to create a scoring image. The image will be registered under an Azure Container Registry instance that belongs to the Azure Machine Learning Service. Any dependencies that the scoring file depends on can also be packaged with the container with an image config. Learn more about how to create a container using the Azure ML SDK with the [Image class](https://docs.microsoft.com/en-us/python/api/azureml-core/azureml.core.image.image.image?view=azure-ml-py#create-workspace--name--models--image-config-) API documentation. Make sure your webapp has the credentials to pull the image from the Azure Container Registry created by the Infrastructure as Code pipeline. Instructions can be found on the [Configure registry credentials in web app](https://docs.microsoft.com/en-us/azure/devops/pipelines/targets/webapp-on-container-linux?view=azure-devops&tabs=dotnet-core%2Cyaml#configure-registry-credentials-in-web-app) page. You'll need to run the pipeline once (including the Deploy to Webapp stage up to the `Create scoring image` step) so an image is present in the registry. After that, you can connect the Webapp to the Azure Container Registry in the Azure Portal. diff --git a/docs/images/model-deploy-artifact-logs.PNG b/docs/images/model-deploy-artifact-logs.PNG deleted file mode 100644 index 2dfee3057bb122de04b0ceea2a7bb1247a623781..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 104171 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 IjV)sAT+2qSh$xE@6H> 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
    LMjdY!oQB+ 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 diff --git a/docs/images/model-deploy-get-artifact-logs.png b/docs/images/model-deploy-get-artifact-logs.png new file mode 100644 index 0000000000000000000000000000000000000000..2249a8d370e86b8bbd1a4718b19f578976eccc2a GIT binary patch literal 53016 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�ar$>Y!7Z?y-U*Xof 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 KCGVPf;Qs)FRfLuR literal 0 HcmV?d00001 diff --git a/docs/images/trained-model.png b/docs/images/trained-model.png index 3753fd7d1b78ddb7b843bb88ac54b46d7560de5c..5bea4fe293ea075da4e08dd10ce58ec09b4a73e5 100644 GIT binary patch literal 28871 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 F{V%?I>tO%@ literal 61705 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 C{76v% diff --git a/docs/images/training-pipeline.png b/docs/images/training-pipeline.png index cbdaf0483e37255375b24d9515f4e5d9710dbf5f..48854513753df062b4608f140ca4b9d853b69c23 100644 GIT binary patch literal 37895 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 UKUZU>k0XyC^*U1X&DkIR2OCCYi2wiq literal 69220 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 z zHNQ%aNoXw2iNr2XaL9CpiL znVCgI-X`ZZ0F|$O$+=nqH_-0NDzZg3RTceIWav49*Q6|boq%R%!s@s-xeXNqmXeH^7gB^B|6BpQvdk^k7{s}RXXtfZcI4L&g=Mh!Z6Yql!3EBP@2 z$B0DUuRdbQTgujoFI1_swi|Zorm-*6_+#}3KT-J)9^Bv{pi;T7v6K&1T$-T?;>{7R zyC4rA>f51BVlv{)A>|Lq(VJMTU=?zHMNuXaFd`_IU>cFKmR)k;Engdb;Eq29veE${Nqf2z#$=q+uha2L z<}_2gzad?TZqczG%VD`lDYO~u?&I~J3xF1Q*k5L$^ZJ{04}%~jTr<;WOe)~v)LfgN z)cM0@MCz*7_msTwaMn~rrc)1huz+fM6cfpy1~ZwN@!hU%_u0GRsQNpE6*z5eI?^h_ zEN{)KFiJBr>Sl5}(hYVNbt6gzlkU(#oKUXh8b@+mF%5l%v9fcVwEdWjDJe-D_%8s4 zhN54ObaFDSR8KOPOB0~<`8RqLyJaU;E3Bd!2Y&mJm#yUUGp%179=)2H;qeWFpoTfVnHolXId3g?V4$=n~H?Ov1z6 zlQXa-b?cVxYf1{}jUDBLWkA8jx9SQHf8?6iu&Vh8{Hxk*$k zC4cKH=hh=yMJ#-ZtV3;MQ?2zEd3sQn0G&G3A=R)sx$YSFGl>Y_{>C*l8aRYjw9&{R zv+ar5lP~cfl#nk(a>1b>rRXMnPM^lV^J2M2%ljCJL%vsVq5>gN3A<}?J2bnu1gTd( zrH?kB9*CIiGEWmN1eS0VZj%^!G&7h*(`$hG*{@bpi@JLs)lvtj{Z$WV2a3`hpIA{-DBvXq7f^usEu%_&eZ29U0b79*1O(K1{U5sf4W?=z!$&(s3E^DQ=St9k z!4M=mNI*bc=#zj_S2`@KXk;9hiYpP@Y|I@_Yl;FN&IW}O^Xn(U3SWm*M6Hr&j4;Cr zPkj6~eox0h&QHEe91(BS`WkO23Kec+ah#sX*zD<40PB4-{Z6Q91_=_~wYi4n#r>|Q z-_KC!1C3Y*_SJ73o^1~@o9>Njo2?7@k2&-}gilVTj9y_a`$N6 zf>t02b#+J7@BAafo3`|tr`JMFd46T{1ayZgk!k(PwWh@f3E_qIsi4r&B&Dq0O1GQ! zL@s2;`a|iHx#O<{M%mVjeC)IDzTH59Ka_`kI`- zcxXkUIpV!u7^=Q<*m@0G6lX+441`BocKO6j+87v(*A|#@2L#f-B%q2WZi%B5nu6z} zav{P*^C-ZCS=*Zt2}zt4Y(TG?RY~gv(NjeR%0d}$aK{9e1TQTg0bYl99}GwT+bi0 zI;h3fu^0L0vA8rF0@1}s^stQ5b?8KZ_>s@aQfh>E7!w*JhG@#M!PL~1Ta+7o_H(KX zCDcq8Hyh%*kgeNzoin+mA z8B`ibfppGeS3K57lXQurQAr3b2?kjBXw@9Did8GL2uSvx$4DOCezvMF z9tD{6$lrd&T?tpeUvTe{cLs<9lP0L1*P2V6x&SI&@e)i!-bZrti@4)0Y{(@i5G$czpg1%&?n$IKDp%U``-gY zi=zMMg*@)wb@^v6b`>@CF@l$u1ZKG1^gRzuEUbL`H>!mU+CVFh^`SS>h)5zq<71vZDaCafhR4J98XBSx zFI$dE)z!DIunCXc2Fm$*D}ex><}+TEY!(>f2+Vz@hZhTH`a7V4_fRy>{jS&b+(m+A z_2Qx-NS)mOR-NM`$7nYgn6W7)nGmy^CPmYI^FQn1i;+xFPl;KuQv;L3UPnj@BfFex zzMlLLwBdQpvDX2Xp_q;R2j3-^ToiwAN-G%mqoK9MDcZ4jpw9)w?uGU)c&!y z%#nj;pW^Qg6Jf$ncD$cl;l)s-@Th@9Uos|zoQ|`0tw!`P;P^j-OaxX6)Afo;*0Rh9 zqxoPlADM(A{bzxV_#thB!FDDE^IPQ8Yx)nT5baR8wr6(kiP4^ay%J-`j^g`puI`9V zJJ;$(pR{^3J#NqPx_0jG3-QY(EkUQ$JO4%Dxdw8~RIC5P)LRBb5w`8$(%n+hg5*j| zcSwhVxOA6Ak&Eo6Ay&JaMCl}`Wz=xTp4I3Bi zg>R>6%uCJ`_aw+VHK}+-4v4Bs2MfPn5~XdP)8gzZ)F_{nWJl63I*hBXTGxH}?2@P4 zaXt70;aZChkJv+C1r_EU?ZcVDS*1qVx9sZJeocu_qr?tU_OYEiQypQl185Row3@tX z3Aoeg`x(?trailYx{GlBh0`MDl{A^Oap0AkPc7(WcRIEZ?2@m#>)Gp7`Xl;}wl0=u z4m;>aiy!RtUY7cqu^vn}*#{{xT(a#K_wK6eG4D{qwRi7#R)0&`U%&;~iun|8AdasNsVN zP0;;b`S&NFqW1mWI(X@&=n5c^fo2T6D}9c;(cn*m=>6}V_B3BMO*Rl2vTyI@n^a_m z)$-FJAuJOo(bH3eVH=qarh||-ooXgU=QPGJ$M%YtA`uGpq#LjY_iLm*;iEQsX)*G| z7s)*yY#=3nJq~$Qz-DIlWXcDe^~1RjXH3mk>(O@Ou)crV`e zyNjska!=BI-@d%x2qUB#V4k4BOgrsMy(r$Gt?+jqvp75k|A*^sEo84_f=^;Yck9s{ zB|SSE%a@|x_f@>%Cwrc!+uB}Jx+f0pblN_=UTZ<2Bs3;FwV;A8{(2-d!5t4b`>`JR z(pQCk26#;3%hW}^M@~IHS4(T|oGu;2a7oc=K&^|1;cHWm6@F1fp<^~-buC=>-bEqxM7 zlG#F|ojLG#9mYK{)~pK*Xf^*4qnyd7LhAsoxso_c)wO5QC{gBe`u*dx;he`ttcsXf zOsf!TEkMd-;x2khhlM?I>fN0ErLWX&Xza#3z{JA*)pG_Yt;21eryx9{6jSgwr#}M5 zA_BmC85V@a&dJsVh}w+dG=5FT6N`Ly3t&-ypaiX>cHkez(gt+r&#i35vw*MlW0~9_ zgvxxy_p(7UF_6%P+IUsU@9=jG_PaFEi&^RU1{+I1bkJ9FRQ#-Mbg1hVSE zXB5@t@A@^h2JIj2uBTOx+U_A|e`jXaZ>{}zXTHacTkNQKOX5~jA2x62OdtMEY3xR< z-GGQTs5;xde{$fO0e}e!qv;Ke7D+@8FwM1c?*s(A4s0?`iRuvFyOY7mT5~1(D9c>m z#-)rS;I6$@Os}ZU3RJtlIj>uu_EUL}>q`@jh)gEuDR9H%YDrjPple$by4#I|a?YqW zmLr<-jfrs_V0W-&$fL&rrP%!MSc9ato<_V;1=;VFO8gjvIj5n5?-SciV%ydWsyVz0 zn3$Nz`v-C~zGgEHxnjOQ_ulwiIjqeOa*>P=TJh{DuQ1?Ea}5LmgZa&Kegl5xu0StR z4z|=Wv3uo?#|Q8I-rs_EjAnd$C~m(u^TVmRxrc?HxzCxCUUxp;inqSYSL-+#pa^R4 z-e9L#0L%Fo#<~QgIC_~5G)?Iak~6&?Vi5Hu`+2kHp`otMJSKXXb&hgFWrrtdk(K|q zdW);%9iQFLrhx`E9eal+>w@pjNV5K41RM*_OHr^$hhlakeJal~lK>X4yg~AZedf16 z&f4Gn9V?BSPxos@4!$V|=n0HC(=}R84J1E9=65P~m+QeeEo4jG&1&N89CfUhd`r58 zcTZ0A-NFc51-&qBVeWC<{iNd&&k}>dDVAm) zIrZR?wXK%Tv{~}%hlW}v3xqRm4H&A7e3O=X?1SUD2kC*Z!ep-rjG~P@#%2Y82*gMJ2>kMr50_dO zx_&I!w+;i?k6n^@Fy+iJ1C<2YK}YMN@0cheLIziG%fYKw8#0LGJz(;vMaV@+!oV&^ z^NbVRA~QBIl`z3?l{0r>x;*fIpdY04uDCn@?%yyRC>evW3aDNDqAl+G>?=N}u>@F* zRzIh)DN#^R!f^T`yCZxc+k1scf@tRNwsEP1$Q(`MeE=Ev7wez|rljCn2oVe*p&Ahq zht~ngv0CyfQHi~#g$Jx*>0mBp#2u(CnO;W9uz%$L*eU{W89fXxy*T{ne*C+uc zg?(>a=uN>VRn1#3G}09qGhIuR7x@?N5o9Z^axeqzr2}cwc4NeB2jh#^{LSY-)St%VaGUp-ii3H`&uaJ zyc6_^_52$o8)uU-{9FmEFWqm*b;R|V>f(@5xB2@JhH=ZC-t8=3$U*Z=&Rf4H)flrW zWFrtEK2-d7bYxCrf!f56rV?Sd9cJ%?=I|_+Nd>p0AcLhA*CgP9=sWA3k5oMy1}<}a zfNegxLp9fDXDz(qNGeBONuMSBH1NwdbvrdJhW}MBP3^pRU{T}+*F4go3UX2UNpdDS zI^_oX%ufI*H8-U+gVY@K5vkQvV7P?r6mXd4$GsHzUlzbi->8nED`bP#!}*2zL^tUN z1T;!o>2M%ith#PgNa^PCh~uMyXYms9c*o361G@IxEh_g#;|-);@?Q4#v-j77;t$3$ zX+Hc*E=l?ui!ug)vq#Gh5UR1At4r}Digr)I`fSn{<;nrrlJ~tR=o+T9PbKmcx&tX5 zLVjI1Brqu&2Z~kVa>(6W-E*wM1559>MukX9?EEV6%hjXfI*7=jHL1(^~|5d%#MENP3eQE?YLZVzmN+0Ts}OsdU-7TN~4 zxFsvaKpd1s!DE1$2s%jUUhgj&4(OxpdgcH)4d(O--QO!G8wHzN11_U@yB|whDnm41 zAX-KwkDLc9&j%r~3B(`CjV6p}|TgTx&a zyg0s9Px|*A7;ME5*0f*MIXWq+s@=0`Pqr@X2{+ppcVBW%+q9HIQuS%rD?64BXE7= zUt!COgrxfFgQ!gC3RJqI_%;VngQ8!>2$`H;ADoWCu81H%6bM1he7`aCaS!^YA4etdf~(3Gz3<7G1t{#IXPE_)bEzk_Bv3Qp9HW7)h4iW%96^{G&wu>0pjls2nOK_ ztNG>FJ*kx26C_L1v>wHlJZoSXf`&MJ9YqX%O>>{d6-c2u|D`cJeQJeVyyoHEwEK#m zCBO6{tweP*i^&~|cNGizOS@q66vtq$V6NDUe1oQ_<8nTPk%>2M?$4v71Xflz2RT7! zM7d6T4U*Emi_bri3it+?c`=CGum93~OBUuM{sS(hJzU#!3?E^Ar9`oaz$g0dop42( ztd1VboL9~_-P!}qFJ^jP_Ys2`l%g+Chua`=(E5;J@#0A)*YmS4RFW+Elc&uhX_8*w z%S+D%rkHS|YaJYxRNlU~U}nl?)gENA_`z<% z6pM{1)1Nu6nC(K9E1)2FW@UlUw;HmR-iL{WWp`|L%2MJO@yz5#ZK`kD7j0+)P%U@#At9eciB z_+~wR<2)Y{A`NrIzWep%O0+?(=qWCd3vX|qxJ7q z(sJk&zJF0)W4-qqVJQVuO;E9s*ePW@0xz8s8pp-%4FRWYb+kRew-Rjo9*NZ6)&blR zQ8>nv@5F;F=w$1oT-T?4wL#`+=h;e^YOY0zoYhjuqZA*nStUBeVtn?7$r6@thdwA7 zG7LS(wg=-hv(qVpQ8Er3f3KWZ2Yh-kRz4P!_U5c|EDSJ@b*i3}G9eSEZ8&2aApVZ_ zH{?x<1H3M4|4M^qZ|q!26!1iP(+hz<)G?q>bSFk{g#9`VMDU%j>2?YO#jv4Kxx`zu}#pkDSogQ;o1ELQNS7`kgcRk^258Nw?4?_ z3kc7UdjxNI6AYVrh0}f)zP#nq5V!__LJLf$&i&4)ilUAX-DT_>UCLt53>`F>XOrid znpC0LJyJ9E(XO=b>z|up7)cMx-1>Op7DK5$1F%*La+eW?6*$9GOO-)buD6&AI`r7Z zIDH#qWAc8;QJIU!`NXl?sdOz#(JSYVs3pD(NiZ3sC%Y<57g-bgdnj&5&?_27lhoJp za?~I);GGnYlZEXDGL#%A(_Cn@v61QL@MCwd$$a*C5F`7mP&ViQ4emC1^LE+7# zgevV2n6HccXNG!u1$hx2qVl=`BY`}qg)5=yq0iHhHipI*FB;=8^K(aoSlBBpC@m4G zdw;yqagkqgugsq|ZRg#}zPMKdJfi|r^Ifm87=bR*O6`UrNe?m|s(`NaJn4lUs-Tqr z4aMQfU~Y9}q8OLtYc~PD2kH4Pq!7Y^6ELei zgM=p3?1)q%&Adn@Hw)$GTE(goxDzm2ug-J)TQ?KiK~wT-d5i@wt2wo46nr72b`xXB zu>%IOGrJ zW)#*RaEjcNhd=uZOXt~bHvKiUR>XzmY%J~8v`TA$PZvQ75&j%O znCba=@uPDtq`&W(f=NbLV3I<#`HLe&0+$+iloXg5L!1;mYfjs}@O0fE zGJIM{ktGs+EqPfrZyuBP2hQHQzJTIy5=^PK!Y&raXlyQtpnQOI9}}`N~{k za?S-%RdFLPK$-XDvzc?fsx1-9p9ga)z26Dyz!zW?tx!{*4KXc7q_}YLTnIBCf53(- z$KzWt;vXBaB>43$W2dUREt^{|Yy^iADk0fnOLn~+PNa0dUkz|ghBHHNb-@N7?)50} z$_h0gI zwG#{xs#uW}g_l_C-3^%Cn=L(pyXVQC-8x52Y z;`@Y6pVX+|V+5$w>Eypj9MQpoZRaxc?cvz=Jx4n|%8+z9BowZ3Gy_8BrNO^+XP0|DqC}!QIRw^}AtR!|oW`gnZ$qGu%;mG+tj@-@Yk4 z^3-9Z-$R+}RueN*KZHB(M^iX)1$=X^9q3E&N8E|NtwxtspEG2|^1`y+KVnhkwHoGOYPKQ%5Z?2}gFf-yE85y19&8qB+S6TJ- zuY6+!Zpe~QZr6u;1??m=<|=LxUzdY#nY}dJ_f)d2@f-%#3@r)@vcWIm`+>vB4_K;a z7!_J)2=ka(WZ@GOf@kLQgxbnEXQ3*scC6>8uAj-$d?1B-_ZtN-8%YBm0@YVZ~O3#;0=% z$+s06G4e5f$j2KeEkgrj*E6O840-JPO8M<}X;*)0Z`ZB>F(u(C)Za;s#W_EdhK#k- z{31+ajIjYpY4CicL4kTOVxL%?n=EsDq6PtN%V)&op;&Ld`Js7hm+0rO13VZih7Gq} zADC?Vs|dDD%rn6}Wz>o|Cw?ipwe`LjRHUuNDf9POoApM|ty6AsySO z?idL0vGne&{&W&T?=06+9#e59GAF|E-6w+A45@YiN2`U6jYCU?k6!%pz}e}T4(;Qo z94G^u2Dk+`W0WoP`#@Tk(Iu~tS-1lB+i-;#g`n0koj3MN*Pqd{v|3W zuD^8*UD?PmBNCb#! z=M+AAyf~C^iq2nhT+UqrGStFFsKdmQ*B;JzjlC{2@$WUh)<4hCA|Bgzs&&QQry4nP zs6w&Vae!p+uW$E-8efTamJUBx6LUBA@k-CNJl*kXR_4e(cY`-(OiV%i)mawv^&Y~zK)DZ^A#)>C&CcWNs85CzMqE)oF| z`8rS0ijwd-DvM?X`UIpBpE73uHn*rgf#4 z9^%^(N_g%Wk+UB*rg}x&X+%2;Ok=eJe1;38!~1@C)6xZWBX{2j*yJ`w@6#|y+S+R+r zDanrXAqTMp$tv(o&pSq_*Fk?CrSkPo05+L3VC~gTF5^EhUXJIZgmSPC0#Nx14&vFn z`7gP;0e<``y0K9VoXp}#)(#?qMFA`cN5Yu29it<^8m_NbJ=-7S3bJWS+rzeFR9n;e@mJhd1SnK8F6*W!;_l`7Ee?i|D zCT}-d!z()7cMMNI1d}5I*8(w4KXi(l+HiEj2F_-)L1>4=jx^P*ZU|fX0}1)# z9U}pFf#c>2DluzPS6%@CHJ^O^vbd(-`F?^pFez%V0DtK-Uf>E;K%IE~0?1~JC8WLR zmO!1=0MaiI&zY$GU7(n>DVwz9AbLqD`LXvz9AUjZJx+un!AxIgt@?H7&B9_!@yRbp z*1-N|Q#@+E3GAJIej_iCJu&%t(|15}LQiaeX`QHuFml2m%QRC4u} zdd>_68<9C3jnsJw`<(HIp7$Z9r9yG^ra0x8b$oOuYBENzWxIyr_V}##OtkC4G`=%T z+O*_0Nv5+b23jxebp9lz{__0d{Fh16hRE+-T13|oN??UJ%GS@g*beYpTK3K`wy~Dy z18du82(*%HK>jtT*zC3i115bGe9~04@1~FR!;<io%)^#wp(ahP^Xb%zYf|x|xU2=9?}T1nnT#mDcGuc>)67 z#7Jmi;8SD*EXs?MZq{CzxYOa~xRlDmQcJkAi7c3T%G^^&oT-%sM>b^tA$*ky6ry<~i-L`N8`Ey0NYp)Y%rOltUn zJOl2TPQ$`~mR35rH_*Iz9D&_waHoT@A^HEufTq|sEIQ4fplt_by( zTw0Q!L5hRF&TA0US-ANzZ|q?63gTH@Db_h7yV&(6dga4}LZNBv4WZVrci|a2`hZvN z`2{`)|$0bBdjP zWUMSbF-`9TJ?<6BzV*7P9i8fhvaa<0C%r^pwGon%qW||@l(6%~((0_Z##~U{hY99V zH(CjCQ^S5HP zdL}ECat1cIvmg0#5DQWNS(4}E09$^9+?c1iXlC}kui)HA9>o}R1_S0{;k;U7gbLl1aO%8yv=0?0M+gXp6c)ik-t9e?68F@5r2GF%hfM*@{v@uVXsn|{MKalb%+_nq{T?SE;LPv1=e>nEjkMI4{KQSR5g#YJy z>?CN}IHW3YB>I74N(98!&Qlakb+%`O$ccZqra{Iv#NG4U`~9_UK%C^K`{;ORt>X?v ztTT*VA!42GpUJX<7&vOZ7O%AC`j3ETuA;`Q;y@_bfxYdg@?WQ+CDtft}&y(wb=Y;Iv2O! zoyQzNIGJU;PS^P4hn9JLsr<6ws$XxF;PWIq=1Zf^xlF0NUVHLq5{N_Mfw7ALkRWHU z(NghEANxPI+6E0#n@Iwi`aOR0rq}U@9zTaYkB;ycp-=Cqkh3(~;3I5KC;g;pYB46(SE;8_%};#iq`1k;&3 z1D2M;6efo}NnoVGg{y=M3!?!J?p6y3qX6)E$f}eIO6a`XcunGxkEi0iC?ue3&#IltK!*?=kq)4+0O^fW%P)Gejag)vfnS-TZnLa0(oI1 zRBH79`21M9YA1$K3xZ}=t+WpK*jp}2j@)bsXyG_*}b?qdCCj;L-_bad=$l3RBWN)I9NJs}(6ZAdk1ECs*n)@Zg3JmOR=lJ+iSf~iKJ zCgyxCoMr@&30~^)XAH%$;NJyi0n=lps5IhIse}d~4l60P3jBT9|Is%?$o1RsYbCrh zx}zroX}44@*WQ(`y;Xf10C|UipgNYLwo^#V^iAT-)Xn+U^?#ESe)B#(r=Bss(9}rK z>r@n_^D=hIzSp#Wi#_@`qNy) z3}|SePjGT^xb@OeaLuMlRqI+Du!3PC3SE~9ABjVE9`^tQ`7ipe1vzFkK5n98Hwx*H z;~#7eoY&9X(~VU1VpBm0-`RIz4gFkn%PXUfYs?K zPPRIR-?67pbMkalSdG19=OsNOU_JUr3wvE2zTU5Dt;+Jd*=-EWY{?JaM=+L>0~y&? zGm6fDU~#eQ0%`!i`Mw!&UK9f?V=X|9DLy{jo10d0c%tD^+gkHzhl5`JmtTGpBB5pB zUV_-UoylpaCd53v^IO4fsVMksHkk-pRd-h)QZb-DHyWBe-e0CYr4PV=@{G-9a}}Wv z=G_2zHx%GrZQbLGnt{Lo^U*9px3v2wLx%t3t>F{py9rGDe+d6Hho%kder`AS^iV|O zx0~l}28f)Wlf2GbAaVdE>?e}*J5+7vd5ZhdxD{a*Zi#q?e*Bya*F^Pk3r%|fllQne zkmLuDXgQl8kabA|l5BQ$+5`k}VtH(t4It`|r=a_!tPqk&q$VWRBMW?QhBu<@a|}JKx%0FPswx>i%!!OjLzo2H()}0uo$fD4Rnge0KbS zq^WesVqOg3_L?+(v;MVCg>SAeC;5~+$M43P-Us+XGquw^ULFF9ShY>NVW(d)y2h85 z6W)KT_ir*pZ8`~|+J(H^y<74H*Y^yqMK0%>NS3p!N1L)(E%a}0(30FX(L^;DG#A@{v=@kdZ zzHafS3dzFNH^I-Kf}jtQ0<;@q9)*hz8#qqDEbogfLlWQFrPuX2GIR*YE`5zB zavVUA4?r5i%dRu}(}QyrKe?-kBICqvhAv1ZzK;p*gX&0JCn;h9oKWYnxB_tUgESI0 z!#p3iERdRqU_SugHYRNIdOMdCBzM?U({wfo{V5d<0e_c|dlU7Fozm55@E01y#yc2? z4}VY4sOuSEl<@}LJy{4$?}+}rRHqpb|1e6Z8i`Tzf4uN?P8@10cKS74X%>BP?bO{V zo}h7fBlU3qz+9dLxiuGp8M&Sa+t8djpI5z@5-d57Bx0JU+5(&qpF$!L7WfNl0k{m6 zF{iw$MG;r*%E+4)&G{~#PTCA$B5PH?fn=-4f<)hfP$Y6_#X;hn<4LKtT)*&uXh}-v z-&|kaTbfkOwO+oxJ0v(3H3qYL#Nn#B8B4CA5j4HW5Eci$!J**e72!UoNDFR2E5NH^ zilO%fNbZ|?^Ui5OS0+o>yT=6x=tgSFcAFoD z>~!I6D-FbpQu1T#F@aL30BoFuZhG!!rF3O8GdjD%+=$r;=86K6tU{Xflu*xa9L%Pxcvr zW*YVx->aq3Uo3mmG~mb91cKEG(dd<_Y>{J4yQEZ7w#?H>d-U0Pid2Xd|(IpsriKZ}c1x?ERiviW#JPGHz+{Eyv3dLfR^x)J0mC zCWlTcZb#Kwl5fj;MBr=>ItKFv-`Hi|)ome0afpXm?RI$a8<0ful6&SSN-%XK&Vi+<(RG*JHMZaRuf3%tG41 zV<^NwnsiTdrPt9?7HHcbNfE2m#xt}(xQc1r{b{Px&|kaSA@HDS1L6dPAP(cqtQdW+ zHFq$dLtw-EJm3F{?_Gzf`e z!)9@0vxa*^uyo03HJ-^Q;l4ZB-*;`cQM*y&_Hy<98B_&uK8_%FQ!C7fWe?LK6$F_R zDMcA76}evHqum@mC1o%`hq0lu#6SY)^EM&ef-vHdVbzj0g9j%SEMW5u%1$^X-kVjh zqW5M>nycEBXk-1hr-vcojL7Gq3omayk^fZ3U*6{JAYOqof zrSO;+j9Xi8nd7PT$wcahfCL5TM2!&PM}&YU)2srbAGJa_vbj@H;TSO7OBYveEwf4x z4eJ2jqG>M~K__tJj5M09wHK1?YNl&iKgP5eMd6P4680qAn~tKi9s(dUu$B94e(6%5 zM2ts#Aiw761_E+w-iE7%!#^ml>xER_2=dUb5_Ahk=B)c$w|gfYe2McztAgTrWZ~9` zOh(amk}U2a>%OZpeu8pb8+SZ+nY7kju_OBs6N!IP6<#v-8SrxsXR4!D(m5oH(8laa z2rspBNDc<2$&sDlb5fpw%vak$!jb+j5jSb$Be9cH+9ZQf8y83XcrSj9Z_|>3g?4`s z4XAP2Y+09PH%6fwG^G!pFfeFM{+Xap%7XWd$HLS02=zQFLp{Mx7M*z3q#W9yTtE2N zitp2NIA>qr{MM(ywsvyVEC>1~8+_0})ha3N37UUP?I+B@Z$z{p0mT>dZ$2{^9{!PJ zbeS{Q+deW2$*->!Y{{<$e`)yidI^irJ;ZfSz?U^U5dptvt*AFnEYCX&FF9*NB>Pr0 z$C;4?eu{P4n#-GBdjQd&S|3sqyUb()Dh@LO1b?}4K##RX9=Zh;Aq-OUW+gdAAjM^! zcI0TN3ik7zFFa8Eoq>hARCAz3GjlMQS=+g08Jd>E6b!ymk4;h@;jF*AQxg*$1ASX- z=vijuv%W27okd>;l2mow27;8@vk#1y%*hY>Nez>Cc}kR88~-ZmL(6vvk^U2&KtfQ) zjlfMsE4kOW?BaVn2gt|*+LAGNE$rMeSR1{-rVzYhH6C7ZYH2Asd_U#%TnG^G9fH>H z%ec$TMmE&6Pi6(Z=N^v3#limJlp?nWbr%9c-hZl-@dvmkpEbBi1pv_k$llpVsbuT4 z;%$Ry@ZQV8D`m7%*E4u8r&9bK5{qQVih79SgPV0)cS5n*qF77Cd3QKXIx(6kIA?1! zBA$lN_Lgw=&5R!X9e7J<$4K8qwL>*pZeJU5qqipEE~HG(ALw7J8S%@g5fnc)Nx6$G ztY*wrn|_UmDl$>wwFVV35**_Uh}?fjaF#-l?7rUEx~fS&0M>wuja_Cx@4xM7Z5Mks zG7D329}Qg_L}j<8M-E%`Li!_O?`=o7GYtS=c86%HD)mJ}&DU9~BIIqM4fpo!00KV1 z2(bVOX$jjV)PG&NW%=K~M63o+7uc&}+aij|JJ}TJ~-@pVrOXjN}B# z;S-Fw62e;QN+Zrh*2gqbsZ~2phz6idH5;(ViHTwNbp7}uM& z!+r8t=T05)fmn%#hEVG0gM@WdL{z&8P)A-yw$E7J`lMbSP_>RN=d>Hi$cr>*2;VT1+aWr^652vG+47Vm?vl^YDd&86{LMQI=%?fnG^Z=Dff?8{XFo;fG9yOm1<+9!$bs$5Iy$>%O28`A)xzE`V4p+qL~Hg@kL&u#lh& zQIbh7RZxO>&Oz&=WPmMt`AhRw(7%IH1~$;IlH@g*!UQP;G3C1Wq$(V`*~fv?Q6k9Y z$)IbZBSfj#q1RDGe|LU8+)sL;DVIk=XOvo|^PAyw)W0*m!3@NtlPJz=Q7?SvWKI=0 zBGI+oqlx;Bed_5bfr<3$bjUmHxs#iN*3rc(8^5b-U**G%E?CeLVte|=oG*{q&oz1# z&5A#RFvl#QYp?(GNAU}v-3umeu!Sv?E_z}@k!&={@OZxTCXm7e`Ci5a=eC&! zk&FAac@4j1XGc`#cZR21ojkRNwvBTZE$5xnRjOP%X0TR{p7dh`AV@8l+hQhZhu*62D7B3IB9vo z7VkCQpAVe_q-j06_qXb=S+AM+;L2f{0##Mc=!?h7y2@St~lsYPQ-q zF(DzJkeoI6`T5a`;nvR#`lo3UFSXj-{ZXr0yIUs^g_oF{o9zBL=<*pf=~)^o!a|E^%T07m<_-Onpd1>zzY3Y0oZdylXQqUrxL^BT~y>r z@c;SVO_4`FBbYEms^z`^izJy|$2^`t8!>|#cvs|XATY1VfQ^q8mP||ZG){Sn3WiUq ziL)RG9d{v_uXY8(flN3y7AbV(op@>71R(2KZW8Gvu>NfCkCFnub$pQ$d%LF25BtiZ zCn$s%_B3sIn$IZ#3`^*>q)(0yT)`UHJZLefaJhkkHyP-N<(b_9OFOf6PfG~#F7RC@ zKTR9=O`Asl&o%!RK^{>HuyT$$uE0KZeG%?CeoR$RYjR@7q7d-x9teH=G!gh*C7n~U zQUF`D;q!_ZJ7OY$T8Juz3krcv)OsC+r_(_&c6Y?Rf%O?+*!Mv*!ihm9gIo`^gMfu^uG2#zb(zU5(yLxo6^W7=AZ46*aW&e%Ti~F4yfCwc4ZLZc6P7>w$Z*_fI zcqjv3gh=fDqD%f@7@;y9<>Pr?>dEbT=rnB6p*Fi8{@3q{nH-ZRZ-GxOgI6VMjcND9tVVu^2JUkkk^iX*+FV~}G{T3i2P1O71_vUG# zT--FV1rTdyOvY+cd1LG-Wk~tyuwlkPXiiA6AbunN=4F?2w~Uw8RfZb-y2yWTe1$lA z@*IUo`Oq#;EmC*$ZFZ#7W5ji>bX_%p$pb49e)b4_F=evSS=w`_k9xA%wXkT2F%hi_ zL)KL>@;V8le?8coMLR%X378?mfk9mPD;Dh>GgtiZezf=IsbwqvkNSKoKF(B_Y~MP} z;G*_Rv__Y%`rg5Y{FRqF|9wqh2XYh95_J)jhhmXHkLTo zu>Q!84_bPtYUS_HXGOm&B5G1f{5kP{2gKHIJw2%sc9MB_NqI^UGOl#uE&aK5 zh~JL?6Kx!>6`LRwt1{eWz4h`FgRZ+`QZJ2C+8mZs3UYr8cln1;w;#1Fm9^KaW%ei= zB)n$71TIZEV#lCFxWE&tJRK1!gY=y{%!Uawcv%j9QwMF%M1Oifqny1;{`)!xTXx}- zBX97<+wVk~Z-vScD%;kO!Vc&LMo(TPB>ks=$g`kbMJ}^gWSXf(r3=7eJex8`F$>f? zUKbIx4Hp725Z;f46FH|*z-#o_q1_cpyeda)s;z zv>fZ}Lze(_x>r&Pi(T)ftO4R46^FG7vYMWWJ3g%*u@Wi25WYw6tU+sW=P~ zc+cUTSQE%9JW;ouzANR4_f%om5jbF}|LX9s@_qBx=y#ua?MAAKrnCS-5gMYzYC2)- ztoLmRx7%cGPsq>;D$WaZu^n2*gRs%@v0ywg=B6NH(la2+P$3e5N-$gO0e)N<9-W4O zggW%m(6@MZOzgJeu)y!vpO57(e9z6BV)V!6W}@uqfSh0@6;rY@ZbUn#nCvg~{G#Hz zIi9ACA}6DI*IY)(*WGUCTjR3ug8&!LWB)o>!sWKoR;`r&&!AJF?%7v8il>ps3aPf4 zseAR?T@KO5m8nS%jUCL@5wlea+;sz6ACUN*_ep6@6FzOvq!Z&1^^^0Z-$Qjw zAX1eBZThMyg@ul`xDc>>{F3X!Q2*5#z8v%^N+O!`vcx&F2bXmJZOl<$L&H8hom$|bKm?>_B=22gy+&_)J|!sY(`B9DQ1$mZf+QdCJm62(6183tH{$aVc$}D?c^)2 zc3|1j$6le)ct{Lm3fFJkkzvP3&;_4>WN$@%1M@}FXH{b1mlDx&Z300~uf{>(;82WLC!2t9Mdtp35n$m&% z^oi-l;%K8Cq;!r+q}ww~M`P+rp^{26GoNMY&?eerv;8ayq;!q^ObS(ko6Dy2q>O}p zUGuMd%aWKtH7^rEK+BmS=vc@LZ`HTk~-d4y>g^#r&#FdH3;7`P$e7LRl-P^nvA7W3&haa=S8P zh>AyD!4Mibg8g_76rdmLCE?Xhl8Dv|K!23dMYe{(7S>jM%(;l-iOdm3LT*4$^)eEh zGtg+sp%+IeF5+5qh%WBm=chu~Tv8oJ;NYj8frOVZ{s_X2fmCq22bIK`6`9>E5<6{B zoNn$$3(4PC?;4w|DC86yTixf|SLx&bhBs71~|kKNln|K~&;*$HAkz zbAU+v2jlqnSB*C-fFwmPd{7;%ifs`}lr1`qMR|8|xTK4L0PVOv+btwvKqu<8)F`>5 zVpJNNQTU_fZ@yyMi->JY$m`le^id_uKm!X1Y#}=iJf;M4bv|`J=_ASLCT~n#$zWlE z|8il@Y@QRHS5{QEpywHnJlMkTzVp19VthWsCP)3_Y|r^I6`8+WoPZD4QN>7iLw1# zlWI328av^W$eBpbCiZV4*3_5;oFKNOXYYupfGK8ILI(G0sjcVEncHN+FsrybOdCJU zkKN0-DyuN?*QT zh`a4qg}ULfWkMVsfmZLIvh{MCN895Rsik@KT$)}bSDy)0LE8BNo*p)ZLdW>G<4;5}U zYX<3%eZDRP%WM?5exv=@6Eq+OV$w^jEfGrP7n>MdUhalNUEDK8FPq2HGaElqCu7P&SZyN z>qTaCKFi=uZk!YaBRxv_6zB;VY}s=D`2UzX%cv^5_3KMXN(zXybf?nYB@LTyX_Zdt z6r{VmyCg-rQ@Xp6ZqRq_=lP%aoKKE{V=y-Co3*bsuiu=L;&s1Ni_>QFslB;+SUgn* z52-Fi?D~tU(BF%lX;@v~cwR8BUsX}V1{tYil3C44z2hedOQ?v;{5zbGFK4e_+&l8i zbTQ*wzSb$$2e+B2853~EK`#sRsJ?Iej0TldH&9z;o|FkAGnsWbf zQ4M{*Hs0%cp}80wN3BtP|96EHo_+%aq7eMs$+hJa^px?ck6(3b9(vC^f2VJ+j4br; zb$JXF9H-zll!g46<2|T0=^F$(LlJnM1=z_2j@D!sR*gET?J&`)d25mh@h~>1<&&~z z6uDRiT8jrt_jj`dLg zc`vPKV7C_#`}?~TjcP7bb3gRoEjq=NH`gU7dS@~b>u|<#+&gMcu_shSeeWHPI_7(u z_ze!L#$H*PDPo!kBE7d%Z3T_|KHm)x+TI9b)~NA$yH!$J5%cHi;gGrfD7q89u{|iB za7^f?6+1*#Q9yle^bfd<{!%A_R`o({(V*$I;C6fhS5r6pAxl^V0{d9${UjIqyk*FK z6uk9YTz$#Sdew8Fl$7$ zhrRPV-OFH#?iDK|V*~il^mbE1z}w(>VazP+iY7_WhA6aL8F2j9k|K4n+Lv%B`!C8z z^ttcwZ@z<(YY&BN)Ry*}vpd8E=~?@#zf*Ag?9o3LC9pT55Egm8d@z@6g!)iv-XC$C zBE5S(vQ_t~us;WvVS9GdL#{GnB>%4_&h~Gt+O16!E>+lod7*~--~*EcOhy{VTO0dc zrE$<@Tn4{4!nG0y5-Z*_H=e?dM5>zt=|omKi6Nk8H!fB&8o&c$H@^+(SU zexoG29#!{E4R!@t4rd$PB8zs8sKA;h_fMSVhJF3)CqqoLLD8#%jzsqb5?~c|K5r@G2pu9UI|NDeb{#X7z?D{{# zRw4eUtnG-Uzo=7fu$`wy;-P{8SEGqT3)pk$AY*k8m3@dJU1;4-(4nSEo49{kf+`5m zvjMV-32CEYHak2si^HEA9!+gX9Ama&)bn>Tm-zVOXu7K6F|A#cN{q$z( zJoTq4GR7v{&N87}R^waLNnbOBm`+o5q^@f|8`4>H_Md-9wkVXm0A4q-PB#kbz3Gho zIgtiIutQ}6;X95N@EAC?WpkMAcU zpWcsSoy>8!27Im-LJJ5L7CQ4Y==&J(38*#5vtc7oua{{@S9hsSEjc8Ckud| z$G&;VdHloq_$-cD>U*X`?j71rA~qaUOhJ{LQ(noh`+N6W@7{& z!e>b1B8bF!Za_tJuD>R7+lrPoR%3&A@ z1wen22|h}a6Hm3^5=XAVOJ58ag5SdS+@t#HJU>RQ*b3LTqqNU0m-$w_z)QCh6={l~v_@*nm-d>3pP03&X>+*)WGc&zGF z&A)4w5xKheGF*dAY(W6Dh*w?3VLv}{5U?_ZlslkWAWGn7NtKBOBA@iB>+>sLif$MN z9IrS=psaC5KHaeGPd0_2d$YCgfXGDEQjDztBaR&^kp`r6xHH4sZ$2I{{L&n=NXGFg zDi-Ta;P>w2dJJk2{HM%S0FV>{llmDV$P5hq%~2#LWNX% z?v?;kBRx?m=W8m~@aM<@;nBa*iEtB8?%?RuU9kAO2a-Gkr#3|Y?>Q+!@nt`OGsVj~ z*cwb!V{5L59Q&F8 zy$j{#lha6z3v6k74mq0vXL*rBh_GWnvS=JPV&CB8z&vJ5&pey9i}G$lq6w#B4*Gg)UBL2t`f)eY-}S+dl8 zBwA;f(n)Nx;IV(tnk;8>rH`;`zt*bIS(8@=CS!W27<6=(7EH^S+PLQ>^3{Wea}G*m z&VuB$kTA{uU50@%79D<201@ex#uaL||4;1fCwT8F*}3Y|n(_BoqqEAaaxygsvH4VC zavBYdjr9Xnj)!SsvFb5(Ut?5bnr906oik?&-+Ac#`-qqSvy}Sw13ujNQW8Vb=?J1j zUe@TWu7;?iY)@Zd#ys$!W3fmdsZ4OF(S3hs;r|Q6Q0agUx}19n(JT5N;oTfQ?V0*+ z%VsmreY7K-PLfz#{2o;WXbwY2ZCGq zzh8+Ec9P5zP3WMpCi9pO=ZYxBS<)`kX3i`N==<;Y2e0HUk{Sw3&9__Zo80Q#63dj? zjsHs65yJM+;lEtXTi?m_?2$2<*GuD6iz=ptU(x-zs+!YA+n`)Dw7Xv|Ogo&hqNp|D z_rH6>|9kdj!@zi+MSJJ=l+eL`R!tB?(=>US#anarM_{|i0fROHo@bu!`1s=SKQ9@) z96We>8*ImHnj7Ajgk26pf26ji z#&jTt>TK+Mdua0xXXvvnskQ4yeb2+hf8GPA#!U;0YYf9ar1;_0wfoHq3)L6nAkLL6 z-?IMU_+BQ$p$8YV__FLfmA{!+IZlT>c?d&eoq?#^0J)40dO>(_1uY#13yp->_qK%xHcyT=VH0eviAet(2NzZexT7+jJ;%@YZ8uQAnkPWr1VrP9^j3_5@( z(_m#vTRu2RngZ&Z8AIT)D*X132LY(BT>=wrOlD@K21!4rFFze!pkygn>+HELlhp#4 zDkdR;dP}F;IBSJfNih>1wx}q-+9#B3rkck%^Vy%69%|S4ZS44nM;=K)FM^u@ID&z&M=n z{UhNUf?xOm`!&<|l}_&zExuAU9hfq!>B(N+nq#<$l^h{_*@QB@wY|NKObQGC0j#ZJ z0f8hbGXka#>g5)fM3BEG12#l7`%}fSjtf<>JA~Yyvo7~0#7JD%VCtVMuarrodHml1 z^6x*Gw225v0l@7LNF$>nw5jraeCYK)RGNn(oAdMY_FxaS=lRA|qy+35 z)B}Yt-NG_dy=x9Fh<2TAcbyqS|7bK&x(O)uP#A)CM?vw;F5;Q5JldXWIALLfA-xit z<+_{#T50js6mA*}IBpWuJ8W*#Pp@nv>pQCSbK9zWDVbvP+CzrIJcSerh;wUNZ*cZN$qrh&XD}C0(Kv(}4JN@jr&g(vl<{qidvT)-1 zKXbK(b|T9~70Lw8`b*JGNdQ1}S+X+FT^W>>ThJ#ALW-CCr4Ve9wt+chzV94fV3!f1 z&d#HeU}Egn@{VVs)r`kr)2lb&Wq#tcVna9o+2Ndnm7Bb#9L>rGHw*nRz}z49awbc~ zJd=ZeDv=03%lX)*Hh(guS0|9W`k>0hu0u4V5Ya*n@k$9as+`*ip|WHx{aJN{`8t?K z1lk`4jq9+o+1#AwN4_zD|_qWX1+w;joPVg_*Ra8}D8+_dN z18!H8Xu5v%o4(@V;yUWU-4IY?hBX{{swa10-Ss*Xi+C_Ok=bZWTuQv;aiDy=#IWL| z5n(HQJJGi!CHUwg#ysZZB)FuL!7&Nh>!>x}Z#eaLJjc0wBFbPmzp$Au)l~dW2*vva zX`o7@U?D$WoQTWdXT2qdV4DWUYEJ@!i>}t;cl2TRmN-u8&cd3kIbZh1TtZHgmoX}G zS7|0g;H**mg*AT!2fqWOGs7lrYqUo5NQYv=Ri zy`TJ$3{bnZV3F>OQ3N7$ke6M5G*&K=w(LTN!sB8yIUOZk7D9Eal7Z``Q6H-y!%+=w zKu2vYU7TP+hUZdL^Ya=H)4>;wxK`OPjI}tvvSEW__Rfeg1X7{5b!*e9h`6RK+68uZ z)ph4;*dMi9UG=^6JJNU@Q1Dpvbuk%5UwuXebau|Z5#1LN*SSr%r*151anLl+N$*K_ zMX=Gifqjv%wJ;czt^EZLq!tGIoleqngEli%KPnXoc>4-VmbS|n{fo!nU=@!5kUB6c zE58KDy6ms6$9g~De<>$xExY7x4Y=e6#644DJG=Lb_@b~eKLk`%Q7IztKV7I*WM~AH z(W?~n=)R|Znnvw^?n_q+L2=T-87N+wxHT-EIRx2@hi72yo%Xo&{(Iw%0F4*y)dLw- zDK}8R1rl*>@7a5B6rG@Se)blr^6c9Tp&=bZu7M4uLkbh#*mqg7lj;DfFlIaYmh2cQ z2>aO#u`m3?QVlmhAn9jZki@Lm+p5)cp|7`-je2!5~bRBNuw^2Xb>S2Va_ zl_H}pEp0nR_Kqr9?kf`^mTH0OFFMR*u#avOzRK4FM10XTD!BN0bU;JkSe=g`3Wsx` zJFE-izz@Lxct>Ctd&VAz8fJ^~@yFeVo|%`jnXwgaw}0$2f5x6H>`mmNIxpGv`C0xd z#1H7AClI048)+uOH5)qv(sX(0*!F!U z16pjhb~S4->;7)Vbo{NA3Pmm77|h%TBuaq zIz3ZzLh=NKE$*vxV~m)uzTjUSFKUWP<%q?VshFMhf}0Kl*c4}+>KY25*( zY19FY`1>glLQdIDMts$eC>cqTzsmL-rjae)7_cZRa#*W0 zs1S)g9SaPNSmD=O03n%v_!>w_)&1-Gv`bQx_CgQA8Wp0V-C#rT{S?8T(l;dFUTO#` zoy-s36W0rV9M4j`6gUIDktn6PT6Dx-x&r~oIHmvxj~9l&BJP6ChLR(P;sz@?{04cs z9AlznLhdKkQCiSc(t0QX!~z0tR0;SQT2sHGe0W0Ll0I91dKoXno6Xyru2ElCG!w^~ zK{%jLJj<#e_Zgjy{*$z)@a<%v0k73{3m`?Ps%F)%dh~BY%?3;T6J6kEf`s+;E7Cr9 zBHzRAm~}f0%HdqFu>1g@C6M?0XX0PxCuPpC=bRU9sUCT!*rQzZU%~U@@QUld?vSNi z$FGQ?czWNHaaJTa;W|o?vL+EhG&=G~%(S_S8~HPc(3Uox&jpV+j4s=MP0*XTVXN^W zqs43|JlP&39qpB9@V*}PxH`y}%E0yNpT8!F+ZEd#K7B!qu{&(r3NC(e+-%(n!5#4Va)pKi&@fv zRGXSm^d5NY0W7O6ai#C4Gm&qU1r(3utkf#WN~DpNlid{{OcQvM77 zUkye4A#h{xP6!O&J}#=vTodl_9oLzVnGp_w}N2CXk z0vvbwySk5LvOKb<{JUn6*7+1_2$K5A3W&ayB67=vM=dBJ8L_s_9_d~T zb|r+};>kmoE{%3&_|6=GE9s+@@f_dF90jJR?D^UFS+$|hVm&FbuaoaH78Pmq_L5E| zKO$f*V+T#19qi+k20~8~?_5s}c{am2>cmhAK0iqqw2OTCLNKX(M!eDUEIEf`JFp`x zTv!`K#=X#QzV6Hx%M#n95~IV%IX>+!XmBN+Q%UPRDZYaClNIobUvP-sijK8$zn4KE+8E|tyRZ@;e3zr1iTof5scNXo=T3?jH2eG~a0Y)FgkIp>3q9f})4 zAtr-IM%s#Vbhp;z3e1IDU~gL(qi`M%ZxV|ypv@D4CRRGt!{>7o@f5W|@P_o{N7{cGAGYo^mKCVGkj%S{RSJ`ct)GK;uXLgD-@@Yk4mDayV-6Ze1MYr5` zs(H`4Mi($`HPtfv6a`dN2BNK zJvdK#46Ru4npeC|*H1z#Z5O>$R}}Ozt2K^JMD3y>=5w4fICTtZb-cUk2}@%lvmw!y zxinQrWJxMH@R`{y41EyU?XqI#eXV~A^%n}F@|!F-yTnSM;#<;)nxiGJYZ;=Ww}&Ku z?|M1`3k9#ea98TN+3<)o9$KicTRZO6sNa+d{@Cjol6OJdS{wL6SED`s(dzwr zfS^zaIW4opXi9ATbSr{z=0_$vTHeO5*jnlOywMyoGES;8aLR{A#h4g%apIp!FHHfD zjArqDA8Q)ujORJ1-62XTH4+1ipFGo_EgbB`oy%SV#^sf0#MMg2i&>pgC#)M}S%AuB_>?Mm% zGOSfpt7g+};!fQwY-Z)TtpL=h&a;gAKtaDfUC5hQInEgy<*Q6&EsochBz|Z{1Zxn%XMp8lw>)dWL*TESsh=|uWalZJp#S^mg4gEz_-`0Yg za*cdOzG?(!yaGwA$yOgy692J79p{B#Ev;~ezg4*itgu2=n*KgzT^5QoccC@ktf?*#zl@$}z=KrA zGA7kCK0erl$UF^|s(i0dVEWzE14>E?=@&Mf)c9c!hc4FPi#9Te6ZihB$xQ=Do=Q0U zg)y%jUdV1Hlu!8o3dqb`SX^G@1!_sE2vTbO%0o$yr~gW8RbCWIMtEcipK4s5rBbtb zStNkXIb*4bL3lmFIZf@$`?;)o1dy4;JbWJgSQXIuP6%nC20av+=kKC#e7ixohUIU7SN!HIwr z`*&|LLj}7{Eo@U{wo)XDvO3>o@%e%u^l(?n6+t|+OL9;Y3o3yEm{B-O7d~V(`bGVz z;}aBX!oU@-&SvI4fks>(NZ@(D4KUs6V-$#@@r+vn;1QVPD!ZRb#?Mw>HH0ft!p`uN zuGK$Qw+;l&Vuxw3bl*xE01de^#<%dtVvDvnIZspnd2fm^;RoL$r$nHOI)EEd`Hq0=?dkdf zJf^6BW{Ma(k9d6jV`z#_aA>U14(2kH@}nalrQfN?6QbV1C1k*YL5)S={Y1=fg2d!m z#(ciOoVZ05nSeoIRZLep$RQPKKhZjIyircV7qjY_EsR9lhehCtM8w2QKWq9q4?R}Q z>rzt4nlK^pQ3)T00I%$QMeM$1(i@KE@}~H(nGT*iG>kx)2@ zb-YEye(u)ASLO7$)l(9PcmgUF^Z`pi(B}s&#nAn7HEj%N~~LV9Bjz0nAqioRbHTx)t&IR%z)$*i8izuz%F|Gfuw z9eS{0wNg0ek~ba-a=-@-*hSn?;H~_C4*i&IZLT zyxFf+pa~>b<6*(tyo=xlsI>y}I(YuJUQ9ongZHPBm_8lU_2^O7nvZD+kkJ6Wq0keg z1Jr;I5IVb#&GQ;Fo(_(4XW1Nm_kAiJDANy0%TzEH`U|>9LCLVL!^m6Nq*D@kLure| zHLB!R%v3lGZY4ZsZCatoJ1vrj6BEBOs4pS{q~b$kLgE_N;_+>U{otP0?Z>IUk7hIJ zl?JGPyg2J4VpEp`+e#Ll|Lh92LaGIcG=ezNQ#7(n#|CVZkB`XF>7P>f=W^Kk!K)r8 z0=|xG9r)>F#Qn*fmNDA%7NiahWCr;9uGuj%rW;o`;0mBxMzFEO4%sA=T(STTloi?+ zFL?4++)VQy=MVtUBbwtqA{ z`v)^~%itB@ExC%4r{M(Q`{@=6=2IZ_<<5H2U@}JnwVp^hD4U&d()XF6!U8x%oo>xG zxaPoLCz zrQi=C1;8*&fy-n_!5~h zkE*fP4N#{RO+WVwL_j%I1Qes%7>HbeRI|Ybpnc920DbpU555S+z$0uATpDz~og4mW z8@Iy7WGQRULgD!?jReQPrV&|UZTawB#DF_3S9xV0wLqM_h`bg|$Tl)R2JfEm)pv<> z;5)}dqQB@Sa|TquNZV@(YFFl_RT<>ghF&0={&Q?k0hvR>r;2)<&9FXOHSiI$qWPf2 zP??A92QQjvcht*tYO}8g;?n-D!X*G3b&^JSBS8~+)KH1Xn zvJ&+M`*^~-Vj_n67%F8%Tm-R(5;7oluyWrlImBnNKK6dbz3cr(SeSqll+XZ#FkgNV z`lvo73XOaa+2L(P(3vxxB?4DZsf>{%4i`H?a8E(Pjxy0HYJNA@{A|*p6Pc!{C%leW2c>1dlu9 zHRV@#wBVxA>8rGdg)*($gOZHH?SJP0C0Y1Ed7rWiV`GK{w4GthSAUFG=Eo?pzg+@#*#x=ZaH22(I#C)aRT9b-Kk^d|JS~npo zg+^x>65I-rn+ppWMR{Tr&Uj^i4_XPbyW}82WO7_9pL1g}K_rNd_Hzd8gwPBDE>$^n zr;#)s)m?It_f^K2WN#q;8DFloh>eZkD?2*9z7mD)57tK$U}KbG-RQ&GI0ZzC4wL5a zosr-RG2=bxJ;R#sC+s1rc;HW^HyvBb5$o(h4;EbRelQ&ik<$pe9g#*HAu$L@=wi-$ z9ZOl@?^kgVIoc>G%!uvtpS33pQ|Eh|HWtHy$1gjz+O+MWQl|^Pws;DuVF@p=Q->-HK?WfSB&C|_>~L<%t5x6|sRuf&-IG%qfb8Ag{W#OV&Lw`y7vyXGvC!g+B*6{p zw=LAw)j;D4tKIcKe{H;M>(-7MEMG$AMiwbjdou6?q`n8fcNqxH1^q zx4|eRHO&#!wvVNt=={-4nu8zvBAFTQQ%yZ%G?wnwCRmzX39(oKIA2*z>K4Nl?1`R4OFD*qcmiERyJs? zKGA9T))gq}@szBJ2-Xqta%G$>T#5&a_g_ATG4YFs@8Mz>D_xAR~ z$q^yaWD1xtybjW@9L)FntD}S`_p+)B#(82fh?65b{ktd)`q5|63bQk{6m3RjFJW>8 zkzOXetaZ+!Z6?dSFG^%J=|wv}tyYW1PiGoV%TKEK!edr;7-4j@a-lLLoN|4y?-?$E<4=YV|)Bpr>8 z@V?}mv@^!d7W>|4F~2c7n?QwD_LB5spriF|zg z%(4|zyPg5Ek-_1yBo^DnI^0t><5ec!{)Q6=8#N{Mkh}b@7V)cvLKG22M@-sXv1J_pMza zo*QrP7)J-y3Qc4dtnVwCJ~>%wnjNa_$c%@6WrJyGG+e_^EG)CU9@oAbEE_r~LYDF# zFTG}_JE23k6KSc(3aQUeEDSV@ZqrVN=Ma68}oiI&VNAa$`7=sJX> z`su~Isi()S@txPBN-{f(CdnPG*q@9x-2uhAR;|z+TS;fz7xI_pXMPA}>kYa5cDfhY zV)fP$5c2uJl?_JH*|Gyu7zAH?Pl)4BScFlgPaDyXj6R0HNjoN|)sqwLK#)H@6@w-f1EL;^iMxD{`s)~Ytel^2u8`qdbB04sCrIqrbsK?t10j8wqrY}_k z4l|@pYO4z?d2%DBScQh_HV&0K`lY~z0lFVa3;J#`Wl$BrOMdJ1mxRakA8#z(KkEB> zULUI5S#Gd1<(@|k(0s5D9jte~4E5@_Hd9qaMP&xgiYMIAjjLiQ67ER6C@tlL>1hpIwz#LeS?W+=D(J?}WF`jjUJ;RfCIbYBAVG><&KV;Ht z?OHL9Gt!BIVxZr7e7U27TN}mifi+c4&50bb05MPF#{I!nNmr;Pkx0fHXpV1R)b#yv zF%)?{#wzvjN>aBHBfB%`=L}+1>$eEuH?T7k=FB6Bg@SsFpaN&WmZe~*H@&Ojc}Iy# zyGRM+$Y|_H3s+pFoXo}}liB$o>Q&>W2=?~k zs|k}$dMS0Eh#Rbt+`Nz|_X?}!{B+`)W7s|g+O(^y&N~eCo-a-j5%AkYPgQD49n2_B zxL+SEo4$P;{5ONCT>+hvJ}T|bL8D)=g%iXB9t$ZbEYCdxiF8$ATv zF__*Er^sY7y&lS&XE0r>3XCDVTrJbY;j!4=sSz7`S&YB(dW0~4uz>hL?kT94-Pp6? zk?7JNo(Vm`YE>_F=v{W(ra5Dx;txH_yP@-ZmvPJ0;}n_G($W^Mse;*3Cp^a}8@0g? zW$+E&{X=81i3aXk|;yf5mpi54S_w=gLDBil*ywdRDv^;YJkhPNi^ zsud6yzcHfdm|h~Y)Anf)HB2L>3o?9;Lh`u~rPrsi<>bJts#npo>M{!7_ z1R&rG)L~%XgQUk|Dn#$7r7)<2{^p&@th+9{FUJg~bNebVs{}r+&5h%$_+W@%*P3kV z9VBDFTW;Hmk%Q+FvUyM@_7fnjbIPnj71H2+Slj!-l2jmJrZ69OTa0$RU@}E^x#{^_~K5;%{3aGqK%(jXSB&W!;{Oo zSodmG;`}t2poY~We+i#aTnvtffFNjq`3Jq2;2*D0-Mb0wyS`cnv))Htp0#zyrk!Of zcB?^@roA1syAMn3S`Ehe!%4Ne1%)gaAI@M2-dZN>e%|&3nug5mmlP@*K_Nv+csDV9 z)CVmleeztI?S3lr;n+{!I`p&XgE7k)sWjft&mHb^YqwT~w)#UPoVHG_e{G*6^GsIA z%$ag7{o)C`*xF>klYOsI;fa6HdK%-#ZX@5I`!s0Wba#xF%t@me(d1FU&*j{NHbfic zU!j~&bz%Q^o16gGacQkMq|l?T+hj?H-!S^~G@{>_R6sg0tJ zd%7o$PZ4WbO_k2#+%gTLBcI=praM+vDKk6-tz$%weiisJ7ls<#fAl_*%4E_YHf~rL zZ5;K68C5;IHzD4y+IYxuqCdzNzqE1$&^lBa6C5Z9mYm!aeQduRKN^*9tr0+h(&})*6 z%fH8<-1!s6H&BEux7`Die7;m)z8xZPi<`i(=!9OOO3jiO*QT-^D`dYFr3Y($Kp=l( zG+eCrWQa50@MFnkK4>z}tr_igCdF(JkMJVbd*p;y57OlvJ2Ee%ciHExp|%8+5qz%YvR`*UZt-$_s!yium8poeW%=5iIe zcV4igNoIHY+RHYEz$FHes4}eRA;U$P-T4MStbSFKUMyHrNnl$ACe{R zxbXyRS=G_26c%gr)O)3tzz6_mFQ7c&xy9Q7$ffbok>VMb4CxdHu3O5T=JBO=c^P_ z>X7>mGcsAm(EDS^Z$4o<-;c(=+*wkpfVp6HE&h6mvfCsgx%r%K@?8|lMoPdZi!Vcj z{5b)tmd~}UAdvS70rv@8GWV^gVa}Fw9sE;me}6Dhe);H<9VmCE@$isgkC}c2PcJ4~O?u1BOVnsQDcNuXx!T z2>ElgS6O&3d1-lZ8R2mLkOdKD(zBJ#q_r(2x29x6wLPL z_V@OO_qWJ+r^4QQ7Ww~lTW&7yc&)_Ul;}=w0q-cUz*J`=Y>$Knm(6lv{CP}FIB5TU z^L|d~y5a_j8JL=#JGzKx4`>FA4Tdy(sXqtop zv&i~592aZq_QwP&&9*o?nlT-^%18)3sosjl^TOSsUepUS0*Au(p%)s#u)xUpxb-V* z@r#iKBZmRrbAg-t_8|M2AK$ieb~(1=o-VfQ*X6c>8P_CVb&jufKKA^|`bU^0?ZS~8%C9(*4hn)w~~l+tTE#MK!^CDS1JJ(M4U zXii7^s$OcK^70&p6P&wIq3PJ*2J!5j?yZr-G;E;y!D9(in?BnxO{a`4NaeIFOQ3ti znmpr3^OFd0BS&k(iZbG5BSn(KPp7GfNTTSDBD$;Q)mqt^KI6($W;cdty&_9=)4jD_0z1viAEJI1aCicb>hG+Uq%(<^ zgpBCAjJprSU@xZ0-1%c6*p@eI9sXBoMs;{!WG34jp>(X9m5ztPq^a&j0{(&3YQYajq}U`alE1%5wX8ZUaf61Es+P)4;0T1+ zxo6PS2IRepP%kT{t2VSk03YOXg&fXMQgi-D@;?w#36T=}}7^gT*LaE0!_h z@h-Zf-E^p1i@{VRq-A$K@LZ*e_3Ci(O=}3McNbgh^=UCg*Fl*R$FM)M<2~jxY8?(WQGy+MBf6}QI)bB~z|K54+^NtGQt({reKOgG$@mXcv>((SjCYv&_3CF zM|C{DKFH$V{z>R($*b=CP)?F?EH+bhkJVR2?`}A-+2k{I%I}LchGbbstlQu9RKT>v zwd2bMFUik6`L49EX0f(niw{Oyv)`lb5FX}1RFe`Whx}D|7`s)#jY>X*KOu0v=1@O_ zf#MGudVmCJ z8W_)aTRY0&X=)RfdU(+YPd}kIdEtKb`BKb~@+>U?@6OmP|`zz;E;_J=i*VJOO7#cbHgfofHjr1}03*cUU(CFu2 zK~uOw>azdlw@s&3{087CAs>P+!&%k7%RH#>lk-kyh^DJ42ITVb249FSi^1=fc&zg@ zN5}JH(jB~Eai4AwCah1dzT>IGh!OTcwoCi@X3GddPL_R^XRS-wo`9?f?Q6m4NnWieNT z9oqL>C+XZL_+P6BG?DpOef7`LVNAMu7p#wK>_g8P+mxiIAKwy}eQar1aI2iF{cxOR zJIsSic=+Y;tb3I04EET5?x1jIq|_M)6zOk(8=&HI?6-oI=`D>w4!}1Tqp_ zi4{*{uU^CapusD1sJ8~G7WD|e3mjwyI=@4{cVW>Yz+S4(sEc^UM3WBX?jzSsCt=1$ zGYXKm7|a;M=ioh~5vaeF^!No#GcaGp)@eW_hFBJ5o|&!NOoIM}lHIo;Qj}RunEK-7fNzBCzJm2@Z1n^!s|{!u(xKkbI+~EVO`0!PrGbaNyk1^w#9AytT(c zT*z5gui2(}(5Te$fQuON?iG{f6i>|@RouH*#kKA-a*XD)N3Z3c{^N-RYM|jV)CFTo z`~X4?oW2h$3w@iMc~uUCd=6cS#RroTUFKz68xeY# zZtmuTU0MmpVoq%!Hy)#D^_N?~Mym_nuPY>SH#GFIi?`VjD)L-*=x~^w5nKSFr-W;l zR#`MC_#pJz7~xH2;{$>>i>?OAXy--2ZZ)^I+5Ut>*ybw|QKmk+4pZeqY_nK`b4y*L z26Z=z*)+UAjI?E3DRHkz+Z*n4rM4)GGq1BN_kF{s7qClNl^gV8ZSIcwnOUg0sNZ-& zDBAHDyBXx_8j=SM{ZU8F5DxdY#N@V|yEf2VZPN|g^9lz$_(-ECSiv-0M=B<-|s z;nV6{>&$!_K5c@@uY;u1zMgerhiiVAme%WLw9#8FF{A{p0nn0d|V>!Kwd=cP+kg_H6+90hVulz7h(zF`=!%Ve}A4bF>b`}eNt0|T?g00z_lZ=0<&uC*hND> z`tfwFBcShfw|!uNS@;QRG%sI1LkmB_heb!Ri|f1oy%$bO;+Ze(OvYgF>z!DVPenI#)ZiuBt7u2SELi6-<-#@E11^?|r{|T^_Q{2vK zJuMu99z}$H@OGVSZ?;gSzK~cwhuwh-S&q@v+Et?P zm#8#Nf5h#!>jgO(Wbsl!Bb-BnYru}1`sv{&5sF(>G~bsPPA|wf1@B#gY`Rb^^k>!2 z*dq4>aNa9DSuos-{V6&DJMNkLDl0ZA6hsGze-*af3uKNr#RN}^_2SP?79gRSWgpE0iyJSd zh*y^PRZI@WM!)F}h}SQnDzZFnM9a?BpFG=WA%i5Jh7-Nm8)9*TO~~{9bCD^lG5(@* zaLNf(s1ymh4hQD3YVP(DeneY|;F_($tODMH0gzvS^+||YqV zXmHRimqEK}d$mKjo{XyXTo1LCkkRX&4mrVK|9A44+AZlAzbvHS~^6ir6WREVzjmVp-MCx*F_5 zg-|159^i!F2UA?l^A;L1L-hG43~zhLIyLdwRLmPtTcM7Mn>fti_n90Ogt!e3s+jwv ziGd7=M`CGQ9AFl4GbjEihJR_CfsqYQ4_xRsgSMIlqOnJ9FWbRuGlW})R3f7I5q z{MGy|26qF}Ea)*~lb#jsgs{PGHAQRmemsfI1Ps#{;y$ND-b-ipi^t#hm0r#eQ@=HV z>3jp%WNgXjgk9t!dm4deX=H&G_Of)@g3FCeLYITH^A3z+1-5Tkjy2tQhVo4cBRapb zF&cDpT+Zf7Veo*@j4!ux(G|@?*Gn@R=0)nkd9(kn-$o>}hT%g#=$K;%l4$`)-#i%e zax5ntNs*aFl&E zYp*ruGoLWwQR0@mlRA~kR&YfVG(jX+=MGVm?qP|C+x0MSpGO_>yrXtM1!OD3FS3Bv zhVp$&`EtgKdZjFX#sL;;+A2xe|E$4PCbd+Z!CWt!gC$~p(k`5p=JDeByerutlP~trBTwHB1 zgv8m(R+0!AUVfu_e4J8OfTiS9aL=*yKh-vHh@gO)^qQ+_>3wggAImBb^JP(GTztwX znt%=25i{=o;ZyUmnf5kd@5Ujy4eO{Q zlx>xdez2$2Qb+ib`umkIC~@y$#Jy&ClXI~7uO!t7QR+I&A1ePDRxU!n{VkzQS7X91 zztQy%c@RjCb#NZ=!@{A|-b^HPXPH;Evx@Pqiqt3kdWEV5)LhXcST)VQ{C{=Vp(v_z zc3ubkk8oc$yZzxfl0$a<#RBoE$*@cqDIb-xMY=xzkNx=TFBqs5kc=A%mI?nx6;@m9y)U;%73l+F!sTOY`aRFYT5+uNPNHzby4os6K&4Zgs0~6awHwm*gCMPrefxIeO~f~ z?`u*t=~4=%6OL%v*`Hm!Ea<^xR`6FrojkSqbM<2Jz)VNdP}8R?;{8J%n=!4LgITSF zXBiI_)QjT08$R@Wqe$%C>U9Q~n@lL#IdJpnhZ z9n^19UI8j1Z+atxEL|Jb=Nh_WhSS@NuZg%z(IZ97=wa*%4DTQ&vs=}@?|EM*K)F$G z)6%|Z3$3$sm~|Xv{f~HDa~dTs97fCHVldiQ?o`J0gU`;BPt%QQ5nq=dSWV@IKBeSW z-}x{Zujgq`dx%NOM4yaaW!MTQxL4M`25c24hRDJryz_^L1Vv82k3Ug|;k-9oAK2mk zSt&tj0YDq;pdp-G>$on8&{7eQ@TVpS=(tf&q$qCGbFONs?;Y&zjh(HuuztH9=uQq! zgdHS*gcEIT)u2wth@f@m1cmc4iHf(+^DZmm!uvx76RNGp%cW0=oX&wRh;6xWJ$l00 zY>#BJ8@PD><_SYwLw}jQO2hhWj+d`*mc}_6ZCU?VH+b^SOl!>O^P=fgRd2=iTJVQa z^`9|TXM8c|k-L3uoeCeEyKBZWeZB~&giI+QM>m3_LiQf-%lpa6$rT_s>B&2>+%gm+ zE0A{e2FfVp0_+S@e!J9E$1YN!&&PxMHBB1300ngqlp}gS%XxF?iK)otGJJeJh@y)3 z*e$L_L&yQAg!Tr=>cTs50amc9p!(6h0@fU6;NQhTv!0*~BWM7VYwa%OW6%7+Ex_4) zr=jm5-4#W_4AQOMHN8GlTTJG@sOz&>4PR112<$+Kt7Zi0|z?^>;IR2Rd$qg4k;KZ>} zRugpWKFvgua?6-SP(IeKnS06HiK|P)x-|y~e%o`^g^d6ra{_wA9dGIk?bL%hNs%9W z+)%e7sOlby_L?36m)|KTLj=Jaa4whv1wg{Wf-dRV__MK3FBq?YU$L4&S=%$>8Ruq@ zYGo9E3T|0H5ENGzkG^gy8EPf-K4J_aBZhPQ(|Ao$A@te7hGDw0V450#ZN!k@c8$BK zs;GQ=d&T&P-#InH)-xa?Ie`Yf$wy&s=uVZ0RgVFkh?NOXOUO!SlFH{&{QBaM9a>Gi zg+m+hFtMV63SRH7ciFcWKiBR7ztLY2a&3s{>#2s30+-8g)}b~4kI!c$fqTHmc4?Ox zS#rmK1t8--0X71?qIbvGg2x^Bypi>f;%G#zbYC0-O%F&8sEmA@0n*W!Ax3qd^Fq0>*mG!;d3BYT5#J*wge80=c6HJG zvp9_-UIFX^Kqz6%C& z+EP>GLfEM&sOT5ib3LNh(@e0@M7b?vO9SrS+MB>|j8!u(|6RR=CYY1sq7%U;Ylc(f zYc@jpkhbim@M+~vDoEioNMtsdo4TSvI9~w_oF0gai*6tp(fFG}Gv^Xmbv~Z#W8X*C z3kJRtL=hVW`3a-wNmWJz|Dwx_UJylXTJkJIMB+U)|G<|y5c8%cOhmJC z0W7=deI_K|L;IsnRO29#(2GTvf94y?lh7NTl^>fKDO43du-7@}HY%{)aAm~xd0hYP zqXTBEn9ol=4;l+2w3Ri4s;p={JOc3(@X4$w=n^Q4s9la+?liHWP6+$?G)xFZ90^p< zW8NngcEBhg1z@!KBO)oFQ+$ps1P-p2O^8QBt++maA)y~WND6nZF&dN#b?YhYjc;v27I7wNTF@zBO`@l2c zemD(H2qA@ltDeiK^xP-sT>T=UfztYo6zjF3%Ax1zquj&7Ia6uC%n8Vhmyd#JxXFmx z@r*Y+=&0}l^#@$r@T7i}Rfj}5^2Gwu@J$dz@%|Q zl+x+9WA1I#iNR3wYdV*ibErznVt&dr;bq2|)})r}#tY~~=JF@>r{NijjeYy}Uf<29 z?KLC0kQ)r9*hJJ;9J(G9b*v)lt)O+}FVqiXBEjSIFjUgQ)TCUT^6W+QWT=v^Bzb=D z^`)|gr)L9}0q1c_jZr8py4|xbe+;YH><=|m*~r`C*esklkKl;Nj*{_$zURZgHBn~_ zLABZn!@^Mr>Pu3M>O|UW#UhOpXFPFM@^OLm#109bnybA2TR;@y0_l zMztp$^V6q_-6L#wf8+}S@7B4MsVr@MkmB*HZyfJT%`-izxvr|CF?4#gV)V4bD|DKw z@h5~uvreoR5kH?sGUoGGk6fGp_@8_{Ot=ZeEDN zo}1lOj^pTQ^@r}$iXFkxbHbg`E!v$AEHue%DLC@s)A%cU!dh3RjttBxMDa#vI^X%Eq(b zO$9%~!$26dTA2nBwP=|8GocQXs|URQIXJ~(K-wbBo+L~=|6g`Z%s9aOiP|LOmjL=}qx2j}9t$ge2>gk%pe z;gtNIyh+&nkLL;%r)h&WVh=u`y??#+LSyAT*gZ~8{u3SM&U7K6p$FZcN9C6jvN9W7 zm6I6+FLku}*;{FageR3HLiNU1lb&3pA$S{8@63s6W*;8wv`q` zkoxrzg$bL{0fUH$sNQ@LN|dSC`$@Cb>JeIaSn;~)z(~`~`&hkAQlb7HkX2h|Gh4Ca zNl#C&S?@%Da&ls$U%x%?t^0m#?DH8XSJoKS~Hk$&~PN3RY#K;aXbolQF*<;oNS@>qkat*6y5)`vO= z<#ljzV1Io;awJj62xO+jN|f1p zG%R`lq>zaqf$&;S0VAIyXr&jMoNN_+C82oXNR$BfT#6qThqdbiCLUs9evjGM*t!6Y zrRzPw#b~Ijx4|hGyK?=?dvCrL+ram>y11RI#@Q9r+hIVp(~)o-o^5d*u`Rcl90uIB zP{WDYOW2s1*jj-vkw3tm#y9F67cM6WtLflqsegTpEF*Z)`bqe|QF;D6D9tLlr!`naAL?13X*GEX-hsrGm8;D>8hUy};DONw4yzDZO79MBb2xZ-(AZcQP8Dgn zpY$>o$2hiyuB?GlsoFn4BK)d~%)dEIt}#YV@bBFV0~SSD)wtv?qAF`6Likj~(Lj}gQ3W%Y{+J9v zxYD}1OdZV;M}b>MnOQ&44Bn2p#L zi%JG#b%Kzh5g>zMHU}PWK|mh2gi;1`vup6P4S?U4dd39gP$?h9L5g)rIe0d90OU~4 zRwL-Vp=ph&X9JvN2%u3a!eI5Q%av2=89>_sitx6rATql$Z)YC@tyF7wcLAS^&r7pj zc679~BcMNI{@CEU8w3<9-P#!smNj1iGc!Js2M@W>%FD~Ap11;CnRe{@!prItm5(SP ze!oASpTB`xS0Ckd4H5rIFKluw|V_KkX3NCHB?hA_o z2}f$(B%BHP;KtN6IX@cR>F_=uR#nv{t$SKaqUXRi+V(Cz{Q%3BN|*$Q=Bhcq0QD?i zSFi_xY}Jl({%AIj zOwG|F$R-5W{Md?GiDH8ExRtPOYmZaF;}Uga<6!%;fa}6NU1!o;RFs`+_6M^@IA_S^ z9r8gf+ruy@OpXS6=Je{m8({t00go+gSp4Aj`mCMIz7ZA;y$g%;z#J6Xnsp9YgtS&x zR_>rZv$YupEsz5cm99MVy?*Cf$?10mh8+^Vj zNvJ_hL({4qrb~{Ch|a1Kahla1`Qxd}mr*!EQc^2D+9eZ}#=I&dTyj67_8&Bq1Qz zEtigMHQWI%TQeUvt2RbHNWZ!_Uy*uyB8l5}6BC0&h5+JWUw+<8-zPnMSHq9#5qu(+ zI0c$*3szB(tyAUvu_7ncqzGpia=PK+U?n^p=*>}A~o)i52)2aFD^)-FK*30Z4{luSYnuJe#% z=hes-iX04YgF-gyzbAqR7Bw@7q3G^!#Q>0X)J&OI@;o$u&*vZpYS@X9fXU`RyMkB_ z9r(%?TPVZ*zX#z6!hOGcDP`Bhf3CpN1^Sgm`q6;DS9>qT?-`=BH8i^E~IpsEBf^Ye#X032c2QAI?AfLFAW4+8KqCvNJJAKWD39dkXhhG ztTD(n>?vA1T(eFXe~94hs<(77GtU~B{+cnV*89_!zn9vMceLHFTv_2Kl~r0|UchC40xOHAb&?&X_>hT|$<*NfwZhzst-1@_dhc2@(exk9xdxNADF_Q^ zQ~k>CH_pb3pm(W71HsE2_K9M@RNn!H>E3XlfuF~`U|(5hNLIw&8_h~4L^CyegHr32 ztE($HC8awEAw3-({Ezefb|4uqdwpTY?90Q{%(4G#wg2JJq>!Rd=_yPW>Pkm85T(es=0v+y_Y1xuGr zM(s#Yl(psyS!r1r4*B?5FW*gB>O8cB0YLfW?PsT9&ZO>DU>ju&JS|Bcxv_wX#WwwY zPTKoeyP|%o~2k-Ogw%Ynk^e2AS`>0cDT5Artm7 zJlB+7kSa_WK_b%Dby#IHJB9|L z1QNAjp>F*n5(Id7{#X=3hSMc_e4?D3xL}WweDWlWP!&`LGRn$0w6wH)Wdzhup+aFx z%LiOs+_6os*v}7_>=AoGxL=E7hWiRCG%YSkz>(J2*tm!~yVHCkUnL|gtnJsnCO}{V zvYkVV@rj6nK)GTJ0zcHtFe!yegiGJP#q+v7n|8Yc0t>{=I@@`^BE4E7y|)d9Eq<_W zO4ol^zkm>em!VHS0l{nTiqSl4WK-feI@b{sf$zbcnz7muKJxpq@$Z6HR`9HE^F6c) z?hmm_t2hJKwYi62!cXY`=FKQg7CclrUu4is369l=0KFh9GN`3Q#v*S4kfj+SK3SQF zo_1A9;&J8KLqV2yROJ>Ev*Y%ev760vCd&D(v(dBBB-NxS#n=vBWiF7<+i>qg(PPRJ!`9nSW;|{<{*!ajg`6Xs^1((`&QW+ zo0t^48;cY_9#FX|I#FgkJ; z2(SczTKv`e@6K75bW+_NAu|ts1PAfyYOWBRFzQ&7Ww1C00%FfOrOG^oN_ z-`LPDBq&zqHXmpKSNNZu}LP>1goQ#bv*IkW`ut< z2iHM%mDPq9Ky=V)ul>PzBJ?pX8BvHs^K*>7Y0R9t&8*kUO5`jLxM17Ns?%e`!$YH^ zyIUae#q>c$6b(5^btw^cdBDp8eROn`1SDw^$}i;ohzu?C-15&p%1p|f-vJO;g_#e7 zSZKLmdar0E7gDf?WDrKVH2IqnK8AGS`J?t@OX;xi@XCZtYPt;p^;)|{8$I9gX6NF^ zpt4Tlw!i|80A`yl%eLp+9oS?JBH+|USdFnub)vgFNo=0+`A+|5*LQG1nb3g|d^Olq zM9!jHLupVn1NW0{b%g2Dqd8=C--xFcQy-BwmTJ`-7q00 z+8y`)^@z4l-Lqq91$8&Kn#b7MiFI#n=c=rx^t$h?)>9t8t|62oO(va8cu=G9_o1|O zhlA}ZaMJJ&&az};c?g^F6Q6`Av_$Xi(-wQCsgHZz>HavUESZ*7DAx6|@V8A*NqM=bkKs-!p~u#AZH8;23PCw`R6Dk`Dkup@J}QziYXVV>&6`ZCWFwJ4>>pb*<#d1sW3?Ji zq7fGtXWIQCFw|@>7&4QJ{=;~L2aymy128&lShcH69YcTWk8VT7syNF~aD_osEB5wSX0s+e{_&~s#pB&N z?_sB5Z;|=n{`uW^JEt+-*Ae3j^L4u)kZJfX4E%=-z)!2kKhlPoM2aaFp=YpTWT`qS z-JRRHQKi&Vz%Y07jpx3cc~MvQp5)ZVp%Pb)a6Nwb(5RW^l@77tpm6Ol7cs&9wHfJd zo#*)^=|?htNAZCSg1rL$4b<<4`=VnOjS z#ba_`xKFctvNC}jyZ>E(ZCWz>@OkyY>zWU=Cj#bFC5nSSdOzpF{`MN=zbms)D*3da zN5CQL&oe^}7mPZ=Zn*C7djD@379#czT2ZaBB{Tee-7+gIDz!ao!M{@G|KHavzkpTM z*N+Md3u8bQ$0zz*Lh2)UJ@mV|z5TYic>#~R#uW0<@NN=EjyL-8aphiK-{akvU>*Ge zy1?hCIKOGQ9@MzDHi^dXV+uV3168#7joIWk$~c^(LTlZ=YH+=wWR#TylS}}l`f8C} zXwQB2cPpcY6QN$NhH-KRts4!)v-AkyM?J&hE9!gnLRD4O!=^~`X=i7r`h$qqI(2L}!q`vem5Q+a>K1^K;v!oYxpM8r#= z#%9(ZiWY=1eT{=g(G37#28i#f_8XJ){w?$nKStO?T|>2+9M|2cZvdxg1rF-wqM($O zxj0xn26Ig9R!K(}Fq5X`=O>0{9J_|^fBiBab|3A2ST?9WX_%N$LqkIa0G4qK%)plc zb+39Q%=Z)XzsJL`6lG!_PD%rA)up1M;s^}aSE_$D27RLoTAeoWjU@ZH;721FybO+Y zXgvoUUn7AZ=v-K)N{)=yg$BTM${kl_nBThX%@`q$10e4WaJSb?Bncdm#C{wwuJmY7 zI~YJC3>tx@fG3Fid-*}km0Fl#J7%b~?ZABuUV49-787I0Y^q+YA6RWYHRrdvw`T)A z_h%YCDsQ2dUL=5X5P5YqJ>mNeOsyqtY*@fi1~F<6{st_Jp*GPiYGx7RNgy(NuG-py z9l!g<--8AR)*jWJ5Mdwg$>ROJ=NAPZb_YxZHJk*Ai8TD`y{CiLtMKZZgf#+H5CVgO z<_by{s>jt4b|hPFqX-c6s61c(0wlY!A)Y#ZAuU>_sg{l)Nd2ATI)U)POeoc>0ipDj z;H$m%_!l=08LM^WHr@Z$Dh@0=iaWjELY>lOoyoKEwmi|#CZ7$?IHWWZbu{#ycRQjj z^!CI5Y-=HYwFr$mh;9fuWb=xyti!iE0~s@p{#%R%`EvgrMITNG60umbyUfeqFzK() zm`}yv@*%K=um2YPU9v5^B-CBo94OlI2vI~3KR>@5-ng#czW@Ox)CmI^#}A2GX`LT- zyv8c+o^)@s=fdZ4v#!Zih;#XV!5@CnkuYmFi2`Ipo(u8=cPp7>8cC;y+ zkZW{mY|DfC$CO%ggb*aU%t;7lkU9nQO^H>~EaSuGl0C1y`m!bU-@jR|qs~+_?Cvz1 zkpF{&q1@oXVbc2T^>HA{|Ifk{qq`6Gt~F!G7T#$o+FSGVTxGh(la#mrReU@qa3Z0w z**#fX-}1`x5zrG#C4Izclt_KxR^ffl~G#|mP?_2^(Zhzh)`Tuo(JcHBM@k=dZ zVr7=~F~Z&OsYj!j?=rdcOTTp4ez>-_kyV#F5f+^xxrY!of2VtE@O+54reZ0Db~o|6 zN@WTAkAm6SsK58%9zaWos2P2pk8>TZ?+iX*VUyODAzGo+$;`||N&bPoT>Pv_>Zz%~ z^(#fOCCaoSm@J&*rzIKCr<0qzvOx({EZ!}~ir-e4gcsg#C2yW2Z${156cu3rPjXhz zv%SErq^%uBjn5usY!{2=uPdtiE4@c!E$&`#)L+}_e&)^FINYo*`QDM^{pXhtOND>5 zqqL9EGHuOgvRBr$HC_F944Yu(J?o>R^`OC-G(A5zN8F^N-K@)v&!z-~iK^ik!>0~# z#_N6YTl2N->ArU!!ho=$p6`J1?1C_w$zdV*w(N_A$ms%SEd&CA!d2xm6ox9UItdNWC#_KLG!0ectr zh|n2S0yC3wzbto)ZKChHv4J5Yh6p6EDmvMjhS`W)0M+gW=-%Ej@K`TG%m*yjo}Qkv z1o9@QoZMUl&=8|wVoHMngH77XiZQe|`}XbI)@&ssbi$JMcI>&7w9LxeW?lcf8G+nG z1=(1~$#U>2z}JYPS4c?Gu)cqfSR1yY zveFSil*@qY(GCV9#s>A}?#ITdZgW=ZF}hB@^dzD_!a^=vhJpC=O<)o+71nVM@-(_H zmb`<(q~3UE;uDFW)BUfWr>xM}k<99CfPQxaFu1sr3Cub`@OIb1;^$+7pJxWk#{DN4abK}LFDk&kc*O8R>8><@eLUA{PbxJzlTw4h^peVPx@FCy&O62&)4q|ZNwkGW& zxiiP|eSZ!%_ynz>VA?6?6A#QR*%%=26a~@?3Ek5$aOP$E^8NV@Aj^Z+Hx&XM6oJO1 z!gv*6?=89V?>Jtc+gR^wl^MbUwht4t#8+90RWEBnzGKuG?K&=Lx_${I3Tl4wWTsoj1n$uA<6TBpI%IsGM{s!-Iz@#K$Lc;m(06in9tC_PDQW4f?8Y{`*$^VK zhUz5EQcxDS`L+e18ZM>6zxnuTZw3PV(R;#Z8m1ovB?0c2JtEe{wtr6kN)kqe53uGs z2D~)?vosXr$N%7=E@^NUuNl7*stWBMU{|O1_GRPZ=HlF)$7uX~LS1wJkV|2?|7iQI z8VWkPw7X^e=PZUd52dA!#fgbmt!wNSUm{{Yb^)AgKBybg-cmCa@R{pCrt&iECt>FS zY;IkLRz%H8^GHIbh@YX6q0;kwwzgE{VW&5MY8KhTR9PDz#S2rx8Wj~O_ zIh8HNPqgaouNZ-|8cp(|Lkj(^bu&QE$(UW1TVTm7y?;==T5i}aX$Nr&wtC)wiy0mz zIQ>qT`nu2#w_+Shq6iNBXDZ675#im@ZJ*kI7;1PDdA{05LCgKd=u$iNwt=IJ9gRAS z97*&A!a8|R>yc5rBQRdi1jrjMF0T3|$Ae^7%P&S4IH&cdcVK*12^o>sdy7LxW?d}e zBCj$t@=_`s$3%o=VW8z@!>pwi==&vQ-%XcBYxPbwXSn8Yii8*k7mitO8~v;j7;R{0 z6(umxMU_!G?`6y|T%4<}11^=t))AZAmlLi-eWH8_?s^39E;cjPs=p3i7KED!fy-Fg zzW2TRGx1TK%*~a0-**#2#J!_zqzUp=5)F@7K5u_~fAo3jcBpF^OwAHL3)dDG4sd6P z&zOrhT0h@BN49;L%&rkOO8;@f9ktH7htRv~K#SOlb-Lm>9b(S#t8ZFHhZ8~d-;jEc z^WeS^W0iPe-GjIkffO)}v-URf&|3*Id&;so7@Cn1n(gl>s0;TjJW8j&T{xk<7@rE9 z`+IM^1;tlR7BNSvztz-u*E|~Ivui4eBpYA1X8zNcjntuBF2JoJAU%7h-L(~tB%i*@ z(*tw1^<9ot{%lKI(Mzi3*3K061XtPhSGA=W=QqqEc5q{*Sk6bD<5PFI+d)S1Lh}3m zzHW3!V z{K~NX&gv8XuVWID^OU-5ubZ=5)&uRH5<(O$?CEQ4j)y(MWTz-ow-lWoRuBGr-4kjK z`iuOiyjH2@8NAFR&Zs4cQV2Fv77~B>KWV-C{ zh@d;l4`HO-q%<~~9#&eCO5ysR4)iLc1Yt8+-fUKSES!4mh|r0is+upl?rh||&3Pi$ z`csy$7703cfON@#IsOBInc>Ed{-qVm@MzYlwDvr@t}n1oX-Dsw2@(7*tf4P85d+V& zR3UcYa6<8;!TH&7Tmk~iC1iDPN_Cv8*$a1RY3b}|hv}2j)%)(+u?z3g_0k`e6zdH( zhN0!uMC=%o)%>KlwLbr_x*8{@nB|k2{!!^SmYC@Vr;keQ)|;4Nuc#!x*@4i}-I-lg z^*z|XeZjKtN&nGgnA+B4W%sj&)-75SUoRO2Evx!{MvnXwB{glQH3>f4$kXIWPGqXu}{QtmrtLE zuKBqFa}ik)o2d;IIh>7d?Y(JzCy{iYBg)3_3p}P4>&ESKYL}k9UI<7@jFPo<1u_(3eUZjB39I0`_|}1I;?Rltvt{*SDU>+F2SMZKKA#EcLkSflQZ%%aV$0s) ze#xi0jks*B>J#KbNx|@fvmy4g_aNfpArWCRfyt_$1EMZ(GZ?j0T!7DjLQa0!NDU?$ zT3I%ui9rIc?S~LPXKZxrwpRG7n$of(2dVCkJ7Mw3|9B=~{N{wPqkLc1jnV~ow2eE{ z*WP7+jI=oC&8YWux7^$rTZ5hVy+yYnsreqUD*l6Vm3CyERu${vk5oeWTNPp9_MvPP zw45hv2J;1E>ZKhi_KDwGAmj^Pg9eTlto(*;rAW))KHG7xbl3HaT^Q}eF(215v$b(! zFNNb(P7ExGwxDDgn&uvM${se`cD#VK`(npM$)AvAv^Wo(Bt1ToYu1>e+SPA7*LC{( zNmIZ+ics|Dj{!RO<#XTVtL}qZb!Kkfe<$K<1hk@Wh#{#T_ka;}4%vHqm&{p_(Wmisd)`&$E@w_uW zW5|oxxk)?tHKjKe_M$8EREcgNJFySsjuES~7@xB3OYQAo!$6x(Rc3Vm4ZG}D8j~x| zotNAG9`38Fh;@4n&8t)zw}`h$SY6!FH=?>uSFUnf6Qt9(>u|b1E__K4akis?@8{QYdN}Zo}BuzHG*?`%cA^)&Hy!)mzi+I9zoc_-Mi zmcd^I$`~=*mB{_xFu(}XWa-7LeN6CBKf@=aFew&Qzln<@702`I>3I+k7&tFxUUPGl z_OnvF&-Z3Go?%N62|gI3{Y@7|LWTExLLrQlgUO440+?+v7r8A{xFYzG53iqHk~*vT zX+1pu(O)7fCzp?_t+6~Sd(fR%`L!GMjS>%0w$G*EH5m%0!r0x9y2j0$1o0BL! zcjdYbN}@ku>ix`NHb!-{GEeoMB!|eYQ(eA1RJ=eNE5kzFUs}4hOni2)JF+v-qASES z;Mw|HuXAhT;(aIYq1v*ti3wKj+rSz3jJL*>a|6QR4}=){&ea}c?~_v@SlaR&%(d-3 zz2AkDBP|t2IOMr8e(dPsN(8-Lhg^il3YdEF2Yg%R4}ssgL~soXCKgXgp;Je9_k12l zWdz#xW+RrF8n)2)M$-8Ac{B-$SMN9OHnc>u+yaRc3yF#2-+SZd>aM4Uh1eK%6?kd$ zWIS5Ceo#7hG2r|x-rT#Xsa=krE`)?fF^j-3KsC z@DqDZSHn9tuj7(3sgZd3t2nX@t+zP6TBW=v-oTU=vxuF+u*>U0PL5#Fk1Y?@c#Fx z1z%~vyA-p%CxZlCh4S%-2^l~O5z7h$61SqiGy-b4!7#B*Vc5YP&s|e_KT*%yqca`o z{tYo#q%M15S}Ee2=EZ#<$8s-ygEVn6`iW%_ic25#5=Zt>5l+lA@52p7`gsJVMTiaV zXYc+3fm+`9twkea>{I?kxGZA)v-iZnjM@J|j-@hZagP?c+%NKY6Nyht_o!^E59(%b z8(iA{yKy6OsF!juq@5<|w=eef9JKRZ>Rf43=Y`#4LRI`X!<@xAg1{8u@dXMVF*65x z7!fN!H`FgMt68V_6OBHFgzzEl#D-JIzv#+Z zr{=hs@y7feGp0e|u+$i)9+|5ldiS$J$xFU7oSSmuI|2b89c3dH3BtR=Q4t1=Y2@bU zo*~9;+K0G4CAN`PDgnwj9P68#bUbnPzWnxH{8vgila?!$?Lh}i7Witif0vOyett6y zm!!s=?~Sr5c>w0?6OJ+sJQ>WbsFkrkjTYqO={Cm0g*Ve1rPBI71hmXM`Ysz%Ltrci z?TuM9%V0n|*`}tU7YM|~cgs?Gdc#kLg@?U|gH ze!~|_$ZUlfI+XbaNUkd&39S>DmK*4OuBsvcRp#UrbxoGTw>*I1*K8)7%@Fr5=GE0* zBHt=caFnx-gFN|T;EhDb&p%CB>20KvWjpMxu|%}<@0Z^D>sH)r>qBX%N5dkiO$>D{ zskn(#N5vmwddMbiXz2IJq(i#bh-O88sQwF7bk+#$^94YD(@2f24rt_Ow9THoQ$36gQG7?n2^$TIq^aTGYr(p{W)IuLR7V&>V+jAOb^=EdH z!UqLNt?xJ)5ABPDT1UIcRVxb%&=y8k+Js+2S?O#9u!uP$B`*0$CQ8PKtv*Ub45f3iE|4GoQd~FRg4lkr(@w18*xm$ zw}M_y7Q|OKjNDcM3XXL-RIy~MGuHPmB_%AojaC<=5dc&!uX+rcz6r$_0m^0jUSgH) z$EN7dP^0#sSvLR~NL@F%NXg31Hzkt-q&YK_y2^SQD^18%0?--F2U7x*l1KpN-xEgH zuxLq$hJ{t));x>#Z^krYiaNnFPkt3ja%`e!=mW_|v9w?j7oUl1M1OQ)YG~a@`9prT z5}T}cPb$_iG9DR39%qT}EOpK(N2FR83AXByCBM}phY0Ik<7bP_NwyY-tam7LddEryWSP3rmh~9o4|^r zUe(?KLx0bqcsJk`2nICKIpHH4m#m!vaie1WLyG*10pV;7C?J0Cu=r6pEfm)SuxAZ> z7mf-Cr(;HT7|{nHzxoEmmT;?qBxF)FydXIO8g_CC@;3^1Uo4M&=qk5VGgkf%jAuF+8Al9dNd}A65(1tGrb$53@Umq?@e@)nTV3mgJj9R$ zs`vIq0tBKF@F@U7#*F(&*i%0_Bg*=;h>DQV?8isy%3t;x3v27-sU+ zSm(n>#g^M4l7*oqB42p6Qmc$)^WXjdkpjxZ5}c`Qxwx45F!nbJWSYh=p~tAG+zQPN z@97WCb*B0eL{96x*Hd?JL|I%)IP6H@v`1TnMMNNoK5aBYL`wRk5qM9fMF2f!p39Dr znYka0B#dO3fQ)R{!x8{ztKA<00uX8oi~sDCEsioR3g|I8{O#YAU|?VoxZbZ8t9`LomH71qD2D!(B`Ny3#J{t!5KIxcoQQ_f*XY5`Y!gYt_dhhQ+)9mMWh%mxV^4(IkcyPy=r)!er@Ao1z#BMX-CoYE-x&H@Q&_ Date: Fri, 10 Jul 2020 16:23:01 -0700 Subject: [PATCH 13/29] Update getting_started.md (#317) --- docs/getting_started.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting_started.md b/docs/getting_started.md index 430ae0a6..a59cad0a 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -14,7 +14,7 @@ If you would like to bring your own model code to use this template structure, f - [Create the IaC Pipeline](#create-the-iac-pipeline) - [Create an Azure DevOps Service Connection for the Azure ML Workspace](#create-an-azure-devops-service-connection-for-the-azure-ml-workspace) - [Set up Build, Release Trigger, and Release Multi-Stage Pipeline](#set-up-build-release-trigger-and-release-multi-stage-pipelines) - - [Set up the Model CI Training, Evaluation, and Registration Pipeline](##set-up-the-model-ci-training-evaluation-and-registration-pipeline) + - [Set up the Model CI Training, Evaluation, and Registration Pipeline](#set-up-the-model-ci-training-evaluation-and-registration-pipeline) - [Set up the Release Deployment and/or Batch Scoring Pipelines](#set-up-the-release-deployment-andor-batch-scoring-pipelines) - [Further Exploration](#further-exploration) - [Deploy the model to Azure Kubernetes Service](#deploy-the-model-to-azure-kubernetes-service) From a6014d04ce531e6b27b610496f6e694aa0864693 Mon Sep 17 00:00:00 2001 From: Jenny So Date: Fri, 4 Sep 2020 13:42:01 -0700 Subject: [PATCH 14/29] update azureml sdk (#326) --- diabetes_regression/ci_dependencies.yml | 2 +- diabetes_regression/conda_dependencies.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/diabetes_regression/ci_dependencies.yml b/diabetes_regression/ci_dependencies.yml index c54f3e32..80fc4059 100644 --- a/diabetes_regression/ci_dependencies.yml +++ b/diabetes_regression/ci_dependencies.yml @@ -17,7 +17,7 @@ dependencies: - pip: # dependencies with versions aligned with conda_dependencies.yml. - - azureml-sdk==1.6.* + - azureml-sdk==1.13.* # Additional pip dependencies for the CI environment. - pytest==5.4.* diff --git a/diabetes_regression/conda_dependencies.yml b/diabetes_regression/conda_dependencies.yml index 57f2b999..081cc7cb 100644 --- a/diabetes_regression/conda_dependencies.yml +++ b/diabetes_regression/conda_dependencies.yml @@ -23,11 +23,11 @@ dependencies: - pip: # Base AzureML SDK - - azureml-sdk==1.6.* + - azureml-sdk==1.13.* # Minimum required for the scoring environment. Must match AzureML SDK version. # https://docs.microsoft.com/en-us/azure/machine-learning/concept-environments - - azureml-defaults==1.6.* + - azureml-defaults==1.13.* # Training deps - scikit-learn From bf34623249121423db630881fa564ef2103eccf4 Mon Sep 17 00:00:00 2001 From: Jenny So Date: Tue, 22 Sep 2020 15:06:27 -0700 Subject: [PATCH 15/29] Update azureml-sdk to use latest (#331) * Update ci_dependencies.yml * Update conda_dependencies.yml --- diabetes_regression/ci_dependencies.yml | 2 +- diabetes_regression/conda_dependencies.yml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/diabetes_regression/ci_dependencies.yml b/diabetes_regression/ci_dependencies.yml index 80fc4059..542db0c4 100644 --- a/diabetes_regression/ci_dependencies.yml +++ b/diabetes_regression/ci_dependencies.yml @@ -17,7 +17,7 @@ dependencies: - pip: # dependencies with versions aligned with conda_dependencies.yml. - - azureml-sdk==1.13.* + - azureml-sdk # Additional pip dependencies for the CI environment. - pytest==5.4.* diff --git a/diabetes_regression/conda_dependencies.yml b/diabetes_regression/conda_dependencies.yml index 081cc7cb..49405c47 100644 --- a/diabetes_regression/conda_dependencies.yml +++ b/diabetes_regression/conda_dependencies.yml @@ -23,11 +23,11 @@ dependencies: - pip: # Base AzureML SDK - - azureml-sdk==1.13.* + - azureml-sdk - # Minimum required for the scoring environment. Must match AzureML SDK version. + # Must match AzureML SDK version. # https://docs.microsoft.com/en-us/azure/machine-learning/concept-environments - - azureml-defaults==1.13.* + - azureml-defaults # Training deps - scikit-learn From 74885302c4f8382992b964615b0b989a74578ddc Mon Sep 17 00:00:00 2001 From: Jenny So Date: Wed, 23 Sep 2020 16:37:39 -0700 Subject: [PATCH 16/29] Fix Batch Scoring docs (#333) * docs * more fixes --- data/README.md | 2 +- docs/custom_model.md | 29 +++++++++++++++++++++++++++++ docs/getting_started.md | 14 ++++---------- 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/data/README.md b/data/README.md index a25aa451..d43d139c 100644 --- a/data/README.md +++ b/data/README.md @@ -1,3 +1,3 @@ This folder is used for example data, and it is not meant to be used for storing training data. -Follow steps to [Configure Training Data]('docs/custom_model.md#configure-training-data.md') to use your own data for training. \ No newline at end of file +Follow steps to [Configure Training Data](../docs/custom_model.md#Configure-Custom-Training) to use your own data for training. \ No newline at end of file diff --git a/docs/custom_model.md b/docs/custom_model.md index d21c8b8d..a554f376 100644 --- a/docs/custom_model.md +++ b/docs/custom_model.md @@ -10,6 +10,7 @@ This document provides steps to follow when using this repository as a template 1. [Optional] Update the evaluation code 1. Customize the build agent environment 1. [If appropriate] Replace the score code +1. [If appropriate] Configure batch scoring data ## Follow the Getting Started guide @@ -35,6 +36,8 @@ To bootstrap from the existing MLOpsPython repository: * `[dirpath]` is the absolute path to the root of the directory where MLOpsPython is cloned * `[projectname]` is the name of your ML project +# Configure Custom Training + ## Configure training data The training ML pipeline uses a [sample diabetes dataset](https://scikit-learn.org/stable/modules/generated/sklearn.datasets.load_diabetes.html) as training data. @@ -83,6 +86,8 @@ The DevOps pipeline definitions in the MLOpsPython template run several steps in * Create a new Docker image containing your dependencies. See [docs/custom_container.md](custom_container.md). Recommended if you have a larger number of dependencies, or if the overhead of installing additional dependencies on each run is too high. * Remove the container references from the pipeline definition files and run the pipelines on self hosted agents with dependencies pre-installed. +# Configure Custom Scoring + ## Replace score code For the model to provide real-time inference capabilities, the score code needs to be replaced. The MLOpsPython template uses the score code to deploy the model to do real-time scoring on ACI, AKS, or Web apps. @@ -92,3 +97,27 @@ If you want to keep scoring: 1. Update or replace `[project name]/scoring/score.py` 1. Add any dependencies required by scoring to `[project name]/conda_dependencies.yml` 1. Modify the test cases in the `ml_service/util/smoke_test_scoring_service.py` script to match the schema of the training features in your data + +# Configure Custom Batch Scoring + +## Configure input and output data + +The batch scoring pipeline is configured to use the default datastore for input and output. It will use sample data for scoring. + +In order to configure your own input datastore and output datastores, you will need to specify an Azure Blob Storage Account and set up input and output containers. + +Configure the variables below in your variable group. + +**Note: The datastore storage resource, input/output containers, and scoring data is not created automatically. Make sure that you have manually provisioned these resources and placed your scoring data in your input container with the proper name.** + + +| Variable Name | Suggested Value | Short description | +| ------------------------ | ------------------------- | --------------------------------------------------------------------------------------------------------------------------- | +| SCORING_DATASTORE_STORAGE_NAME | | [Azure Blob Storage Account](https://docs.microsoft.com/en-us/azure/storage/blobs/) name. | +| SCORING_DATASTORE_ACCESS_KEY | | [Azure Storage Account Key](https://docs.microsoft.com/en-us/rest/api/storageservices/authorize-requests-to-azure-storage). You may want to consider linking this variable to Azure KeyVault to avoid storing the access key in plain text. | +| SCORING_DATASTORE_INPUT_CONTAINER | | The name of the container for input data. Defaults to `input` if not set. | +| SCORING_DATASTORE_OUTPUT_CONTAINER| | The name of the container for output data. Defaults to `output` if not set. | +| SCORING_DATASTORE_INPUT_FILENAME | | The filename of the input data in your container Defaults to `diabetes_scoring_input.csv` if not set. | +| SCORING_DATASET_NAME | | The AzureML Dataset name to use. Defaults to `diabetes_scoring_ds` if not set (optional). | +| SCORING_DATASTORE_OUTPUT_FILENAME | | The filename to use for the output data. The pipeline will create this file. Defaults to `diabetes_scoring_output.csv` if not set (optional). | + diff --git a/docs/getting_started.md b/docs/getting_started.md index a59cad0a..7a311cf8 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -64,9 +64,8 @@ The variable group should contain the following required variables. **Azure reso | WORKSPACE_NAME | mlops-AML-WS | Azure ML Workspace name | | AZURE_RM_SVC_CONNECTION | azure-resource-connection | [Azure Resource Manager Service Connection](#create-an-azure-devops-service-connection-for-the-azure-resource-manager) name | | WORKSPACE_SVC_CONNECTION | aml-workspace-connection | [Azure ML Workspace Service Connection](#create-an-azure-devops-azure-ml-workspace-service-connection) name | -| ACI_DEPLOYMENT_NAME | mlops-aci | [Azure Container Instances](https://azure.microsoft.com/en-us/services/container-instances/) name | -| SCORING_DATASTORE_STORAGE_NAME | [your project name]scoredata | [Azure Blob Storage Account](https://docs.microsoft.com/en-us/azure/storage/blobs/) name (optional) | -| SCORING_DATASTORE_ACCESS_KEY | | [Azure Storage Account Key](https://docs.microsoft.com/en-us/rest/api/storageservices/authorize-requests-to-azure-storage) (optional) | +| ACI_DEPLOYMENT_NAME | mlops-aci | [Azure Container Instances](https://azure.microsoft.com/en-us/services/container-instances/) name | | + Make sure you select the **Allow access to all pipelines** checkbox in the variable group configuration. @@ -88,10 +87,6 @@ More variables are available for further tweaking, but the above variables are a **ACI_DEPLOYMENT_NAME** is used for naming the scoring service during deployment to [Azure Container Instances](https://azure.microsoft.com/en-us/services/container-instances/). -**SCORING_DATASTORE_STORAGE_NAME** is the name for an Azure Blob Storage account that will contain both data used as input to batch scoring, as well as the batch scoring outputs. This variable is optional and only needed if you intend to use the batch scoring facility. Note that since this resource is optional, the resource provisioning pipelines mentioned below do not create this resource automatically, and manual creation is required before use. - -**SCORING_DATASTORE_ACCESS_KEY** is the access key for the scoring data Azure storage account mentioned above. You may want to consider linking this variable to Azure KeyVault to avoid storing the access key in plain text. This variable is optional and only needed if you intend to use the batch scoring facility. - ## Provisioning resources using Azure Pipelines @@ -295,11 +290,10 @@ The pipeline stages are summarized below: - If run locally without the model version, the batch scoring pipeline will use the model's latest version. - Trigger the *ML Batch Scoring Pipeline* and waits for it to complete. - This is an **agentless** job. The CI pipeline can wait for ML pipeline completion for hours or even days without using agent resources. -- Use the scoring input data supplied via the SCORING_DATASTORE_INPUT_* configuration variables. +- Use the scoring input data supplied via the SCORING_DATASTORE_INPUT_* configuration variables, or uses the default datastore and sample data. - Once scoring is completed, the scores are made available in the same blob storage at the locations specified via the SCORING_DATASTORE_OUTPUT_* configuration variables. -**Note** In the event a scoring data store is not yet configured, you can still try out batch scoring by supplying a scoring input data file within the data folder. Do make sure to set the SCORING_DATASTORE_INPUT_FILENAME variable to the name of the file. This approach will cause the score output to be written to the ML workspace's default datastore. - +To configure your own custom scoring data, see [Configure Custom Batch Scoring](custom_model.md#Configure-Custom-Batch-Scoring). ## Further Exploration From 31512d3d6ec25e64d4195939b0ac036ce74c9b1a Mon Sep 17 00:00:00 2001 From: Jenny So Date: Wed, 9 Dec 2020 14:23:10 -0800 Subject: [PATCH 17/29] Update docs (#339) * Update getting_started.md * Update custom_model.md --- docs/custom_model.md | 2 +- docs/getting_started.md | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/custom_model.md b/docs/custom_model.md index a554f376..5c7f8f4a 100644 --- a/docs/custom_model.md +++ b/docs/custom_model.md @@ -80,7 +80,7 @@ To disable the evaluation step, either: ## Customize the build agent environment -The DevOps pipeline definitions in the MLOpsPython template run several steps in a Docker container that contains the dependencies required to work through the Getting Started guide. If additional dependencies are required to run your unit tests or generate your Azure ML pipeline, there are a few options: +The DevOps pipeline definitions in the MLOpsPython template run several steps in a Docker container that contains the dependencies required to work through the Getting Started guide. These dependencies may change over time and may not suit your project's needs. To manage your own dependencies, there are a few options: * Add a pipeline step to install dependencies required by unit tests to `.pipelines/code-quality-template.yml`. Recommended if you only have a small number of test dependencies. * Create a new Docker image containing your dependencies. See [docs/custom_container.md](custom_container.md). Recommended if you have a larger number of dependencies, or if the overhead of installing additional dependencies on each run is too high. diff --git a/docs/getting_started.md b/docs/getting_started.md index 7a311cf8..52bb04d6 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -389,6 +389,7 @@ To remove the resources created for this project, use the [/environment_setup/ia ## Next Steps: Integrating your project - The [custom model](custom_model.md) guide includes information on bringing your own code to this repository template. +- We recommend using a [custom container](custom_model.md#customize-the-build-agent-environment) to manage your pipeline environment and dependencies. The container provided with the getting started guide may not be suitable or up to date with your project needs. - Consider using [Azure Pipelines self-hosted agents](https://docs.microsoft.com/en-us/azure/devops/pipelines/agents/agents?view=azure-devops&tabs=browser#install) to speed up your Azure ML pipeline execution. The Docker container image for the Azure ML pipeline is sizable, and having it cached on the agent between runs can trim several minutes from your runs. ### Additional Variables and Configuration From aba8aefc4b340f89707f0abcc82528d5b032c92d Mon Sep 17 00:00:00 2001 From: "SATO Naoki (Neo)" Date: Wed, 17 Feb 2021 06:20:23 +0900 Subject: [PATCH 18/29] development_setup.md update (#349) * development_setup.md update development_setup.md updated to use install_requirements.sh. See #158: > Use conda rather than pip packages when possible (as recommended in AML docs). > Dev environment is hence also constrained to conda (no more pip install -r requirements.txt). * Content of install_requirements.sh deleted * build_train_pipeline.py filename fixed * build_train_pipeline.py filename fixed --- docs/development_setup.md | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/docs/development_setup.md b/docs/development_setup.md index 68e6b6bf..1c8c2479 100644 --- a/docs/development_setup.md +++ b/docs/development_setup.md @@ -10,19 +10,12 @@ In order to configure the project locally, create a copy of `.env.example` in th [Install the Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli). The Azure CLI will be used to log you in interactively. -Create a virtual environment using [venv](https://docs.python.org/3/library/venv.html), [conda](https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html) or [pyenv-virtualenv](https://github.com/pyenv/pyenv-virtualenv). +Install [conda](https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html). -Here is an example for setting up and activating a `venv` environment with Python 3: +Install the required Python modules. [`install_requirements.sh`](https://github.com/microsoft/MLOpsPython/blob/master/environment_setup/install_requirements.sh) creates and activates a new conda environment with required Python modules. ``` -python3 -mvenv .venv -source .venv/bin/activate -``` - -Install the required Python modules in your virtual environment. - -``` -pip install -r environment_setup/requirements.txt +. environment_setup/install_requirements.sh ``` ### Running local code @@ -30,11 +23,11 @@ pip install -r environment_setup/requirements.txt To run your local ML pipeline code on Azure ML, run a command such as the following (in bash, all on one line): ``` -export BUILD_BUILDID=$(uuidgen); python ml_service/pipelines/build_train_pipeline.py && python ml_service/pipelines/run_train_pipeline.py +export BUILD_BUILDID=$(uuidgen); python ml_service/pipelines/diabetes_regression_build_train_pipeline.py && python ml_service/pipelines/run_train_pipeline.py ``` BUILD_BUILDID is a variable used to uniquely identify the ML pipeline between the -`build_train_pipeline.py` and `run_train_pipeline.py` scripts. In Azure DevOps it is +`diabetes_regression_build_train_pipeline.py` and `run_train_pipeline.py` scripts. In Azure DevOps it is set to the current build number. In a local environment, we can use a command such as `uuidgen` so set a different random identifier on each run, ensuring there are no collisions. From 771c8ef1de199cbb77eb5fd95ebf2ad0ec3ca256 Mon Sep 17 00:00:00 2001 From: "SATO Naoki (Neo)" Date: Fri, 19 Feb 2021 04:27:36 +0900 Subject: [PATCH 19/29] fix TRAIN_SCRIPT_PATH value in .env.example (#348) TRAIN_SCRIPT_PATH value updated from 'training/train.py' to 'training/train_aml.py'. This is aligned with /.pipelines/diabetes_regression-variables-template.yml. --- .env.example | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.env.example b/.env.example index 3c63d969..47311d1e 100644 --- a/.env.example +++ b/.env.example @@ -25,7 +25,7 @@ AML_CLUSTER_PRIORITY = 'lowpriority' # Training Config MODEL_NAME = 'diabetes_regression_model.pkl' MODEL_VERSION = '1' -TRAIN_SCRIPT_PATH = 'training/train.py' +TRAIN_SCRIPT_PATH = 'training/train_aml.py' # AML Pipeline Config @@ -78,4 +78,4 @@ SCORING_DATASTORE_INPUT_FILENAME = 'diabetes_scoring_input.csv' SCORING_DATASTORE_OUTPUT_CONTAINER = 'output' SCORING_DATASTORE_OUTPUT_FILENAME = 'diabetes_scoring_output.csv' SCORING_DATASET_NAME = 'diabetes_scoring_ds' -SCORING_PIPELINE_NAME = 'diabetes-scoring-pipeline' \ No newline at end of file +SCORING_PIPELINE_NAME = 'diabetes-scoring-pipeline' From 2f905b25eb06de673b000450f58520c754577d1a Mon Sep 17 00:00:00 2001 From: Daniel Heinze Date: Thu, 11 Mar 2021 19:22:11 +0100 Subject: [PATCH 20/29] Added AKS compute name details (#355) Added a clarification, that the AKS compute name comes from the inference cluster, which needs to be created to continue. --- docs/getting_started.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/getting_started.md b/docs/getting_started.md index 52bb04d6..7a2c25f0 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -313,15 +313,15 @@ Keep the Azure Container Instances deployment active because it's a lightweight In the Variables tab, edit your variable group (`devopsforai-aml-vg`). In the variable group definition, add these variables: -| Variable Name | Suggested Value | -| ------------------- | --------------- | -| AKS_COMPUTE_NAME | aks | -| AKS_DEPLOYMENT_NAME | mlops-aks | - -Set **AKS_COMPUTE_NAME** to the _Compute name_ of the Inference Cluster that references the Azure Kubernetes Service cluster in your Azure ML Workspace. +| Variable Name | Suggested Value | Description | +| ------------------- | --------------- | ----------- | +| AKS_COMPUTE_NAME | aks | The Compute name of the inference cluster, created in the Azure ML Workspace (ml.azure.com). This connection has to be created manually before setting the value! | +| AKS_DEPLOYMENT_NAME | mlops-aks | The name of the deployed aks cluster in your subscripttion. | After successfully deploying to Azure Container Instances, the next stage will deploy the model to Kubernetes and run a smoke test. +Set **AKS_COMPUTE_NAME** to the _Compute name_ of the Inference Cluster that references the Azure Kubernetes Service cluster in your Azure ML Workspace. + ![build](./images/multi-stage-aci-aks.png) Consider enabling [manual approvals](https://docs.microsoft.com/en-us/azure/devops/pipelines/process/approvals) before the deployment stages. From 2892680a58e49806478f045016ae2b61415c754d Mon Sep 17 00:00:00 2001 From: Jenny So Date: Thu, 11 Mar 2021 10:38:53 -0800 Subject: [PATCH 21/29] Pin AzureML SDK > 1.18.0 for pyyaml fix (#356) * Update conda_dependencies_scoring.yml * Update conda_dependencies_scorecopy.yml * Update conda_dependencies_scoring.yml --- diabetes_regression/conda_dependencies_scorecopy.yml | 2 +- diabetes_regression/conda_dependencies_scoring.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/diabetes_regression/conda_dependencies_scorecopy.yml b/diabetes_regression/conda_dependencies_scorecopy.yml index dffafd08..2d73f4fe 100644 --- a/diabetes_regression/conda_dependencies_scorecopy.yml +++ b/diabetes_regression/conda_dependencies_scorecopy.yml @@ -25,7 +25,7 @@ dependencies: - pip: # Base AzureML SDK - - azureml-sdk==1.6.* + - azureml-sdk>1.18.0 # Score copying deps - azure-storage-blob diff --git a/diabetes_regression/conda_dependencies_scoring.yml b/diabetes_regression/conda_dependencies_scoring.yml index 60c45c44..748cf6a5 100644 --- a/diabetes_regression/conda_dependencies_scoring.yml +++ b/diabetes_regression/conda_dependencies_scoring.yml @@ -25,7 +25,7 @@ dependencies: - pip: # Base AzureML SDK - - azureml-sdk==1.6.* + - azureml-sdk>1.18.0 # Scoring deps - scikit-learn From ae60e489f0c658ba313e6e0020c61b40ffe3bdc9 Mon Sep 17 00:00:00 2001 From: Jenny So Date: Thu, 13 May 2021 01:17:44 -0700 Subject: [PATCH 22/29] Pin azureml version to 1.27.* (#361) * Update ci_dependencies.yml * Update diabetes_regression-cd.yml * Update diabetes_regression-package-model-template.yml * Update diabetes_regression-publish-model-artifact-template.yml * Update conda_dependencies.yml * Update conda_dependencies_scorecopy.yml * Update conda_dependencies_scoring.yml --- .pipelines/diabetes_regression-cd.yml | 4 ++-- .pipelines/diabetes_regression-package-model-template.yml | 2 +- .../diabetes_regression-publish-model-artifact-template.yml | 2 +- diabetes_regression/ci_dependencies.yml | 2 +- diabetes_regression/conda_dependencies.yml | 4 ++-- diabetes_regression/conda_dependencies_scorecopy.yml | 2 +- diabetes_regression/conda_dependencies_scoring.yml | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.pipelines/diabetes_regression-cd.yml b/.pipelines/diabetes_regression-cd.yml index 8dd35e47..a691cc47 100644 --- a/.pipelines/diabetes_regression-cd.yml +++ b/.pipelines/diabetes_regression-cd.yml @@ -49,7 +49,7 @@ stages: azureSubscription: '$(WORKSPACE_SVC_CONNECTION)' scriptLocation: inlineScript workingDirectory: $(Build.SourcesDirectory) - inlineScript: 'az extension add -n azure-cli-ml' + inlineScript: 'az extension add --source https://azurecliext.blob.core.windows.net/release/azure_cli_ml-1.27.0-py3-none-any.whl --yes' - task: AzureCLI@1 displayName: "Deploy to ACI (CLI)" inputs: @@ -95,7 +95,7 @@ stages: azureSubscription: '$(WORKSPACE_SVC_CONNECTION)' scriptLocation: inlineScript workingDirectory: $(Build.SourcesDirectory) - inlineScript: 'az extension add -n azure-cli-ml' + inlineScript: 'az extension add --source https://azurecliext.blob.core.windows.net/release/azure_cli_ml-1.27.0-py3-none-any.whl --yes' - task: AzureCLI@1 displayName: "Deploy to AKS (CLI)" inputs: diff --git a/.pipelines/diabetes_regression-package-model-template.yml b/.pipelines/diabetes_regression-package-model-template.yml index 7725b19c..16fc1c1d 100644 --- a/.pipelines/diabetes_regression-package-model-template.yml +++ b/.pipelines/diabetes_regression-package-model-template.yml @@ -17,7 +17,7 @@ steps: azureSubscription: '$(WORKSPACE_SVC_CONNECTION)' scriptLocation: inlineScript workingDirectory: $(Build.SourcesDirectory) - inlineScript: 'az extension add -n azure-cli-ml' + inlineScript: 'az extension add --source https://azurecliext.blob.core.windows.net/release/azure_cli_ml-1.27.0-py3-none-any.whl --yes' - task: AzureCLI@1 displayName: 'Create model package and set IMAGE_LOCATION variable' inputs: diff --git a/.pipelines/diabetes_regression-publish-model-artifact-template.yml b/.pipelines/diabetes_regression-publish-model-artifact-template.yml index 00e45105..d666750d 100644 --- a/.pipelines/diabetes_regression-publish-model-artifact-template.yml +++ b/.pipelines/diabetes_regression-publish-model-artifact-template.yml @@ -6,7 +6,7 @@ steps: azureSubscription: '$(WORKSPACE_SVC_CONNECTION)' scriptLocation: inlineScript workingDirectory: $(Build.SourcesDirectory) - inlineScript: 'az extension add -n azure-cli-ml' + inlineScript: 'az extension add --source https://azurecliext.blob.core.windows.net/release/azure_cli_ml-1.27.0-py3-none-any.whl --yes' - task: AzureCLI@1 inputs: azureSubscription: '$(WORKSPACE_SVC_CONNECTION)' diff --git a/diabetes_regression/ci_dependencies.yml b/diabetes_regression/ci_dependencies.yml index 542db0c4..73086471 100644 --- a/diabetes_regression/ci_dependencies.yml +++ b/diabetes_regression/ci_dependencies.yml @@ -17,7 +17,7 @@ dependencies: - pip: # dependencies with versions aligned with conda_dependencies.yml. - - azureml-sdk + - azureml-sdk==1.27.* # Additional pip dependencies for the CI environment. - pytest==5.4.* diff --git a/diabetes_regression/conda_dependencies.yml b/diabetes_regression/conda_dependencies.yml index 49405c47..e214c7b2 100644 --- a/diabetes_regression/conda_dependencies.yml +++ b/diabetes_regression/conda_dependencies.yml @@ -23,11 +23,11 @@ dependencies: - pip: # Base AzureML SDK - - azureml-sdk + - azureml-sdk==1.27.* # Must match AzureML SDK version. # https://docs.microsoft.com/en-us/azure/machine-learning/concept-environments - - azureml-defaults + - azureml-defaults==1.27.* # Training deps - scikit-learn diff --git a/diabetes_regression/conda_dependencies_scorecopy.yml b/diabetes_regression/conda_dependencies_scorecopy.yml index 2d73f4fe..9ed22ccd 100644 --- a/diabetes_regression/conda_dependencies_scorecopy.yml +++ b/diabetes_regression/conda_dependencies_scorecopy.yml @@ -25,7 +25,7 @@ dependencies: - pip: # Base AzureML SDK - - azureml-sdk>1.18.0 + - azureml-sdk==1.27.* # Score copying deps - azure-storage-blob diff --git a/diabetes_regression/conda_dependencies_scoring.yml b/diabetes_regression/conda_dependencies_scoring.yml index 748cf6a5..e744b369 100644 --- a/diabetes_regression/conda_dependencies_scoring.yml +++ b/diabetes_regression/conda_dependencies_scoring.yml @@ -25,7 +25,7 @@ dependencies: - pip: # Base AzureML SDK - - azureml-sdk>1.18.0 + - azureml-sdk==1.27.* # Scoring deps - scikit-learn From c321a263297d9109860e0371c6c90549dc8306b3 Mon Sep 17 00:00:00 2001 From: Katzmann1983 Date: Tue, 14 Dec 2021 15:15:02 +0100 Subject: [PATCH 23/29] update documentation (#379) Co-authored-by: Jens Humrich --- docs/code_description.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/code_description.md b/docs/code_description.md index d30295e9..81abc78f 100644 --- a/docs/code_description.md +++ b/docs/code_description.md @@ -52,8 +52,8 @@ The repository provides a template with folders structure suitable for maintaini - `.pipelines/code-quality-template.yml` : a pipeline template used by the CI and PR pipelines. It contains steps performing linting, data and unit testing. - `.pipelines/diabetes_regression-ci-image.yml` : a pipeline building a scoring image for the diabetes regression model. - `.pipelines/diabetes_regression-ci.yml` : a pipeline triggered when the code is merged into **master**. It performs linting, data integrity testing, unit testing, building and publishing an ML pipeline. -- `.pipelines/diabetes_regression-cd.yml` : a pipeline triggered when the code is merged into **master** and the `.pipelines/diabetes_regression-ci.yml` completes. It performs linting, data integrity testing, unit testing, building and publishing an ML pipeline. -- `.pipelines/diabetes_regression-package-model-template.yml` : a pipeline triggered when the code is merged into **master**. It deploys the registered model to a target. +- `.pipelines/diabetes_regression-cd.yml` : a pipeline triggered when the code is merged into **master** and the `.pipelines/diabetes_regression-ci.yml` completes. Deploys the model to ACI, AKS or Webapp. +- `.pipelines/diabetes_regression-package-model-template.yml` : Pipeline template that creates a model package and adds the package location to the environment for subsequent tasks to use. - `.pipelines/diabetes_regression-get-model-id-artifact-template.yml` : a pipeline template used by the `.pipelines/diabetes_regression-cd.yml` pipeline. It takes the model metadata artifact published by the previous pipeline and gets the model ID. - `.pipelines/diabetes_regression-publish-model-artifact-template.yml` : a pipeline template used by the `.pipelines/diabetes_regression-ci.yml` pipeline. It finds out if a new model was registered and publishes a pipeline artifact containing the model metadata. - `.pipelines/helm-*.yml` : pipeline templates used by the `.pipelines/abtest.yml` pipeline. @@ -84,11 +84,11 @@ The repository provides a template with folders structure suitable for maintaini ### Evaluation Step -- `diabetes_regression/evaluate/evaluate_model.py` : an evaluating step of an ML training pipeline which registers a new trained model if evaluation shows the new model is more performant than the previous one. +- `diabetes_regression/evaluate/evaluate_model.py` : an evaluating step which cancels the pipeline in case of non-improvement. ### Registering Step -- `diabetes_regression/evaluate/register_model.py` : registers a new trained model if evaluation shows the new model is more performant than the previous one. +- `diabetes_regression/register/register_model.py` : registers a new trained model if evaluation shows the new model is more performant than the previous one. ### Scoring From fa03633cdb562f4d17f478f8ad11d21840e158aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Pedro=20Martins?= Date: Tue, 14 Dec 2021 16:54:49 +0100 Subject: [PATCH 24/29] Revision of getting started guide up to Batch scoring. Also new diagam and fix to ARM template to remove region restrictions. (#387) Co-authored-by: Joao Pedro Martins --- docs/getting_started.md | 84 +++++++++++------- docs/images/aci-in-azure-portal.png | Bin 0 -> 52224 bytes .../arm-templates/cloud-environment.json | 10 --- 3 files changed, 54 insertions(+), 40 deletions(-) create mode 100644 docs/images/aci-in-azure-portal.png diff --git a/docs/getting_started.md b/docs/getting_started.md index 7a2c25f0..3cd1f263 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -36,13 +36,13 @@ If you already have an Azure DevOps organization, create a new project using the ### Install the Azure Machine Learning extension -Install the **Azure Machine Learning** extension to your Azure DevOps organization from the [Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=ms-air-aiagility.vss-services-azureml). +Install the **Azure Machine Learning** extension to your Azure DevOps organization from the [Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=ms-air-aiagility.vss-services-azureml) by clicking "Get it free" and following the steps. The UI will tell you if try to add it and it's already installed. -This extension contains the Azure ML pipeline tasks and adds the ability to create Azure ML Workspace service connections. +This extension contains the Azure ML pipeline tasks and adds the ability to create Azure ML Workspace service connections. The documentation page on the marketplace includes detailed instructions with screenshots on what capabilities it includes. ## Get the code -We recommend using the [repository template](https://github.com/microsoft/MLOpsPython/generate), which effectively forks the repository to your own GitHub location and squashes the history. You can use the resulting repository for this guide and for your own experimentation. +We recommend using the [repository template](https://github.com/microsoft/MLOpsPython/generate), which effectively forks this repository to your own GitHub location and squashes the history. You can use the resulting repository for this guide and for your own experimentation. ## Create a Variable Group for your Pipeline @@ -59,15 +59,14 @@ The variable group should contain the following required variables. **Azure reso | Variable Name | Suggested Value | Short description | | ------------------------ | ------------------------- | --------------------------------------------------------------------------------------------------------------------------- | | BASE_NAME | [your project name] | Unique naming prefix for created resources - max 10 chars, letters and numbers only | -| LOCATION | centralus | [Azure location](https://azure.microsoft.com/en-us/global-infrastructure/locations/), no spaces | +| LOCATION | centralus | [Azure location](https://azure.microsoft.com/en-us/global-infrastructure/locations/), no spaces. You can list all the region codes by running `az account list-locations -o table` in the Azure CLI | | RESOURCE_GROUP | mlops-RG | Azure Resource Group name | | WORKSPACE_NAME | mlops-AML-WS | Azure ML Workspace name | | AZURE_RM_SVC_CONNECTION | azure-resource-connection | [Azure Resource Manager Service Connection](#create-an-azure-devops-service-connection-for-the-azure-resource-manager) name | | WORKSPACE_SVC_CONNECTION | aml-workspace-connection | [Azure ML Workspace Service Connection](#create-an-azure-devops-azure-ml-workspace-service-connection) name | | ACI_DEPLOYMENT_NAME | mlops-aci | [Azure Container Instances](https://azure.microsoft.com/en-us/services/container-instances/) name | | - -Make sure you select the **Allow access to all pipelines** checkbox in the variable group configuration. +Make sure you select the **Allow access to all pipelines** checkbox in the variable group configuration. To do this, first **Save** the variable group, then click **Pipeline Permissions**, then the button with 3 vertical dots, and then **Open access** button. More variables are available for further tweaking, but the above variables are all you need to get started with this example. For more information, see the [Additional Variables and Configuration](#additional-variables-and-configuration) section. @@ -75,11 +74,11 @@ More variables are available for further tweaking, but the above variables are a **BASE_NAME** is used as a prefix for naming Azure resources and should be unique. When sharing an Azure subscription, the prefix allows you to avoid naming collisions for resources that require unique names, for example, Azure Blob Storage and Registry DNS. Make sure to set BASE_NAME to a unique name so that created resources will have unique names, for example, MyUniqueMLamlcr, MyUniqueML-AML-KV, and so on. The length of the BASE_NAME value shouldn't exceed 10 characters and must contain letters and numbers only. -**LOCATION** is the name of the [Azure location](https://azure.microsoft.com/en-us/global-infrastructure/locations/) for your resources. There should be no spaces in the name. For example, central, westus, westus2. +**LOCATION** is the name of the [Azure location](https://azure.microsoft.com/en-us/global-infrastructure/locations/) for your resources. There should be no spaces in the name. For example, central, westus, northeurope. You can list all the region codes by running `az account list-locations -o table` in the Azure CLI. **RESOURCE_GROUP** is used as the name for the resource group that will hold the Azure resources for the solution. If providing an existing Azure ML Workspace, set this value to the corresponding resource group name. -**WORKSPACE_NAME** is used for creating the Azure Machine Learning Workspace. You can provide an existing Azure ML Workspace here if you've got one. +**WORKSPACE_NAME** is used for creating the Azure Machine Learning Workspace. *While you should be able to provide an existing Azure ML Workspace if you have one, you will run into problems if this has been provisioned manually and the naming of the associated storage account doesn't follow the convention followed in this repo -- as the environment provisioning will try to associate it with a new Storage Account and this is not supported. To avoid these problems, specify a new workspace/unique name.* **AZURE_RM_SVC_CONNECTION** is used by the [Azure Pipeline](../environment_setup/iac-create-environment-pipeline.yml) in Azure DevOps that creates the Azure ML workspace and associated resources through Azure Resource Manager. You'll create the connection in a [step below](#create-an-azure-devops-service-connection-for-the-azure-resource-manager). @@ -96,11 +95,16 @@ The easiest way to create all required Azure resources (Resource Group, Azure ML ### Create an Azure DevOps Service Connection for the Azure Resource Manager -The [IaC provisioning pipeline](../environment_setup/iac-create-environment-pipeline.yml) requires an **Azure Resource Manager** [service connection](https://docs.microsoft.com/en-us/azure/devops/pipelines/library/service-endpoints?view=azure-devops&tabs=yaml#create-a-service-connection). +The [IaC provisioning pipeline](../environment_setup/iac-create-environment-pipeline.yml) requires an **Azure Resource Manager** [service connection](https://docs.microsoft.com/en-us/azure/devops/pipelines/library/service-endpoints?view=azure-devops&tabs=yaml#create-a-service-connection). To create one, in Azure DevOps select **Project Settings**, then **Service Connections**, and create a new one, where: -![Create service connection](./images/create-rm-service-connection.png) +- Type is **Azure Resource Manager** +- Authentication method is **Service principal (automatic)** +- Scope level is **Subscription** +- Leave **`Resource Group`** empty after selecting your subscription in the dropdown +- Use the same **`Service Connection Name`** that you used in the variable group you created +- Select **Grant access permission to all pipelines** -Leave the **`Resource Group`** field empty. +![Create service connection](./images/create-rm-service-connection.png) **Note:** Creating the Azure Resource Manager service connection scope requires 'Owner' or 'User Access Administrator' permissions on the subscription. You'll also need sufficient permissions to register an application with your Azure AD tenant, or you can get the ID and secret of a service principal from your Azure AD Administrator. That principal must have 'Contributor' permissions on the subscription. @@ -111,7 +115,9 @@ In your Azure DevOps project, create a build pipeline from your forked repositor ![Build connect step](./images/build-connect.png) -Select the **Existing Azure Pipelines YAML file** option and set the path to [/environment_setup/iac-create-environment-pipeline-arm.yml](../environment_setup/iac-create-environment-pipeline-arm.yml) or to [/environment_setup/iac-create-environment-pipeline-tf.yml](../environment_setup/iac-create-environment-pipeline-tf.yml), depending on if you want to deploy your infrastructure using ARM templates or Terraform: +If you are using GitHub, after picking the option above, you'll be asked to authorize to GitHub and select the repo you forked. Then you'll have to select your forked repository on GitHub under the **Repository Access** section, and click **Approve and Install**. + +After the above, and when you're redirected back to Azure DevOps, select the **Existing Azure Pipelines YAML file** option and set the path to [/environment_setup/iac-create-environment-pipeline-arm.yml](../environment_setup/iac-create-environment-pipeline-arm.yml) or to [/environment_setup/iac-create-environment-pipeline-tf.yml](../environment_setup/iac-create-environment-pipeline-tf.yml), depending on if you want to deploy your infrastructure using ARM templates or Terraform: ![Configure step](./images/select-iac-pipeline.png) @@ -125,11 +131,13 @@ Check that the newly created resources appear in the [Azure Portal](https://port ![Created resources](./images/created-resources.png) +**Note**: If you have other errors, one good thing to check is what you used in the variable names. If you end up running the pipeline multiple times, you may also run into errors and need to delete the Azure services and re-run the pipeline -- this should include a resource group, a KeyVault, a Storage Account, a Container Registry, an Application Insights and a Machine Learning workspace. + ## Create an Azure DevOps Service Connection for the Azure ML Workspace At this point, you should have an Azure ML Workspace created. Similar to the Azure Resource Manager service connection, you need to create an additional one for the Azure ML Workspace. -Create a new service connection to your Azure ML Workspace using the [Machine Learning Extension](https://marketplace.visualstudio.com/items?itemName=ms-air-aiagility.vss-services-azureml) instructions to enable executing the Azure ML training pipeline. The connection name needs to match `WORKSPACE_SVC_CONNECTION` that you set in the variable group above (eg. 'aml-workspace-connection'). +Create a new service connection to your Azure ML Workspace using the [Machine Learning Extension](https://marketplace.visualstudio.com/items?itemName=ms-air-aiagility.vss-services-azureml) instructions to enable executing the Azure ML training pipeline. The connection name needs to match `WORKSPACE_SVC_CONNECTION` that you set in the variable group above (e.g., 'aml-workspace-connection'). ![Created resources](./images/ml-ws-svc-connection.png) @@ -138,23 +146,25 @@ You'll need sufficient permissions to register an application with your Azure AD ## Set up Build, Release Trigger, and Release Multi-Stage Pipelines -Now that you've provisioned all the required Azure resources and service connections, you can set up the pipelines for training (CI) and deploying (CD) your machine learning model to production. Additionally, you can set up a pipeline for batch scoring. +Now that you've provisioned all the required Azure resources and service connections, you can set up the pipelines for training (Continuous Integration - **CI**) and deploying (Continuous Deployment - **CD**) your machine learning model to production. Additionally, you can set up a pipeline for batch scoring. 1. **Model CI, training, evaluation, and registration** - triggered on code changes to master branch on GitHub. Runs linting, unit tests, code coverage, and publishes and runs the training pipeline. If a new model is registered after evaluation, it creates a build artifact containing the JSON metadata of the model. Definition: [diabetes_regression-ci.yml](../.pipelines/diabetes_regression-ci.yml). 1. **Release deployment** - consumes the artifact of the previous pipeline and deploys a model to either [Azure Container Instances (ACI)](https://azure.microsoft.com/en-us/services/container-instances/), [Azure Kubernetes Service (AKS)](https://azure.microsoft.com/en-us/services/kubernetes-service), or [Azure App Service](https://docs.microsoft.com/en-us/azure/machine-learning/service/how-to-deploy-app-service) environments. See [Further Exploration](#further-exploration) for other deployment types. Definition: [diabetes_regression-cd.yml](../.pipelines/diabetes_regression-cd.yml). - 1. **Note:** Edit the pipeline definition to remove unused stages. For example, if you're deploying to Azure Container Instances and Azure Kubernetes Service only, delete the unused `Deploy_Webapp` stage. + 1. **Note:** Edit the pipeline definition to remove unused stages. For example, if you're deploying to Azure Container Instances and Azure Kubernetes Service only, you'll need to delete the unused `Deploy_Webapp` stage. 1. **Batch Scoring Code Continuous Integration** - consumes the artifact of the model training pipeline. Runs linting, unit tests, code coverage, publishes a batch scoring pipeline, and invokes the published batch scoring pipeline to score a model. -These pipelines use a Docker container on the Azure Pipelines agents to accomplish the pipeline steps. The container image ***mcr.microsoft.com/mlops/python:latest*** is built with [this Dockerfile](../environment_setup/Dockerfile) and has all the necessary dependencies installed for MLOpsPython and ***diabetes_regression***. This image is an example of a custom Docker image with a pre-baked environment. The environment is guaranteed to be the same on any building agent, VM, or local machine. In your project, you'll want to build your own Docker image that only contains the dependencies and tools required for your use case. Your image will probably be smaller and faster, and it will be maintained by your team. +These pipelines use a Docker container on the Azure Pipelines agents to accomplish the pipeline steps. The container image ***mcr.microsoft.com/mlops/python:latest*** is built with [this Dockerfile](../environment_setup/Dockerfile) and has all the necessary dependencies installed for MLOpsPython and ***diabetes_regression***. This image is an example of a custom Docker image with a pre-baked environment. The environment is guaranteed to be the same on any building agent, VM, or local machine. **In your project, you'll want to build your own Docker image that only contains the dependencies and tools required for your use case. Your image will probably be smaller and faster, and it will be maintained by your team.** ### Set up the Model CI, training, evaluation, and registration pipeline -In your Azure DevOps project, create and run a new build pipeline based on the [diabetes_regression-ci.yml](../.pipelines/diabetes_regression-ci.yml) +In your Azure DevOps project, create and run a new build pipeline based on the [./pipelines/diabetes_regression-ci.yml](../.pipelines/diabetes_regression-ci.yml) pipeline definition in your forked repository. If you plan to use the release deployment pipeline (in the next section), you will need to rename this pipeline to `Model-Train-Register-CI`. -Once the pipeline is finished, check the execution result: +**Note**: *To rename your pipeline, after you saved it, click **Pipelines** on the left menu on Azure DevOps, then **All** to see all the pipelines, then click the menu with the 3 vertical dots that appears when you hover the name of the new pipeline, and click it to pick **"Rename/move pipeline"**.* + +Start a run of the pipeline if you haven't already, and once the pipeline is finished, check the execution result. Note that the run can take 20 minutes, with time mostly spent in **Trigger ML Training Pipeline > Invoke ML Pipeline** step. You can track the execution of the AML pipeline by opening the AML Workspace user interface. Screenshots are below: ![Build](./images/model-train-register.png) @@ -162,13 +172,13 @@ And the pipeline artifacts: ![Build](./images/model-train-register-artifacts.png) -Also check the published training pipeline in the **mlops-AML-WS** workspace in [Azure Machine Learning Studio](https://ml.azure.com/): +Also check the published training pipeline in your newly created AML workspace in [Azure Machine Learning Studio](https://ml.azure.com/): ![Training pipeline](./images/training-pipeline.png) Great, you now have the build pipeline for training set up which automatically triggers every time there's a change in the master branch! -After the pipeline is finished, you'll see a new model in the **ML Workspace**: +After the pipeline is finished, you'll also see a new model in the **AML Workspace** model registry section: ![Trained model](./images/trained-model.png) @@ -188,19 +198,26 @@ The pipeline stages are summarized below: - Trigger the _ML Training Pipeline_ and waits for it to complete. - This is an **agentless** job. The CI pipeline can wait for ML pipeline completion for hours or even days without using agent resources. - Determine if a new model was registered by the _ML Training Pipeline_. - - If the model evaluation determines that the new model doesn't perform any better than the previous one, the new model won't register and the _ML Training Pipeline_ will be **canceled**. In this case, you'll see a message in the 'Train Model' job under the 'Determine if evaluation succeeded and new model is registered' step saying '**Model was not registered for this run.**' - - See [evaluate_model.py](../diabetes_regression/evaluate/evaluate_model.py#L118) for the evaluation logic. + - If the model evaluation step of the AML Pipeline determines that the new model doesn't perform any better than the previous one, the new model won't register and the _ML Training Pipeline_ will be **canceled**. In this case, you'll see a message in the 'Train Model' job under the 'Determine if evaluation succeeded and new model is registered' step saying '**Model was not registered for this run.**' + - See [evaluate_model.py](../diabetes_regression/evaluate/evaluate_model.py#L118) for the evaluation logic. This is a simplified test that just looks at MSE to decide whether or not to register a new model. A more realistic verification would also do some error analysis and verify the inferences/error distribution against a test dataset, for example. + - **Note**: *while it's possible to do an Evaluation Step as part of the ADO pipeline, this evaluation is logically part of the work done by Data Scientists, and as such the recommendation is that this step is done as part of the AML Pipeline and not ADO pipelines.* - [Additional Variables and Configuration](#additional-variables-and-configuration) for configuring this and other behavior. #### Create pipeline artifact - Get the info about the registered model -- Create a pipeline artifact called `model` that contains a `model.json` file containing the model information. +- Create an Azure DevOps pipeline artifact called `model` that contains a `model.json` file containing the model information, for example: + +```json +{ "createdTime": "2021-12-14T13:03:24.494748+00:00", "framework": "Custom", "frameworkVersion": null, "id": "diabetes_regression_model.pkl:1", "name": "diabetes_regression_model.pkl", "version": 1 } +``` + +- Here's [more information on Azure DevOps Artifacts](https://docs.microsoft.com/en-us/azure/devops/pipelines/artifacts/build-artifacts?view=azure-devops&tabs=yaml#explore-download-and-deploy-your-artifacts) and where to find them on the ADO user interface. ### Set up the Release Deployment and/or Batch Scoring pipelines --- -**PREREQUISITE** +**PRE-REQUISITES** In order to use these pipelines: @@ -229,14 +246,17 @@ resources: The release deployment and batch scoring pipelines have the following behaviors: -- The pipeline will **automatically trigger** on completion of the Model-Train-Register-CI pipeline for the master branch. -- The pipeline will default to using the latest successful build of the Model-Train-Register-CI pipeline. It will deploy the model produced by that build. +- The pipeline will **automatically trigger** on completion of the `Model-Train-Register-CI` pipeline for the master branch. +- The pipeline will default to using the latest successful build of the `Model-Train-Register-CI` pipeline. It will deploy the model produced by that build. - You can specify a `Model-Train-Register-CI` build ID when running the pipeline manually. You can find this in the url of the build, and the model registered from that build will also be tagged with the build ID. This is useful to skip model training and registration, and deploy/score a model successfully registered by a `Model-Train-Register-CI` build. + - For example, if you navigate to a specific run of your CI pipeline, the URL should be something like `https://dev.azure.com/yourOrgName/yourProjectName/_build/results?buildId=653&view=results`. **653** is the build ID in this case. See the second screenshot below to verify where this number would be used. ### Set up the Release Deployment pipeline -In your Azure DevOps project, create and run a new build pipeline based on the [diabetes_regression-cd.yml](../.pipelines/diabetes_regression-cd.yml) -pipeline definition in your forked repository. +In your Azure DevOps project, create and run a new **build** pipeline based on the [./pipelines/diabetes_regression-cd.yml](../.pipelines/diabetes_regression-cd.yml) +pipeline definition in your forked repository. It is recommended you rename this pipeline to something like `Model-Deploy-CD` for clarity. + +**Note**: *While Azure DevOps supports both Build and Release pipelines, when using YAML you don't usually need to use Release pipelines. This repository assumes the usage only of Build pipelines.* Your first run will use the latest model created by the `Model-Train-Register-CI` pipeline. @@ -244,11 +264,11 @@ Once the pipeline is finished, check the execution result: ![Build](./images/model-deploy-result.png) -To specify a particular build's model, set the `Model Train CI Build Id` parameter to the build Id you would like to use. +To specify a particular build's model, set the `Model Train CI Build Id` parameter to the build ID you would like to use: ![Build](./images/model-deploy-configure.png) -Once your pipeline run begins, you can see the model name and version downloaded from the `Model-Train-Register-CI` pipeline. +Once your pipeline run begins, you can see the model name and version downloaded from the `Model-Train-Register-CI` pipeline. The run time will typically be 5-10 minutes. ![Build](./images/model-deploy-get-artifact-logs.png) @@ -260,6 +280,10 @@ The pipeline has the following stage: - Smoke test - The test sends a sample query to the scoring web service and verifies that it returns the expected response. Have a look at the [smoke test code](../ml_service/util/smoke_test_scoring_service.py) for an example. +- You can verify that an ACI instance was created in the same resource group you specified: + +![Created Resouces ](./images/aci-in-azure-portal.png) + ### Set up the Batch Scoring pipeline In your Azure DevOps project, create and run a new build pipeline based on the [diabetes_regression-batchscoring-ci.yml](../.pipelines/diabetes_regression-batchscoring-ci.yml) diff --git a/docs/images/aci-in-azure-portal.png b/docs/images/aci-in-azure-portal.png new file mode 100644 index 0000000000000000000000000000000000000000..e7bfa8cd5340b9db52a189ced82aad6db54ee0c5 GIT binary patch literal 52224 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 Date: Tue, 14 Dec 2021 20:56:50 +0100 Subject: [PATCH 25/29] JP aks deployment fix (#388) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Change AKS deployment configuration Deployment config changed from 1CPU/4GB to 0.5CPU/2GB so it fits a AKS created with default parameters * Update custom_model.md Co-authored-by: João Pedro Martins --- diabetes_regression/scoring/deployment_config_aks.yml | 4 ++-- docs/custom_model.md | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/diabetes_regression/scoring/deployment_config_aks.yml b/diabetes_regression/scoring/deployment_config_aks.yml index 1299dc9d..cd81009d 100644 --- a/diabetes_regression/scoring/deployment_config_aks.yml +++ b/diabetes_regression/scoring/deployment_config_aks.yml @@ -7,8 +7,8 @@ autoScaler: targetUtilization: 70 authEnabled: True containerResourceRequirements: - cpu: 1 - memoryInGB: 4 + cpu: 0.5 + memoryInGB: 2 appInsightsEnabled: True scoringTimeoutMs: 5000 maxConcurrentRequestsPerContainer: 2 diff --git a/docs/custom_model.md b/docs/custom_model.md index 5c7f8f4a..28a15d78 100644 --- a/docs/custom_model.md +++ b/docs/custom_model.md @@ -97,6 +97,7 @@ If you want to keep scoring: 1. Update or replace `[project name]/scoring/score.py` 1. Add any dependencies required by scoring to `[project name]/conda_dependencies.yml` 1. Modify the test cases in the `ml_service/util/smoke_test_scoring_service.py` script to match the schema of the training features in your data +1. Check and modify [project name]/scoring/deployment_config_aks.yml if AKS deployment is planned. The deployment configuration shall suit custom model as well as AKS cluster size. # Configure Custom Batch Scoring From d081fc2fe66f2541b33f6f118f6cbc41640a1a75 Mon Sep 17 00:00:00 2001 From: Katzmann1983 Date: Tue, 14 Dec 2021 21:00:54 +0100 Subject: [PATCH 26/29] Fix evaluate issue (#381) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * update documentation * fix evaluate issue * linting Co-authored-by: Jens Humrich Co-authored-by: João Pedro Martins --- diabetes_regression/evaluate/evaluate_model.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/diabetes_regression/evaluate/evaluate_model.py b/diabetes_regression/evaluate/evaluate_model.py index 5a69addb..d1ff3c6a 100644 --- a/diabetes_regression/evaluate/evaluate_model.py +++ b/diabetes_regression/evaluate/evaluate_model.py @@ -118,17 +118,21 @@ production_model_mse = 10000 if (metric_eval in model.tags): production_model_mse = float(model.tags[metric_eval]) - new_model_mse = float(run.parent.get_metrics().get(metric_eval)) + try: + new_model_mse = float(run.parent.get_metrics().get(metric_eval)) + except TypeError: + new_model_mse = None if (production_model_mse is None or new_model_mse is None): - print("Unable to find", metric_eval, "metrics, " + print("Unable to find ", metric_eval, " metrics, " "exiting evaluation") if((allow_run_cancel).lower() == 'true'): run.parent.cancel() else: print( - "Current Production model mse: {}, " - "New trained model mse: {}".format( - production_model_mse, new_model_mse + "Current Production model {}: {}, ".format( + metric_eval, production_model_mse) + + "New trained model {}: {}".format( + metric_eval, new_model_mse ) ) From 4b2667e34be793fa74abe801223279454b502d97 Mon Sep 17 00:00:00 2001 From: Tim Johnson <43890311+Inevitable-Marzipan@users.noreply.github.com> Date: Tue, 14 Dec 2021 20:27:26 +0000 Subject: [PATCH 27/29] Improve readability of exceptions in build pipeline script (#357) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update manage_environment.py * Update attach_compute.py * Update attach_compute.py * Update manage_environment.py Co-authored-by: João Pedro Martins --- ml_service/util/attach_compute.py | 5 +++-- ml_service/util/manage_environment.py | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/ml_service/util/attach_compute.py b/ml_service/util/attach_compute.py index ad9668db..cf8c07a6 100644 --- a/ml_service/util/attach_compute.py +++ b/ml_service/util/attach_compute.py @@ -1,4 +1,5 @@ +import traceback from azureml.core import Workspace from azureml.core.compute import AmlCompute from azureml.core.compute import ComputeTarget @@ -32,7 +33,7 @@ def get_compute(workspace: Workspace, compute_name: str, vm_size: str, for_batch show_output=True, min_node_count=None, timeout_in_minutes=10 ) return compute_target - except ComputeTargetException as ex: - print(ex) + except ComputeTargetException: + traceback.print_exc() print("An error occurred trying to provision compute.") exit(1) diff --git a/ml_service/util/manage_environment.py b/ml_service/util/manage_environment.py index 54c5a72f..b61c97fe 100644 --- a/ml_service/util/manage_environment.py +++ b/ml_service/util/manage_environment.py @@ -1,5 +1,6 @@ import os +import traceback from azureml.core import Workspace, Environment from ml_service.util.env_variables import Env from azureml.core.runconfig import DEFAULT_CPU_IMAGE, DEFAULT_GPU_IMAGE @@ -35,6 +36,6 @@ def get_environment( if restored_environment is not None: print(restored_environment) return restored_environment - except Exception as e: - print(e) + except Exception: + traceback.print_exc() exit(1) From 4a9a1ff7bbf41aa34ada00494db07c52b5faa647 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Pedro=20Martins?= Date: Tue, 14 Dec 2021 22:04:31 +0100 Subject: [PATCH 28/29] Add details on the Batch scoring session of Getting Started (#389) * Revision of getting started guide up to Batch scoring. Also new diagam and fix to ARM template to remove region restrictions. * Detail on Batch scoring for Getting Started and additional debug message in the copy to ease of diagnosing issues * Tweaked text and added a NOQA for message Co-authored-by: Joao Pedro Martins --- .../scoring/parallel_batchscore_copyoutput.py | 2 +- docs/getting_started.md | 32 ++++++++++++------ docs/images/batch-child-run-scoringstep.png | Bin 0 -> 9057 bytes 3 files changed, 22 insertions(+), 12 deletions(-) create mode 100644 docs/images/batch-child-run-scoringstep.png diff --git a/diabetes_regression/scoring/parallel_batchscore_copyoutput.py b/diabetes_regression/scoring/parallel_batchscore_copyoutput.py index cc4af42c..1bcde4b6 100644 --- a/diabetes_regression/scoring/parallel_batchscore_copyoutput.py +++ b/diabetes_regression/scoring/parallel_batchscore_copyoutput.py @@ -86,6 +86,6 @@ def copy_output(args): or args.output_path is None or args.output_path.strip() == "" ): - print("Missing parameters") + print("Missing parameters in parallel_batchscore_copyoutput.py -- Not going to copy inferences to an output datastore") # NOQA E501 else: copy_output(args) diff --git a/docs/getting_started.md b/docs/getting_started.md index 3cd1f263..977fe626 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -286,39 +286,49 @@ The pipeline has the following stage: ### Set up the Batch Scoring pipeline -In your Azure DevOps project, create and run a new build pipeline based on the [diabetes_regression-batchscoring-ci.yml](../.pipelines/diabetes_regression-batchscoring-ci.yml) -pipeline definition in your forked repository. +In your Azure DevOps project, create and run a new build pipeline based on the [.pipelines/diabetes_regression-batchscoring-ci.yml](../.pipelines/diabetes_regression-batchscoring-ci.yml) +pipeline definition in your forked repository. Rename this pipeline to `Batch-Scoring`. Once the pipeline is finished, check the execution result: ![Build](./images/batchscoring-ci-result.png) -Also check the published batch scoring pipeline in the **mlops-AML-WS** workspace in [Azure Portal](https://portal.azure.com/): +Also check the published batch scoring pipeline in your AML workspace in the [Azure Portal](https://portal.azure.com/): ![Batch scoring pipeline](./images/batchscoring-pipeline.png) Great, you now have the build pipeline set up for batch scoring which automatically triggers every time there's a change in the master branch! -The pipeline stages are summarized below: +The pipeline stages are described below in detail -- and you must do further configurations to actually see the batch inferences: #### Batch Scoring CI - Linting (code quality analysis) - Unit tests and code coverage analysis -- Build and publish *ML Batch Scoring Pipeline* in an *ML Workspace* +- Build and publish *ML Batch Scoring Pipeline* in an *AML Workspace* #### Batch Score model - Determine the model to be used based on the model name (required), model version, model tag name and model tag value bound pipeline parameters. - If run via Azure DevOps pipeline, the batch scoring pipeline will take the model name and version from the `Model-Train-Register-CI` build used as input. - If run locally without the model version, the batch scoring pipeline will use the model's latest version. -- Trigger the *ML Batch Scoring Pipeline* and waits for it to complete. +- Trigger the *ML Batch Scoring Pipeline* and wait for it to complete. - This is an **agentless** job. The CI pipeline can wait for ML pipeline completion for hours or even days without using agent resources. -- Use the scoring input data supplied via the SCORING_DATASTORE_INPUT_* configuration variables, or uses the default datastore and sample data. -- Once scoring is completed, the scores are made available in the same blob storage at the locations specified via the SCORING_DATASTORE_OUTPUT_* configuration variables. - -To configure your own custom scoring data, see [Configure Custom Batch Scoring](custom_model.md#Configure-Custom-Batch-Scoring). - +- Create an Azure ML pipeline with two steps. The pipeline is created by the code in `ml_service\pipelines\diabetes_regression_build_parallel_batchscore_pipeline.py` and has two steps: + - `scoringstep` - this step is a **`ParallelRunStep`** that executes the code in `diabetes_regression\scoring\parallel_batchscore.py` with several different batches of the data to be scored. + - `scorecopystep` - this is a **`PythonScriptStep`** step that copies the output inferences from Azure ML's internal storage into a target location in a another storage account. + - If you run the instructions as defined above with no changes to variables, this step will be **not** executed. You'll see a message in the logs for the corresponding step saying `Missing Parameters`. In this case, you'll be able to find the file with the inferences in the same Storage Account associated with Azure ML, in a location similar to `azureml-blobstore-SomeGuid\azureml\SomeOtherGuid\defaultoutput\parallel_run_step.txt`. One way to find the right path is this: + - Open your experiment in Azure ML (by default called `mlopspython`). + - Open the run that you want to look at (named something like `neat_morning_qc10dzjy` or similar). + - In the graphical pipeline view with 2 steps, click the button to open the details tab: `Show run overview`. + - You'll see two steps (corresponding to `scoringstep`and `scorecopystep` as described above). + - Click the step with the with older "Submitted time". + - Click "Output + logs" at the top, and you'll see something like the following: + ![Outputs of `scoringstep`](./images/batch-child-run-scoringstep.png) + - The `defaultoutput` file will have JSON content with the path to a file called `parallel_run_step.txt` containing the scoring. + +To properly configure this step for your own custom scoring data, you must follow the instructions in [Configure Custom Batch Scoring](custom_model.md#Configure-Custom-Batch-Scoring), which let you specify both the location of the files to score (via the `SCORING_DATASTORE_INPUT_*` configuration variables) and where to store the inferences (via the `SCORING_DATASTORE_OUTPUT_*` configuration variables). + ## Further Exploration You should now have a working set of pipelines that can get you started with MLOpsPython. Below are some additional features offered that might suit your scenario. diff --git a/docs/images/batch-child-run-scoringstep.png b/docs/images/batch-child-run-scoringstep.png new file mode 100644 index 0000000000000000000000000000000000000000..6b87f52dbe502d9a9e262aecfa169c24f97301a9 GIT binary patch literal 9057 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 Y>K~DKA#y$FZ83nnw95N3Ns}-C4bb Date: Wed, 15 Dec 2021 18:09:36 +0100 Subject: [PATCH 29/29] Clarified/Fixed getting started instructions for WebApp/AppService deployment (#390) * Revision of getting started guide up to Batch scoring. Also new diagam and fix to ARM template to remove region restrictions. * Detail on Batch scoring for Getting Started and additional debug message in the copy to ease of diagnosing issues * Tweaked text and added a NOQA for message * Clarified/Fixed getting started instructions for WebApp/AppService deployment Co-authored-by: Joao Pedro Martins --- docs/getting_started.md | 47 +++++++++++++----- docs/images/ADO-CD-pipeline-to-webapp.png | Bin 0 -> 8019 bytes .../appservice-webapp-deploymentcenter.png | Bin 0 -> 27306 bytes .../container-registry-webapp-image.png | Bin 0 -> 16757 bytes 4 files changed, 35 insertions(+), 12 deletions(-) create mode 100644 docs/images/ADO-CD-pipeline-to-webapp.png create mode 100644 docs/images/appservice-webapp-deploymentcenter.png create mode 100644 docs/images/container-registry-webapp-image.png diff --git a/docs/getting_started.md b/docs/getting_started.md index 977fe626..4ba694d7 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -366,23 +366,46 @@ When deploying to Azure Kubernetes Service, key-based authentication is enabled ### Deploy the model to Azure App Service (Azure Web App for containers) -If you want to deploy your scoring service as an [Azure App Service](https://docs.microsoft.com/en-us/azure/machine-learning/service/how-to-deploy-app-service) instead of Azure Container Instances and Azure Kubernetes Service, follow these additional steps. +If you want to deploy your scoring service as an [Azure App Service](https://docs.microsoft.com/en-us/azure/machine-learning/service/how-to-deploy-app-service) instead of Azure Container Instances or Azure Kubernetes Service, follow these additional steps. -In the Variables tab, edit your variable group (`devopsforai-aml-vg`) and add a variable: +- First, you'll need to create an App Service Plan using Linux. The simplest way is to run this from your Azure CLI: `az appservice plan create --name nameOfAppServicePlan --resource-group nameOfYourResourceGroup --sku B1 --is-linux`. -| Variable Name | Suggested Value | -| ---------------------- | ---------------------- | -| WEBAPP_DEPLOYMENT_NAME | _name of your web app_ | +- Second, you'll need to create a webapp in this App Service Plan, and configure it to run a certain container. As currently there is no UI in the Azure Portal to do this, this has to be done from the command line. We'll come back to this. -Set **WEBAPP_DEPLOYMENT_NAME** to the name of your Azure Web App. This app must exist before you can deploy the model to it. +- In the Variables tab, edit your variable group (`devopsforai-aml-vg`) and add a variable: -Delete the **ACI_DEPLOYMENT_NAME** variable. + | Variable Name | Suggested Value | + | ---------------------- | ---------------------- | + | WEBAPP_DEPLOYMENT_NAME | _name of your web app_ | -The pipeline uses the [Azure ML CLI](../.pipelines/diabetes_regression-package-model-template.yml) to create a scoring image. The image will be registered under an Azure Container Registry instance that belongs to the Azure Machine Learning Service. Any dependencies that the scoring file depends on can also be packaged with the container with an image config. Learn more about how to create a container using the Azure ML SDK with the [Image class](https://docs.microsoft.com/en-us/python/api/azureml-core/azureml.core.image.image.image?view=azure-ml-py#create-workspace--name--models--image-config-) API documentation. + Set **WEBAPP_DEPLOYMENT_NAME** to the name of your Azure Web App. You have not yet created this webapp, so just use the name you're planning on giving it. -Make sure your webapp has the credentials to pull the image from the Azure Container Registry created by the Infrastructure as Code pipeline. Instructions can be found on the [Configure registry credentials in web app](https://docs.microsoft.com/en-us/azure/devops/pipelines/targets/webapp-on-container-linux?view=azure-devops&tabs=dotnet-core%2Cyaml#configure-registry-credentials-in-web-app) page. You'll need to run the pipeline once (including the Deploy to Webapp stage up to the `Create scoring image` step) so an image is present in the registry. After that, you can connect the Webapp to the Azure Container Registry in the Azure Portal. +- Delete the **ACI_DEPLOYMENT_NAME** or any AKS-related variable. -![build](./images/multi-stage-webapp.png) +- Next, you'll need to run your `Model-Deploy-CD` pipeline + + - The pipeline uses the [Azure ML CLI](../.pipelines/diabetes_regression-package-model-template.yml) to create a scoring image. The image will be registered under an Azure Container Registry instance that belongs to the Azure Machine Learning Service. Any dependencies that the scoring file depends on can also be packaged with the container with an image config. Learn more about how to create a container using the Azure ML SDK with the [Image class](https://docs.microsoft.com/en-us/python/api/azureml-core/azureml.core.image.image.image?view=azure-ml-py#create-workspace--name--models--image-config-) API documentation. + + - This pipeline will **fail** on the `Azure Web App on Container Deploy` step, with an error saying the webapp doesn't exist yet. This is expected. Go to the next step. + +- If you want to confirm that the scoring image has been created, open the Azure Container Registry mentioned above, which will be in the Resource Group of the Azure ML workspace, and look for the repositories. You'll have one that was created by the pipeline, called `package`, which was created by the CD pipeline: + + ![Azure Container Registry repository list](./images/container-registry-webapp-image.png) + +- Notedown the name of the Login Server of your Azure Container Registry. It'll be something like `YourAcrName.azurecr.io`. + +- Going back to the Step Two, now you can create a Web App in you App Service Plan using this scoring image but with the `latest` tag. The easiest way to do this is to run this in the Azure CLI: `az webapp create --resource-group yourResourceGroup --plan nameOfAppServicePlan --name nameOfWebApp --deployment-container-image-name YourAcrName.azurecr.io/package:latest` + - Here, `nameOfWebApp` is the same you put in your Azure DevOps `WEBAPP_DEPLOYMENT_NAME` variable. + +From now on, whenever you run the CD pipeline, it will update the image in the container registry and it'll automatically update the one used in the WebApp. CD pipeline runs will now succeed. + +![build](./images/ADO-CD-pipeline-to-webapp.png) + +To confirm, you can open the App Service Plan, open your new WebApp, and open the **Deployment Center**, where you'll see something like: + +![WebApp Deployment Center page](./images/appservice-webapp-deploymentcenter.png) + +If you run into problems, you may have to make sure your webapp has the credentials to pull the image from the Azure Container Registry created by the Infrastructure as Code pipeline. Instructions can be found on the [Configure registry credentials in web app](https://docs.microsoft.com/en-us/azure/devops/pipelines/targets/webapp-on-container-linux?view=azure-devops&tabs=dotnet-core%2Cyaml#configure-registry-credentials-in-web-app) page. ### Example pipelines using R @@ -424,7 +447,7 @@ To remove the resources created for this project, use the [/environment_setup/ia - The [custom model](custom_model.md) guide includes information on bringing your own code to this repository template. - We recommend using a [custom container](custom_model.md#customize-the-build-agent-environment) to manage your pipeline environment and dependencies. The container provided with the getting started guide may not be suitable or up to date with your project needs. -- Consider using [Azure Pipelines self-hosted agents](https://docs.microsoft.com/en-us/azure/devops/pipelines/agents/agents?view=azure-devops&tabs=browser#install) to speed up your Azure ML pipeline execution. The Docker container image for the Azure ML pipeline is sizable, and having it cached on the agent between runs can trim several minutes from your runs. +- Consider using [Azure Pipelines self-hosted agents](https://docs.microsoft.com/en-us/azure/devops/pipelines/agents/agents?view=azure-devops&tabs=browser#install) to speed up your Azure ML pipeline execution. The Docker container image for the Azure ML pipeline is sizable, and having it cached on the agent between runs can trim several minutes from your runs. Additionally, for secure deployments of Azure Machine Learning, you'll probably need to have a self-hosted agent in a Virtual Network. ### Additional Variables and Configuration @@ -434,7 +457,7 @@ There are more variables used in the project. They're defined in two places: one For using Azure Pipelines, all other variables are stored in the file `.pipelines/diabetes_regression-variables-template.yml`. Using the default values as a starting point, adjust the variables to suit your requirements. -In that folder, you'll also find the `parameters.json` file that we recommend using to provide parameters for training, evaluation, and scoring scripts. The sample parameter that `diabetes_regression` uses is the ridge regression [_alpha_ hyperparameter](https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.Ridge.html). We don't provide any serializers for this config file. +In the `diabetes_regression` folder, you'll also find the `parameters.json` file that we recommend using to provide parameters for training, evaluation, and scoring scripts. The sample parameter that `diabetes_regression` uses is the ridge regression [_alpha_ hyperparameter](https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.Ridge.html). We don't provide any serializers for this config file. #### Local configuration diff --git a/docs/images/ADO-CD-pipeline-to-webapp.png b/docs/images/ADO-CD-pipeline-to-webapp.png new file mode 100644 index 0000000000000000000000000000000000000000..aac8c9ee5c6da089c683b522edcc94eeadbb3d42 GIT binary patch literal 8019 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 literal 0 HcmV?d00001 diff --git a/docs/images/appservice-webapp-deploymentcenter.png b/docs/images/appservice-webapp-deploymentcenter.png new file mode 100644 index 0000000000000000000000000000000000000000..b79ff615a59944eace04f79e36bc6261499ecc7a GIT binary patch literal 27306 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

      iNuf;M@bp`Gf0UCg_x$BNkQ52O;N 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

      #rx%Wjrlpl&uq$u+^9bPQW@ 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 literal 0 HcmV?d00001 diff --git a/docs/images/container-registry-webapp-image.png b/docs/images/container-registry-webapp-image.png new file mode 100644 index 0000000000000000000000000000000000000000..4ec09f8fa931dae8f9cfca53b8bb526624ad91a7 GIT binary patch literal 16757 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 literal 0 HcmV?d00001