{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# 빌드/학습/배포 MLOps 프로젝트 템플릿 커스터마이징하기 \n", "\n", "2020년 리인벤트에서 최초로 머신러닝을 위한 CI/CD 서비스로 [Amazon SageMaker Pipelines](https://aws.amazon.com/sagemaker/pipelines/) 가 발표되었습니다. SageMaker 파이프라인은 Pipelines, Model Registry, Project의 세가지 요소로 구성되며, 이를 통해 탄력적이고 재사용 가능한 워크플로우를 통해 머신러닝의 업무환경 운영을 제공합니다.\n", "\n", "SageMaker Project는 MLDC(Machine Learning Development Lifecycle)에서 필요한 CI/CD 리소스를 자동으로 프로비저닝하는 MLOps 템플릿을 제공합니다. 사용자는 AWS에서 제공하는 빌트인 템플릿을 이용하거나 자신의 템플릿을 직접 생성할 수 있습니다. \n", "\n", "본 예제는 머신러닝 프로젝트의 기본코드로부터 CI/CD패턴을 구축하기 위해 MLOps 템플릿을 사용하는 방법에 집중합니다. AWS에서 제공되는 빌트인 빌드, 학습, 배포 프로젝트 템플릿을 활용하여 어떻게 실제문제에 적용할 수 있는지 보여줄 것입니다. 문제는 고객이탈여부를 예측 분류하는 사례를 사용합니다. 본 예제의 기본 템플릿은 머신러닝 모델을 학습하고, 모델을 모델 레지스트리에 등록하고, 담당자의 매뉴얼 승인 후에 자동으로 모델을 테스트하고 배포하는 CI/CD 과정을 제공할 것입니다.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 빌드, 학습, 배포를 위한 MLOps 템플릿\n", "\n", "먼저 빌드, 학습, 배포를 위한 MLOps 템플릿이 실행될 때 어떤 AWS 서비스가 실행되는지 자세히 살펴보겠습니다. 그리고 이어지는 단계에서 이 기본코드를 커스터마이징하는 방법에 대해야 논의하겠습니다.\n", "\n", "SageMaker Project를 시작하기 위해 먼저 [SageMaker Studio console에서 활성화](https://docs.aws.amazon.com/sagemaker/latest/dg/sagemaker-projects-studio-updates.html)가 진행되어야 합니다.\n", "\n", "기존에 SageMaker Studio 사용자가 있을 경우 아래 설정을 변경하고 새롭게 사용자를 생성하는 경우 아래 설정을 활성화하여 생성합니다.\n", "\n", "\n", "\n", "위 활성화에 의해 아래 그림과 같이 SageMaker Studio 내의 “Components and registries” 탭에서 \"Projects\"를 선택할 수 있습니다.\n", "\n", "\n", "\n", "프로젝트 페이지에서, SageMaker에서 미리 제공되는 MLOps 템플릿을 론칭할 수 있습니다. 빌드&학습, 배포, 또는 빌드&학습/배포 템플릿을 선택합니다.\n", "\n", "\n", "\n", "주의: 이 템플릿을 실행하는 경우 디폴트로 회귀모델을 학습하는 파이프라인 작업이 시작됩니다. 이 작업은 약간의 비용을 발생시킵니다. \n", "\n", "MLOps 템플릿으로부터 프로젝트가 실행되고 나면 다음 아키텍처가 배포됩니다. \n", "\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 커스텀 유즈케이스를 위해 샘플코드 수정 \n", "\n", "프로젝트가 생성되고 나면 위 아키텍처의 서비스가 배포되고 SageMaker Studio의 파이프라인 드롭다운 메뉴에서 파이프라인이 보일 것입니다. \n", "\n", "실행된 템플릿에서 제공되는 샘플코드를 수정하기 위해 AWS CodeCommit 레포지토리의 소스코드를 로컬 SageMaker Studio 인스턴스로 복제(clone)하겠습니다. 방금 생성한 프로젝트 리스트에서 \"Repositories\"탭에 있는 하이퍼링크를 선택하면 샘플코드가 로컬로 복제됩니다. \n", "\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### ModelBuild Repo\n", "\n", "\"ModelBuild\" 리포지토리는 데이터 전처리, 학습, 그리고 모델 평가를 위한 코드를 포함하고 있습니다. 이 샘플코드는 [UCI Abalone dataset](https://archive.ics.uci.edu/ml/datasets/abalone) 데이터를 사용하여 모델을 학습하고 평가합니다. 이제 이 코드를 고객이탈여부를 분류하는 유즈케이스로 수정합니다.\n", "\n", "\n", "\n", "프로젝트를 위한 데이터셋 준비가 필요합니다. 가장 간단한 방법으로 다음 셀의 코드를 SageMaker notebook에서 오픈하고 실행할 수 있습니다.\n" ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "```\n", "!aws s3 cp s3://sagemaker-sample-files/datasets/tabular/synthetic/churn.txt ./\n", "```\n", "\n", "```\n", "import os\n", "import boto3\n", "import sagemaker\n", "prefix = 'sagemaker/DEMO-xgboost-churn'\n", "region = boto3.Session().region_name\n", "default_bucket = sagemaker.session.Session().default_bucket()\n", "role = sagemaker.get_execution_role()\n", "\n", "RawData = boto3.Session().resource('s3')\\\n", ".Bucket(default_bucket).Object(os.path.join(prefix, 'data/RawData.csv'))\\\n", ".upload_file('./churn.txt')\n", "\n", "print(os.path.join(\"s3://\",default_bucket, prefix, 'data/RawData.csv'))\n", "```" ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "### 빌드코드 및 파이프라인 수정하기\n", "\n", "로컬로 복제된 소스코드에서 `pipelines/abalone` 디렉토리를 `pipelines/customer_churn`으로 변경합니다. [예제 빌드스펙](modelbuild/codebuild-buildspec.yml)의 15번 라인을 참고하여 복제한 소스의 `codebuild-buildspec.yml`파일 내용도 수정합니다. \n", "\n", "다음으로 `preprocess.py`, `evaluate.py`, `pipeline.py` 파일을 `modelbuild/pipelines/customer_churn` 디렉토리의 파일로 교체합니다.\n", "\n", "**주의: 파이프라인 실행시 사용할 데이터셋을 지정하는 \"InputDataURL\" 파라미터의 디폴트값을 위 코드를 통해서 업로드한 S3 경로로 수정해야 합니다 **\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## git commit을 통해 새로운 파이프라인 실행하기 \n", "\n", "방금 수정한 변경을 AWS CodeCommit 레포지토리로 제출하면 (SageMaker Studio 소스코드탭에서 가능합니다.) EventBridge의 commit 이벤트 모니터링에 따라 새로운 SageMaker 파이프라인이 실행될 것입니다. 얼마의 시간이 지나면 SageMaker Project에서 파이프라인을 선택하고 실행상태를 모니터링할 수 있습니다. \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "파이프라인 작업이 완료되면 SageMaker Project에서 \"Model groups\" 탭으로 이동하고 모델 아티팩트에 연결된 메타데이트를 살펴봅니다. 내용에 이상이 없다면 모델을 승인합니다. \n", "\n", "\n", "\n", "\n", "\n", "이 승인작업은 ModelDeploy 파이프라인을 실행하고 실시간 추론을 위한 엔드포인트를 생성하게 됩니다. \n", "\n", "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## SDK를 이용하여 새로운 파이프라인 실행하기\n", "\n", "또는 다른 방식으로 SageMaker SDK를 이용하여 파이프라인을 생성하고 실행할 수 있습니다. 템플릿에서 생성한 (또는 본 예제코드의) pipeline.py파일의 `get_pipeline` 을 이용하여 여러분의 노트북에서 직접 실행하고 사용할 수 있습니다. \n" ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "```\n", "# This is the module name or the path to your pipeline.py file.\n", "from pipelines.customer_churn.pipeline import get_pipeline\n", "\n", "model_package_group_name = f\"CustomerChurnPackageGroup\"\n", "pipeline_name = f\"CustomerChurnDemo-p-ewf8t7lvhivm\"\n", "\n", "\n", "# These variables were defined the IAM role.\n", "pipeline = get_pipeline(\n", " region=region,\n", " role=role,\n", " default_bucket=default_bucket,\n", " model_package_group_name=model_package_group_name,\n", " pipeline_name=pipeline_name,\n", ")\n", "```" ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "### SageMaker 파이프라인 제출하고 실행하기\n", "\n", "정의한 파이프라인 워크플로우를 제출합니다. 전달된 역할(role)은 워크플로우가 단계별로 정의된 작업을 실행하고 자원을 생성하는데에 사용될 것입니다.\n", "\n", "```\n", "pipeline.upsert(role_arn=role)\n", "execution = pipeline.start()\n", "\n", "execution.describe()\n", "execution.wait()\n", "```" ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "### 파라미터기반 실행 \n", "\n", "생성한 파이프라인을 다른 파라미터값을 이용하여 다시 실행할 수 있습니다. 파라미터정보는 딕셔너리 형태로 파라미터이름과 값을 지정하여 전달하면 디폴트값을 오버라이드하게 됩니다.\n", "\n", "모델의 성능에 따라 이번에는 컴퓨팅최적화된 인스턴스 타입을 이용하여 파이프라인을 실행하고 승인 상태를 자동으로 \"Approved\"로 설정하고 싶다면 다음 셀의 코드를 실행할 수 있습니다. 모델의 승인상태가 \"Approved\"라는 의미는 RegisterModel 단계에서 패키지버전이 등록될 때 자동으로 CI/CD 파이프라인에 의해 배포가능한 상태가 된다는 것을 의미합니다. 이후 배포파이프라인은 SageMaker project를 통하여 자동화할 수 있습니다.\n", "\n", "\n", "```\n", "# Note: You can change the ModelApprovalStatus to \"PendingManualApproval\". This is the default set in the pipeline.py file.\n", "\n", "execution = pipeline.start(\n", " parameters=dict(\n", " ProcessingInstanceType=\"ml.c5.xlarge\",\n", " ModelApprovalStatus=\"Approved\",\n", " )\n", ")\n", "\n", "\n", "execution.wait()\n", "execution.list_steps()\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "instance_type": "ml.t3.medium", "kernelspec": { "display_name": "Python 3 (Data Science)", "language": "python", "name": "python3__SAGEMAKER_INTERNAL__arn:aws:sagemaker:us-east-2:429704687514:image/datascience-1.0" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.10" }, "pycharm": { "stem_cell": { "cell_type": "raw", "metadata": { "collapsed": false }, "source": [] } } }, "nbformat": 4, "nbformat_minor": 4 }