mirror of
https://github.com/Azure/MachineLearningNotebooks.git
synced 2025-12-19 17:17:04 -05:00
425 lines
13 KiB
Plaintext
425 lines
13 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Copyright (c) Microsoft Corporation. All rights reserved.\n",
|
|
"\n",
|
|
"Licensed under the MIT License."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## 10. Register Model, Create Image and Deploy Service\n",
|
|
"\n",
|
|
"This example shows how to deploy a web service in step-by-step fashion:\n",
|
|
"\n",
|
|
" 1. Register model\n",
|
|
" 2. Query versions of models and select one to deploy\n",
|
|
" 3. Create Docker image\n",
|
|
" 4. Query versions of images\n",
|
|
" 5. Deploy the image as web service\n",
|
|
" \n",
|
|
"**IMPORTANT**:\n",
|
|
" * This notebook requires you to first complete \"01.SDK-101-Train-and-Deploy-to-ACI.ipynb\" Notebook\n",
|
|
" \n",
|
|
"The 101 Notebook taught you how to deploy a web service directly from model in one step. This Notebook shows a more advanced approach that gives you more control over model versions and Docker image versions. "
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Prerequisites\n",
|
|
"Make sure you go through the [00. Installation and Configuration](00.configuration.ipynb) Notebook first if you haven't."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Check core SDK version number\n",
|
|
"import azureml.core\n",
|
|
"\n",
|
|
"print(\"SDK version:\", azureml.core.VERSION)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Initialize Workspace\n",
|
|
"\n",
|
|
"Initialize a workspace object from persisted configuration."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"tags": [
|
|
"create workspace"
|
|
]
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"from azureml.core import Workspace\n",
|
|
"\n",
|
|
"ws = Workspace.from_config()\n",
|
|
"print(ws.name, ws.resource_group, ws.location, ws.subscription_id, sep = '\\n')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Register Model"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"You can add tags and descriptions to your models. Note you need to have a `sklearn_linreg_model.pkl` file in the current directory. This file is generated by the 01 notebook. The below call registers that file as a model with the same name `sklearn_linreg_model.pkl` in the workspace.\n",
|
|
"\n",
|
|
"Using tags, you can track useful information such as the name and version of the machine learning library used to train the model. Note that tags must be alphanumeric."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"tags": [
|
|
"register model from file"
|
|
]
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"from azureml.core.model import Model\n",
|
|
"import sklearn\n",
|
|
"\n",
|
|
"library_version = \"sklearn\"+sklearn.__version__.replace(\".\",\"x\")\n",
|
|
"\n",
|
|
"model = Model.register(model_path = \"sklearn_regression_model.pkl\",\n",
|
|
" model_name = \"sklearn_regression_model.pkl\",\n",
|
|
" tags = {'area': \"diabetes\", 'type': \"regression\", 'version': library_version},\n",
|
|
" description = \"Ridge regression model to predict diabetes\",\n",
|
|
" workspace = ws)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"You can explore the registered models within your workspace and query by tag. Models are versioned. If you call the register_model command many times with same model name, you will get multiple versions of the model with increasing version numbers."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"tags": [
|
|
"register model from file"
|
|
]
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"regression_models = Model.list(workspace=ws, tags=['area'])\n",
|
|
"for m in regression_models:\n",
|
|
" print(\"Name:\", m.name,\"\\tVersion:\", m.version, \"\\tDescription:\", m.description, m.tags)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"You can pick a specific model to deploy"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"print(model.name, model.description, model.version, sep = '\\t')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Create Docker Image"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Show `score.py`. Note that the `sklearn_regression_model.pkl` in the `get_model_path` call is referring to a model named `sklearn_linreg_model.pkl` registered under the workspace. It is NOT referenceing the local file."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"%%writefile score.py\n",
|
|
"import pickle\n",
|
|
"import json\n",
|
|
"import numpy\n",
|
|
"from sklearn.externals import joblib\n",
|
|
"from sklearn.linear_model import Ridge\n",
|
|
"from azureml.core.model import Model\n",
|
|
"\n",
|
|
"def init():\n",
|
|
" global model\n",
|
|
" # note here \"sklearn_regression_model.pkl\" is the name of the model registered under\n",
|
|
" # this is a different behavior than before when the code is run locally, even though the code is the same.\n",
|
|
" model_path = Model.get_model_path('sklearn_regression_model.pkl')\n",
|
|
" # deserialize the model file back into a sklearn model\n",
|
|
" model = joblib.load(model_path)\n",
|
|
"\n",
|
|
"# note you can pass in multiple rows for scoring\n",
|
|
"def run(raw_data):\n",
|
|
" try:\n",
|
|
" data = json.loads(raw_data)['data']\n",
|
|
" data = numpy.array(data)\n",
|
|
" result = model.predict(data)\n",
|
|
" except Exception as e:\n",
|
|
" result = str(e)\n",
|
|
" return json.dumps({\"result\": result.tolist()})"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"from azureml.core.conda_dependencies import CondaDependencies \n",
|
|
"\n",
|
|
"myenv = CondaDependencies.create(conda_packages=['numpy','scikit-learn'])\n",
|
|
"\n",
|
|
"with open(\"myenv.yml\",\"w\") as f:\n",
|
|
" f.write(myenv.serialize_to_string())"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Note that following command can take few minutes. \n",
|
|
"\n",
|
|
"You can add tags and descriptions to images. Also, an image can contain multiple models."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"tags": [
|
|
"create image"
|
|
]
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"from azureml.core.image import Image, ContainerImage\n",
|
|
"\n",
|
|
"image_config = ContainerImage.image_configuration(runtime= \"python\",\n",
|
|
" execution_script=\"score.py\",\n",
|
|
" conda_file=\"myenv.yml\",\n",
|
|
" tags = {'area': \"diabetes\", 'type': \"regression\"},\n",
|
|
" description = \"Image with ridge regression model\")\n",
|
|
"\n",
|
|
"image = Image.create(name = \"myimage1\",\n",
|
|
" # this is the model object \n",
|
|
" models = [model],\n",
|
|
" image_config = image_config, \n",
|
|
" workspace = ws)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"tags": [
|
|
"create image"
|
|
]
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"image.wait_for_creation(show_output = True)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"List images by tag and find out the detailed build log for debugging."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"tags": [
|
|
"create image"
|
|
]
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"for i in Image.list(workspace = ws,tags = [\"area\"]):\n",
|
|
" print('{}(v.{} [{}]) stored at {} with build log {}'.format(i.name, i.version, i.creation_state, i.image_location, i.image_build_log_uri))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Deploy image as web service on Azure Container Instance\n",
|
|
"\n",
|
|
"Note that the service creation can take few minutes."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"tags": [
|
|
"deploy service",
|
|
"aci"
|
|
]
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"from azureml.core.webservice import AciWebservice\n",
|
|
"\n",
|
|
"aciconfig = AciWebservice.deploy_configuration(cpu_cores = 1, \n",
|
|
" memory_gb = 1, \n",
|
|
" tags = {'area': \"diabetes\", 'type': \"regression\"}, \n",
|
|
" description = 'Predict diabetes using regression model')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"tags": [
|
|
"deploy service",
|
|
"aci"
|
|
]
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"from azureml.core.webservice import Webservice\n",
|
|
"\n",
|
|
"aci_service_name = 'my-aci-service-2'\n",
|
|
"print(aci_service_name)\n",
|
|
"aci_service = Webservice.deploy_from_image(deployment_config = aciconfig,\n",
|
|
" image = image,\n",
|
|
" name = aci_service_name,\n",
|
|
" workspace = ws)\n",
|
|
"aci_service.wait_for_deployment(True)\n",
|
|
"print(aci_service.state)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Test web service"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Call the web service with some dummy input data to get a prediction."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"tags": [
|
|
"deploy service",
|
|
"aci"
|
|
]
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"import json\n",
|
|
"\n",
|
|
"test_sample = json.dumps({'data': [\n",
|
|
" [1,2,3,4,5,6,7,8,9,10], \n",
|
|
" [10,9,8,7,6,5,4,3,2,1]\n",
|
|
"]})\n",
|
|
"test_sample = bytes(test_sample,encoding = 'utf8')\n",
|
|
"\n",
|
|
"prediction = aci_service.run(input_data = test_sample)\n",
|
|
"print(prediction)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Delete ACI to clean up"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"tags": [
|
|
"deploy service",
|
|
"aci"
|
|
]
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"aci_service.delete()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
}
|
|
],
|
|
"metadata": {
|
|
"authors": [
|
|
{
|
|
"name": "raymondl"
|
|
}
|
|
],
|
|
"kernelspec": {
|
|
"display_name": "Python 3.6",
|
|
"language": "python",
|
|
"name": "python36"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": {
|
|
"name": "ipython",
|
|
"version": 3
|
|
},
|
|
"file_extension": ".py",
|
|
"mimetype": "text/x-python",
|
|
"name": "python",
|
|
"nbconvert_exporter": "python",
|
|
"pygments_lexer": "ipython3",
|
|
"version": "3.6.5"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 2
|
|
} |