블로그 이미지
평범하게 살고 싶은 월급쟁이 기술적인 토론 환영합니다.같이 이야기 하고 싶으시면 부담 말고 연락주세요:이메일-bwcho75골뱅이지메일 닷컴. 조대협


Archive»


 
 

Ksonnet

조대협(http://bcho.tistory.com)


쿠버네티스의 리소스 배포는 YAML 스크립트를 기반으로 한다.

하나의 마이크로 서비스를 배포하기 위해서는 최소한 Service, Deployment 두개 이상의 배포 스크립트를 작성해야 하고, 만약에 디스크를 사용한다면 Persistent Volume (aka PV)와 Persistent Volume Claim (PVC)등 추가로 여러 파일을 작성해서 배포해야 한다.

그런데 이러한 배포 작업을 보면, 사실 비슷한 성격의 마이크로 서비스간에는 중복 되는 부분이 많다.


예를 들어 간단한 웹서비스 (node.js나 springboot)를 배포할때는 Service의 타입을 지정하고, Deployment에 의해서 관리되는 Pod의 수, 그리고 컨테이너 이미지 정도만 지정하면 기본적인 배포는 가능하다. 여기에 필요하다면, 요구되는 리소스 (CPU, 메모리) 정도만 지정하면 된다.

그러나 이를 위해서는 Service와 Deployment를 정의한 긴 YAML 파일을 작성해야 한다.

그렇다면 이러한 반복작업을 단순화하고, 환경(운영/개발, 또는 미국/유럽과 같은 다른 리전등)에도 반복적으로 재활용할 수 있는 방법은 없을까?


이런 목적에서 여러가지 솔루션이 소개되는데, 그중에 널리 사용되고 있는 것은 패키지 매니저인 Helm이 있다. Helm은 node.js 의 npm이나, 리눅스의 apt 유틸리티와 유사하게, 패키지 형태로 쿠버네티스 리소스를 배포할 수 있도록 해준다. 이외에도 여러가지 솔루션이 있는데, 오늘 이야기하는 솔루션은 ksonnet이라는 오픈소스로, 템플릿엔진 형태의 특징을 가지고 있는 솔루션이다.


Ksonnet

ksonnet은 JSON 기반의 템플릿 엔진인 jsonnet (https://jsonnet.org/)을 기반으로 한다. 기본적으로 템플릿 엔진의 특성을 가지고 있는데, 특이점이 인프라를 지원하는데 있어서 일종의 프로그래밍 언어적인 컨셉을 지원한다.

그러면 기본적인 개념을 이해 해보도록 하자


Prototype, Parameter & Component



먼저 Prototype 이라는 개념을 이해 해야하는데, prototype의 템플릿의 개념으로, 객체 지향형 프로그램에서 클래스의 개념으로 생각하면 된다. 이 prototype을 이용해서 component를 만들어 낸다. component는 객체 지향형에서 객체의 개념으로 생각하면 된다. 이렇게 만들어진 컴포넌트에 속성(변수)를 설정하면 되는데, Deployment 이름이나, 컨테이너 이미지등 실배포에서 애플리케이션 서비스별로 필요한 구체적인 값을 입력한다. 이 값을 입력하는 방법은 parameter 라는 리소스로 정의해서, 필요한 값을 전달한다.

이렇게 값이 채워진 component는 각 서비스 배포에 필요한 쿠버네티스 리소스들을 정의한 쿠버네티스 manifest 파일로 생성된다. (참고 : YAML이 아니라 JSON으로 생성되는데, 쿠버네티스의 manifest는 YAML뿐만 아니라 JSON으로도 설정이 가능하다. )


prototype에서 component를 생성하는 방식은 앞에서도 설명하였듯이, 하나의 prototype에서 parameter만 바꿔서 생성하면 다른 서비스에 대한 component를 반복적으로 생성할 수 있다. 아래 개념 그림은 하나의 prototype에서 도커 이미지와 서비스 타입만 변경해서 Guestbook과 BookStore 서비스에 대해서 각각의 컴포넌트를 생성하는 개념이다.



Environment

이렇게 생성된 component는 쿠버네티스에 적용해서, 실제 쿠버네티스 리소스를 만드는데, ksonnet은 동시에 여러개의 쿠버네티스 환경을 지원할 수 있다. 이를 ksonnet 안에서는 environment 라는 리소스로 정의하는데, 여러개의 쿠버네티스 클러스터를 하나의 ksonnet 프로젝트 안에 등록해놓고, 생성된 component를 등록된 쿠버네티스 환경중 하나에 배포한다. ksonnet의 environment는 쿠버네티스 클러스터에 대한 정보 (예를 들어 마스터 서버의 IP)를 가지고 있다.



Part

그런데 Prototype도 유사점이 있다. 예를 들어 redis 배포를 예를 들었을때, 어떤 redis 배포는 외장 디스크 (PV)를 붙여서 배포할 수 도 있고, 아니면 내장 디스크 (PV 없이) 배포할 수 있다. 비슷한 타입의 prototype의 반복적인 작업을 막기 위해서 prototype은 재사용이 가능한 자원으로 조합해서 정의 될 수 있다. 이를 ksonnet에서는 part라고 정의한다.




위의 그림을 보면 우측에 두가지 프로토 타입이 정의된것을 볼 수 있다. 하나는 PVC(Persistent Volume Claim)이 있는 것이고 하나는 없는 것이데, 이외에 차이가 없고 Service나 Deployment는 정의는 동일 하기 때문에 이를 part로 정의한 후에, 이 part를 조합하여 다른 prototype을 구성할 수 있다.

Application

하나의 애플리케이션은 여러개의 마이크로 서비스로 구성이 된다. 그래서 하나의 애플리케이션을 배포하기 위해서는 여러개의 Prototype과 component들이 필요하게 되는데, 하나의 쿠버네티스 클러스터에는 열개의 애플리케이션이 설치될 수 있기 때문에, 이 애플케이션 단위로, 리소스를 묶을 수 있는 바운더리 개념이 필요하다. ksonnet에서는 이 개념을 application이라는 단위로 정의해서, 이 애플리케이션 안에, 여러개의 prototype, part, component, environment를 묶을 수 있게 한다.

그래서 이 애플리케이션 단위로 설치도 가능하고 반대로 애플리케이션 단위로 설치된 애플리케이션을 삭제할 수 있다.

Package

Part와 Prototype은 다른 애플리케이션에서도 재 사용될 수 있다. 예를 들어 redis 설치 스크립트나, nginx 설치 스크립트 역시 어느 애플리케이션에서나 재 사용될 수 있고, 머신러닝 패키지인 kueflow와 같은 복잡한 애플리케이션의 경우에는 이 prototype과 part들만 있으면 손쉽게 설치될 수 있다. 이렇게 각 모듈들을 재사용 가능하도록 묶어놓은 것을 ksonnet에서는 package라고 한다. Package 안에는 일반적으로 아래와 같이 재 사용이 가능한 part와 prototype들이 들어가 있다.


Registry

그러면 이 패키지들 어디에 저장하고 어떻게 내 애플리케이션에 반영할까? ksonnet에서는 npm이나 docker repository처럼 이러한 패키지들을 저장할 수 있는 레파지토리 개념을 제공하는데, 이것이 바로 registry다.

Github repository나, 파일 시스템 Helm repository를 registry로 사용할 수 있다.


작성한 package는 이 registry에 저장할 수 있으며, 저장된 package들은 package install 명령어를 이용해서 설치한다.



Hello ksonnet

ksonnet의 개념을 이해했으면, 실제 테스트를 통해서 구체적은 사용법을 알아보도록 하자. 테스트를 위해서는 쿠버네티스 클러스터가 설치되어 있어야 하는데, 쿠버네티스 환경이 없는 경우에는 온라인에서 테스트할 수 있는 환경이 https://ksonnet.io/tour/welcome/ 에 있으니,이를 활용하는 것도 하나의 방법이다.

여기서 사용한 예제는 ksonnet 공식 홈페이지에 나와 있는 Guestbook 예제이다. https://ksonnet.io/docs/tutorial/guestbook/ 함축적으로 설명을 해놓은 간단한 예제라서 디테일한 내용을 이해하기는 어렵지만 대략적인 컨셉과 흐름을 이해하는데는 큰 무리가 없다.

애플리케이션 생성

먼저 애플리케이션을 생성한다. ks init 명령을 이용하면 애플리케이션 디렉토리가 생성되고, 필요한 초기 리소스들이 생성된다. 일종의 boiler plate와 같은 개념으로 보면 된다.

%ks init guest book

생성이 되면 아래와 같은 디렉토리 구조로 생성이 된다.

components에는 컴포넌트 파일과 parameter 등이 저장되는데, 정의된 컴포넌트가 없기 때문에, 컴포넌트 관련 파일은 없이 비어 있다.

Environment 디렉토리는 쿠버네티스 환경에 대한 정보가 들어있는데, 기본 환경값은 defaults라는 디렉토리에 저장된다.



Environment 생성

현재 환경을 cloud 라는 이름으로 등록해보자. 환경 등록은 ks add env라는 명령을 사용하면 된다. 등록해야하는 대상 쿠버네티스 클러스터가 많을 경우, 다른 환경을 추가로 등록하면 된다.

%ks add env cloud

Component 생성

다음으로 컴포넌트를 생성하는데, 등록된 prototype을 기반을 component를 생성해야 하는데, ks application을 생성하면 디폴트로 등록되어 있는 prototype이 있다. 등록되어 있는 prototype 목록은 ks prototype list 명령으로 조회가 가능하다.


%ks prototype list




여기서 사용할 prototype은 deployed-service를 사용하는데, image와 type 만을 지정한다.

이 prototype은 웹서비스를 위해서 쿠버네티스 리소스인 Service 와 Deployment를 생성해준다.

deployed-service prototype을 이용해서, 컴포넌트를 생성하기 위해서는 ks generate deployed-service {컴포넌트명} 으로 생성하고, 필요한 parameter는 --{parameter name}={parameter value) 식으로 지정한다.


% ks generate deployed-service guestbook-ui \

 --image gcr.io/heptio-images/ks-guestbook-demo:0.1 \

 --type ClusterIP


Component 생성이 끝나면 ~/components/ 디렉토리에 컴포넌트 파일이 생성된다.


생성된 컴포넌트 파일의 일부를 보면 다음과 같다.  컴포넌트들이 생성되고, parameter 처리되어 있는 부분은 아래 마크한바와 같이 parameter value를 각각 항목마다 지정되어 있다.


~/components/guestbook-ui.libsonnet

중략

:

 {

   "apiVersion": "apps/v1beta2",

   "kind": "Deployment",

   "metadata": {

     "name": params.name

   },

   "spec": {

     "replicas": params.replicas,

     "selector": {

       "matchLabels": {

         "app": params.name

       },

     },

     "template": {

       "metadata": {

         "labels": {

           "app": params.name

         }

       },

       "spec": {

         "containers": [

           {

             "image": params.image,

             "name": params.name,

             "ports": [

               {

                 "containerPort": params.containerPort

               }

             ]

           }

         ]

       }



     "name": params.name

   },

   "spec": {

     "ports": [

       {

         "port": params.servicePort,

         "targetPort": params.containerPort

       }

     ],

     "selector": {

       "app": params.name

     },

     "type": params.type

   }

 },


이하 생략

그리고 parameter로 지정한 내용들은 별도의 param.libsonnet 이라는 파일에 정의된다. 아래 그림과 같이 image명이나 type들이 앞에서 ks generate 단계에서 지정한 내용으로 정의된것을 확인할 수 있다. 다른 값들은 prototype에서 정의된 디폴트 값으로 채워진다.


~/components/param.libsonnet

local env = std.extVar("__ksonnet/environments");

local params = std.extVar("__ksonnet/params").components["guestbook-ui"];

[

중략

 components: {

   // Component-level parameters, defined initially from 'ks prototype use ...'

   // Each object below should correspond to a component in the components/ directory

   "guestbook-ui": {

     containerPort: 80,

     image: "gcr.io/heptio-images/ks-guestbook-demo:0.1",

     name: "guestbook-ui",

     replicas: 1,

     servicePort: 80,

     type: "ClusterIP",

   },

중략

생성된 Manifest 확인하기

생성된 컴포넌트가 각 쿠버네티스 환경에 어떻게 적용되는지를 살펴보기 위해서는  ks show {환경이름} 명령을 실행하면, 쿠버네티스에 적용된 YAML manifest 파일을 먼저확인해볼 수 있다.

%ks show cloud


다음은 “cloud” 라는 환경에 반영할 수 있는 YAML manifest 파일이다.

아래 그림은 YAML 파일중에서 Deployment 파트인데,  아래 그림고 같이 name이나 label등 구체적인 설정 값들이 앞에서 지정한 parameter 값으로 채워진것을 확인할 수 있다.

apiVersion: apps/v1beta2

kind: Deployment

metadata:

 labels:

   ksonnet.io/component: guestbook-ui

 name: guestbook-ui

spec:

 replicas: 1

 selector:

   matchLabels:

     app: guestbook-ui

 template:

   metadata:

     labels:

       app: guestbook-ui

   spec:

     containers:

     - image: gcr.io/heptio-images/ks-guestbook-demo:0.1

       name: guestbook-ui

       ports:

       - containerPort: 80



중략

Manifest 적용

이렇게 컴포넌트가 정의되었으면, 대상 쿠버네티스를 선택해서 ks apply 명령으로 적용 하면 된다. 아래 명령어는 “cloud” 라는 환경에 생성된 컴포넌트들을 적용하는 명령이다.

%ks apply cloud

적용된 서비스 확인 및 테스트

쿠버네티스에 적용된 리소스를 확인해보자. kubectl get svc와 kubectl get pod를 실행해보면 아래와 같이 Service와 Pod들이 생성된것을 확인할 수 있다.

%kubectl get svc




%kubectl get pod




생성된 서비스를 테스트해보자. 서비스를 ClusterIP로 생성하였기 때문에, 외부 IP를 통해서 접속은 불가능하고, kubectl proxy를 이용해서 프록시를 세팅해서 접속해야 한다. 아래는 kubectl proxy 명령어를 이용해서 proxy를 생성하고 접속을 하는 예제이다.

%kubectl proxy > /dev/null &

%KC_PROXY_PID=$!

%SERVICE_PREFIX=http://localhost:8001/api/v1

%GUESTBOOK_URL=$SERVICE_PREFIX/namespaces/default/services/guestbook-ui/proxy/


%open $GUESTBOOK_URL



프록시를 통해서 접속한 웹사이트에 대한 결과이다.


간단하게 컨셉과 예제를 통해서 실제 사용 방법을 확인해보았다.

ksonnet은 쿠버네티스의 다른 YAML 파일 배포 시스템과 다르게 prototype,component,application,environment 등과 같이 잘 추상화된 개념을 가지고 있으며, 특히 배포를 위해서 쿠버네티스에 무엇인가를 설치할 필요가 없이 클라이언트에 ks 툴만 설치하면 되기 때문에, 쿠버네티스 설치에 대한 의존성이 없이 깔끔하게 설치 및 운영이 가능하다.

또한 파일 형태로 모든 리소스를 관리할 수 있기 때문에 gitOps와 같은 형상 관리 시스템을 통해서 리소스를 관리할 수 있기 때문에, 변경 추적이나 코드 재 사용등에 많은 장점을 가질 수 있다.


본인은 구글 클라우드의 직원이며, 이 블로그에 있는 모든 글은 회사와 관계 없는 개인의 의견임을 알립니다.

End2End 머신러닝 플랫폼 Kubeflow 조대협 (http://bcho.tistory.com)

머신러닝 파이프라인

머신러닝에 대한 사람들의 선입견중의 하나는 머신러닝에서 수학의 비중이 높고, 이를 기반으로한 모델 개발이 전체 시스템의 대부분 일 것이라는 착각이다.

그러나 여러 연구와 경험을 참고해보면, 머신러닝 시스템에서 머신러닝 모델이 차지하는 비중은 전체의 5% 에 불과하다.


실제로 모델을 개발해서 시스템에 배포할때 까지는 모델 개발 시간보다 데이타 분석에 소요되는 시간 그리고 개발된 모델을 반복적으로 학습하면서 튜닝하는 시간이 훨씬 더 길다.

머신러닝 파이프라인은 데이타 탐색에서 부터, 모델 개발, 테스트 그리고 모델을 통한 서비스와 같이 훨씬 더 복잡한 과정을 거친다. 이를 머신러닝 End to End 파이프라인이라고 하는데, 자세하게 그 내용을 살펴보면 다음 그림과 같다.




  • Data ingestion : 머신러닝에 필요한 학습 데이타를 외부로 부터 받아서 저장하는 단계

  • Data analytics : 수집된 데이타를 분석하여, 의미를 찾아내고,필요한 피쳐(특징)을 찾아내는 단계로 주로 빅데이타 분석 시스템이 많이 활용된다. EDA (Exploratory Data Analytics) 방법을 많이 사용하는데, 저장된 데이타를 그래프로 시각화해서 각 값간의 관계나 데이타의 분포등을 분석한다.

  • Data Transformation : 수집된 데이타에서 학습에 필요한 데이타만 걸러내고, 학습에 적절하도록 컨버팅 하는 단계. 예를 들어 이미지 데이타의 크기를 정형화하고, 크롭핑 처리를 한후에, 행렬 데이타로 변환하는 과정등이 이에 해당한다.

  • Data Validation : 변환된 데이타가 문제는 없는지 데이타 포맷이나 범위등을 검증하는 단계

  • Data Splitting : 머신러닝 학습을 위해서 데이타를 학습용,테스트용,검증용으로 나눈다.

  • Build a Model : 머신러닝 모델을 만들고 학습하는 단계

  • Model Validation : 만들어진 모델을 검증하는 단계

  • Training at scale : 더 많은 데이타를 더 큰 인프라에서 학습 시켜서 정확도를 높이고, 하이퍼 패러미터 튜닝을 통해서 모델을 튜닝하는 단계로 주로 대규모 클러스터나 GPU 자원등을 활용한다.

  • Roll out : 학습된 모델을 운영환경에 배포하는 단계

  • Serving : 배포된 모델을 통해서 머신러닝 모델을 서비스로 제공하는 형태. 유스케이스에 따라서 배치 형태로 서빙을 하거나 실시간으로 서빙하는 방법이 있다.

  • Monitoring : 머신러닝 모델 서비스를 모니터링 해서 정확도등에 문제가 없는지 지속적으로 관찰하는 단계

  • Logging : 모델에 서비스에 대한 로그 모니터링


이 과정을 데이타의 변동이 있거나 모델을 향상시키고자 하거나 정확도가 떨어지는 경우 첫번째 과정부터 반복을 한다.


위에서 설명한 파이프라인 흐름을 시스템 아키텍쳐로 표현해보면 다음과 같다.




먼저 GPU를 지원하는 인프라 위에 머신러닝 플랫폼이 올라가게 되고, 빅데이타 분석 플랫폼이 같이 사용된다.

머신러닝 플랫폼은 데이타를 분석하는 EDA 단계의 데이타 분석 플랫폼 그리고, 분석된 데이타를 변환 및 검증하고 학습,테스트,검증 데이타로 나누는 Data Processing 시스템이 붙고, 이 데이타를 이용해서, 모델을 개발한후에, 이 모델을 학습 시키기 위한 학습 (Training) 플랫폼이 필요하다. 학습된 모델을 검증하고, 이 검증 결과에 따라서 하이퍼 패러미터를 튜닝한 후에, 이를 운영환경에 배포하여 서비스 한다. 데이타 분석 및 모델 개발 학습 단계는 주로 데이타 사이언티스트에 의해서 이루어지는데, 이러한 엔지니어들이 사용할 개발 환경이 필요한데, 주로 노트북 기반 (예. 파이썬 주피터 노트북)의 환경이 많이 사용된다.

학습이 완료된 모델을 서빙하는 Inference 엔진이 필요하고, 이를 외부 API로 노출하기 위해서 API 키 인증, 오토스케일링, 로깅 및 모니터링을 위한 API Serving 플랫폼이 필요하다.


컴포넌트가 많은 만큼 여기에 사용되는 프레임웍도 많다. 먼저 모델 개발 및 학습을 위해서는 머신러닝 프레임웍이 필요한데, Tensorflow, PyTorch, Sklearn, XGBoost등 목적에 따라서 서로 다른 프레임웍을 사용하게 되며, 완성된 모델을 서빙하는 경우에도 Tensorflow Serving, Uber에서 개발한 Horovod 등 다양한 플랫폼이 있다. 또한 모델을 서빙할때 REST API등으로 외부에 서비스 하려면 보안 요건에 대한 처리가 필요하기 때문에 별도의 API 인증 메커니즘등이 추가되어야 하고, 스케일링을 위한 오토 스케일링 지원 그리고 모델의 배포와 테스트를 위한 배포 프레임웍, A/B 테스트 환경등이 준비되어야 한다.

일부만 이야기한것이지만 실제 운영 환경에서 사용되는 머신러닝 시스템은 훨씬 더 복잡하고 많은 기술을 필요로 한다.

Kubeflow comes in

이러한 복잡성 때문에 머신러닝 플랫폼은 높은 난이도를 가지고 있고, 데이타 분석과 모델 개발에 집중해야 하는 머신러닝 엔지니어 입장에서는 큰 부담이 된다. (배보다 배꼽이 크다)

그래서 이러한 복잡성을 줄이고 머신러닝 엔지니어의 원래 업인 데이타 분석과 머신러닝 모델 개발에만 집중할 수 있도록 플랫폼을 추상화 해놓은 오픈 소스 프레임웍이 Kubeflow이다.

위에서 설명한 머신러닝 파이프라인의 End to End 전체를 커버할 수 있게 하고, 모든 단계의 컴포넌트를 패키지화 해놔서, 어려운 설치 없이 머신러닝 엔지니어는 머신러닝 모델 개발의 각 단계를 손쉽게 할 수 있도록 해준다.


Kuberflow는 Kubernetes(쿠버네티스) + ml flow 를 합한 의미로, 쿠버네티스 플랫폼 위에서 작동한다.

쿠버네티스는 도커 컨테이너 관리 플랫폼으로, 이 컨테이너 기술을 이용하여 머신러닝에 필요한 컴포넌트를 패키징하여 배포한다. 쿠버네티스에 대한 자세한 설명은 링크를 참고하기 바란다.

이로 인해서 가질 수 있는 장점은 다음과 같다.

  • 클라우드나 On-Prem (데이타 센터), 개인 개발 환경에 상관 없이 동일한 머신러닝 플랫폼을 손쉽게 만들 수 있기 때문에 특정 벤더나 플랫폼에 종속되지 않는다.

  • 컨테이너 기술을 이용해서 필요한 경우에만 컨테이너를 생성해서 사용하고, 사용이 끝나면 컨테이너를 삭제하는 방식이기 때문에 자원 활용율이 매우 높다. 특히 쿠버네티스의 경우에는 스케쥴링 기능을 이용해서 비어있는 하드웨어 자원에 컨테이너를 배포해서 (꾸겨넣는 방식으로) 사용하기 때문에 집적률이 매우 높다.

  • 컨테이너로 패키징이 되어있기 때문에 내부 구조를 알필요가 없이 단순하게 컨테이너만 배포하면 된다.

또한 쿠버네티스는 오픈소스 플랫폼이기 때문에 여러 종류의 머신러닝 관련 기술들이 손쉽게 합쳐지고 있다.

Kubeflow 컴포넌트 구성

그러면 간단하게 Kubeflow의 컴포넌트 구성을 살펴보자.

IDE 환경

IDE 개발환경으로는 JupyterLab을 지원한다. JupyterLab은 Jupyter 노트북의 확장 버전으로 코드 콘솔뿐 아니라 파일 브라우져나 시각화창등 확장된 UI를 지원한다.


<출처 : https://jupyterlab.readthedocs.io/en/stable/getting_started/overview.html>


개인적으로 기존 노트북 환경에 비해서 좋은 점은 주피터 노트북을 필요할때 마다 손쉽게 생성이 가능하며, 생성할때 마다 GPU 지원 여부나 텐서플로우 버전등을 손쉽게 선택이 가능하다.


<그림. 노트북 생성시 텐서플로우와 GPU 지원 여부를 선택하는 화면>


또한 아래 그림과 같이 노트북 인스턴스의 하드웨어 스펙 (CPU, Memory, GPU)를 정의할 수 있다.



GPU 드라이버

그리고 쿠버네티스상에서 GPU를 사용할 수 있도록 GPU 드라이버를 미리 패키징 해놓았다. 머신러닝 프레임웍을 사용하면 항상 까다로운 부분이 GPU 드라이버 설정이나 업그레이드인데, 이를 미리 해놓았기 때문에 머신러닝 엔지니어 입장에서 별도의 노력없이 손쉽게 GPU를 사용할 수 있다.

머신러닝 프레임웍

머신러닝 프레임웍으로는 현재 텐서플로우, 파이토치, MxNet등을 지원하는데, 플러그인 컴포넌트 형태이기 때문에 앞으로 더 많은 프레임웍을 지원할 것으로 기대된다.

데이타 프로세싱

데이타 프로세싱에서 데이타 변환 (Transformation)과 데이타 검증 (Validation)은 텐서플로우의 확장팩인 TFX에서 지원하는 TFDV (Tensorflow Data Validation)과 TFT (Tensorflow Transform)을 이용해서 지원한다.

학습 환경

개발된 모델을 학습할때 특히 분산학습의 경우에는 텐서플로우 클러스터와 우버에서 개발된 텐서플로우용 분산 학습 플랫폼인 Hornovod를 지원한다.  

모델 검증

학습된 모델 검증은 데이타 프로세싱과 마친가지로 텐서플로우 확장팩인 TFX의 TFMA (Tensorflow Model Analysis)를 지원한다.

하이퍼 패러미터 튜닝

학습된 모델에 대한 하이퍼 패레미터 튜닝은 katLib라는 컴포넌트를 이용해서 지원한다.

모델 서빙

학습이 완료된 모델은 TFX 패키지의 일부인 Tensorflow Serving 을 사용하거나 모델 서빙 전문 플랫폼인 SeldonIO를 사용한다. SeldonIO는 텐서플로우뿐만 아니라 Sklearn, Spark 모델, H2O 모델, R 모델등 좀 더 다양한 모델을 지원한다.

API 서비스

서비스된 모델에 대한 API 키 인증이나 라우팅등을 위해서 API 게이트 웨이가 필요한데, API 게이트 웨이로 Ambassador라는 오픈 소스를 이용한다. 이를 통해서 API 키등의 인증을 지원하고, 쿠버네티스 위에 네트워크 플랫폼인 ISTIO를 사용하여, API 서비스에 대한 모니터링 및 서비스 라우팅을 지원하는데, 서비스 라우팅 기능은 새 모델을 배포했을때 새모델로 트래픽을 10%만 보내고 기존 모델로 트래픽을 90% 보내서 새모델을 테스트하는 카날리 테스트나 API 통신에 대한 보안등 여러기능을 지원한다. Istio에 대한 자세한 설명은 링크를 참조하기 바란다.

워크플로우

이러한 컴포넌트를 매번 메뉴얼로 실행할 수 는 없고, 워크플로우 흐름에 따라서 자동으로 파이프라인을 관리할 수 있는 기능이 필요한데, 이를 워크플로우 엔진이라고 하고, Kubeflow에서는 argo라는 컨테이너 기반의 워크플로우 엔진을 사용한다. 자세한 내용은 링크 참조.

그런데 argo는 일반적인 워크플로우를 위해서 디자인된 플랫폼으로 머신러닝 파이프라인에 최적화되어 있지 않다. (예를 들어 학습 단계 종료후, 학습 결과/accuracy등을 모니터링 한다던지, Tensorflow Dashboard와 통합된다던지.) 그래서 argo위해 머신러닝 기능을 확장하여 개발중인 오픈소스가 Kubeflow pipeline이 있다. Kubeflow pipeline에 대해서는 나중에 더 자세히 설명하도록 한다.

컴포넌트에 대한 정의

Kubeflow에서 사용되는 거의 모든 컴포넌트에 대해서 설명하였다. 그러면 이런 컴포넌트를 어떻게 쿠버네티스에 배포하고, 어떻게 실행을 할것인가? 매번 쿠버네티스의 설정 파일을 만들어서 하기에는 파일의 수도 많고 반복작업이면서 또한 쿠버네티스에 대한 높은 전문성을 필요로하기 때문에 어렵다.

그래서 이러한 반복작업을 줄여주고, 템플릿화하여 실행하도록 해주는 엔진이 ksonnet 이라는 오픈소스를 사용한다. ksonnet은 jsonnet 템플릿 엔진 기반으로, 위에서 나열한 컴포넌트들을 쿠버네티스에 설치할 수 있도록 해주고, 각 단계별 컴포넌트를 손쉽게 실행할 수 있도록 해준다.


이 솔루션들을 앞에서 설명한 머신러닝 플랫폼 아키텍쳐에 맵핑 시켜보면 다음과 같은 그림이 된다.




Kubeflow는 현재 개발중인 버전으로 이글을 쓰는 현재 0.4 버전이 개발중이다.

컨셉적으로 매우 훌륭하고 0.4 버전인것에 비해서는 매우 완성도가 높지만 1.0 릴리즈 전이기 때문에 다소 변화가 심하기 때문에 버전간 호환이 안될 수 있다. 이점을 염두하고 사용하기 바란다.


Kubeflow를 이해하기 위해서는 먼저 Kubeflow의 컴포넌트를 배포하고 실행하게 해주는 ksonnet에 대한 이해가 먼저 필요하다. 다음 글에서는 이 ksonnet에 대해서 알아보도록 하겠다.

본인은 구글 클라우드의 직원이며, 이 블로그에 있는 모든 글은 회사와 관계 없는 개인의 의견임을 알립니다.