[PYTHON] [Azure] Deploy locally created ML model to the cloud

Introduction

"I made a model of ML and want to make it a web service ..." "If you do it, it's the cloud, but I don't know how to do it ..." It is a memo when I thought that I even deployed the model made in Azure.

As for Azure, I couldn't find any articles in Japanese compared to AWS, so I had a hard time.

If you want to do the same thing, please refer to it.

Premise

This time, we will deploy the cGAN created in the article "CGAN (conditional GAN) to generate MNIST (KMNIST)".

environment

Apparently Azure side does not support python3.7, so I recreated it with python3.6

cloudpickle is a module for pickling a model created with PyTorch. The usage is almost the same as a normal pickle.

Use the .pkl </ code> file created with the code near the end of the above as it is.

Things necessary

  • Azure subscription (free trial version is OK)
  • Appropriate source code editor

I want to try it out, so here I will use the python requests module on the jupyter notebook.

procedure

① Create a resource from Azure home

スライド1.JPG

Create a resource group by selecting "Resource Group"-> "Add" from the home screen of the Azure portal. You can use the original resource group for the following steps, so if you have an existing group, you do not have to create it.

Here, create it as "** FaaS-resource " as the resource group name. The region can be anything, but leave it as " East Japan **".

② Create a workspace for Azure Machine Learning

スライド2.JPG

We will use the features of Azure Machine Learning (AzureML), so we will create resources for AzureML. From the Azure portal home, type "Machine Learning" in "Create Resource" and it should come out. Create with "Create". スライド3.JPG Then, a screen like this will appear. Enter the workspace name (any name is fine), select the subscription, and select the resource group you created earlier. The workspace edition is OK with "** Basic **".

③ Register the model

After creating AzureML, go to Azure Machine Learning Studio from "Try Azure Machine Learning Studio" on the workspace screen. スライド4.JPG The screen should look like this. Click "Model" of "Asset" on the left side to register the locally created ML model. スライド5.JPG When you click "Register model", a screen for entering the model outline will appear, so enter the name and description (not required). This time we will use the model created with PyTorch, so select "** PyTorch ", enter the framework version as " 1.4.0 **", and enter the model .pkl </ code> file. Select.

When you register a model, the model you just registered will be displayed on the "Model List" page.

By the way

