이 포스팅에서는 AzureML 모델을 웹 서비스로 배포하고 Evaluation을 진행한다.

 

(4) AzureML - Azure Machine Learning 모델 배포(Deploy)

 

지난 포스팅 (3) AzureML - Azure Machine Learning 구성요소 에서 AzureML SDK를 이용해 머신러닝 모델을 만들고 모델을 Register 하는 과정까지 진행했다. 지난 포스팅 내용을 완료해야 이번 모델 배포(Deploy)를 완료할 수 있으니, 이전 문서를 참조해 model register까지 완료한다.

마찬가지로, 이 포스팅 역시 Github 공식 AzureML 노트북 문서를 이용해 진행된다.

 

모델 배포를 위한 AzureML 패키지 설정

지난 작업과 같다. 필요한 패키지 설정을 수행.

%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
 
import azureml.core

# display the core SDK version number
print("Azure ML SDK Version: ", azureml.core.VERSION)

 

배포될 서비스에서 사용할 score.py 파일 설정

AzureML 배포 작업을 수행하면 docker 설정이 완료되며, container 환경에서 수행된다. Azure에서 제공하는 container 서비스는 ACI(Azure Container Instance)AKS(Azure Kubernetes Service)가 있으며, 양쪽 모두에 AzureML로 배포가 가능하다. 이 포스팅에서는 ACI로 배포를 수행하고, 이후 AKS 배포 역시 다른 포스트로 진행 예정.

 

이제 score.py 파일을 생성한다. Jupyter notebook에서 파일 쓰기 기능을 선언하고 작성한다.

%%writefile score.py
import json
import numpy as np
import os
import pickle
import joblib

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_mnist_model.pkl')
    model = joblib.load(model_path)

def run(raw_data):
    data = np.array(json.loads(raw_data)['data'])
    # make prediction
    y_hat = model.predict(data)
    # you can return any data type as long as it is JSON-serializable
    return y_hat.tolist()

 

배포 설정 파일 생성

ACI에 배포를 준비 중이다. 이 ACI에 배포하려면 "AciWebservice.deploy_configuration" 구성을 수행해야 한다.

아래 코드와 같이 1개 CPU를 사용하고, 1G의 메모리를 점유하는 ACI 컨테이너를 생성하고 배포한다.

from azureml.core.webservice import AciWebservice

aciconfig = AciWebservice.deploy_configuration(cpu_cores=1, 
                                               memory_gb=1, 
                                               tags={"data": "MNIST",  "method" : "sklearn"}, 
                                               description='Predict MNIST with sklearn')

 

ACI로 배포 수행

이제, 모든 ACI 배포 설정이 완료되었다. 모델 배포를 수행하자.

 

지난 포스팅에서 트레이닝을 수행해 생성한 모델인 "sklearn_mnist" 모델을 참조한다.

...
model = Model(ws, 'sklearn_mnist')
...

 

생성한 Environment를 가져온다.

...
myenv = Environment.get(workspace=ws, name="tutorial-env", version="1")
...

 

Inference config를 설정하고, deploy를 수행한다.

...
inference_config = InferenceConfig(entry_script="score.py", environment=myenv)

service_name = 'sklearn-mnist-svc-' + str(uuid.uuid4())[:4]
service = Model.deploy(workspace=ws, 
                       name=service_name, 
                       models=[model], 
                       inference_config=inference_config, 
                       deployment_config=aciconfig)
...

"service" Object가 이후 prediction에 사용된다. 자세히 살펴보자. 

모델 배포에 사용할 설정을 완료했다. 실제 코드를 실행해 배포를 진행한다.

 

모델을 ACI로 배포하는 코드를 수행

%%time
import uuid
from azureml.core.webservice import Webservice
from azureml.core.model import InferenceConfig
from azureml.core.environment import Environment
from azureml.core import Workspace
from azureml.core.model import Model

ws = Workspace.from_config()
model = Model(ws, 'sklearn_mnist')


myenv = Environment.get(workspace=ws, name="tutorial-env", version="1")
inference_config = InferenceConfig(entry_script="score.py", environment=myenv)

service_name = 'sklearn-mnist-svc-' + str(uuid.uuid4())[:4]
service = Model.deploy(workspace=ws, 
                       name=service_name, 
                       models=[model], 
                       inference_config=inference_config, 
                       deployment_config=aciconfig)

service.wait_for_deployment(show_output=True)

배포에 약간의 시간이 소요된다.

Scoring URL 출력

배포가 완료되면, 아래 명령으로 scoring을 수행할 URL을 출력할 수 있다.

print(service.scoring_uri)

이제 웹 서비스로 배포된 모델에서 Test를 수행한다.

 

 

