지난 시간에 리뷰했던, Azure Databricks를 이용하는 MLOps 문서에 이어서, CI/CD 및 Deployment를 포함하는 Azure Databricks MLOps 코드를 추가로 리뷰.
전체 코드는 아래 Github 리포지토리에서 확인 가능.
원본 repository에서 몇가지 이슈가 있어서, fork한 repository 사용을 권장하며, 이슈가 발생해 수정한 부분은 아래 포스팅에서 진행.
Azure Databricks와 MLOps - CI/CD 및 Deployment 포함
Azure Databricks는 Spark 코어를 사용해 훌륭한 머신러닝 분산 트레이닝 과정을 수행할 수 있으며, MLflow를 활용해 머신러닝 프로젝트의 전체 라이프사이클을 관리할 수 있다. AzureML로 여러 MLOps 프로젝트를 진행하였으며, Databricks에서는 이런 MLOps를 어떻게 구축하는지 실제 코드와 실행 패턴을 살펴보고 리뷰한다.
CI/CD를 위해 Azure DevOps 사용
MLOps에서 필요한 개발자와의 협업, 시너지를 위해 DevOps 기능을 구현하고 있으며, ADO(Azure DevOps, 이하 ADO)를 이용해 CI/CD를 구현한다.
ADO project 생성 및 Repository import
ADO에서 CI/CD 및 전체 DevOps pipeline을 구성하려면, 먼저 ADO에 가입하고 프로젝트를 생성해야 한다.
Azure DevOps Repo에서 외부 Git Repository import 수행
Import할 Git repository는 아래와 같다.
https://github.com/CloudBreadPaPa/MLOps-Databricks.git
Azure DevOps pipeline import
Import가 완료되면 CI/CD pipeline을 수행하기 위해, ADO pipeline을 import한다.
Clone or import a pipeline - Azure Pipelines | Microsoft Docs
이미 코드는 repository로 clone된 상태이기 때문에, azure-pipelines.yml 파일을 선택하면 pipeline 준비가 완료된다.
Azure Databricks를 생성하고, PAT(Personal Access Token)생성
ADO pipeline에서 Databricks를 접근해야 하기 때문에, Databricks를 provision 하고, PAT를 생성해야 한다.
Azure cli 사용법은 이 문서에서 참고. 이 과정은 모두 WSL Ubuntu에서 수행.
# Azure에 cli로 로그인 az login # Resource group 생성. 이름은 rg-dbmlops02 az group create --name rg-dbmlops02 --location koreacentral # databricks를 cli로 사용하기 위한 az extension 추가 az extension add --name databricks # databricks workspace 생성. workspace 이름은 dbsws02 az databricks workspace create --resource-group rg-dbmlops02 --name dbsws02 --location koreacentral --sku standard
생성한 Azure Databricks에서 PAT(Personal Access Token)를 생성해 잘 기록해 둔다.
Authentication using Azure Databricks personal access tokens - Azure Databricks | Microsoft Docs
ADO pipeline에서 databricks variable 추가
ADO pipeline 실행 시 이러한 databricks 접속 관련 정보를 variable로 저장하면 편리하다. 두개의 variable을 추가한다.
- databricks.host
- databricks.token
databricks.host를 원본 repository에서는 사용하지 않는다. 원본의 경우 pipeline variable이 아니라, pipeline code에서 "https://westeurope.azuredatabricks.net/"로 코딩되어 있다. 아마도, 예전 databricks는 이렇게 region명으로 선언되었던 것 같다. Azure Databricks는 URI가 "https://adb-xxxxxxxxxxxx.azuredatabricks.net/" 형태로 지정되도록 변경되었기 때문에, variable 형태로 사용하자.
아래 화면을 참조해 databricks URL과 PAT pipeline variable을 추가한다.
AzureML workspace 생성 및 deployment compute 생성을 위한 Azure Service Principal 생성
Databricks에서 python 코드가 실행되면서 AKS(Azure Kubernetes Service)나 ACI(Azure Container Instance)로 배포하기 위해서는 AzureML workspace를 이용해야 한다.
참고링크: 개발자 커뮤니티 SQLER.com - Azure Databricks - MLflow를 이용한 머신러닝(5) - Model 배포
이 과정을 수행하려면, 권한을 가진 사용자가 필요하나, ADO에서 pipeline과 같이 automation 되어야 하는 작업에서는 interactive login을 사용할 수가 없어 SP(Service Principal, 이하 SP)을 이용해야 한다.
참고링크: 개발자 커뮤니티 SQLER.com - Service Principal과 Azure 리소스 접근/사용을 위한 인증 방법 3+1가지
이를 위해 Azure의 Resource group에 owner 권한을 가지는 SP를 생성한다.
# 이런 패턴으로 Resource group owner권한 SP를 생성 az ad sp create-for-rbac -n "<SP이름>" --role Owner --scopes /subscriptions/<자신의 Subscription ID>/resourceGroups/<Resource Group 이름> # 실제 사용한 코드 az ad sp create-for-rbac -n "dwkim-databricks-mlops02-sp" --role Owner --scopes /subscriptions/3e6494d9XXXXXXXXXXXXXX/resourceGroups/rg-dbmlops02
수행하면, 이렇게 생성한 SP 정보가 출력된다. 잠시 후에 사용하니 잘 기록해 둔다.
{ "appId": "8fXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "displayName": "dwkim-databricks-mlops02-sp", "name": "8f6XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "password": "xX47soXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "tenant": "72fXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" }
Databricks에 Secret 정보를 저장하고 코드에서 사용
위에서 생성한 코드는 Resource group에 권한을 가지는 중요한 SP이다. 이 정보를 Databricks에 plain text로 처리하는 것이 아니라, secret 형태로 자동화시켜 저장/사용할 수 있다. 이때, secret scope를 생성해 사용한다.
다음 명령을 Azure databricks cli에서 수행해 databricks에 secret scope를 저장한다
# Conda 환경을 하나 만들고 수행 pip install -U databricks-cli # databricks cli가 workspace에 접근할 수 있도록 인증. databricks host와 PAT를 입력한다. databricks configure --token # secret scope 생성 이슈. 아래 명령을 수행하면 오류가 발생 # databricks secrets create-scope --scope azureml # 오류 메세지- Premium Tier is disabled in this workspace. Secret scopes can only be created with initial_manage_principal "users" # 아래처럼 수정하여 수행 databricks secrets create-scope --scope azureml --initial-manage-principal "users" # 개별 secret을 입력. SP 정보 등을 입력한다. workspace_name은 생성하고 연결할 AzureML workspace 이름. workspace location은 "koreacentral"으로 설정하자. # Use the "tenant" property from the Azure AD Service Principal command output databricks secrets put --scope azureml --key tenant_id # Use the "appId" property from the Azure AD Service Principal command output databricks secrets put --scope azureml --key client_id # Use the "password" property from the Azure AD Service Principal command output databricks secrets put --scope azureml --key client_secret databricks secrets put --scope azureml --key subscription_id databricks secrets put --scope azureml --key resource_group databricks secrets put --scope azureml --key workspace_name databricks secrets put --scope azureml --key workspace_location
참고로, 이렇게 넘긴 databricks secret key들은 아래와 같은 dbutils.screts.get() 코드 패턴으로 spark notebook에서 가져와 사용된다.
... workspace_name = dbutils.secrets.get(scope = "azureml", key = "workspace_name") workspace_location = dbutils.secrets.get(scope = "azureml", key = "workspace_location") resource_group = dbutils.secrets.get(scope = "azureml", key = "resource_group") subscription_id = dbutils.secrets.get(scope = "azureml", key = "subscription_id") ...
ADO pipeline 실행
이제 설정이 완료되었다. ADO pipeline에서 "Run pipeline"을 진행한다.
실행간, ACI와 AKS Deployment 과정에 대해 사용자의 permit이 필요할 수 있다.
성공적으로 완료되면 이런 화면을 볼 수 있다.
Azure Portal에서 Resource group을 확인하면, 생성했던 SP를 통해 AzureML이 배포가 되었고, ACI와 AKS역시 배포되어 Serving에 사용된다.
Databricks workspace에서 Job / Training run 확인
Job을 확인하면, 이렇게 Training / ACI로 Deploy / AKS로 Deploy 과정이 수행된 것을 확인 가능하다.
WineQuality training 과정에 대해서는 Experiment에서 더 상세한 run기록과 생성된 artifact-model에 대한 정보도 확인 가능하다.
각각의 코드는 아래 링크에서 확인 가능하다.
Deploy - serving_deploy_to_aci.py 코드
Deploy - serving_deploy_to_aks.py 코드
MLOps 관점에서 추가적인 리뷰
훌륭한 프로젝트이다. CI/CD 기능의 통합과 Databricks를 잘 활용해 트레이닝을 수행하며, AzureML은 Databricks 공식 가이드대로, Deployment로 잘 사용된다. 몇 가지 아쉬운 부분으로,
Model evaluation
Job으로 databricks training이 완료되면, test 데이터셋을 통해 model을 evaluation하고, 현재까지 가장 높은 성능의 model과 비교해 더 높을 경우에만 취사 선택되는 부분이 아쉽다.
Staging/Production
ACI에서 AKS로 넘어가나, 적절한 Staging/Production 으로 나뉘어 진행하는 처리가 부족한 것 같다.
AzureML 리소스 처리를 코드로 진행
Container build나 ACI/AKS로 deploy하는 코드에서 AzureML이 아래처럼 사용된다.
workspace = Workspace.create(name = workspace_name, location = workspace_location, resource_group = resource_group, subscription_id = subscription_id, auth=svc_pr, exist_ok=True)
코드에서는 workspace를 create 하는 것보다 ADO pipeline으로 IaC(Infrastructure as Code)해서 미리 모든 리소스들을 생성해 두고, 사용했으면 어떨까 하고 생각한다.
Secret 관리 - Azure Key Vault 사용
Azure Key Vault는 Secret / Key 관리 서비스이다. 이 repository에서는 ADO pipeline variable과 databricks secret을 처리하나, Key Vault를 사용했다면 더 높은 보안성을 얻을 수 있을 듯 하다.
Azure Key Vault Overview - Azure Key Vault | Microsoft Docs
Observability를 위한 클라우드 환경 구성
MLOps 환경을 구축 후, 전체 솔루션의 서비스 상태나 로깅, 이후 다시 머신러닝 training에 사용하기 위한 피드백 루프 등, 여러 페르소나가 필요로하는 부분이 제외되어 있다.
리뷰 후기
Azure Databricks를 활용한 MLOps로 훌륭한 프로젝트라고 생각된다. 이후에 Databricks를 사용하는 머신러닝 및 MLOps 프로젝트를 조금 더 보완해 진행하게 된다면 훌륭하게 잘 활용할 수 있을 것으로 기대된다.
참고링크:
Azure Key Vault Overview - Azure Key Vault | Microsoft Docs
개발자 커뮤니티 SQLER.com - MLaaS - (1) 12가지의 머신러닝을 먼저 도입한 기업들의 고민
개발자 커뮤니티 SQLER.com - Azure Databricks MLflow를 이용한 MLOps
개발자 커뮤니티 SQLER.com - Azure Databricks - MLflow를 이용한 머신러닝(1)
개발자 커뮤니티 SQLER.com - Azure Databricks - MLflow를 이용한 머신러닝(2) - Tracking
개발자 커뮤니티 SQLER.com - Azure Databricks - MLflow를 이용한 머신러닝(3) - Project
개발자 커뮤니티 SQLER.com - Azure Databricks - MLflow를 이용한 머신러닝(4) - Model Registry
개발자 커뮤니티 SQLER.com - Azure Databricks - MLflow를 이용한 머신러닝(5) - Model 배포