ML 모델 배포

snooby·2022년 11월 23일
5

🦾 ML

목록 보기
8/16
post-thumbnail

모델 배포

모델을 구축하고 철저한 테스트를 마치고 나면 모델을 배포할 수 있다.
모델을 운영환경에 배포하면 시스템 사용자가 생성한 쿼리를 처리하게 된다.
입력받은 쿼리는 특징벡터로 변환되고, 변환된 특징 벡터를 모델에 입력해서 채점하고 채점결과를 사용자에게 반환한다.

모델 배포는 머신러닝 프로젝트 수명주기의 여섯번째 단계이다.

배포 방법

훈련을 마친 모델은 다양한 방법으로 배포할 수 있다.

  • 설치 가능한 소프트웨어 패키지의 일부로 정적 방식 배포
  • 동적 방식으로 사용자 기기에 배포
  • 동적 방식으로 서버에 배포
  • 모델 스트리밍을 통해 배포

정적 배포

정적 배포는 기존 소프트웨어 배포와 매우 유사하다.
설치가능한 소프트웨어 바이너리를 준비하고, 런타임에 사용할 수 있는 리소스로 모델을 패키징한다. 운영 체제와 런타임 환경에 따라 모델과 특징 추출기 객체는 동적 연결 라이브러리, 공유 객체의 일부로 패키징하거나 자바와 .NET 같은 가상머신 기반 시스템 표준 리소스 위치에 직렬화하고 저장한다.

정적 배포 장점

  • 소프트웨어에서 모델을 직접 호출할 수 있으므로 사용자 입장에서 실행시간이 빠르다.
  • 예측시점에서 사용자가 데이터를 서버에 업로드할 필요가 없다. 따라서, 시간이 절약되고 개인 정보 보호가능
  • 사용자가 오프라인 상태일 때도 모델을 호출할 수 있다.
  • 소프트웨어 공급 업체는 모델의 운영 유지에 대해 신경 쓸 필요가 없다. 사용자가 책임진다.

정적 배포 단점

  • 머신러닝 코드와 에플리케이션 코드 구분 명확하지 않다.
    전체 애플리케이션을 업그레이드하지 않고는 모델을 업그레이드 하기 어렵다.
  • 모델 계산을 위한 특정한 요구사항이 있는 경우 정적 배포 가능 여부를 판단하기 복잡하다.

동적으로 사용자 기기에 배포

시스템의 일부를 사용자 기기에서 소프트웨어 응용 프로그램으로 실행한다는 점에서 기기에 동적으로 모델을 배포하는 것은 정적 배포와 유사하다. 동적 배포와 차이점은 애플리케이션과 모델의 코드가 분리되어 문제 발생 시 원인 규명이 쉽다. 또한, 업데이트 시 전체 애플리케이션을 업데이트하지 않고도 모델을 업데이트할 수 있다. 그리고 사용 가능한 컴퓨팅 자원에 따라 모델에 적합한 코드를 동적으로 배포할 수 있다.

