이 포스팅에서는 AzureML로 MNIST 예제를 수행하고, 여러 구성요소를 살펴본다.
(3) AzureML - Azure Machine Learning 구성요소
지난 포스팅에서 AzureML에 대해 간단한 튜토리얼 코드로 살펴보았다.
개발자 커뮤니티 SQLER.com - AzureML - Azure Machine Learning 이란 무엇인가?
여러 새로운 AzureML의 구성요소가 있었고, 이 문서에서는 코드 예제를 통해 구성요소들의 역할에 대해 살펴본다.
이 문서에서 사용하는 코드는 이 링크의 notebook을 사용한다.
Python 분석 패키지 설정
notebook에서 사용할 코드를 import한다. 패키지 등이 설정되지 않았다면, 지난 문서의 기본 패키지 설치를 참조한다.
%matplotlib inline import numpy as np import matplotlib.pyplot as plt import azureml.core from azureml.core import Workspace # check core SDK version number print("Azure ML SDK Version: ", azureml.core.VERSION)
Workspace 연결
AzureML에서 Workspace는 무엇인가?
A Workspace is a fundamental resource for machine learning in Azure Machine Learning. You use a workspace to experiment, train, and deploy machine learning models. Each workspace is tied to an Azure subscription and resource group, and has an associated SKU.
azureml.core.workspace.Workspace class - Azure Machine Learning Python | Microsoft Docs
AzureML의 Workspace는 머신러닝 작업의 기초가 되는 리소스이고, Experiment(실험), 모델 트레이닝 및 배포에 사용된다. 개별 workspace는 Azure 구독(Subscription)과 resource group에 소속되며 SKU가 적용되어 있다.
지난 문서에서 이미 write_config()를 수행한 상태로 가정한다. azureml config 파일은 이미 "~/.azureml/config.json" 파일로 생성되었을 것이다. 아래 코드를 수행해 workspace에 연결한다.
# load workspace configuration from the config.json file in the current folder. ws = Workspace.from_config() print(ws.name, ws.location, ws.resource_group, sep='\t')
만약 경로를 찾을 수 없다고 나오면, "write_config()" 했던 디렉토리를 체크해, 해당 경로를 from_config()에 넣어준다.
Experiment(실험, 이하 Experiment) 생성
AzureML의 Experiment는 무엇인가?
Represents the main entry point for creating and working with experiments in Azure Machine Learning. An Experiment is a container of trials that represent multiple model runs.
azureml.core.experiment.Experiment class - Azure Machine Learning Python | Microsoft Docs
AzureML의 여러 머신러닝 작업을 생성하고 수행하기 위한 진입점이고, 여러 모델 트레이닝 작업을 실행하는 컨테이너(집합이라는 표현이 정확할 듯)이다.
레고블록으로 말하자면, 가장 큰 밑판이라고 생각하면 편하다. 이 Experiment위에 Compute, Dataset, Environment, Deploy 같은 여러 AzureML 구성요소가 올라가고 실행할 때마다 Run 구성요소에 의해 개별 실행들이 관리된다.
experiment_name = 'Tutorial-sklearn-mnist' from azureml.core import Experiment exp = Experiment(workspace=ws, name=experiment_name)
Tutorial-sklearn-mnist 이름으로 이렇게 workspace에 experiment를 생성한다.
Compute 리소스 추가
AzureML의 Compute란 무엇인가?
An Azure Machine Learning Compute (AmlCompute) is a managed-compute infrastructure that allows you to easily create a single or multi-node compute. The compute is created within your workspace region as a resource that can be shared with other users.
azureml.core.compute.AmlCompute class - Azure Machine Learning Python | Microsoft Docs
AzureML Compute(AmlCompute)는 관리되는 Compute infrastructure로, 하나 또는 여러 노드의 컴퓨팅 자원을 손쉽게 생성할 수 있다. Compute는 workspace를 생성한 지역에 만들어지고, 다른 사용자들과 공유할 수 있다.
Compute는 머신러닝 과정 등에서 사용가능한 리소스 풀이다. 원하는 수만큼 CPU나 GPU 리소스를 생성하고, 머신러닝 과정 등에서 사용할 수 있다. Databricks와 같은 Spark과 달리 사용 가능한 Compute size가 다양하고, 여러 GPU compute도 손쉽게 선언 가능하며, docker 환경과 conda 환경을 분리 가능해 좀 더 customize된 머신러닝 작업이 가능하다.
아래 코드는 "STANDARD_D2_V2" 사이즈의 VM을 최소 0개, 최대 4개 사용하는 Compute node를 선언한다.
참고로, 이 코드를 수행하면 Compute resource가 배포되어 돈이 나가는 것이 아니다. Compute node 구조를 "선언만" 하는 것이고, 실제 사용은 Experiment에 대해 "Run"을 수행하면서 compute 리소스가 provision되고 과금이 시작된다.
from azureml.core.compute import AmlCompute from azureml.core.compute import ComputeTarget import os # choose a name for your cluster compute_name = os.environ.get("AML_COMPUTE_CLUSTER_NAME", "cpu-cluster") compute_min_nodes = os.environ.get("AML_COMPUTE_CLUSTER_MIN_NODES", 0) compute_max_nodes = os.environ.get("AML_COMPUTE_CLUSTER_MAX_NODES", 4) # This example uses CPU VM. For using GPU VM, set SKU to STANDARD_NC6 vm_size = os.environ.get("AML_COMPUTE_CLUSTER_SKU", "STANDARD_D2_V2") if compute_name in ws.compute_targets: compute_target = ws.compute_targets[compute_name] if compute_target and type(compute_target) is AmlCompute: print("found compute target: " + compute_name) else: print("creating new compute target...") provisioning_config = AmlCompute.provisioning_configuration(vm_size = vm_size, min_nodes = compute_min_nodes, max_nodes = compute_max_nodes) # create the cluster compute_target = ComputeTarget.create(ws, compute_name, provisioning_config) # can poll for a minimum number of nodes and for a specific timeout. # if no min node count is provided it will use the scale settings for the cluster compute_target.wait_for_completion(show_output=True, min_node_count=None, timeout_in_minutes=20) # For a more detailed view of current AmlCompute status, use get_status() print(compute_target.get_status().serialize())
시간이 약간 소요될 수 있다.
AzureML의 "Dataset" 준비
Dataset은 우리가 일반적으로 사용하는 용어이지만, AzureML의 dataset(s)은 중요한 구성요소이다.
AzureML의 Dataset은 무엇인가?
Represents a resource for exploring, transforming, and managing data in Azure Machine Learning.
- azureml.core.dataset.Dataset class - Azure Machine Learning Python | Microsoft Docs
- Create Azure Machine Learning datasets - Azure Machine Learning | Microsoft Docs
먼저, 우리가 AzureML SDK를 이용하는 개발 머신(노트북으로 작업 중이다)과 실제 Machine Learning training을 수행할 머신은 다르다. 즉, 우리가 개발머신에서 아무리 데이터를 모아서 트레이닝을 해도, AzureML Compute로 생성된 노드에서는 이를 알 수 없다. 이렇게, 데이터셋을 생성될 Compute node에서도 작업할 수 있도록 "Dataset"을 연결하기 위한 Object가 필요하고, 그것이 AzureML의 Dataset이다.
AzureML Dataset은 "FileDataset"과 "TabularDataset"을 제공한다.
- FileDataset은 여러 파일들의 집합을 선언하고, Compute 노드가 provision되면 FileDataset을 "download"나 "mount" 하여 사용한다.
- TabularDataset은 파일들의 집합을 tabular format으로 지정해 사용하여, CSV나 parquet, jsonl 등의 포맷으로 생성 가능하다.
이 코드에서는 FileDataset을 이용해 machine learning에 사용할 데이터셋을 구성한다. 마지막의 "mnist_file_dataset.register"를 수행하면, 독립적인 Dataset이 등록되고, 여러 Experiment에서 공유 가능하며, versioning 기능도 제공해 version 관리가 가능하다. 이후 Dataset 포스트에서 상세히 진행 예정.
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) mnist_file_dataset = mnist_file_dataset.register(workspace=ws, name='mnist_opendataset', description='training and test dataset', create_new_version=True)
MNIST 샘플 데이터 조회
샘플 이미지를 plotting 해본다.
# make sure utils.py is in the same directory as this code from utils import load_data import glob # note we also shrink the intensity values (X) from 0-255 to 0-1. This helps the model converge faster. X_train = load_data(glob.glob(os.path.join(data_folder,"**/train-images-idx3-ubyte.gz"), recursive=True)[0], False) / 255.0 X_test = load_data(glob.glob(os.path.join(data_folder,"**/t10k-images-idx3-ubyte.gz"), recursive=True)[0], False) / 255.0 y_train = load_data(glob.glob(os.path.join(data_folder,"**/train-labels-idx1-ubyte.gz"), recursive=True)[0], True).reshape(-1) y_test = load_data(glob.glob(os.path.join(data_folder,"**/t10k-labels-idx1-ubyte.gz"), recursive=True)[0], True).reshape(-1) # now let's show some randomly chosen images from the traininng set. count = 0 sample_size = 30 plt.figure(figsize = (16, 6)) for i in np.random.permutation(X_train.shape[0])[:sample_size]: count = count + 1 plt.subplot(1, sample_size, count) plt.axhline('') plt.axvline('') plt.text(x=10, y=-10, s=y_train[i], fontsize=18) plt.imshow(X_train[i].reshape(28, 28), cmap=plt.cm.Greys) plt.show()
AzureML 머신러닝 트레이닝에 사용할 스크립트와 디렉토리 설정
우리가 개발중인 머신과 실제 머신러닝이 수행될 Compute 노드는 다른 머신이다. 트레이닝에 사용할 여러 머신러닝 Python training 코드 파일들 역시 마찬가지로, 설정을 통해 특정한 디렉토리에 구성하고, 이 디렉토리를 Compute 노드가 provision될때 복사해야 머신러닝을 수행해야 한다.
머신러닝 트레이닝에 사용할 디렉토리 생성
이 디렉토리에 필요한 training 파일들을 구성하고, 추후 Run 할 때 사용하게 된다.
import os script_folder = os.path.join(os.getcwd(), "sklearn-mnist") os.makedirs(script_folder, exist_ok=True)
머신러닝 트레이닝 스크립트 생성
Jupyter notebook의 %%writefile 셀 선언을 통해 셀의 내용을 파일로 write한다. 간단히, LogisticRegression을 수행하는 sklearn 코드이다.
%%writefile $script_folder/train.py import argparse import os import numpy as np import glob from sklearn.linear_model import LogisticRegression import joblib from azureml.core import Run from utils import load_data # let user feed in 2 parameters, the dataset to mount or download, and the regularization rate of the logistic regression model parser = argparse.ArgumentParser() parser.add_argument('--data-folder', type=str, dest='data_folder', help='data folder mounting point') parser.add_argument('--regularization', type=float, dest='reg', default=0.01, help='regularization rate') args = parser.parse_args() data_folder = args.data_folder print('Data folder:', data_folder) # load train and test set into numpy arrays # note we scale the pixel intensity values to 0-1 (by dividing it with 255.0) so the model can converge faster. X_train = load_data(glob.glob(os.path.join(data_folder, '**/train-images-idx3-ubyte.gz'), recursive=True)[0], False) / 255.0 X_test = load_data(glob.glob(os.path.join(data_folder, '**/t10k-images-idx3-ubyte.gz'), recursive=True)[0], False) / 255.0 y_train = load_data(glob.glob(os.path.join(data_folder, '**/train-labels-idx1-ubyte.gz'), recursive=True)[0], True).reshape(-1) y_test = load_data(glob.glob(os.path.join(data_folder, '**/t10k-labels-idx1-ubyte.gz'), recursive=True)[0], True).reshape(-1) print(X_train.shape, y_train.shape, X_test.shape, y_test.shape, sep = '\n') # get hold of the current run run = Run.get_context() print('Train a logistic regression model with regularization rate of', args.reg) clf = LogisticRegression(C=1.0/args.reg, solver="liblinear", multi_class="auto", random_state=42) clf.fit(X_train, y_train) print('Predict the test set') y_hat = clf.predict(X_test) # calculate accuracy on the prediction acc = np.average(y_hat == y_test) print('Accuracy is', acc) run.log('regularization rate', np.float(args.reg)) run.log('accuracy', np.float(acc)) os.makedirs('outputs', exist_ok=True) # note file saved in the outputs folder is automatically uploaded into experiment record joblib.dump(value=clf, filename='outputs/sklearn_mnist_model.pkl')
트레이닝에 사용할 추가 utils.py 파일 복사
마찬가지로, MNIST 분석에서 사용하는 공용 함수들이 포함된 utils.py 파일도 복사해 준비해 둔다.
import shutil shutil.copy('utils.py', script_folder)
AzureML environment 설정
Environment는 무엇인가?
Azure Machine Learning environments are an encapsulation of the environment where your machine learning training happens. They specify the Python packages, environment variables, and software settings around your training and scoring scripts. They also specify run times (Python, Spark, or Docker).
About Azure Machine Learning environments - Azure Machine Learning | Microsoft Docs
Compute 노드를 생성했다면, 그 위에서 수행될 docker와 python training을 위한 conda와 pip 패키지 환경 구성이 필요하다. 이 설정이 Environment이다.
Environment는 curated와 custom으로 크게 나뉜다.
- Curated environment: 이미 구성 완료된 environment로 sklearn이나, tensorflow, PyTorch를 수행 가능하게 구성되어 있다.
Curated environments - Azure Machine Learning | Microsoft Docs
- Custom docker: 이름 그대로, 모든 필요한 환경 설정이 완료된 docker image를 만들어, Azure의 private container registry인 ACR에 올려 두고, AzureML의 머신러닝 트레이닝 작업에 사용할 수 있다.
Train a model by using a custom Docker image - Azure Machine Learning | Microsoft Docs
여러 기업 AzureML 프로젝트를 수행하였다. 대부분의 경우 요구하는 트레이닝 환경이나 복잡한 요구사항을 맞추기 위해 curated environment를 사용하기 보다는 custom docker를 더 자주 사용하였다. custom docker 구성도 이후 포스팅에서 다룰 예정이다.
코드에서는 sklearn 과정을 수행할 environment를 설정한다. "tutorial-env"라는 이름으로 생성하고, sklearn등의 패키지를 구성한다.
from azureml.core.environment import Environment from azureml.core.conda_dependencies import CondaDependencies # to install required packages env = Environment('tutorial-env') cd = CondaDependencies.create(pip_packages=['azureml-dataset-runtime[pandas,fuse]', 'azureml-defaults'], conda_packages = ['scikit-learn==0.22.1']) env.python.conda_dependencies = cd # Register environment to re-use later env.register(workspace = ws)
Run에서 사용할 config - "ScriptRunConfig" 설정
실행할 ScriptRunConfig를 설정한다. 위에서 우리가 구성한
- Compute node 설정: compute_target
- 트레이닝 코드 스크립트 디렉토리: script_folder
- 트레이닝을 실행할 진입 파일: train.py
- FileDataset을 Compute node에 mount하기 위한 argument: '--data-folder', mnist_file_dataset.as_mount()
- Curated environment로 구성한 environment: env
설정을 이렇게 맞춰서 ScriptRunConfig object로 저장한다.
from azureml.core import ScriptRunConfig args = ['--data-folder', mnist_file_dataset.as_mount(), '--regularization', 0.5] src = ScriptRunConfig(source_directory=script_folder, script='train.py', arguments=args, compute_target=compute_target, environment=env)
트레이닝 실행 - Run
Experiment에 submit하면, Run object로 실행된다.
AzureML Run이란 무엇인가?
A run represents a single trial of an experiment. Runs are used to monitor the asynchronous execution of a trial, log metrics and store output of the trial, and to analyze results and access artifacts generated by the trial.
Run은 Experiment 1회 실행을 의미한다. Run은 머신러닝 과정과 log metric, 실행 결과를 저장하기 위해 사용되며, 실행간 생성된 결과물(artifact) 분석에도 사용된다.
run = exp.submit(config=src) run
성공적으로 run이 수행되면, AzureML studio의 경로를 통해 수행 과정과 결과를 체크 가능하다.
Jupyter notebook에서 Run 수행 과정 확인
AzureML studio에서도 확인 가능하며, Notebook에서도 확인 가능하다.
from azureml.widgets import RunDetails RunDetails(run).show()
"ModuleNotFoundError: No module named 'azureml.widgets'" 오류 메세지가 발생하면, conda 환경에서 아래 package를 추가한다.
pip install 'azureml-sdk[notebooks]'
아래 코드를 수행해, 다른 작업을 수행하지 않고 대기하도록 할 수 있다.
다른 포스팅에서 소개할 AzureML pipeline 과정에서는 이전 step이 완료된 후 다음 step을 진행해야 할 경우가 있다. 그럴 경우 wait_for_completion을 보통 사용한다. 수행시 환경에 따라 10~15분 정도 시간이 소요될 수 있다.
# specify show_output to True for a verbose log run.wait_for_completion(show_output=True)
실행 후 metric 출력
우리는 train.py 코드에서 다음 절차로 logging을 수행했다. 다시 코드를 체크해 보자.
# train.py 파일 ... run = Run.get_context() ... run.log('regularization rate', np.float(args.reg)) run.log('accuracy', np.float(acc)) ...
이렇게 우리는 regularization rate과 accuracy를 logging하였다.
train.py 코드에서 logging한 metric 결과를 출력해 보자.
print(run.get_metrics())
{'regularization rate': 0.5, 'accuracy': 0.9193}
이런 형태로 metric 결과가 출력될 것이다. 이 결과는 현재 실행해 참조되고 있는 "Run" 개체의 결과로 AzureML에 등록된 metric을 가져오는 것이다.
생성된 Model Register
AzureML 트레이닝이 완료되었고, 결과 metric도 잘 확인했다. 마지막 남은 작업은 training간 생성된 model 파일을 잘 등록/관리하는 것이다. 이때 Model 이 사용된다.
AzureML의 Model이란 무엇인가?
A model is the result of a Azure Machine learning training Run or some other model training process outside of Azure. Regardless of how the model is produced, it can be registered in a workspace, where it is represented by a name and a version.
azureml.core.model.Model class - Azure Machine Learning Python | Microsoft Docs
AzureML의 model은 Run으로 수행되거나 Azure 외부에서 수행된 트레이닝 결과이다. 모델의 생성 방식과 무관하게, 이 모델은 AzureML의 workspace에 등록(register)될 수 있고, 모델명과 버전으로 표현될 수 있다.
생성한 모델을 이렇게 AzureML이 제공하는 model storage에 저장하고 이후 여러 어플리케이션이나 다른 트레이닝 작업 등에서 사용 가능하며, MLOps 등에서 자동으로 model 등록/배포 역시 가능해진다. 우선 코드를 수행하자.
# 현재 run에 속해 있는 파일들을 출력 print(run.get_file_names()) # register model model = run.register_model(model_name='sklearn_mnist', model_path='outputs/sklearn_mnist_model.pkl') print(model.name, model.id, model.version, sep='\t')
이렇게 AzureML에서 Experiment를 수행하고, Model 등록까지 완료하였다. 이 패턴이 전형적인 AzureML의 머신러닝 과정이다. 새로운 AzureML 용어가 많이 나왔지만, 실제로는 우리가 그간 머신러닝을 해 왔던 과정을 세분화하고, 독립적이며, 재사용 가능하게 구성한 것과 같다.
그렇다면, 왜 이렇게 Experiment, Compute, Environment, Dataset, Model, Run 등으로 다양하게 분리해 사용하는가?
다음 포스팅에서는 AzureML의 개별 과정에 대해 조금 더 다양한 진행을 수행한다.
참고링크
개발자 커뮤니티 SQLER.com - MLaaS - (1) 12가지의 머신러닝을 먼저 도입한 기업들의 고민
개발자 커뮤니티 SQLER.com - (2) AzureML - Azure Machine Learning 이란 무엇인가?