Amazon Web Services 한국 블로그

Amazon SageMaker Neo – 다양한 하드웨어를 위한 기계학습 모델 컴파일러

기계 학습(Machine Learning)은 훈련(Training)과 추론(Inference)의 두 가지 단계로 나뉩니다. 훈련은 모델 구축과 관련됩니다. 즉, 데이터 세트에서 ML 알고리즘을 실행하여 유의미한 패턴을 식별합니다. 이 프로세스에는 다량의 스토리지와 컴퓨팅 파워가 필요하기 때문에 클라우드에서 Amazon SageMakerAWS Deep Learning AMI 같은 서비스를 사용하여 ML 작업을 훈련하는 것이 적절합니다.

추론은 모델 사용과 관련됩니다. 즉, 모델이 한 번도 보지 못한 데이터 샘플의 결과를 예측합니다. 추론의 요구 사항은 훈련과 다릅니다. 일반적으로 개발자는 지연 시간(단일 예측에 소요되는 시간) 및 처리량(동시에 실행할 수 있는 예측의 수)을 최적화하는 데 중점을 둡니다. 물론 이러한 지표에는 예측 환경의 하드웨어 아키텍처가 지대한 영향을 미칩니다. 리소스가 제한된 디바이스를 다룰 때는 특히 더 그렇습니다. 저는 Raspberry Pi를 많이 사용하지만, 추론 코드를 빠르게 실행하기에는 성능이 약간 아쉬울 때가 종종 있습니다.

특정 하드웨어 아키텍처에 적합하게 모델을 튜닝할 수는 있지만 도구가 없으면 튜닝 프로세스에서 오류가 많이 발생하고 시간이 오래 걸립니다. ML 프레임워크 또는 모델 자체를 조금만 변경하려고 해도 처음부터 다시 시작해야 하는 게 일반적입니다. 이로 인해 대부분의 ML 개발자는 기반 하드웨어에 대한 고려 없이 어디에나 동일한 모델을 배포하게 되는데 이렇게 하면 중요한 성능 이점을 얻지 못합니다.

이제 그러한 문제를 끝낼 때가 왔습니다. 오늘 Amazon SageMaker의 새로운 기능인 Amazon SageMaker Neo가 발표됩니다. Amazon SageMaker Neo를 사용하면 기계 학습 모델을 한 번 훈련한 후 클라우드와 엣지의 모든 위치에서 최적의 성능으로 실행할 수 있습니다.

Amazon SageMaker Neo 소개

Amazon SageMaker Neo는 Amazon EC2 인스턴스, Amazon SageMaker 엔드포인트 및 AWS Greengrass로 관리되는 디바이스에 배포된 모델을 수동 개입 없이 최적화합니다.

지원되는 구성은 다음과 같습니다.

  • 프레임워크 및 알고리즘: TensorFlow, Apache MXNet, PyTorch, ONNX 및 XGBoost
  • 하드웨어 아키텍처: 현재 ARM, 인텔 및 NVIDIA를 지원하며 곧 Cadence, Qualcomm 및 Xilinx 하드웨어를 지원할 예정입니다. 또한 Amazon SageMaker Neo는 Apache Software 라이선스 아래 오픈 소스 코드로 릴리스되므로 하드웨어 벤더에서 자체 프로세서 및 디바이스를 사용자 지정할 수 있습니다.

Amazon SageMaker Neo 컴파일러는 모델을 효율적인 공통 형식으로 변환합니다. 이 형식은 일반 프레임워크가 소모하는 리소스의 1/100 미만을 사용하는 컴팩트 런타임으로 디바이스에서 실행됩니다. Amazon SageMaker Neo 런타임은 ML 추론을 가속화하는 특정 명령어 세트를 사용하여 기반 하드웨어에 맞게 최적화됩니다.

여기서 다음과 같은 3가지 이점을 얻을 수 있습니다.

  • 변환된 모델은 정확성을 그대로 유지하면서 최대 두 배 빠른 속도로 작동합니다.
  • 거의 모든 리소스 제약 디바이스에서 정교한 모델을 실행할 수 있으므로 자율 차량, 자동 비디오 보안 및 제조 시 이상 감지 같은 혁신적인 사용 사례를 자유롭게 구현할 수 있습니다.
  • 개발자는 대상 하드웨어에서 프레임워크에 종속되지 않고 모델을 실행할 수 있습니다.

내부 작동 원리

