SageMaker 개요

    목차
반응형

SageMaker란?

완전관리형 기계 학습 서비스로 데이터 전처리부터 학습, 배포까지 수행할 수 있도록 지원하고 있다.

 

SageMaker에서 분석하기

SageMaker에서는 jupyter lab용 EC2를 생성할 수 있으며 크게 두 가지 방법이 있다.

 

노트북 인스턴스

  • SageMaker 콘솔 - 노트북 - 노트북 인스턴스에서 생성

  • 노트북 인스턴스 생성에서 필요에 따라 인스턴스 종류를 선택할 수 있다.
    • 생성 후에도 인스턴스 종류는 바꿀 수 있다.

  • 시작을 누르면 인스턴스가 가동이 되고, InService가 되면 그 때부터 사용한 시간만큼 과금이 된다. 본인에게 편한대로 Jupyter (Notebook)이나 JupyterLab을 열면 된다.

 

 

SageMaker Studio

  • SageMaker 콘솔 - Studio

  • 도메인과 사용자 프로필 생성 필요
  • SageMaker Studio 열기를 하면 아래 이미지와 같은 홈 화면이 나오고, JupyterLab을 선택한다.

  • 우상단 Create JupyterLab Space 버튼을 클릭해 새로운 space를 생성한다.
  • 인스턴스 종류, 볼륨 사이즈 등을 설정할 수 있다.
    • 노트북 인스턴스와 마찬가지로 SageMaker Studio도 인스턴스 종류를 자유롭게 선택할 수 있다.

  • Run Space를 하고 Open하면 우리가 아는 JupyterLab을 사용할 수 있다.

 

[주의!] 노트북 인스턴스와 JupyterLab Space 모두 인스턴스를 종료하지 않으면 계속해서 과금이 되기 때문에 주의해야 한다.

 

 

SageMaker에서 모델 학습하고 배포하기

앞서 SageMaker에서 Jupyter 환경을 만들어 보았으나 실질적으로 모델을 학습하는 것은 Jupyter에서 하지 않는다. Jupyter는 EDA나 코드가 잘 작동하는지 정도만 확인하는 용도이며 대게 별도의 인스턴스에서 모델을 학습시킨다.

모델 학습 뿐만 아니라 데이터 전처리와 배포까지도 별도 인스턴스에서 진행할 수 있다. 모델 학습하는 인스턴스에서 데이터 전처리를 하는 것도 충분히 가능하지만 그렇게 하지 않는 이유는 특성에 맞는 인스턴스를 사용해서 비용을 절감해야 하기 때문이다.

예를 들어 딥러닝 모델을 학습하기 위해 GPU가 탑재된 인스턴스를 사용할 때, 이 인스턴스에서 데이터 전처리까지 수행하면 그 시간만큼 비용이 낭비된다. 또한 학습에 필요한 GPU 메모리보다 추론할 때 필요한 GPU 메모리는 훨씬 적기 때문에, 배포를 위해 굳이 높은 사양의 인스턴스를 쓸 필요가 없다. 따라서 SageMaker에서는 데이터 전처리, 모델 학습, 배포를 별도의 인스턴스에서 수행하는 게 일반적이다.

게다가 데이터 전처리와 모델 학습에 사용되는 인스턴스는 작업이 끝나면 자동으로 꺼지기 때문에 불필요한 과금을 막을 수 있다.

처리 중

  • 작업 처리 중: 데이터 전처리 등을 위한 작업 (processing_job)

 

훈련

  • 훈련 작업: 모델을 학습하는 작업 (training_job).
    • 훈련에 쓰였던 파라미터, 리소스(인스턴스 종류, 개수 등), 훈련 시간(과금 시간) 등 상세 내용을 확인할 수 있다.
    • 모니터링 - 로그 보기를 클릭하면 CloudWatch에서 훈련한 동안의 로그를 확인할 수 있다.
    • 훈련이 완료되면 S3에 `model.tar.gz`의 이름으로 모델 아티팩트가 저장된다.
      • (참고) 모델 아티팩트: 학습이 완료되어 덤프된 모델 파일(`.pkl`이나 `.joblib` 등)

 