동적 배포 방법

  • 모델 매개변수 배포
  • 직렬화된 객체 배포
  • 브라우저에 배포
  • 모델 매개변수 배포
    모델 파일에는 학습된 매개변수만 있고, 사용자 기기에는 모델의 런타임 환경이 설치되어 있다.

  • 직렬화된 객체 배포
    모델 파일은 직렬화된 객체이고 응용 프로그램 실행 중에 이를 역직렬화한다.
    이 방식의 장점은 사용자 기기에 모델을 위한 별도의 런타임 환경이 필요하지 않다. 필요한 모든 종속성은 모델 객체와 함께 역직렬화된다.

  • 브라우저에 배포
    TensorFlow.js와 같은 일부 머신러닝 프레임워크는 자바스크립트 런타임을 사용하므로 브라우저에서 모델을 학습시키고 실행할 수 있다.

    장점
    사용자가 모델을 빠르게 호출할 수 있다.
    조직의 공용 서버에 미치는 부하를 줄일 수 있다.

    단점
    애플리케이션 시작 시간이 늘어남. -> 웹 응용 프로그램을 시작할 때마다 모델의 매개변수를 다운로드해야 하기 때문이다.
    직렬화된 객체의 크기가 상당히 클 경우 업데이트 시간이 오래 걸리기 때문에 일부 사용자는 업데이트 도중 오프라인 상태가 될 수 있고 결과적으로 사용자 마다 모델 버전이 파편화되거 서버 측 부분을 업그레이드 하는 것도 어려워진다.
    모델 성능을 모니터링하기 어렵다.

    서버에 동적 배포

    가장 있기 있는 배포 패턴은 모델을 하나의 서버에 배포하고, 웹 서비스나 구글 원격 프로시저 호출 서비스 형태의 REST API로 제공하는 것이다.

  • 가상 머신에 배포
    클라우드 환경에 배포된 모델의 예측은 정형화된 형식의 HTTP 요청에 대한 응답으로 서빙됩니다.
    가상머신에서 실행되는 웹 서비스는 입력 데이터가 포함된 사용자 요청을 받아서 해당 입력 데이터로 머신러닝 시스템을 호출한 다음, 머신러닝 시스템의 출력을 JSON이나 XML 문자열로 변환된다.
    높은 부하량을 대처하기 위해 동일한 가상머신이 병렬로 실행된다.

    로드 밸런서는 가용성에 따라 수신요청을 특정 가상 머신으로 보낸다. 또한 사용량에 따라 가상머신을 시작하거나 종료하는 오토스케일링 그룹으로 관리할 수 있다.

    인스턴스에는 특징 추츨기와 모델을 실행하는 데 필요한 모든 코드가 포함되어 있고 해당 코드에 접근할 수 있는 웹 서비스도 포함되어 있습니다.

    장점
    소프트웨어 시스템의 아키텍처나 일반적인 웹 서비스나 gRPC 서비스와 같이 개념적으로 간단하다.

    단점
    가상화를 사용하는 경우 가상화와 여러 운영 체제 실행으로 인해 추가적인 컴퓨팅 비용이 발생한다.
    네트워크 지연 시간

    컨테이너에 배포

    가상머신 기반의 배포보다 최근에 나온 방법이 컨테이너 기반의 배포이다.
    컨테이너는 가상머신보다 자원효율적이고 유연하다.
    컨테이너는 자체 파일 시스템, CPU, 메모리, 프로세스 공간이 있는 격리된 런타임 환경이라는 점에서 가상머신과 유사하지만, 모든 컨테이너가 동일한 가상시스템이나 물리적 시스템에서 실행되고 운영체제를 공유하는 반면 각 가상머신은 별도의 운영체제 인스턴스를 실행한다는 차이점이 있다.

장점
컨테이너에 배포하면 가상 머신에 배포할 때보다 자원 효율성이 높다.
scale-to-zero 옵션을 제공하는데 유휴 상태일 때 컨테이너 개수를 0으로 줄이고 서비스 요청이 오면 컨테이너 개수를 다시 복구할 수 있다.

서버리스 배포

아마존, 구글을 포함한 여러 클라우드 서비스 제공 업체는 서버리스 컴퓨팅을 제공한다.
서버리스 배포를 위해 머신러닝 시스템을 실행하는 데 필요한 모든 코드가 포함된 zip 보관소를 준비한다.
클라우드 플랫폼은 서버리스 함수에 입력을 전달하는 API를 제공하는데, API를 통해 이름을 지정하고, 페이로드를 제공하고 결과를 얻는다. 클라우드 플랫폼은 컴퓨팅 자원에 맞게 코드와 모델을 배포하고 코드를 실행하고 출력을 다시 사용자에게 전달하는 책임이 있습니다.