대부분의 기계 학습 프레임워크는 모델을 계산 그래프로 표현합니다. 꼭짓점은 데이터 어레이(텐서)의 연산을 나타내고 모서리는 연산 간의 종속성을 나타냅니다. Amazon SageMaker Neo 컴파일러는 계산 그래프의 패턴을 활용하여 고급 최적화를 적용합니다. 예를 들어 다수의 작은 연산을 하나로 결합하는 연산자 결합, 그래프의 일부를 정적으로 미리 계산해 실행 비용을 절감하는 상수 폴딩, 각 중간 텐서를 유지할 메모리를 미리 할당하는 정적 메모리 계획 전달 및 내부 데이터 레이아웃을 하드웨어 친화적 형태로 변환하는 데이터 레이아웃 변환 같은 최적화가 적용됩니다. 그런 다음 각 연산자에 대한 효율적인 코드를 생성합니다.

모델이 컴파일되면 Amazon SageMaker Neo 런타임으로 실행할 수 있습니다. 이 런타임에는 주요 딥 러닝 라이브러리에 필요한 500MB~1GB와 비교되는 약 1MB의 디스크 공간이 소요됩니다. 애플리케이션이 런타임을 로드하여 모델을 호출하면 런타임이 모델 정의, 모델 파라미터 및 미리 컴파일된 연산을 로드합니다.

Raspberry Pi에서 이 동작을 확인해 볼 수 있습니다. 이제 작업을 시작합니다.

기 훈련된 모델 다운로드

Apache MXNet, Gluon CV 또는 TensorFlow 모델 모음에서 다수의 미리 훈련된 모델을 사용할 수 있습니다. 이 게시물에서는 ResNet 아키텍처 기반의 50계층 모델을 사용합니다. 이 모델은 ImageNet 데이터 세트에서 Apache MXNet으로 미리 훈련되었습니다.

먼저, 227MB 모델과 다양한 계층을 정의하는 JSON 파일을 다운로드합니다. 이 파일은 특히 중요합니다. 이 파일을 보면 입력 기호가 ‘data’이고 셰이프는 [1, 3, 224, 224]인 것을 알 수 있습니다. 이는 1개 이미지, 3개 채널(빨간색, 녹색, 파란색), 224×224픽셀을 나타냅니다. 이 정확한 셰이프를 가진 모델로 이미지를 전달해야 합니다. 출력 셰이프는 [1, 1000]입니다. 즉, 1,000개 클래스의 각 클래스에 대한 확률을 포함하는 벡터가 ImageNet 데이터 세트에 나타납니다.

성능 기준을 정의하려면 이 모델과 Apache MXNet 1.2의 최적화되지 않은 일반 버전을 사용하여 몇 가지 이미지를 예측합니다. 평균적으로 추론에는 약 6.5초가 소요되며 약 306MB의 RAM이 필요합니다.

지금은 속도가 꽤 느리지만 모델 컴파일을 통해 얼마나 빨라지는지 확인해 보겠습니다.

Raspberry Pi에 대한 모델 컴파일

먼저, 두 모델 파일을 압축된 TAR 아카이브에 저장하고 Amazon S3 버킷에 업로드합니다.

$ tar cvfz model.tar.gz resnet50_v1-symbol.json resnet50_v1-0000.params
a resnet50_v1-symbol.json
a resnet50_v1-0000.paramsresnet50_v1-0000.params
$ aws s3 cp model.tar.gz s3://jsimon-neo/
upload: ./model.tar.gz to s3://jsimon-neo/model.tar.gz

컴파일 작업에 사용할 단순한 구성 파일을 작성합니다. 다른 프레임워크 및 하드웨어 대상에 대해 호기심이 생긴다면 ‘aws sagemaker create-compilation-job help‘에서 정확한 구문을 확인하여 사용할 수 있습니다.

{
    "CompilationJobName": "resnet50-mxnet-raspberrypi",
    "RoleArn": $SAGEMAKER_ROLE_ARN,
    "InputConfig": {
        "S3Uri": "s3://jsimon-neo/model.tar.gz",
        "DataInputConfig": "{\"data\": [1, 3, 224, 224]}",
        "Framework": "MXNET"
    },
    "OutputConfig": {
        "S3OutputLocation": "s3://jsimon-neo/",
        "TargetDevice": "rasp3b"
    },
    "StoppingCondition": {
        "MaxRuntimeInSeconds": 300
    }
}

컴파일 프로세스는 단일 명령으로 시작됩니다.

$ aws sagemaker create-compilation-job --cli-input-json file://job.json

몇 초 안에 컴파일이 완료됩니다. 컴파일 아티팩트의 이름을 확인하고 Amazon S3에서 가져와 로컬로 추출합니다.

$ aws sagemaker describe-compilation-job \
--compilation-job-name resnet50-mxnet-raspberrypi \
--query "ModelArtifacts"
{
"S3ModelArtifacts": "s3://jsimon-neo/model-rasp3b.tar.gz"
}
$ aws s3 cp s3://jsimon-neo/model-rasp3b.tar.gz .
$ tar xvfz model-rasp3b.tar.gz
x compiled.params
x compiled_model.json
x compiled.so

