[AWS] Lambda와 API Gateway를 이용한 Amazon SageMaker 모델 엔드포인트 호출하기

노라에몽·2023년 4월 8일
1

AWS

목록 보기
2/3

📝서론

CloudWatch 메트릭을 통해 확인할 수 있는 SageMaker의 엔드포인트 지표는 ModelLatencyOverheadLatency 이 있습니다. 오늘은 OverheadLatency를 줄일 수 있는 방법에 대해서 작성해보려고 합니다.

OverheadLatency가 길어지는 이유

OverheadLatency는 SageMaker 오버헤드가 있는 호출 요청에 응답하는 데 걸리는 시간입니다. 이는 SageMaker가 요청을 수신한 시점부터 응답을 반환할 때까지의 기간에서 ModelLatency를 뺀 값입니다.

문서 : https://docs.aws.amazon.com/ko_kr/sagemaker/latest/dg/monitoring-cloudwatch.html#cloudwatch-metrics-endpoint-invocation

간단하게 말하면 OverheadLatency는 SageMaker가 특정 요청에 대하여 응답하는 시간이라고 할 수 있습니다. 이 Latency가 생기는 이유에는 여러가지 원인이 있을 수 있습니다.

  • 요청 인증 또는 권한 부여
  • 요청 및 응답의 페이로드 크기
  • 요청 빈도가 적을 때

따라서 이러한 Cold Start를 방지하기 위해서 dummy 호출을 통해 pre-warming을 할 수 있습니다. 오늘은 Lambda와 API Gateway를 이용하여 endpoint를 호출하는 과정을 정리해보도록 하겠습니다.

🤜 본론

SageMaker notebook instance 생성하기

사용할 notebook instance를 하나 생성해줍니다. 아래와 같이 'create notebook instance' 버튼을 눌러 쉽게 생성할 수 있습니다.

'Open Jupyter' 버튼을 누르면 Jupyter notebook 화면을 볼 수 있습니다.

endpoint 생성하기

저는 사전에 구축해둔 모델이 있어서 해당 모델을 사용하도록 하겠습니다. SageMaker notebook의 Jupyter 환경을 열면 아래와 같이 사용해볼 수 있는 sample notebook 파일들이 있습니다. 이를 테스트로 이용해보는 것도 좋을 것 같습니다.

생성된 엔드포인트의 이름을 확인해줍니다. 메모장 어딘가에 복사 붙여넣기를 해두는 것이 좋겠습니다.

Lambda 함수 생성하기

lambda 콘솔에 접속하여, 'Create Function' 버튼을 누른 뒤 함수 이름, Runtime등을 설정해줍니다. 이미 생성해둔 Execution Role이 있지만 혼동을 방지하기 위해 새로 생성해줍니다.

함수가 생성 완료 되면, Configuration 탭으로 들어가 Execution role을 확인해줍니다. 이때, 이 Execution Role에는 SageMaker Endpoint를 호출해주는 Action인 'InvokeEndpoint'에 대한 권한이 존재하지 않을 것이기 때문에, 직접 policy를 작성해준 후 추가해줄 것입니다.

다음 내용을 갖는 정책을 생성해준뒤, 이용할 role에 attach 해줍니다.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": "sagemaker:InvokeEndpoint",
            "Resource": "*"
        }
    ]
}

attach가 잘 되었습니다. 이제 Lambda 콘솔로 다시 돌아가, 다음과 같이 코드를 붙여넣어줍니다.

import os
import io
import boto3
import json
import csv

ENDPOINT_NAME = os.environ['ENDPOINT_NAME']
runtime= boto3.client('runtime.sagemaker')

def lambda_handler(event, context):
    print("Received event: " + json.dumps(event, indent=2))
    
    data = json.loads(json.dumps(event))
    payload = data['data']
    print(payload)
    
    response = runtime.invoke_endpoint(EndpointName=ENDPOINT_NAME,
                                       ContentType='text/csv',
                                       Body=payload)
    print(response)
    result = json.loads(response['Body'].read().decode())
    
    return result

Configuration 탭에서 아까 복붙해둔 Endpoint 이름을 환경변수로 지정해줍니다. Key 부분에는 ENDPOINT_NAME, Value 부분에는 Endpoint의 이름을 다음과 같이 넣어준 뒤 Save 버튼을 누릅니다.

Lambda 콘솔에서 deploy 버튼을 눌러 함수를 update 해줍니다.

API Gateway

API Gateway란?

말 그대로 '대문'의 역할을 합니다. 통신시 사용하는 API들을 유지 관리, 모니터링, 생성할 수 있습니다. API Gateway를 이용하면 client가 요청을 보낼 때 API Gateway로 요청을 보내고, 유저의 설정에 맞추어 특정 서비스의 Endpoint로 전달되며 다시 응답을 client에게 보내주는 proxy 역할을 합니다.

문서 : https://docs.aws.amazon.com/ko_kr/apigateway/latest/developerguide/welcome.html

아래와 같이 REST API를 빌드해줍니다.

Protocol을 REST로 골라준 뒤, API 이름을 적어줍니다.

Actions 탭에서 Create Method 버튼을 누른 뒤 'POST'로 선택해줍니다.

아래와 같이 Lambda function을 선택하고, 우리의 Lambda function이 위치한 리전과 Lambda의 이름을 적어줍니다. Save 버튼을 눌러줍니다.

이후 Action 탭에서 Deploy API를 해줍니다. New Stage를 선택해주며, Stage 이름을 정해주세요. 이후 Deploy 버튼을 누르면, invoke url이 등장합니다. 이 친구 역시 메모장에 복사 붙여놓기 해야겠습니다.

Postman 이용해 테스트하기

이제 마지막 단계인 테스트 단계만 남았습니다. Postman을 이용하여 엔드포인트를 호출해봅시다.
Postman 다운로드 : https://www.postman.com/downloads/

Access Key, Secret Key

위와 같이 Method는 POST로 선택해주며, Authorization 탭에서 AWS AccessKey, SecretKey, 해당 리전을 입력해줍니다. POST 부분에는 아까 복사 붙여놓기 해둔 Invoke url을 붙여넣기 해줍니다.

다음으로 데이터에서 한 줄을 긁어 옵니다. raw를 택하여 위와 같이 긁어온 데이터를 붙여넣기 해주고, send 버튼을 눌러 결과를 확인해줍니다. 결과가 잘 출력됩니다.


Lambda와 API Gateway를 이용하여 SageMaker endpoint를 호출하는 방법에 대하여 정리해보았습니다. SageMaker 왕초보는 앞으로의 나날들이 매우 걱정되는데요. 또 새롭게 알아야 하는 내용들이 생기면 정리해볼 수 있도록 하겠습니다. 감사합니다.

profile
대나무 헬리콥터

0개의 댓글