MLOps 구현하기 1: Azureml examples 튜토리얼 따라하기 (파이프라인 만들기)
들어가기 전에
MLOps 첫 편에서 파이썬 코드만을 이용해 모델을 클라우드 환경에서 훈련시키고 결과를 확인할 수 있도록 했다. 다음으로 모델을 배포시키는 과정을 밟았다. 이번 편에서는 Azure 머신러닝과 Azure 머신러닝 Python SDK v2를 이용해 프로덕션 환경에서 사용할 머신러닝 프로젝트를 만들어보려고 한다. 동일한 저장소의 pipeline.ipynb 파일을 실행한다.
즉, 다음을 할 수 있다.
- Azure 머신러닝 워크스페이스에 대한 핸들링 생성하기
- Azure 머신러닝 데이터 에셋 생성하기
- 재사용 가능한 Azure 머신러닝 컴포넌트 만들기
- Azure 머신러닝 파이프라인을 만들고, 검증하고, 실행시키기
이번 편에서는 이미 이전 편에서 진행해본 것들이 많다. 그럼 왜 똑같은 걸 또 하느냐? 이번 편의 핵심은 각 단계를 “컴포넌트”(= 레고 부품)으로 만들어 조합하여 자동화하는 것이기 때문이다!
머신러닝 파이프라인의 핵심은 전체 머신러닝 작업을 여러 단계의 워크플로로 분할하는 것이다. 각 단계는 개별적으로 개발, 최적화, 구성, 자동화할 수 있는 관리 가능한 구성 요소이다. 각 단계는 잘 정의된 인터페이스를 통해 연결된다.
Azure 머신러닝 파이프라인 서비스는 파이프라인 단계 간의 모든 디펜던시를 자동으로 오케스트레이션한다. 파이프라인을 사용함으로써 MLOps 사례를 표준화할 수 있고, 팀 협업을 확장 가능하게 만들 수 있고, 모델 훈련을 더 효율적으로 할 수 있으며 비용 절감 효과가 있다. (참고 What are Azure Machine Learning pipelines)
내가 만들 파이프라인은 다음과 같은 두 단계를 컴포넌트화하여 다룬다.
- 데이터 준비
- 머신러닝 모델 훈련시키고 워크스페이스에 등록하기
파이프라인 리소스 세팅하기
Azure 머신러닝 프레임워크는 CLI, 파이썬 SDK 혹은 Azure 스튜디오에서 사용할 수 있다. 이 예제에서는 이전 편에서도 그랬듯이 Python SDK v2를 사용하여 파이프라인을 만든다.
파이프라인을 만들기 위해서는 다음 리소스가 필요하다.
- 훈련을 위한 데이터 자산
- 파이프라인을 실행할 소프트웨어 환경
- 작업이 실행되는 컴퓨팅 리소스
워크스페이스 핸들 생성하기
MLOps 첫 편과 두번째 편에서 했듯이 워크스페이스를 참조할 수 있는 방법이 필요하다. ml_client
를 생성하는 것이 그것이다.
이미 전편과 전전편에 걸쳐 두 번이나 진행한 단계이므로 설명을 생략한다.
from azure.ai.ml import MLClient
from azure.identity import DefaultAzureCredential
# authenticate
credential = DefaultAzureCredential()
# # Get a handle to the workspace
ml_client = MLClient(
credential=credential,
subscription_id="your-subscription-id",
resource_group_name="your-resource_group_name",
workspace_name="your-aml-workspace_name",
)
외부 URL을 이용해 데이터 등록하기
Azure 머신러닝은 Data
객체를 이용해 재사용가능한 데이터를 등록한다. 그리고 파이프라인 내에서 데이터를 다룬다.
다음 코드는 외부 웹 URL을 이용해 데이터를 소비한다. 다른 소스에서의 Data
에셋도 물론 만들 수 있다.
from azure.ai.ml.entities import Data
from azure.ai.ml.constants import AssetTypes
web_path = "https://dwstorpersonal.blob.core.windows.net/aml-temp/default_of_credit_card_clients.xls"
credit_data = Data(
name="creditcard_defaults",
path=web_path,
type=AssetTypes.URI_FILE,
description="Dataset for credit card defaults",
tags={"source_type": "web", "source": "UCI ML Repo"},
version="1.0.0",
)
위 코드에서 Data
에셋을 생성했다. 차차 빌드해나갈 파이프라인에서 input 값으로 언제든 사용될 수 있다. 게다가 데이터를 워크스페이스에 등록했으므로 다른 파이프라인에서도 이 데이터를 재사용할 수 있다.
다음 코드에서 ml_client
를 처음으로 호출함으로써 인증 절차와 함께 워크스페이스 연결이 완료된다. 인증이 끝나면 "Dataset with name creditcard_defaults was registered to workspace, the dataset version is 1.0.0"와 같은 등록 완료 출력문을 받게 된다.
# 튜토리얼을 지금까지 따라한 경우 or 이미 데이터를 등록한 경우
credit_data = ml_client.data.create_or_update(credit_data)
print(
f"Dataset with name {credit_data.name} was registered to workspace, the dataset version is {credit_data.version}"
)
이제 앞으로는 똑같은 데이터셋을 워크스페이스로부터 불러오려면 credit_dataset = ml_client.data.get("<DATA ASSET NAME>", version='<VERSION>')
를 호출하면 된다.
Azure 스튜디오에서도 데이터셋이 잘 등록됐는지 살펴보자. Azure 머신러닝 스튜디오 > Data > Data assets에 방금 등록한 데이터셋이 뜬다. 굳.
파이프라인을 실행하기 위한 컴퓨팅 리소스 생성하기
서버리스 컴퓨팅으로 모델 학습을 실행시키려면 이 단계를 스킵할 수 있다. 서버리스 컴퓨팅을 통해 Azure 머신러닝은 컴퓨팅의 생성, 확장, 삭제, 패치 및 관리를 처리하고 관리되는 네트워크 격리를 제공하므로 유저의 부담을 줄여준다고 한다.
Azure 머신러닝 파이프라인의 각 단계는 해당 단계의 특정 작업을 실행하기 위해 다른 컴퓨팅 리소스를 사용할 수 있다. 작업에 필요한 계산 능력이 단계별로 다를 수 있기 때문이다. 리눅스나 윈도OS가 설치된 단일 or 다중 노드 머신이나 Spark 같은 특정 컴퓨터 프레임워크가 될 수도 있다. 이는 파이프라인의 유연성과 확장성을 높이며, 다양한 작업에 최적화된 리소스를 할당할 수 있게 한다.
여기서 잠깐, Spark 프레임워크는 처음 들어봐서 내용을 좀 찾아봤다.
[!NOTE] Spark 프레임워크란?
Apache Spark는 큰 데이터 집합을 처리하기 위한 오픈 소스 분산 컴퓨팅 시스템이다. 병렬 처리를 통해 대규모 데이터를 빠르게 처리하며 다양한 데이터 처리 작업에 사용된다. 배치 처리, 실시간 처리, 머신러닝, 그래프 분석 등에 사용된다. 빅데이터 분석 및 처리에 널리 사용되는 프레임워크로 속도, 유연성, 사용 편의성 등이 주요 강점이라고 한다.
이 단계에서는 리눅스 컴퓨팅 클러스터를 이용해 컴퓨팅 리소스를 할당하고 준비한다. 이번에는 Standard_DS2_v3 모델을 사용한다.
MLOps 첫 번째 편에서 이미 진행한 작업이기도 하다. 이미 생성한 CPU 클러스터가 존재하면 그것을 사용하도록 되어있다. 나는 이미 만들어 둔 CPU 클러스터가 있으므로 그것을 사용한다.
from azure.ai.ml.entities import AmlCompute
# Name assigned to the compute cluster
cpu_compute_target = "cpu-cluster"
try:
# let's see if the compute target already exists
cpu_cluster = ml_client.compute.get(cpu_compute_target)
print(
f"You already have a cluster named {cpu_compute_target}, we'll reuse it as is."
)
except Exception:
print("Creating a new cpu compute target...")
# Let's create the Azure Machine Learning compute object with the intended parameters
# if you run into an out of quota error, change the size to a comparable VM that is available.
# Learn more on https://azure.microsoft.com/en-us/pricing/details/machine-learning/.
cpu_cluster = AmlCompute(
name=cpu_compute_target,
# Azure Machine Learning Compute is the on-demand VM service
type="amlcompute",
# VM Family
size="STANDARD_DS2_V3", # 이름 주의
# Minimum running nodes when there is no job running
min_instances=0,
# Nodes in cluster
max_instances=1, # 최소 0개, 최대 1개만 생성
# How many seconds will the node running after the job termination
idle_time_before_scale_down=180,
# Dedicated or LowPriority. The latter is cheaper but there is a chance of job termination
tier="Dedicated", # 추가 quota 설정이 없을 경우 Dedicated 으로 설정
)
print(
f"AMLCompute with name {cpu_cluster.name} will be created, with compute size {cpu_cluster.size}"
)
# Now, we pass the object to MLClient's create_or_update method
cpu_cluster = ml_client.compute.begin_create_or_update(cpu_cluster)
파이프라인 각 단계를 위한 Job 환경 생성하기
지금까지는 개발 머신 용도로 사용하는 컴퓨팅 인스턴스에 개발 환경을 만들어왔다. 거기에 더하여 파이프라인의 각 단계에 사용할 환경 또한 필요하다. 각 단계마다 고유한 환경을 사용할 수도 있고 여러 단계에서 공통된 환경을 사용할 수도 있다.
conda yaml 파일을 이용해 작업을 위한 conda 환경을 만들어보자. 먼저 파일을 저장할 디렉터리를 만든다.
import os
dependencies_dir = "./dependencies"
os.makedirs(dependencies_dir, exist_ok=True)
다음으로 해당 디렉토리에 저장할 conda yaml 파일을 생성한다.
%%writefile {dependencies_dir}/conda.yaml
name: model-env
channels:
- conda-forge
dependencies:
- python=3.10
- numpy
- pip
- scikit-learn
- scipy
- pandas
- pip:
- inference-schema[numpy-support]
- xlrd
- mlflow
- azureml-mlflow
위 스펙은 파이프라인에서 사용하는 일반적인 패키지(pip, numpy)와 더불어 Azure 머신러닝 전용 패키지(azureml-mlflow)가 포함되어 있다.
Azure 머신러닝 패키지는 필수는 아니지만, 이런 패키지를 이용하여 Azure 머신러닝 작업 내에서 메트릭을 로깅하고 모델을 등록하기 위해 Azure 머신러닝과 상호작용할 수 있다.
다음 코드를 실행하면 위의 conda yaml 스펙을 워크스페이스에 등록한다.
Azure 스튜디오 > Environments에서 등록된 환경을 확인할 수 있다.
첫 번째 MLOps 편을 진행할 때 환경을 생성하여 등록했었기 때문에 version을 선택할 수 있다. 방금 만든 것은 version 0.2.0으로 등록되었다.
아래처럼 스펙을 확인할 수도 있다.
학습 파이프라인 빌드하기
이제 파이프라인을 실행하기 위한 모든 에셋을 다 갖췄으니 파이프라인 자체를 빌드할 차례다.
Azure 머신러닝 파이프라인은 재사용가능한 ML 워크플로우로, 주로 여러 개의 컴포넌트로 구성되어 있다. 일반적으로 컴포넌트의 주기는 아래와 같다.
- 컴포넌트의 yaml 스펙을 작성한다. 혹은
ComponentMethod
를 이용해 프로그래밍 방식으로 생성한다. - 원하는 경우, 컴포넌트를 재사용하고 공유할 수 있도록 이름과 버전을 붙여 워크스페이스에 등록한다.
- 파이프라인 코드에서 컴포넌트를 로드한다.
- 컴포넌트의 입력, 출력, 매개변수를 사용해 파이프라인을 구축한다.
- 파이프라인을 제출한다.
컴포넌트를 만드는데는 두 가지 방법이 있다. yaml 명세 방식과 프로그래밍 방식이다. 두 가지 방법 모두 사용하여 컴포넌트를 생성하는 과정을 거칠 예정이다.
그리고 이 과정에서 모든 컴포넌트에 동일한 컴퓨팅 리소스를 사용할 것이다. 하지만 각기 컴포넌트에 다른 컴퓨팅 리소스를 사용할 수 있다고 한다. 관련 예시가 더 궁금하면 Basic pipeline job section in the cifar-10 pipeline tutorial
컴포넌트 만들기 1: 프로그래밍 방식 (data_prep.py)
첫 번째 컴포넌트를 생성해보자. 이 컴포넌트는 데이터의 전처리를 다룰 것이다. 데이터 전처리 작업은 data_prep.py
파이썬 파일에서 이루어진다.
우선 data_prep 컴포넌트를 위한 소스 폴더를 만들자.
import os
data_prep_src_dir = "./components/data_prep"
os.makedirs(data_prep_src_dir, exist_ok=True)
그 다음 아래 스크립트는 데이터를 학습용, 테스트용으로 나누는 간단한 작업을 한다.
MLFlow는 파이프라인이 실행되는 동안 파라미터와 로그를 기록하는 역할을 한다.
%%writefile {data_prep_src_dir}/data_prep.py
import os
import argparse
import pandas as pd
from sklearn.model_selection import train_test_split
import logging
import mlflow
def main():
"""Main function of the script."""
# input and output arguments
parser = argparse.ArgumentParser()
parser.add_argument("--data", type=str, help="path to input data")
parser.add_argument("--test_train_ratio", type=float, required=False, default=0.25)
parser.add_argument("--train_data", type=str, help="path to train data")
parser.add_argument("--test_data", type=str, help="path to test data")
args = parser.parse_args()
# Start Logging
mlflow.start_run()
print(" ".join(f"{k}={v}" for k, v in vars(args).items()))
print("input data:", args.data)
credit_df = pd.read_excel(args.data, header=1, index_col=0)
mlflow.log_metric("num_samples", credit_df.shape[0])
mlflow.log_metric("num_features", credit_df.shape[1] - 1)
credit_train_df, credit_test_df = train_test_split(
credit_df,
test_size=args.test_train_ratio,
)
# output paths are mounted as folder, therefore, we are adding a filename to the path
credit_train_df.to_csv(os.path.join(args.train_data, "data.csv"), index=False)
credit_test_df.to_csv(os.path.join(args.test_data, "data.csv"), index=False)
# Stop Logging
mlflow.end_run()
if __name__ == "__main__":
main()
이제 우리가 바라고자 하는 작업을 하는 스크립트가 생겼다. 이걸 가지고 Azure 머신러닝 컴포넌트를 만든다.
명령줄 작업을 실행할 수 있는 CommandComponent
를 사용한다. 이 명령줄은 시스템 명령을 직접 호출하거나 스크립트를 실행할 수 있다. 인풋과 아웃풋은 ${{ ... }}
표기를 통해 가능하다.
from azure.ai.ml import command
from azure.ai.ml import Input, Output
data_prep_component = command(
name="data_prep_credit_defaults",
display_name="Data preparation for training",
description="reads a .xl input, split the input to train and test",
inputs={
"data": Input(type="uri_folder"),
"test_train_ratio": Input(type="number"),
},
outputs=dict(
train_data=Output(type="uri_folder", mode="rw_mount"),
test_data=Output(type="uri_folder", mode="rw_mount"),
),
# The source folder of the component
code=data_prep_src_dir,
command="""python data_prep.py --data ${{inputs.data}} --test_train_ratio ${{inputs.test_train_ratio}} --train_data ${{outputs.train_data}} --test_data ${{outputs.test_data}} """,
environment=f"{pipeline_job_env.name}:{pipeline_job_env.version}",
)
그 다음 재사용성을 위해 워크스페이스에 컴포넌트를 등록한다.
"Component data_prep_credit_defaults with Version 1 is registered"와 같은 출력문을 만나면 성공.
# Now we register the component to the workspace
data_prep_component = ml_client.create_or_update(data_prep_component.component)
# Create (register) the component in your workspace
print(
f"Component {data_prep_component.name} with Version {data_prep_component.version} is registered"
)
컴포넌트 만들기 2: yaml 명세 방식 (훈련시키기)
두 번째 만들 컴포넌트는 우리가 앞서 전처리 과정에서 분리한 학습용, 테스트용 데이터를 소비하고, 트리 기반 모델을 훈련시키고, 아웃풋 모델을 반환한다.
방금 CommandComponent
클래스를 이용해 첫 번째 컴포넌트를 생성했다. 이번엔 yaml 명세 방식으로 두 번째 컴포넌트를 만든다. 각각의 방법은 장단점이 있다. yaml 명세 방식은 코드와 함께 체크인될 수 있고, 히스토리 추적이 가능하다. CommandComponent
프로그래밍 방식은 빌트인 클래스 문서와 코드 완성과 함께 더 쉬울 수 있다.
이 컴포넌트를 위해 디렉토리를 만들자.
import os
train_src_dir = "./components/train"
os.makedirs(train_src_dir, exist_ok=True)
그리고 이 디렉토리에 저장 될 훈련 스크립트를 만든다. Azure 머신러닝은 데이터셋을 폴더째 마운팅한다. 따라서 select_first_file
이라는 보조 함수를 생성하여 마운트된 폴더의 데이터 파일에 접근할 수 있도록 하자.
%%writefile {train_src_dir}/train.py
import argparse
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.metrics import classification_report
import os
import pandas as pd
import mlflow
def select_first_file(path):
"""Selects first file in folder, use under assumption there is only one file in folder
Args:
path (str): path to directory or file to choose
Returns:
str: full path of selected file
"""
files = os.listdir(path)
return os.path.join(path, files[0])
# Start Logging
mlflow.start_run()
# enable autologging
mlflow.sklearn.autolog()
os.makedirs("./outputs", exist_ok=True)
def main():
"""Main function of the script."""
# input and output arguments
parser = argparse.ArgumentParser()
parser.add_argument("--train_data", type=str, help="path to train data")
parser.add_argument("--test_data", type=str, help="path to test data")
parser.add_argument("--n_estimators", required=False, default=100, type=int)
parser.add_argument("--learning_rate", required=False, default=0.1, type=float)
parser.add_argument("--registered_model_name", type=str, help="model name")
parser.add_argument("--model", type=str, help="path to model file")
args = parser.parse_args()
# paths are mounted as folder, therefore, we are selecting the file from folder
train_df = pd.read_csv(select_first_file(args.train_data))
# Extracting the label column
y_train = train_df.pop("default payment next month")
# convert the dataframe values to array
X_train = train_df.values
# paths are mounted as folder, therefore, we are selecting the file from folder
test_df = pd.read_csv(select_first_file(args.test_data))
# Extracting the label column
y_test = test_df.pop("default payment next month")
# convert the dataframe values to array
X_test = test_df.values
print(f"Training with data of shape {X_train.shape}")
clf = GradientBoostingClassifier(
n_estimators=args.n_estimators, learning_rate=args.learning_rate
)
clf.fit(X_train, y_train)
y_pred = clf.predict(X_test)
print(classification_report(y_test, y_pred))
# Registering the model to the workspace
print("Registering the model via MLFlow")
mlflow.sklearn.log_model(
sk_model=clf,
registered_model_name=args.registered_model_name,
artifact_path=args.registered_model_name,
)
# Saving the model to a file
mlflow.sklearn.save_model(
sk_model=clf,
path=os.path.join(args.model, "trained_model"),
)
# Stop Logging
mlflow.end_run()
if __name__ == "__main__":
main()
이 훈련 스크립트에서 보듯이, 일단 모델이 훈련되면 이 모델 파일은 저장되고 워크스페이스에 등록된다. 그러면 이 등록된 모델을 추론 엔드포인트에서 사용할 수 있게 된다.
이 단계의 환경 구성을 위해서는, 빌트인 Azure 머신러닝 환경을 이용한다. curated environment 라고도 한다. azureml
이라고 태그가 붙어있으며, 이는 curated environments에서 해당하는 이름의 환경을 찾으라고 시스템에 명령한다.
우선 컴포넌트를 명세하는 yaml 파일을 만든다.
%%writefile {train_src_dir}/train.yml
# <component>
name: train_credit_defaults_model
display_name: Train Credit Defaults Model
# version: 1 # Not specifying a version will automatically update the version
type: command
inputs:
train_data:
type: uri_folder
test_data:
type: uri_folder
learning_rate:
type: number
registered_model_name:
type: string
outputs:
model:
type: uri_folder
code: .
environment:
# for this step, we'll use an AzureML curate environment
azureml:AzureML-sklearn-1.0-ubuntu20.04-py38-cpu:1
command: >-
python train.py
--train_data ${{inputs.train_data}}
--test_data ${{inputs.test_data}}
--learning_rate ${{inputs.learning_rate}}
--registered_model_name ${{inputs.registered_model_name}}
--model ${{outputs.model}}
# </component>
이제 다음 코드에서 컴포넌트를 생성하고 등록한다. 등록함으로써 다른 파이프라인에사도 이 컴포넌트를 재사용할 수 있다. 또한 워크스페이스에 접근이 가능한 어느 누구라도 이 등록된 컴포넌트를 사용할 수 있다.
# importing the Component Package
from azure.ai.ml import load_component
# Loading the component from the yml file
train_component = load_component(source=os.path.join(train_src_dir, "train.yml"))
# Now we register the component to the workspace
train_component = ml_client.create_or_update(train_component)
# Create (register) the component in your workspace
print(
f"Component {train_component.name} with Version {train_component.version} is registered"
)
여러 컴포넌트로 파이프라인 만들기
이제 두 개의 컴포넌트를 정의하고 등록했다. Azure 스튜디오 > Components에서 만들어진 두 개의 컴포넌트가 잘 보인다!
그러면 이것들로 파이프라인을 구축할 차례다.
이전 단계에서 load_component()
에 의해 반환된 파이썬 함수는 파이프라인 내에서 각 단계(컴포넌트)를 호출하는데 사용된다.
파이프라인을 코딩하려면 Azure 머신러닝 파이프라인을 식별하는 특정 @dsl.pipeline
데코레이터를 사용한다. 이 데코레이터에서 파이프라인 설명과 컴퓨팅 리소스나 저장소같은 기본 리소스를 지정할 수 있다.
일반적인 파이썬 함수를 정의할 때처럼, 파이프라인은 입력 값을 가질 수 있다. 그런 다음 서로 다른 입력으로 하나의 파이프라인의 여러 인스턴스를 생성할 수도 있다.
여기서는 입력 데이터, split ratio, 학습률, 등록된 모델 이름 이 세 가지가 입력 변수로 주어져야 한다. 그 다음 컴포넌트를 호출하고 그 입력/출력 식별자를 통해서 컴포넌트에 연결한다. 각 단계의 출력 값은 .outputs
속성으로 접근 가능하다.
# the dsl decorator tells the sdk that we are defining an Azure Machine Learning pipeline
from azure.ai.ml import dsl, Input, Output
@dsl.pipeline(
compute=cpu_compute_target, # replace cpu_compute_target with "serverless" to run pipeline on serverless compute
description="E2E data_perp-train pipeline",
)
def credit_defaults_pipeline( # 파이프라인의 입력 변수
pipeline_job_data_input,
pipeline_job_test_train_ratio,
pipeline_job_learning_rate,
pipeline_job_registered_model_name,
):
# using data_prep_function like a python call with its own inputs
data_prep_job = data_prep_component(
data=pipeline_job_data_input,
test_train_ratio=pipeline_job_test_train_ratio,
)
# using train_func like a python call with its own inputs
train_job = train_component(
train_data=data_prep_job.outputs.train_data, # note: using outputs from previous step
test_data=data_prep_job.outputs.test_data, # note: using outputs from previous step
learning_rate=pipeline_job_learning_rate, # note: using a pipeline input as parameter
registered_model_name=pipeline_job_registered_model_name,
)
# a pipeline returns a dictionary of outputs
# keys will code for the pipeline output identifier
return {
"pipeline_job_train_data": data_prep_job.outputs.train_data,
"pipeline_job_test_data": data_prep_job.outputs.test_data,
}
이제 이 파이프라인을 이용해 파이프라인을 인스턴스화 해보자! 데이터 셋, 분할 비율, 학습률, 모델 이름을 사용한다.
registered_model_name = "credit_defaults_model"
# Let's instantiate the pipeline with the parameters of our choice
pipeline = credit_defaults_pipeline(
pipeline_job_data_input=Input(type="uri_file", path=credit_data.path),
pipeline_job_test_train_ratio=0.25,
pipeline_job_learning_rate=0.05,
pipeline_job_registered_model_name=registered_model_name,
)
Job 제출하기
이제 Azure 머신러닝에서 실행할 job을 제출할 차례다. ml_client.jobs
의 create_or_update
메소드를 사용한다.
여기서는 또한 실험 이름도 같이 넘겨주는데, 실험이란 특정 프로젝트에서 수행하는 모든 반복을 위한 컨테이너다. 동일한 실험 이름으로 제출된 모든 작업은 Azure 머신러닝 스튜디오에서 나란히 리스트로 볼 수 있다.
완료되면 모델 훈련 결과로 워크스페이스에 모델을 등록한다.
이 작업은 시간이 좀 걸린다.
# submit the pipeline job
pipeline_job = ml_client.jobs.create_or_update(
pipeline,
# Project's name
experiment_name="e2e_registered_components",
)
ml_client.jobs.stream(pipeline_job.name)
이 코드를 실행하면 출력문에 Web View 링크가 제공되는데, 이 링크를 따라가면 파이프라인의 진행 상황을 눈으로 볼 수 있다. 혹은 Azure 머신러닝 스튜디오 > Pipelines에 접속하면 아래처럼 생성한 파이프라인을 확인할 수 있다.
처음에는 Running 상태였다가 파이프라인이 완료되면, 각각의 컴포넌트의 결과를 볼 수 있다. credit_defaults_pipline 파이프라인을 클릭하면, 아래와 같은 다이어그램이 자동으로 그려진 것이 보인다.
Data를 준비하고, 두 개의 컴포넌트를 생성했으며 각각의 컴포넌트의 실행 결과를 잘 표시하고 있다. 와 신기해라~
컴포넌트를 클릭하여 parameters도 확인할 수 있다.
더블클릭하면 각각의 상세정보가 뜬다. data_prep_job 컴포넌트를 더블클릭하여 확인해보자. Outputs + Logs 탭을 클릭해 user_logs
> std_log.txt
파일에서 스크립트 실행 출력을 볼 수 있다.
train_job 컴포넌트를 클릭해 이번에는 Metric 탭에서 메트릭을 확인해봤다.
이로써 데이터 전처리 + 모델 학습 및 워크스페이스 등록 과정을 자동화하는 파이프라인을 만들었다. 짝짝짝. 파이프라인의 인풋 값을 조절하여 여러 번 실행하고 클라우드에서 각 컴포넌트의 결과를 비교하고 한 눈에 보는 작업이 가능해진 것이다!
마치며
여기까지가 Azureml examples을 통해 MLOps를 구현하는 과정이었다. 이제 다음 편에서는 MLOps 구현 2탄으로 돌아옵니다.