머신러닝에서 앙상블(ensemble)은 여러 모델의 예측을 결합하여 최종 결과를 내는 기법을 의미한다. 예를 들면 분류(classification) 문제에서 가장 많은 모델이 선택한 클래스(class)를 최종 답으로 채택하거나 회귀(regression) 문제에서 여러 모델의 예측값을 가중치 평균내는 것이다. 그 외에도 여러 앙상블 기법들이 있다.
이번 포스트에서는 셀던 코어의 combiner라는 기능을 이용하여 앙상블 파이프라인을 쿠버네티스에 배포해보고자 한다.
Ensemble Pipeline 설계
모델 A와 모델 B의 결과를 앙상블하는 파이프라인이다. 두 모델은 전처리된 데이터를 받은 다음 예측값을 combiner 컴포넌트에게 보낸다. Combiner는 두 모델의 예측값을 결합하여 최종 결과를 도출한다.
A/B Testing with Seldon Core에서 만든 전처리와 모델 A, B의 inference 도커 이미지를 재사용할 것이다. Combiner 컴포넌트의 도커 이미지만 새로 빌드하면 된다. 우리의 파이프라인에서는 combiner가 모델 A와 모델 B의 예측값들을 평균 내도록 구현할 것이다.
Combiner 컴포넌트 구현 및 도커 이미지 빌드
Combiner.py에 구현해보자. 셀던 코어에서 여러 child 컴포넌트의 아웃풋을 받아 결합하는 기능을 가진 컴포넌트의 컴포넌트 타입이 COMBINER이다.
from seldon_core.user_model import SeldonComponent
import numpy as np
class Combiner(SeldonComponent):
def __init__(self):
super(Combiner, self).__init__()
def aggregate(self, Xs, features_names=None):
x = np.stack(Xs, axis=0)
return np.mean(x, axis=0)
aggregate 함수 안에 child 컴포넌트들의 아웃풋을 평균내는 코드를 구현하였다. 파라미터 Xs에 child 컴포넌트들의 아웃풋, 즉 이 문제에서는 모델 A와 모델 B의 예측값을 담은 list가 들어온다.
아래 도커파일을 작성하고 이미지 빌드, 푸쉬하면 된다.
FROM python:3.7
RUN mkdir /home/app && chmod -R 777 /home/app
COPY ./Combiner.py /home/app/Combiner.py
WORKDIR /home/app
EXPOSE 9000
ENV GUNICORN_WORKERS {구니콘 워커 수}
ENV MODEL_NAME Combiner
ENV SERVICE_TYPE COMBINER
RUN pip install numpy==1.18.5 seldon-core==1.6.0
CMD exec seldon-core-microservice $MODEL_NAME --service-type $SERVICE_TYPE --workers $GUNICORN_WORKERS
YAML 파일 작성
앙상블 파이프라인을 위한 seldon_deployment.yaml을 작성하자.
apiVersion: machinelearning.seldon.io/v1alpha2
kind: SeldonDeployment
metadata:
labels:
app: seldon
name: ensemble
spec:
name: ensemble-deployment
predictors:
- componentSpecs:
- spec:
containers:
- image: {전처리 컴포넌트 이미지 URL}
imagePullPolicy: Always
name: {전처리 컨테이너 이름}
resources:
requests:
cpu: "2"
memory: 1Gi
limits:
cpu: "4"
memory: 2Gi
- image: {Combiner 컴포넌트 이미지 URL}
imagePullPolicy: Always
name: {Combiner 컨테이너 이름}
resources:
requests:
cpu: "2"
memory: 1Gi
limits:
cpu: "4"
memory: 2Gi
- image: {Inference 컴포넌트 이미지 URL}
imagePullPolicy: Always
name: {모델 A inference 컨테이너 이름}
resources:
requests:
cpu: "1"
memory: 1Gi
limits:
cpu: "2"
memory: 2Gi
- image: {Inference 컴포넌트 이미지 URL}
imagePullPolicy: Always
name: {모델 B inference 컨테이너 이름}
resources:
requests:
cpu: "1"
memory: 1Gi
limits:
cpu: "2"
memory: 2Gi
graph:
name: {전처리 컨테이너 이름}
endpoint:
type: REST
type: TRANSFORMER
parameters:
- name: container_name
type: STRING
value:
- name: run_name
type: STRING
value:
children:
- name: {Combiner 컨테이너 이름}
endpoint:
type: REST
type: COMBINER
children:
- name: {모델 A inference 컨테이너 이름}
endpoint:
type: REST
type: MODEL
parameters:
- name: container_name
type: STRING
value:
- name: run_name
type: STRING
value:
children: []
- name: {모델 B inference 컨테이너 이름}
endpoint:
type: REST
type: MODEL
parameters:
- name: container_name
type: STRING
value:
- name: run_name
type: STRING
value:
children: []
name: ensemble-deployment
replicas: {Pod 개수}
새로운 모델을 추가하고 싶으면 spec > predictors > componentSpecs > spec > containers에 컨테이너를 추가하고 ('image: {Inference 컴포넌트 이미지 URL}') graph에서 combiner 컨테이너의 children에 새로 추가해주면 된다.
Kubernetes에 배포하고 요청 보내는 방법은 A/B Testing 파이프라인과 동일하다.
'MLOps' 카테고리의 다른 글
AWS Serverless 1편 (0) | 2023.01.02 |
---|---|
Amazon SageMaker (0) | 2022.04.25 |
Multi-Armed Bandit with Seldon Core (0) | 2022.02.20 |
셀던 코어와 텐서플로우 서빙 (0) | 2022.02.07 |
A/B Testing with Seldon Core (0) | 2022.02.07 |