장점
자원을 프로비저닝을 할 필요가 없다.
종속성 때문에 필요한 패키지를 설치하거나 시스템을 유지보수하거나 업그레이드할 필요가 없다.
확장성이 뛰어나기 때문에 초당 수천 개의 요청을 쉽게 처리할 수 있다.
동기 모드와 비동기 모드를 모두 지원한다.
비용 효율적이어서 컴퓨팅 사용 시간에 대해서만 비용을 지불하면 된다.

모델 스트리밍

모델 스트리밍은 REST API의 역과정으로 볼 수 있는 배포 패턴이다.
REST API에서 사용자는 서버에 요청을 보낸 다음 응답을 기다린다.

REST API 배포 패턴에 따르면 모델 하나당 REST API가 필요하다. 모든 모델과 이를 실행하는 데 필요한 코드가 스트림 처리 엔진에 등록된다.
스트리밍 예로는 아파치 스톰, 아파치 스파크, 아파치 플링크가 있고 때로는 아파치 삼자, 아파치 카프카 스트림과 같은 라이브러리를 통해 애플리케이션으로 패키징된다.

REST API. vs 스트리밍

  • REST API
    하나의 데이터 요소를 처리하기 위해 REST API를 사용하는 사용자는 일련의 요청을 하나씩 보내고 응답을 동기적으로 수신
  • 스트리밍
    하나의 데이터 요소를 처리하기 위해 스트리밍을 사용하는 사용자는 연결 설정 후 요청을 보내고 업데이트 이벤트가 발생하면 해당 이벤트를 수신

배포전략

단일 배포

아주 간단한 개념으로 새 모델이 있으면 새 모델로 파일로 직렬화한 다음 이전 파일을 새 파일로 바꾸는 것이다.

자동 배포

단일 배포와 달리 새 모델과 특정 추출기를 배포하면서 이전 버전도 유지한다. 즉 두 버전 모두 병렬로 실행하는 것이다. 그러나 전환이 완료될 때까지 사용자는 새 버전이 노출되지 않는다.

사용자에게 악영향을 미치지 않고 새 모델이 정상적으로 작동하는 지 충분히 테스트할 수 있다는 장점이 있다. 하지만 사용자에게 노출하지 않고는 새 모델을 평가하기 어렵다는 단점이 있다.

카나리 배포

카나리 배포나 카나리 작업을 새로운 버전의 모델과 코드는 소수의 사용자에게만 푸시하고 대부분 사용자는 이전 버전을 실행하는 것이다.

자동 배포와 달리 새 모델의 성능과 예측 효과를 검증할 수 있고, 단일 배포와 달리 버그가 발생할 경우 많은 사용자에게 영향을 미치지 않는다.
그러나 눈에 잘 띄지않는 오류를 발견하기 어렵다.

멀티 암드 밴딧

운영 환경에서 하나 이상의 모델 버전을 비교하고 가장 성능이 좋은 모델을 선택하는 방법이다.

모델이 중요한 구성요소이지만 모델만 단독으로 제공하지 않는다.
운영 환경에서 모델이 손상되지 않았는지 확인하기 위한 테스트할 수 있는 추가항목이 있습니다.

모델에 수반되는 항목

  • 모델 입력과 출력을 정의하는 종단 간 세트
  • 신뢰도 테스트 세트
  • 성능 지표
  • 성능 지표의 허용 가능한 값의 범위

모델을 적용한 시스템이나 서버나 사용자의 기기의 인스턴스가 처음 호출되면, 외부 프로세스에서 종단 간 테스트 데이터로 모델을 테스트하고 모든 예측이 올바른지 확인해야합니다.
또한 동일한 외부 프로세스에서 신뢰도 테스트 세트를 통해 모델의 성능 지표가 허용 가능한 값의 범위 내에 있는지 검증해야 합니다.

버전 동기화

  • 훈련 데이터
  • 특징 추출기
  • 모델