보시다시피 아티팩트에는 다음이 포함됩니다.

  • 원본 모델과 기호 파일
  • 컴파일되고 하드웨어에 최적화된 후 모델에 사용되는 연산자를 저장하는 공유 객체 파일

편의를 위해 ‘model.params’, ‘model.json’ 및 ‘model.so’로 이름을 바꾼 후 Raspberry pi의 ‘resnet50’ 디렉터리에 복사하겠습니다.

$ mkdir resnet50
$ mv compiled.params resnet50/model.params
$ mv compiled_model.json resnet50/model.json
$ mv compiled.so resnet50/model.so
$ scp -r resnet50 pi@raspberrypi.local:~

Raspberry Pi에서 추론 환경 설정

모델을 사용하여 이미지를 예측하려면 먼저 Raspberry Pi에 적절한 런타임을 설치해야 합니다. 미리 구축된 패키지([neopackages])를 사용할 수 있습니다. ‘armv7l’ 아키텍처에 대한 패키지를 다운로드하고 제공된 스크립트를 사용해 Pi에 설치합니다. 추가 딥 러닝 프레임워크(이 경우 Apache MXNet)를 설치할 필요가 없으므로 최대 1GB의 영구 스토리지가 절약됩니다.

$ scp -r dlr-1.0-py2.py3-armv7l pi@raspberrypi.local:~
<ssh to the Pi>
$ cd dlr-1.0-py2.py3-armv7l
$ sh ./install-py3.sh

설정이 끝났습니다. 이제 이미지를 예측할 수 있습니다.

SageMaker Neo 런타임 사용

Pi에서 런타임은 ‘dlr’(deep learning runtime)이라는 이름의 Python 패키지로 제공됩니다. 이 런타임을 사용하여 이미지를 예측할 때 예상되는 동작은 다음과 같습니다.

  • 모델을 로드하고 입력 및 출력 기호 정의
  • 이미지 로드
  • 예측!

해당하는 Python 코드는 다음과 같습니다.

import os
import numpy as np
from dlr import DLRModel

# Load the compiled model
input_shape = {'data': [1, 3, 224, 224]} # A single RGB 224x224 image
output_shape = [1, 1000]                 # The probability for each one of the 1,000 classes
device = 'cpu'                           # Go, Raspberry Pi, go!
model = DLRModel('resnet50', input_shape, output_shape, device)

# Load names for ImageNet classes
synset_path = os.path.join(model_path, 'synset.txt')
with open(synset_path, 'r') as f:
    synset = eval(f.read())

# Load an image stored as a numpy array
image = np.load('dog.npy').astype(np.float32)
print(image.shape)
input_data = {'data': image}

# Predict 
out = model.run(input_data)
top1 = np.argmax(out[0])
prob = np.max(out)
print("Class: %s, probability: %f" % (synset[top1], prob))

다음 이미지에 예측을 시도해 보겠습니다. Raspberry Pi와 잘 어울리는 치와와입니다.



(1, 3, 224, 224)
Class: Chihuahua, probability: 0.901803

예측은 맞았지만 속도와 메모리 사용량은 어떨까요? 이 예측에는 약 0.85초가 소요되고 약 260MB의 RAM이 필요합니다. Amazon SageMaker Neo를 사용하면 일반 모델을 사용할 때보다 속도가 5배 더 빨라지고 RAM 효율성이 15%개선됩니다.

복잡하고 시간 소모적인 작업 없이 모델을 컴파일하는 것 만으로 이와 같은 엄청난 성능 이점을 얻었습니다. 물론 이러한 성능 이점은 모델 및 하드웨어 아키텍처에 따라 다르겠지만 Amazon EC2 인스턴스(예: C5 또는 P3 패밀리)를 포함하여 전반적인 성능이 크게 개선되었다는 것이 중요합니다.

지금 이용 가능

이 게시물에서 유용한 정보를 얻으셨습니까? Amazon SageMaker Neo를 사용한 모델 컴파일은 무료이며 모델을 사용하는 기반 리소스(Amazon EC2 인스턴스, Amazon SageMaker 인스턴스 및 AWS Greengrass로 관리되는 디바이스)에 대한 요금만 지불하면 됩니다.

이 서비스는 오늘부터 미국 동부(버지니아 북부), 미국 서버(오레곤) 및 EU(아일랜드)에서 사용할 수 있습니다. 서비스를 살펴보고 의견을 공유해 주십시오. 이 서비스를 사용해 혁신적인 모델을 구축할 수 있기를 바랍니다.

Julien;