BLOG

실무를 위한 테크실습 – SageMaker 처리를 사용한 추론 C ++ 모델
작성일: 2020-09-01

머신 러닝은 수십 년 전 등장했습니다.  Python으로 머신 러닝을 수행하기 전에는 Java 및 C ++와 같은 다른 많은 언어가 모델을 빌드하는 데 사용되었습니다. C ++ 또는 Java로 레거시 모델을 리팩토링을 하게 되면 많은 비용과 시간이 소요될 수 있습니다. 고객은 모델 추론을 더 빠르고 저렴한 비용으로 실행할 수 있도록 C ++의 레거시 모델을 클라우드로 가져오는 방법을 알아야 합니다.

 

Amazon SageMaker Processing은 완전 관리형 환경으로 처리 및 모델 평가 워크로드를 실행하기 위한 Amazon SageMaker의 새로운 기능입니다. Amazon SageMaker Processing을 사용하면 고객이 Amazon SageMaker에서 데이터 엔지니어링 및 모델 평가를 위한 분석 작업을 손쉽게 대규모로 실행할 수 있습니다. SageMaker Processing을 통해 고객은 Amazon SageMaker에 내장된 모든 보안 및 컴플라이언스를 통해 완전 관리형 환경의 이점을 누릴 수 있습니다.

 

이 블로그 게시물에서는 SageMaker 처리를 사용하여 C ++ 모델을 추론하는 방법을 보여줍니다. 먼저 간단한 선형 회귀 모델을 나타내는 데 사용하는 C ++ 프로그램과 추론을 실행하는 데 사용하는 Python 스크립트에 대해 설명합니다. 그런 다음 C ++ 모델과 Python 스크립트를 포함하는 사용자 지정 컨테이너를 빌드합니다. 마지막으로 ScriptProcessor추론을 위해 SageMaker 작업을 실행합니다. 이 게시물의 코드는 GitHub 저장소에서 사용할 수 있습니다.

 

 

전제 조건

이 코드를 실행하려면 Amazon S3에 액세스하고, Docker 이미지를 Amazon ECR에 푸시하고, SageMaker 처리 작업을 생성할 수 있는 권한이 있어야 합니다.

 

 

C ++ 모델 준비

데모 목적으로 간단한 C ++ 테스트 파일을 사용하겠습니다. 이 C ++ 프로그램은 쉼표로 구분된 일련의 문자열을 입력 데이터로 입력받습니다. 예를 들어, “2,3”은 두 개의 개별 열에서 2와 3으로 레이블이 지정된 입력 데이터 행을 나타냅니다.

 

이 블로그 게시물에서는 데모 목적으로 간단한 선형 회귀 모델 y = x1 + x2를 사용합니다. 고객은 C ++ 추론 코드를 수정하여 보다 현실적이고 정교한 모델을 추론할 수 있습니다. C ++ 코드는 다음 단계로 구성됩니다.

 

  • C ++ 명령 줄 매개 변수에서 추론할 데이터 레코드를 받습니다.
  • 데이터 열을 구문 분석하고 데이터를 C ++ 벡터에 저장합니다. “,”를 사용하여 데이터 열을 구분합니다.
  • 데이터 열을 반복하고 합계를 계산합니다.
  • 결과를 표준 출력 스트림으로 인쇄합니다.

 

g ++를 사용하여 C ++ 프로그램을 실행 파일로 컴파일할 수 있습니다. 전체 C ++ 스크립트는 다음 코드에 표시됩니다.

#include <sstream>

#include <iostream>

#include <string>

#include <vector>

#include <sstream>

#include <iostream>

using namespace std;

void print(std::vector<int> const &input)

{

    for (int i = 0; i < input.size(); i++)

    {

        std::cout << input.at(i);

        if (i!=input.size()-1)

            cout<< ‘,’;

    }

}

std::vector<std::string> split(const std::string& s, char delimiter)

{

   std::vector<std::string> tokens;

   std::string token;

   std::istringstream tokenStream(s);

   while (std::getline(tokenStream, token, delimiter))

   {

      tokens.push_back(token);

   }

   return tokens;

}

int main(int argc, char* argv[])