데이터를 업데이트할 때마다 데이터 저장소에 새로운 버전을 만들어야한다.
특정 버전의 데이터로 훈련한 모델은 해당 데이터의 버전과 동일한 버전으로 모델 저장소에 저장해야한다.

특징 추출기가 변경되지 않았더라도 데이터 및 모델과 동기화되도록 특징 추출기의 버전도 업데이트해야한다.
새로운 버전의 모델 배포는 트랜잭션 방식을 사용하여 스크립트로 자동화해야한다.

모델 버전관리를 위한 메타데이터

각 모델의 버전관리를 위해 코드, 메타데이터를 함께 제공해야한다.

  • 모델 훈련에 사용된 라이브러리와 패키지 이름과 버전
  • requirements.txt
  • 학습 알고리즘명, 하이퍼파라미터 이름과 값
  • 모델에 필요한 특징 목록
  • 출력물 목록, 유형, 사용방법
  • 모델 훈련에 사용된 데이터의 버전과 위치
  • 모델의 하이퍼파라미터를 조정하는 데 사용한 검증 데이터의 버전과 위치
  • 새 데이터로 모델을 실행하고 예측을 출력하는 모델 채점 코드

심층 모델 배포

필요한 속도를 얻기 위해 GPU 에서 채점을 할 수도 있다.
모델만 빠르게 채점할 수 있도록 최적화된 GPU가 있는 환경에 배포하고 나머지 애플리케이션은 CPU 환경에 배포한다.

캐싱

다음에 동일한 매개변수 값으로 해당 함수가 호출될 때 캐시에서 결과를 읽는다.
이렇게 하면 캐싱은 처리하는 데 시간이 오래 걸리거나 동일한 매개변수 값으로 자주 호출되는 함수가 있는 애플리케이션 속도을 높이는 데 도움이 된다.
특히 GPU에서 실행되는 머신러닝 모델의 경우 이러한 경우가 많습니다.

간단한 캐시는 애플리케이션 자체에서 구현할 수 있다.

from function import lru_cache

# 파일에서 모델 읽음
model = pickle.load(open("model_file.pkl","rb))

@lru)cache(maxsize-=500)
def run_model(input_example):
	retunr model.predict(input_example)
    
# 이제 새로운 데이터에 대해서 run_model을 호출할 수 있음.

일부 입력에 대해 run_model 함수를 처음 호출하면 model.predict가 호출된다.
입력값이 동일하면 run_model을 다시 호출하면 최근 model.predict 호출 결과를 저장하고 있는 maxsize 크기의 캐시에서 출력을 읽는다.

모델 및 코드에 대한 전달 형식

직렬화는 모델과 특징 추출기 코드를 운영 환경에 제공하는 가장 간단한 방법이다.
파이썬에는 pickle이 있다.

import pickle
form sklean import svm, datasets

classifier = svm.SVC()
X, y = datasets.load_iris(return_X_y=True)
classfier.fit(X,y)

# 모델을 파일에 저장
with open("model.pickle","wb") as outfile:
	pickle.dump(classifier, outfile)
    
 # 파일에서 모델을 읽음
classifier2 = None
with open("model.pickle","rb") as infile:
	classifier2 = pickle.load(infile)
if classifier2:    
	prediction = classifier2.predict(X[0:1])

사이킷런에서는 pickle 대신 joblib을 사용하는 것이 더 나을 수 있는데, 이는 큰 넘파이 배열을 전달하는 객체에서 더 효율적이다.

from joblib import dump. load

# 모델을 파일에 저장
dump(classifier, "model.joblib")

# 파일에섬 모델을 읽음
classifier2 = load("model.joblib")

예측 모델 마크업 언어는 데이터 분석가각 PMML 호환 애플리케이션 간에 모델을 저장하고 공유할 수 있는 방법을 제공하는 XML 기반 예측 모델 교환 형식이다.

profile
DevOps 🐥

0개의 댓글