추론

  • 모델: 데이터를 처리 및 예측하기 위한 코드, 모델 아티팩트 등 정보를 등록하여 관리
  • 엔드포인트 구성: 실제 배포를 하기 전에 사용할 모델, 리소스(인스턴스 종류 등)에 대한 정보, 추론을 수행하는 데 필요한 환경 변수 등 엔드포인트가 실행될 때 필요한 설정들을 정의
  • 엔드포인트: 모델을 호스팅하여 외부 애플리케이션에서 모델로 API를 통한 추론 요청을 보내어 결과를 전송함
    • 엔드포인트 종류에는 실시간, 배치, 비동기, 서버리스가 있다.
      • 실시간(Realtime): 인스턴스가 24시간 돌아가며, 계속해서 추론하거나 사용자가 많은 서비스에 이용하며 결과는 API 호출자에게 바로 전달된다.
      • 배치(Batch): 준비된 많은 양의 데이터에 대한 추론에 사용되며 결과는 S3에 저장된다. 사용한 만큼만 과금
      • 비동기(Asynchronous): 추론하는데 매우 오래 걸리는 모델에 사용하며, 결과는 S3에 저장된다. 특별한 설정을 하지 않는 한 인스턴스가 24시간 작동하여 비용이 많이 발생할 수 있다.
      • 서버리스(Serverless): 추론 빈도가 낮은 서비스에 주로 사용하며, 추론한 횟수만큼 비용이 과금되어 다른 엔드포인트 종류에 비해 저렴한 편이다. 단점은 사용할 수 있는 모델의 크기에 제한이 있고 GPU를 제공하지 않아 대용량 딥러닝 모델에는 부적합하다.

 

[주의!] 실시간이나 비동기 엔드포인트는 운영이 아닌 실험 단계에서 실험이 끝나면 반드시 삭제를 하여 불필요한 과금을 막도록 해야 한다.

 

정리하면 Jupyter에서 전처리, 훈련용 인스턴스를 생성하고 각 인스턴스에서 전처리와 훈련이 진행되고 결과는 S3에 저장되며, 그 데이터가 모델, 엔드포인트 구성까지 연결되고 엔드포인트에서 추론을 한다. 노란색으로 칠해진 부분이 개별 인스턴스를 갖는다.

 

[Note] Jupyter에서 로컬 모드를 켜서 Jupyter 인스턴스를 모델 학습에 사용할 수도 있다.
사용 방법: instance_type에 'local'을 넣으면 된다. (Sagemaker SDK만 가능)
사용하는 이유: 인스턴스를 켜는 데 길면 2~3분의 시간이 소모되는데, 로컬 모드로 하면 이미 켜져있는 인스턴스를 이용하기 때문에 시간을 절약할 수 있어 빠른 디버깅이 가능하다.

 

 

SageMaker SDK? boto3?

SageMaker에서 모델을 학습하는 방법에는 크게 두 가지가 있다.

  • SageMaker SDK
  • boto3

 

SageMaker SDK

SDK는 import sagemaker를 통하여 모델을 학습, 배포하는 방법으로 scikit-learn 등에 익숙한 `.fit`으로 학습을 진행할 수 있다는 장점이 있다. 또한 배포는 `.deploy`, 추론은 `.predict`로 쉽게 할 수 있다.

import sagemaker
from sagemaker.inputs import TrainingInput

sess = sagemaker.Session()
bucket = sess.default_bucket()

# 데이터 전처리 과정 생략

# 컨테이너 가져오기
container = sagemaker.image_uris.retrieve("xgboost", sess.boto_region_name, "1.7-1")

# train, validation 데이터 지정
s3_input_train = TrainingInput(
    s3_data="s3://{}/{}/train".format(bucket, prefix), content_type="csv"
)
s3_input_validation = TrainingInput(
    s3_data="s3://{}/{}/validation/".format(bucket, prefix), content_type="csv"
)


# XGBoost 모델에 대한 인스턴스 지정
xgb = sagemaker.estimator.Estimator(
    container,
    role,
    instance_count=1,
    instance_type="ml.m4.xlarge",
    output_path="s3://{}/{}/output".format(bucket, prefix),
    sagemaker_session=sess,
)

# XGBoost 하이퍼 파라미터 지정
xgb.set_hyperparameters(
    max_depth=5,
    eta=0.2,
    gamma=4,
    min_child_weight=6,
    subsample=0.8,
    verbosity=0,
    objective="binary:logistic",
    num_round=100,
)

# XGBoost 모델 학습
xgb.fit({"train": s3_input_train, "validation": s3_input_validation})


# 학습이 완료된 XGBoost 모델 배포
xgb_predictor = xgb.deploy(
    initial_instance_count=1, instance_type="ml.m4.xlarge", serializer=CSVSerializer()
)


# 모델로 예측
pred = xgb_predictor.predict(array).decode("utf-8")


# 배포한 모델 삭제
xgb_predictor.delete_endpoint()

컨테이너, 모델 배포 등 처음 보면 이해가 되지 않는 것도 있지만 xgb.fit, xgb_predictor.predict처럼 익숙한 모습도 확인할 수 있어 SageMaker를 통해 모델 학습과 배포를 배우는 첫걸음으로는 나쁘지 않다.
SageMaker Tutorial (Github)

 

 

 

boto3

`boto3`는 `import boto3`, `client = boto3.client('sagemaker')`로 sagemaker 클라이언트를 불러와서 명령을 내리는 구조다.

import boto3
client = boto3.client('sagemaker')

# 컨테이너 지정
container = f'000000000.dkr.ecr.ap-northeast-2.amazonaws.com/{algorithm_name}:{container_version}'