배포가 완료된 웹 서비스에서 모델 테스트 수행

Python 코드를 이용해 생성된 모델로 test나 evaluation이 가능하다. 물론 이 노트북처럼 웹 서비스에 Restful API 방식으로 batch 요청을 보내 처리도 가능하다.

 

테스트 수행을 위해 test 데이터를 다운로드

import os
from azureml.core import Dataset
from azureml.opendatasets import MNIST

data_folder = os.path.join(os.getcwd(), 'data')
os.makedirs(data_folder, exist_ok=True)

mnist_file_dataset = MNIST.get_file_dataset()
mnist_file_dataset.download(data_folder, overwrite=True)

 

테스트 데이터를 로드

from utils import load_data
import os
import glob

data_folder = os.path.join(os.getcwd(), 'data')
# note we also shrink the intensity values (X) from 0-255 to 0-1. This helps the neural network converge faster
X_test = load_data(glob.glob(os.path.join(data_folder,"**/t10k-images-idx3-ubyte.gz"), recursive=True)[0], False) / 255.0
y_test = load_data(glob.glob(os.path.join(data_folder,"**/t10k-labels-idx1-ubyte.gz"), recursive=True)[0], True).reshape(-1)

 

Predict 수행

service.run()이 prediction을 수행하는 코드이다. 이렇게 AzureML SDK가 제공하는 기능을 사용해 손쉽게 prediction이 가능하다.

import json
test = json.dumps({"data": X_test.tolist()})
test = bytes(test, encoding='utf8')
y_hat = service.run(input_data=test)

 

Confusion matrix 조회 / plotting 수행

실제 label 데이터와 예측한 y_hat 데이터가 있어서 confusion matrix 생성이 가능하다.

from sklearn.metrics import confusion_matrix

conf_mx = confusion_matrix(y_test, y_hat)
print(conf_mx)
print('Overall accuracy:', np.average(y_hat == y_test))


# normalize the diagonal cells so that they don't overpower the rest of the cells when visualized
row_sums = conf_mx.sum(axis=1, keepdims=True)
norm_conf_mx = conf_mx / row_sums
np.fill_diagonal(norm_conf_mx, 0)

fig = plt.figure(figsize=(8,5))
ax = fig.add_subplot(111)
cax = ax.matshow(norm_conf_mx, cmap=plt.cm.bone)
ticks = np.arange(0, 10, 1)
ax.set_xticks(ticks)
ax.set_yticks(ticks)
ax.set_xticklabels(ticks)
ax.set_yticklabels(ticks)
fig.colorbar(cax)
plt.ylabel('true labels', fontsize=14)
plt.xlabel('predicted values', fontsize=14)
plt.savefig('conf.png')
plt.show()

 

confusion-matrix.png

heatmap의 가독성이 약간 기대와 틀린 듯 한데... 여하간 출력하였다.

 

 

Prediction 결과 출력

30건 정도의 랜덤 샘플로 prediction을 수행하고, 결과를 plot으로 표시.

import json

# find 30 random samples from test set
n = 30
sample_indices = np.random.permutation(X_test.shape[0])[0:n]

test_samples = json.dumps({"data": X_test[sample_indices].tolist()})
test_samples = bytes(test_samples, encoding='utf8')

# predict using the deployed model
result = service.run(input_data=test_samples)

# compare actual value vs. the predicted values:
i = 0
plt.figure(figsize = (20, 1))

for s in sample_indices:
    plt.subplot(1, n, i + 1)
    plt.axhline('')
    plt.axvline('')
    
    # use different color for misclassified sample
    font_color = 'red' if y_test[s] != result[i] else 'black'
    clr_map = plt.cm.gray if y_test[s] != result[i] else plt.cm.Greys
    
    plt.text(x=10, y =-10, s=result[i], fontsize=18, color=font_color)
    plt.imshow(X_test[s].reshape(28, 28), cmap=clr_map)
    
    i = i + 1
plt.show()

 

위의 prediction들은 모두 service.run() 으로 prediction을 수행했다. 물론, Restful API이기 때문에 Python Requests 패키지를 이용해 HTTP POST 방식으로 요청도 가능하다.

import requests

# send a random row from the test set to score
random_index = np.random.randint(0, len(X_test)-1)
input_data = "{\"data\": [" + str(list(X_test[random_index])) + "]}"

headers = {'Content-Type':'application/json'}

# for AKS deployment you'd need to the service key in the header as well
# api_key = service.get_key()
# headers = {'Content-Type':'application/json',  'Authorization':('Bearer '+ api_key)} 

resp = requests.post(service.scoring_uri, input_data, headers=headers)

print("POST to url", service.scoring_uri)
#print("input data:", input_data)
print("label:", y_test[random_index])
print("prediction:", resp.text)

 