{

    vector<int> result;

    int counter = 0;

    int result_temp = 0;

    

    //assuming one argv

    string t1(argv[1]);

    vector<string> temp_str = split(t1, ‘,’);

    vector<string>::iterator pos;

    for (pos = temp_str.begin(); pos < temp_str.end(); pos++)

    {

        int temp_int;

        istringstream(*pos) >> temp_int;

       

        if (counter == 0)

        {

            result_temp += temp_int;

            counter++;

            continue;

        }

        if (counter == 1)

            result_temp += temp_int;

            result.push_back(result_temp);

            result_temp = 0;

            counter = 0;

    }   

    print(result);

    return 0;

}

 

 

SageMaker 처리 스크립트 생성

이 노트북은 Amazon SageMaker Python SDK의 ScriptProcessor 클래스를 사용합니다. ScriptProcessor 클래스는 입력 데이터를 처리하는 고유한 Docker 이미지로 Python 스크립트를 실행하고 처리된 데이터를 Amazon S3에 저장합니다. 자세한 내용은 자체 처리 컨테이너로 스크립트 실행을 검토하세요.

 

처리 작업이 시작되면 SageMaker가 S3에서 처리 컴퓨팅 인스턴스의 지정된 로컬 디렉터리로 데이터 파일을 자동으로 다운로드합니다.

 

Python스크립트인 process_script.py 먼저 /opt/ml/processing/input/디렉터리 아래의 모든 데이터 파일을 찾습니다. 기본적으로 여러 인스턴스를 사용하는 경우 S3의 데이터 파일이 각 처리 컴퓨팅 인스턴스에 복제됩니다. 즉, 모든 인스턴스가 전체 데이터 세트를 가져옵니다.  s3_data_distribution_type=’ShardedByS3Key’를 설정하면 각 인스턴스는 대략 총 입력 날짜 파일 수의 1/n를 가져옵니다. 여기서 n은 컴퓨팅 인스턴스 수입니다. 보다 효과적인 병렬 처리를 위해 입력 데이터를 여러 파일로 분할하여 각 노드가 서로 다른 입력 데이터 세트를 처리하도록 합니다.

 

Python 스크립트는 각 데이터 파일을 메모리로 읽고 C ++ 실행 파일이 사용할 수 있는 긴 문자열로 변환합니다. subprocess Python 의 모듈은 C ++ 실행 파일을 실행하고 출력 및 오류 파이프에 연결합니다. 출력은 CSV 파일로 /opt/ml/processing/output디렉토리에 저장됩니다. 완료되면 SageMaker Processing은 모든 Processing 인스턴스에서 Amazon S3로 이 디렉터리의 출력 파일을 업로드합니다.

def call_one_exe(a):

    p = subprocess.Popen([“./a.out”,

 a],stdout=subprocess.PIPE)

    p_out, err= p.communicate()

    output = p_out.decode(“utf-8”)

    return output.split(‘,’)