You can operate jupyter notebook from "Notebook" on the screen of Azure Machine Learning Studio. From model training to deployment, you can also operate on this jupyter notebook, [Tutorial of official Azure documentation](https://docs.microsoft.com/en-us/azure/machine-learning/tutorial -deploy-models-with-aml) has an example of the procedure.

④ Deploy the model

You can select the model registered in the "Model List" and deploy it from "Deploy". スライド6.JPG A screen like this will appear. Enter the name and description (not required), select "** ACI **" (= Azure Container Instance) as the computing type, and select the entry script file and Conda dependency file respectively. This will be discussed later.

Now select "Deploy" and the deployment will start. At this time, you can change the number of CPU cores and memory size of the virtual machine to be uploaded from the "Detailed conditions" below, but the default is also acceptable.

Entry script file

As explained in Official Azure documentation, web services deployed with ACI Now it takes the data sent by the client, passes it to the model, and returns the resulting result to the client. It is this file that defines this flow.

Create it with an appropriate source code editor.

score.py



# coding: utf-8
# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.3.2
#   kernelspec:
#     display_name: Python 3.6 - AzureML
#     language: python
#     name: python3-azureml
# ---

import torch
import torchvision
import torchvision.transforms as transforms
import numpy as np
import os
import torch.nn as nn
import torch.nn.functional as F
import cloudpickle
from azureml.core.model import Model
import json

def init():
    global model
    path = os.path.join(os.getenv('AZUREML_MODEL_DIR'), 'KMNIST_cGAN.pkl')
    with open(path, 'rb')as f:
        model = cloudpickle.load(f)
    
def run(raw_data):
    indexs = json.loads(raw_data)["indexs"]
    index_list = indexs.split(',')
    num_class = 49
    z_dim = 100

    for i, num in enumerate(index_list):
        #Noise generation
        noise = torch.normal(mean = 0.5, std = 1, size = (1, z_dim))
    
        #Generate a label to put in the Generator
        tmp = np.identity(num_class)[int(num)]
        tmp = np.array(tmp, dtype = np.float32)
        label = [tmp]
    
        #Sample generation with Generator
        sample = model(noise, torch.Tensor(label)).detach()

        #Format and list
        sample = sample.reshape((28,28))
        img = sample.detach().numpy().tolist()
        
        if i == 0:
            comp_img = img
        else:
            comp_img.extend(img)
    
    return comp_img

Two functions are defined.

  • The init () </ code> function is called only once when the service starts and loads the model.
  • The run (raw_data) </ code> function defines how to pass the received data to the model and return the result to the client.

When you register the model, the model is saved in the directory AZUREML_MODEL_DIR </ code>, so call it. Also, since the data sent from the client is in json format, we take it out, put the label in the model (Generator of cGAN), and return the result. At this time, the last return in the above code is python's list type data, but it seems that it is converted to json format before sending it to the client on the Azure side, so it ison the client side You need to do it with json.loads () `.

Conda dependency file

The name is the same, but it is a file that defines the necessary Conda packages. This is also created in .yml format with a source code editor.

myenv.yml


# Conda environment specification. The dependencies defined in this file will
# be automatically provisioned for runs with userManagedDependencies=False.

# Details about the Conda environment file format:
# https://conda.io/docs/user-guide/tasks/manage-environments.html#create-env-file-manually

name: project_environment
dependencies:
  # The python interpreter version.
  # Currently Azure ML only supports 3.5.2 and later.
- python=3.6.2

- pip:
  - azureml-defaults
  - azureml-sdk
  - azureml-contrib-services
- numpy
- pytorch
- torchvision
- cloudpickle
channels:
- conda-forge
- pytorch

I just changed the .yml from the official documentation. In this, ʻazureml-defaults` seems to be a necessary package to host a web service, so it is essential. It needs to be changed a little depending on the package used for the model.

⑤ Confirmation of deployment

It takes a long time to deploy. I think it depends on the environment, but it took me about 10 to 15 minutes. Check if the deployment is successful.

If you look in the resource group you are using from the home of the Azure portal in "Resource group", the created container instance will be displayed after a while from the start of deployment. Go to the page for that container instance. Azure.jpg This time, I deployed it with the name "** kmnist-cgan **" earlier, so the name of the container instance is that. When you open "Container" in "Settings", the above screen will appear, and if the "Status" (red frame) of the three containers changes from "Waiting" to "Running", the deployment is successful.

By the way, if an error occurs during the deployment process, the error content will be displayed in the "Log" section below. In particular, bugs inside score.py and errors during request processing are displayed in the log of the" kmnist-cgan "container this time, so looking here may be useful for troubleshooting.

⑥ Try using the deployed service

What I deployed here is "cGAN **" that when you enter a ** character, it returns a jumbled character for that character. Try this locally.

When the deployment is completed and the web service is ready for use, the IP address and FQDN will be displayed on the Azure container instance page, so use that.

import requests
import json
import matplotlib.pyplot as plt
%matplotlib inline

url = "http://[FQDN of the created container instance]/score"

strings = input()

#Generate the target number using the extracted model
def FaaS_KMNIST(url, strings):
    letter = 'Aiue Okakikuke Kosashi Suseso Tachi Nune no Hahifuhe Homami Mumemoya Yuyorari Rurerowa ゐ'
    indexs = ""
    input_data = {}
    for i in range(len(strings)):
        str_index = letter.index(strings[i])
        indexs += str(str_index)
        if i != len(strings)-1:
            indexs += ','
        
    print(indexs)
    input_data["indexs"] = str(indexs)
    input_data = json.dumps(input_data)
    headers = {"Content-Type":"application/json"}
    
    resp = requests.post(url, input_data, headers=headers)
    
    result = json.loads(resp.text)
    
    return result

response = FaaS_KMNIST(url, strings)

plt.imshow(response,cmap ="gray")

Write a code like this and try it. Since input is accepted by ʻinput ()`, when you type the characters appropriately, such an image will be displayed at the end. FaaS-test.png Isn't it "OK"?

Finally

I tried deploying the created ML model on Azure. I don't think the method itself is so difficult. At least I think it's easier than deploying in the jupyter notebook of Azure Machine Learning Studio, so please give it a try.