# 학습 파라미터 지정 (인스턴스 종류, 학습 데이터 경로, 하이퍼 파라미터 등)
create_training_params = {
    "AlgorithmSpecification": {"TrainingImage": container, "TrainingInputMode": "File"},
    "RoleArn": role,
    "OutputDataConfig": {"S3OutputPath": f"{output_bucket_path}/{output_prefix}/model"},
    "ResourceConfig": {"InstanceCount": 1, "InstanceType": "ml.m5.xlarge", "VolumeSizeInGB": 4},
    "TrainingJobName": training_job_name,
    "HyperParameters": {
        'max_depth':5,
        'eta':0.2,
        'gamma':4,
        'min_child_weight':6,
        'subsample':0.8,
        'verbosity':0,
        'objective':"binary:logistic",
        'num_round':100,
    },
    "StoppingCondition": {"MaxRuntimeInSeconds": 3600},
    "InputDataConfig": [
        {
            "ChannelName": "training",
            "DataSource": {
                "S3DataSource": {
                    "S3DataType": "S3Prefix",
                    "S3Uri": f"{output_bucket_path}/{output_prefix}/train",
                    "S3DataDistributionType": "FullyReplicated",
                }
            },
            "ContentType": "text/csv",
            "CompressionType": "None",
        },
    ],
}

# 모델 학습
client.create_training_job(**create_training_params)


# 모델 만들기
client.create_model(
    ModelName=model_name, ExecutionRoleArn=role, PrimaryContainer=primary_container
)

# 엔드포인트 구성 만들기 (serverless)
client.create_endpoint_config(
  EndpointConfigName=endpoint_config_name,
  ProductionVariants=[
      {
          "ModelName": model_name,
          "VariantName": "AllTraffic",
          "ServerlessConfig": {
              "MemorySizeInMB": 6144,
              "MaxConcurrency": 20
          }
      } 
  ]
)


# 엔드포인트 만들기 (배포)
client.create_endpoint(
    EndpointName=endpoint_name, EndpointConfigName=endpoint_config_name
)


# 추론
runtime_client = boto3.client("runtime.sagemaker")
response = runtime_client.invoke_endpoint(
    EndpointName=endpoint_name, ContentType="application/json", Body=payload
)

result = response["Body"].read()
result = result.decode("utf-8")
result = json.loads(result)


# 배포한 모델 삭제
client.delete_endpoint(
    EndpointName=endpoint_name
)

`sagemaker`보다 훨씬 파라미터 입력할 것도 많고 모델, 엔드포인트 구성도 직접 관리해 줘야 한다.
엔드포인트를 생성 및 모델 배포 - Amazon SageMaker

 

추천하는 건 boto3

그럼에도 `sagemaker`보다 `boto3`를 추천한다. 왜냐하면 `boto3`가 더 확장성이 있고 `sagemaker`가 편해보이기는 하지만 이런 단점들이 있다.

  • 노트북 인스턴스를 끄면 (당연하게도) `xgb_predictor`가 사라지기 때문에 모델 추론이 불가능해지며, 배포된 모델을 삭제하려면 콘솔에 들어가 직접 삭제해줘야한다.
    • 반면 `boto3`로 배포한 경우 추론 부분만 다시 호출하여 사용하면 언제든 추론이 되며, 삭제도 쉽게 가능하다.
  • 같은 이름의 엔드포인트가 있는 경우, 같은 이름으로 재배포(업데이트)가 불가능하다.
    • 반면 `boto3`로는 `update_endpoint`로 모델을 업데이트할 수 있다.
    • 이게 중요한 이유는, 보통 데이터 분석 모델이란 건 한 번 만들면 끝이 아니라 데이터가 쌓이면 계속해서 업데이트를 해줘야 한다. 모델 업데이트가 불가능한 SDK는 치명적일 수밖에 없다. 그나마 방법이 있다면 엔드포인트 삭제 후 재배포를 하는 것인데, 그 사이에 서비스가 유실된다는 사실을 피할 수 없다. (`boto3`의 `update_endpoint`는 유실 없이 계속 모델을 사용할 수 있다.)
  • `boto3`의 확장성을 따라잡을 수 없다.
    • 위에서 이야기했듯 모델은 계속해서 업데이트 해주어야 한다. 그럴 때마다 주피터를 들어가서 모델이 있는 폴더에 들어가서 열고 코드를 실행해주고... 를 수행하는 건 매우 비효율적이다.
    • 한편 EventBridge와 Lambda, StepFunction 등의 서비스를 이용하면 손쉽게 주기적인 배포를 할 수 있다. (MLOps의 첫발이라고도 할 수 있다.) Lambda에서는 `boto3`로 sagemaker를 호출하여 사용할 수 있기 때문에 확장성이 있다고 설명을 한 것이다.

 

 

`boto3`로 모델을 학습하고 배포하는 게 어렵긴 하지만 AWS Sagemaker Example Github를 보면서 직접 실습을 해보며 배우는 걸 추천한다.

728x90
반응형