배포 삭제

이렇게 ACI로 모델을 배포하고 prediction도 잘 수행했다. 여러 테스트가 완료되면 ACI를 삭제한다.

service.delete()

 

 

AzureML을 이용해 생성한 모델을 배포하는 과정을 수행하였다. 일반적으로 ACI는 테스트 형태로 validation 목적으로 배포해 사용하고, 실제 production 수준의 scale이나 GPU inference가 필요할 경우 AKS에 배포를 수행한다.

 

실제 어느정도 개발팀과 DS(Data Scientist) 팀에 규모가 있을 경우, 모든 배포 과정은 이렇게 코드를 통해 배포하지 않고, DevOps를 이용해 자동화해서 모델을 배포하게 된다. 이러한 머신러닝 모델 라이프사이클 관리가 MLOps이다. 

 

다음 포스팅에서는 여러 AzureML의 구성요소에 대해 좀더 깊이 있게 다루는 과정을 진행할 예정이다.

 

참고자료

개발자 커뮤니티 SQLER.com - MLaaS - (1) 12가지의 머신러닝을 먼저 도입한 기업들의 고민

개발자 커뮤니티 SQLER.com - (2) AzureML - Azure Machine Learning 이란 무엇인가?

개발자 커뮤니티 SQLER.com - (3) AzureML - Azure Machine Learning 구성요소

MachineLearningNotebooks/img-classification-part2-deploy.ipynb at master · Azure/MachineLearningNotebooks (github.com)

 

No. Subject Author Date Views
Notice SQL강좌: 챗GPT와 함께 배우는 SQL Server 무료 강좌 목차와 소개 (2023년 9월 업데이트) 코난(김대우) 2023.08.18 36254
Notice Python 무료 강좌 - 기초, 중급, 머신러닝(2023년 6월 업데이트) 코난(김대우) 2021.01.01 18854
54 AI, 머신러닝, MLOps – Azure에서 톺아보기! | Developer Digital Meetup Tour 코난(김대우) 2022.11.15 132
53 자동화된 ML, 나도 해보자! | ep4-1. 자동화된ML 결과 해석하기 | 애저 듣고보는 잡학지식 코난(김대우) 2022.11.11 74
52 자동화된 ML, 나도 해보자! | ep3-2. GUI로 자동화된ML 직접 해보기 | 애저 듣고보는 잡학지식 코난(김대우) 2022.11.09 100
51 자동화된 ML, 나도 해보자! | ep3-1. GUI로 자동화된ML 직접 해보기 | 애저 듣고보는 잡학지식 코난(김대우) 2022.11.05 96
50 자동화된 ML, 나도 해보자! | ep2. 애저ML 처음 시작하기 | 애저 듣고보는 잡학지식 코난(김대우) 2022.11.02 83
49 자동화된 ML, 나도 해보자! | ep1. 자동화된 ML이 왜 필요한가 | 애저 듣고보는 잡학지식 코난(김대우) 2022.11.01 83
48 자동화된 ML, 나도 해보자! | ep0. 인트로 | 애저 듣고보는 잡학지식 코난(김대우) 2022.10.31 95
47 마이크로소프트 신텍스(Syntex) file 코난(김대우) 2022.10.27 90
46 텍스트로 3D 오브젝트를 생성 - 구글의 DreamFusion file 코난(김대우) 2022.10.21 441
45 콘텐츠가 데이터 분석을 만났을 때 - #hashTECH Start-Up 코난(김대우) 2022.10.18 81
44 DALL-E 2 - Azure OpenAI 서비스 file 코난(김대우) 2022.10.18 179
43 Ignite 2022의 Codex 데모 - 2022년 10월 버전 file 코난(김대우) 2022.10.16 96
42 kakaobrain pororo - Natural Language Inference 리뷰 코난(김대우) 2021.10.29 844
» (4) AzureML - Azure Machine Learning 모델 배포(Deploy) [1] file 코난(김대우) 2021.10.27 520
40 (3) AzureML - Azure Machine Learning 구성요소 file 코난(김대우) 2021.10.27 316
39 (2) AzureML - Azure Machine Learning 이란 무엇인가? file 코난(김대우) 2021.10.25 421
38 kakaobrain pororo - Automated Essay Scorer 리뷰 코난(김대우) 2021.10.21 390
37 kakobrain에서 발표한 pororo 리뷰 file 코난(김대우) 2021.10.20 1329
36 Azure Databricks MLflow를 이용한 MLOps - CI/CD 및 deployment 포함 file 코난(김대우) 2021.10.15 304
35 Azure Databricks MLflow를 이용한 MLOps file 코난(김대우) 2021.10.14 325





XE Login