if __name__==’__main__’:

    parser = argparse.ArgumentParser()

    #user can pass their own argument from Processor.

   

    args, _ = parser.parse_known_args()

    print(‘Received arguments {}’.format(args))

   

    files = glob(‘/opt/ml/processing/input/*.csv’)

    for i, f in enumerate(files):

        try:

            print(f)

            data = pd.read_csv(f, header=None)

            string = str(list(data.values.flat)).replace(‘ ‘,”)[1:-1]

            predictions = call_one_exe(string)

            output_path = os.path.join(‘/opt/ml/processing/output’, str(i)+’_out.csv’)

            print(‘Saving training features to {}’.format(output_path))

            pd.DataFrame({‘results’:predictions}).to_csv(output_path, header=False, index=False)

        except Exception as e:

            print(str(e))

 

 

나만의 SageMaker 프로세싱 컨테이너 구축

처리 컨테이너는 다음 이미지와 같이 정의됩니다. 컨테이너에 Anaconda와 Pandas가 설치되어 있습니다. a.out모델 추론 논리를 포함하는 C ++ 실행 파일입니다. process_script.py는 C ++ 실행 파일을 호출하고 결과를 저장하는 데 사용하는 Python 스크립트입니다. C ++ 프로그램에 대한 자세한 내용은 process_script.py 뒤에서 설명하겠습니다. 이제 Docker 컨테이너를 빌드하고 Amazon ECR로 푸시하겠습니다. Dockerfile는 다음 코드와 같이 보입니다:

FROM ubuntu:16.04

RUN apt-get update && \

    apt-get -y install build-essential libatlas-dev git wget curl

RUN curl -LO http://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh && \

    bash Miniconda3-latest-Linux-x86_64.sh -bfp /miniconda3 && \

    rm Miniconda3-latest-Linux-x86_64.sh

ENV PATH=/miniconda3/bin:${PATH}

RUN conda update -y conda && \

    conda install -c anaconda scipy

# Python won’t try to write .pyc or .pyo files on the import of source modules

# Force stdin, stdout and stderr to be totally unbuffered. Good for logging

ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1 PYTHONIOENCODING=UTF-8 LANG=C.UTF-8 LC_ALL=C.UTF-8

RUN pip install –no-cache -I scikit-learn==0.20.0 pandas==1.0.3 boto3 sagemaker retrying

ADD process_script.py /

ADD a.out /

 

 

 

ScriptProcessor 스크립트 설정 및 실행

이 데모에는 10개의 샘플 데이터 파일이 포함되어 있습니다. 각 파일에는 임의로 생성된 데이터의 5000 행이 포함됩니다. 먼저 이러한 파일을 Amazon S3에 업로드합니다. 추론을 위해 ml.c5.xlarge 인스턴스 하나를 사용하겠습니다. 더 큰 데이터 세트의 경우 인스턴스 수를 늘려도 됩니다. 아마존 SageMaker 프로세싱은 다음 명령과 비슷한 방법으로 스크립트를 실행하며 EntryPoint는 process_script.py이고 ImageUri는 이전에 내장된 도커 이미지입니다.

docker run –entry-point [EntryPoint] [ImageUri]

SageMaker Processing 작업은 다음과 같이 설정됩니다.

role = get_execution_role()

script_processor = ScriptProcessor(command=[‘python3’],

                image_uri=Account_number + ‘.dkr.ecr.us-east-1.amazonaws.com/cpp_processing:latest’,

                role=role,

                instance_count=1,

                base_job_name = ‘run-exe-processing’,

                instance_type=’ml.c5.xlarge’)

output_location = os.path.join(‘s3://’,default_s3_bucket, ‘processing_output’)

script_processor.run(code=’process_script.py’,

                     inputs=[ProcessingInput(

                        source=input_data,

                        destination=’/opt/ml/processing/input’)],

                      outputs=[ProcessingOutput(source=’/opt/ml/processing/output’,

                                               destination=output_location)]

 

처리 작업이 시작되면 Amazon SageMaker에 작업 진행률이 표시됩니다.  Job Name, input및 output과 같은 정보들이 보고됩니다. 완료되면 아웃풋 몇 행을 검토하여 처리 작업이 성공했는지 확인할 수 있습니다.

 

print(‘Top 5 rows from 1_out.csv’)

!aws s3 cp $output_location/0_out.csv | head n5

 

 

결론

이 게시물에서는 Amazon SageMaker Processing을 사용하여 C ++ 모델에서 추론을 실행했습니다. 고객은 더 낮은 비용으로 더 빠른 추론을 위해 레거시 C ++ 모델을 SageMaker로 가져올 수 있습니다. 자세한 내용은 Amazon SageMaker 처리에서 확인하세요.

 

Field Notes는 고객을 위해 실제 비즈니스 문제를 해결하는 현장에서의 경험을 기반으로 AWS Solutions Architects, 컨설턴트 및 기술 계정 관리자의 실무 기술 지침을 제공합니다.

 

원문URL: https://aws.amazon.com/ko/blogs/architecture/field-notes-inference-c-models-using-sagemaker-processing/

** 메가존 클라우드 TechBlog는 AWS BLOG 영문 게재 글 중에서 한국 사용자들에게 유용한 정보 및 콘텐츠를 우선적으로 번역하여 내부 엔지니어 검수를 받아서, 정기적으로 게재하고 있습니다. 추가로 번역 및 게재를 희망하는 글에 대해서 관리자에게 메일 또는 SNS 페이지에 댓글을 남겨주시면, 우선적으로 번역해서 전달해드리도록 하겠습니다.