<jupyter_start><jupyter_text>Copyright (c) Microsoft Corporation. All rights reserved.Licensed under the MIT License. ![Impressions](https://PixelServer20190423114238.azurewebsites.net/api/impressions/MachineLearningNotebooks/how-to-use-azureml/deployment/deploy-to-local/register-model-deploy-local.png)  Register model and deploy locallyThis example shows how to deploy a web service in step-by-step fashion: 1. Register model 2. Deploy the image as a web service in a local Docker container. 3. Quickly test changes to your entry script by reloading the local service. 4. Optionally, you can also make changes to model, conda or extra_docker_file_steps and update local service  PrerequisitesIf you are using an Azure Machine Learning Notebook VM, you are all set. Otherwise, make sure you go through the [configuration](../../../configuration.ipynb) Notebook first if you haven't.<jupyter_code># Check core SDK version number
import azureml.core

print("SDK version:", azureml.core.VERSION)<jupyter_output><empty_output><jupyter_text>Initialize WorkspaceInitialize a workspace object from persisted configuration.<jupyter_code>from azureml.core import Workspace

ws = Workspace.from_config()
print(ws.name, ws.resource_group, ws.location, ws.subscription_id, sep='\n')<jupyter_output><empty_output><jupyter_text>Register Model You can add tags and descriptions to your models. we are using `sklearn_regression_model.pkl` file in the current directory as a model with the name `sklearn_regression_model_local` in the workspace.Using tags, you can track useful information such as the name and version of the machine learning library used to train the model, framework, category, target customer etc. Note that tags must be alphanumeric.<jupyter_code>from azureml.core.model import Model

model = Model.register(model_path="sklearn_regression_model.pkl",
                       model_name="sklearn_regression_model_local",
                       tags={'area': "diabetes", 'type': "regression"},
                       description="Ridge regression model to predict diabetes",
                       workspace=ws)<jupyter_output><empty_output><jupyter_text>Create Environment<jupyter_code>from azureml.core.conda_dependencies import CondaDependencies
from azureml.core.environment import Environment

environment = Environment("LocalDeploy")
environment.python.conda_dependencies = CondaDependencies("myenv.yml")<jupyter_output><empty_output><jupyter_text>Create Inference Configuration<jupyter_code>from azureml.core.model import InferenceConfig

inference_config = InferenceConfig(entry_script="score.py",
                                   environment=environment)<jupyter_output><empty_output><jupyter_text>Model ProfilingProfile your model to understand how much CPU and memory the service, created as a result of its deployment, will need. Profiling returns information such as CPU usage, memory usage, and response latency. It also provides a CPU and memory recommendation based on the resource usage. You can profile your model (or more precisely the service built based on your model) on any CPU and/or memory combination where 0.1 <= CPU <= 3.5 and 0.1GB <= memory <= 15GB. If you do not provide a CPU and/or memory requirement, we will test it on the default configuration of 3.5 CPU and 15GB memory.In order to profile your model you will need:- a registered model- an entry script- an inference configuration- a single column tabular dataset, where each row contains a string representing sample request data sent to the service.At this point we only support profiling of services that expect their request data to be a string, for example: string serialized json, text, string serialized image, etc. The content of each row of the dataset (string) will be put into the body of the HTTP request and sent to the service encapsulating the model for scoring.Below is an example of how you can construct an input dataset to profile a service which expects its incoming requests to contain serialized json. In this case we created a dataset based one hundred instances of the same request data. In real world scenarios however, we suggest that you use larger datasets with various inputs, especially if your model resource usage/behavior is input dependent.<jupyter_code>import json
from azureml.core import Datastore
from azureml.core.dataset import Dataset
from azureml.data import dataset_type_definitions


# create a string that can be put in the body of the request
serialized_input_json = json.dumps({
    'data': [
        [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
        [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
    ]
})
dataset_content = []
for i in range(100):
    dataset_content.append(serialized_input_json)
dataset_content = '\n'.join(dataset_content)
file_name = 'sample_request_data_diabetes.txt'
f = open(file_name, 'w')
f.write(dataset_content)
f.close()

# upload the txt file created above to the Datastore and create a dataset from it
data_store = Datastore.get_default(ws)
data_store.upload_files(['./' + file_name], target_path='sample_request_data_diabetes')
datastore_path = [(data_store, 'sample_request_data_diabetes' +'/' + file_name)]
sample_request_data_diabetes = Dataset.Tabular.from_delimited_files(
    datastore_path,
    separator='\n',
    infer_column_types=True,
    header=dataset_type_definitions.PromoteHeadersBehavior.NO_HEADERS)
sample_request_data_diabetes = sample_request_data_diabetes.register(workspace=ws,
                                                   name='sample_request_data_diabetes',
                                                   create_new_version=True)<jupyter_output><empty_output><jupyter_text>Now that we have an input dataset we are ready to go ahead with profiling. In this case we are testing the previously introduced sklearn regression model on 1 CPU and 0.5 GB memory. The memory usage and recommendation presented in the result is measured in Gigabytes. The CPU usage and recommendation is measured in CPU cores.<jupyter_code>from datetime import datetime
from azureml.core import Environment
from azureml.core.conda_dependencies import CondaDependencies
from azureml.core.model import Model, InferenceConfig


environment = Environment('my-sklearn-environment')
environment.python.conda_dependencies = CondaDependencies.create(pip_packages=[
    'azureml-defaults',
    'inference-schema[numpy-support]',
    'joblib',
    'numpy',
    'scikit-learn'
])
inference_config = InferenceConfig(entry_script='score.py', environment=environment)
# if cpu and memory_in_gb parameters are not provided
# the model will be profiled on default configuration of
# 3.5CPU and 15GB memory
profile = Model.profile(ws,
            'profile-%s' % datetime.now().strftime('%m%d%Y-%H%M%S'),
            [model],
            inference_config,
            input_dataset=sample_request_data_diabetes,
            cpu=1.0,
            memory_in_gb=0.5)

profile.wait_for_completion(True)
details = profile.get_details()<jupyter_output><empty_output><jupyter_text>Deploy Model as a Local Docker Web Service*Make sure you have Docker installed and running.*Note that the service creation can take few minutes.NOTE:The Docker image runs as a Linux container. If you are running Docker for Windows, you need to ensure the Linux Engine is running:     PowerShell command to switch to Linux engine    & 'C:\Program Files\Docker\Docker\DockerCli.exe' -SwitchLinuxEngine<jupyter_code>from azureml.core.webservice import LocalWebservice

# This is optional, if not provided Docker will choose a random unused port.
deployment_config = LocalWebservice.deploy_configuration(port=6789)

local_service = Model.deploy(ws, "test", [model], inference_config, deployment_config)

local_service.wait_for_deployment()
print('Local service port: {}'.format(local_service.port))<jupyter_output><empty_output><jupyter_text>Check Status and Get Container Logs<jupyter_code>print(local_service.get_logs())<jupyter_output><empty_output><jupyter_text>Test Web Service Call the web service with some input data to get a prediction.<jupyter_code>import json

sample_input = json.dumps({
    'data': [
        [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
        [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
    ]
})

sample_input = bytes(sample_input, encoding='utf-8')

local_service.run(input_data=sample_input)<jupyter_output><empty_output><jupyter_text>Reload ServiceYou can update your score.py file and then call `reload()` to quickly restart the service. This will only reload your execution script and dependency files, it will not rebuild the underlying Docker image. As a result, `reload()` is fast, but if you do need to rebuild the image -- to add a new Conda or pip package, for instance -- you will have to call `update()`, instead (see below).<jupyter_code>%%writefile score.py
import os
import pickle
import json
import numpy as np
from sklearn.externals import joblib
from sklearn.linear_model import Ridge

from inference_schema.schema_decorators import input_schema, output_schema
from inference_schema.parameter_types.numpy_parameter_type import NumpyParameterType

def init():
    global model
    # AZUREML_MODEL_DIR is an environment variable created during deployment.
    # It is the path to the model folder (./azureml-models/$MODEL_NAME/$VERSION)
    # For multiple models, it points to the folder containing all deployed models (./azureml-models)
    model_path = os.path.join(os.getenv('AZUREML_MODEL_DIR'), 'sklearn_regression_model.pkl')
    # deserialize the model file back into a sklearn model
    model = joblib.load(model_path)

input_sample = np.array([[10,9,8,7,6,5,4,3,2,1]])
output_sample = np.array([3726.995])

@input_schema('data', NumpyParameterType(input_sample))
@output_schema(NumpyParameterType(output_sample))
def run(data):
    try:
        result = model.predict(data)
        # you can return any datatype as long as it is JSON-serializable
        return 'hello from updated score.py'
    except Exception as e:
        error = str(e)
        return error
local_service.reload()
print("--------------------------------------------------------------")

# After calling reload(), run() will return the updated message.
local_service.run(input_data=sample_input)<jupyter_output><empty_output><jupyter_text>Update ServiceIf you want to change your model(s), Conda dependencies, or deployment configuration, call `update()` to rebuild the Docker image.```pythonlocal_service.update(models=[SomeOtherModelObject],                     inference_config=inference_config,                     deployment_config=local_config)```  Delete Service<jupyter_code>local_service.delete()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.08387339156569926, 'fraction_numerical': 0.010425471963933503, 'mean_word_length': 4.57778941854374, 'pattern_counts': {'":': 0, '<': 53, '<?xml version=': 0, '>': 49, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 5, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '12', 'dir': 'jupyter-structured-clean-dedup', 'id': '55330', 'license': 'MIT', 'n_tokens_mistral': 3070, 'n_tokens_neox': 2902, 'n_words': 1041, 'path': 'how-to-use-azureml/deployment/deploy-to-local/register-model-deploy-local.ipynb', 'repo_name': 'rndazurescript/MachineLearningNotebooks', 'size': '10647'}