더 이상 tistory 블로그를 운영하지 않습니다. glanceyes.github.io에서 새롭게 시작합니다.

새소식

AI/AI 실습

ML 실험을 위한 관리 플랫폼인 MLflow

  • -

 

들어가기 전에

MLflow가 등장하기 이전에는 사람들이 각자 자신의 코드를 jupyter notebook에서 작성하여 머신러닝 모델을 학습할 때 사용한 파라미터와 metric을 따로 기록했다. 학습하며 생긴 weight file을 저장하여 coworker에게 공유하기도 했으며, weight file 이름으로 모델 버전을 작성하거나 아예 모델 버전을 지정하지 않기도 했다.
그러나 개인 컴퓨터 등을 사용하다가 메모리 초과(Memory Exceed) 오류가 발생할 수도 있고, 실험을 추적하기 어렵거나 코드를 재현하기 어렵다는 단점이 있었다. 또한 모델을 패키징하고 배포하는 방법이 어려우며, 이를 관리하기 위한 중앙 저장소가 없다는 것도 큰 문제였다.
이러한 문제를 해결할 수 있는 관리 플랫폼 중 하나로서 MLflow가 있으며, 이에 관해서 실습 예제를 따라가며 알아보고자 한다.

 

 

MLflow

 

MLflow란?

간단히 설명하자면 머신러닝 실험, 배포를 쉽게 관리할 수 있는 오픈소스이며, CLI, GUI(웹 인터페이스 환경)가 지원되는 플랫폼이다. 백문이 불여일견인 것처럼 실습을 통해 어떠한 플랫폼인지를 익히는 것이 이해하는 데 더 빠르다. 머신 러닝 또는 딥 러닝 모델 프로그램을 Python으로 구현하여 실행할 때 아래처럼 mlflow 라이브러리를 import 해 와서 원하는 작업을 수행할 수 있다. 다음 예제는 모델을 학습할 때 학습 내용을 로그로 MLflow에 기록하는 과정이며, with as 구문을 사용하여 실행 자체의 id를 기록한다.

 

import numpy as np
from sklearn.linear_model import LinearRegression
import mlflow

def main():
    # 자동으로 로그를 저장할 수 있도록 한다.
    mlflow.autolog(log_input_examples=True)
    
    # 학습 데이터를 생성한다.
    X = np.array([[1, 1], [1, 2], [2, 2], [2, 3]])
    y = np.dot(X, np.array([1, 2])) + 3
    # y = [6, 8, 9, 11]
    
    # 모델을 학습한다.
    model = LinearRegression()
    with mlflow.start_run() as run:
        model.fit(X, y)
        print("Logged data and model in run {}".format(run.info.run_id))

if __name__ == "__main__":
    main()

 

 

MLflow 핵심 기능

 

MLflow의 기능은 실험을 추적하고 관리하며, 실험에서 실행한 모델을 저장하여 언제든지 가져다 쓸 수 있는 역할을 한다고 볼 수 있다. 크게 세 가지로 구분지어 기능을 설명하면 다음과 같다.

 

Experiment Management & Tracking

머신러닝 관련 실험들을 관리하고 각 실험의 정의와 내용들을 기록할 수 있다. 실행에 사용한 소스 코드, 모델을 만들 때 사용한 모델 구조, 파라미터 등 실행 기록할 수 있으며, 특정 metric 기준으로 성능이 가장 좋았던 모델 구조, 데이터, 파라미터 등의 조합을 기록할 수 있다.

머신러닝 실험을 하면서 생기는 부차적인 데이터(이미지 등)도 저장할 수 있고 여러 종류의 모델에 관해 모델 생성일, 모델 성능, 모델 메타 정보 등을 저장할 수 있다.

 

 

Model Registry (모델 저장소)

MLflow로 실행한 머신러닝 모델을 Model Registry(모델 저장소)에 등록할 수 있다. 

모델 저장소에 모델이 저장될 때마다 해당 모델의 버전이 자동으로 올라가는데, Model Registry에 등록된 모델을 다른사람에게 쉽게 공유하고 활용할 수 있다.

Git은 소스에 대한 버전 관리, Docker는 Docker Image에 대한 버전 관리라면, Mdoel Registry는 머신러닝 실험과 모델에 대한 버전 관리라고 볼 수 있다.

 

 

Model Serving

Model Registry에 등록한 모델을 REST API 형태의 서버로 serving 할 수 있어서 모델의 input과 output을 이용할 수 있다.

 

 

 

MLflow 요소

 

MLflow Tracking

머신러닝 코드를 실행하고 로깅을 할 수 있는 API와 UI를 제공한다. Tracking 결과를 local 또는 server에 기록하여 여러 실행과 비교할 수 있다. 팀에서는 다른 사용자의 결과와 비교하며 협업할 수 있다.

 

MLflow Project

머신러닝 프로젝트 코드를 패키징하기 위한 표준이며, 소스 코드가 저장된 폴더이다. 의존성, ENTRYPOINT 등 머신러닝 모델을 어떻게 실행해야 하는지를 저장할 수 있고, MLflow Tracking API를 사용하면 MLflow에서 프로젝트 버전에 따라 모든 파라미터를 자동으로 로깅할 수 있다.

 

MLflow Model

모델 파일과 코드를 저장하고, 다양한 플랫폼에 배포할 수 있는 여러 도구를 제공한다. MLflow Tracking API를 사용하면 MLflow는 자동으로 해당 프로젝트에 대한 내용을 가져와서 사용할 수 있다.

 

MLflow Registry

MLflow Model의 전체 life cycle에서 사용할 수 있는 중앙 모델 저장소이다.

 

 


 

MLflow 실습

 

다음 소개할 간단한 실습으로 MLflow를 익혀보자. 진행하고자 하는 실험에 필요한 코드를 작성하고, 거기에 MLflow Project 파일을 만든 후, GUI 환경에 접속해 실험이 어떻게 되었는지 그 결과를 확인하는 과정으로 요약할 수 있다.

 

 

Experiment

 

mlflow experiments create --experiment-name my-first-experiment로 Experiment를 생성한다.

 

ls -almlruns라는 폴더를 확인할 수 있다.

 

mlflow experiments list로 experiment 리스트를 확인할 수 있다.

 

logistic_regression 폴더를 생성한 후, 머신러닝 코드를 생성한다.

 

# train.py
import numpy as np
from sklearn.linear_model import LogisticRegression

import mlflow
import mlflow.sklearn

if __name__ == "__main__":
    X = np.array([-2, -1, 0, 1, 2, 1]).reshape(-1, 1)
    y = np.array([0, 0, 1, 1, 1, 0])

    penalty = "l2"
    l1_ratio = 0.1
    lr = LogisticRegression(penalty=penalty, l1_ratio=l1_ratio)

    lr.fit(X, y)

    score = lr.score(X, y)
    print("Score: %s" % score)

    mlflow.log_param("penalty", penalty)
    mlflow.log_param("l1_ratio", 0.1)
    mlflow.log_metric("score", score)
    mlflow.sklearn.log_model(lr, "model")

 

 

 

Project

다음과 같이 MLProject 파일을 IDE 또는 vim, touch 등 편집기를 이용해 생성한다.

 

 

Run

하나의 Run은 코드를 한 번 실행한 것을 의미하는데, 보통 Run은 모델 학습 코드를 실행한다.

한 번 코드가 실행되면 하나의 Run이 생성되며, Run을 하면 여러가지 내용이 기록된다.

  • Source : 실행한 Project의 이름
  • Version : 실행 Hash
  • Start & end time
  • Parameters : 모델 파라미터
  • Metrics : 모델의 평가 지표, Metric을 시각화할 수 있다.
  • Tags : 관련된 Tag
  • Artifacts : 실행 과정에서 생기는 다양한 파일들
    • 이미지, 모델 Pickle 등

 

 

mlflow run logistic_regression --experiment-name my-first-experiment --no-conda로 run을 실행한다.

 

UI

mflow ui로 GUI로 관리할 수 있는 환경을 실행할 수 있다.

 

http://127.0.0.1:5000으로 접속하면 mlflow UI를 볼 수 있다.

 

Autolog

파라미터를 매번 mlflow.log_param()을 명시할 필요 없이 mlflow.sklearn.autolog()을 사용하면 자동으로 모델의 파라미터를 기록해준다.

# train.py
import numpy as np
from sklearn.linear_model import LogisticRegression

import mlflow
import mlflow.sklearn

if __name__ == "__main__":
    mlflow.sklearn.autolog()
    X = np.array([-2, -1, 0, 1, 2, 1]).reshape(-1, 1)
    y = np.array([0, 0, 1, 1, 1, 0])

    penalty = "l2"
    l1_ratio = 0.1
    lr = LogisticRegression(penalty=penalty, l1_ratio=l1_ratio)

    with mlflow.start_run() as run:
        lr.fit(X, y)

    score = lr.score(X, y)
    print("Score: %s" % score)

 

단, 모든 프레임워크에서 사용 가능한 것은 아니며, 대표적으로 pytorch.nn.Module은 지원되지 않는다.

 

 

Parameter

아예 모델을 만들어서 실행할 때 argument를 넘겨서 실행할 수도 있다. 앞서 생성한 project 파일에서 argument를 사전에 정의한 후 코드를 실행할 때 sys 패키지를 사용하여 argument 값이 저장된 argv 멤버 변수를 인자로 받아와 사용하면 된다.

# train.py

import argparse
import sys

import numpy as np
from sklearn.linear_model import LogisticRegression

import mlflow
import mlflow.sklearn

if __name__ == "__main__":
    mlflow.sklearn.autolog()
    X = np.array([-2, -1, 0, 1, 2, 1]).reshape(-1, 1)
    y = np.array([0, 0, 1, 1, 1, 0])

    penalty = "l2"
    l1_ratio = 0.1
    lr = LogisticRegression(
        solver=sys.argv[1],
        penalty=sys.argv[2], 
        l1_ratio=float(sys.argv[3])
    )

    with mlflow.start_run() as run:
        lr.fit(X, y)

    score = lr.score(X, y)
    print("Score: %s" % score)
# MLProject
name: tutorial

entry_points:
    main:
        parameters:
            solver:
                type: string
                default: "saga"
            penalty:
                type: string
                default: "l2"
            l1_ratio:
                type: float
                default: 0.1
        command: "python train.py {solver} {penalty} {l1_ratio}"

 

 

Hyperparameter Tuning

Autolog와 더불어 최적의 하이퍼 파라미터를 찾는 하이퍼 파라미터 튜닝도 같이 할 수 있다.

from sklearn import svm, datasets
from sklearn.model_selection import GridSearchCV

import mlflow

def main():
    mlflow.sklearn.autolog()
    
    iris = datasets.load_iris()
    parameters = {"kernel": ("linear", "rbf"), "C": [1, 10]}
    svc = svm.SVC()
    clf = GridSearchCV(svc, parameters)
    
    with mlflow.start_run() as run:
        clf.fit(iris.data, iris.target)

if __name__ == "__main__":
    main()

 

 

 

MLflow 서버로 배포하기

 

주로 공용으로 협업할 때 mlflow 서버로 실험 결과 또는 모델을 배포할 수 있다. 이러면 직접 파일을 따로 저장하여 협업자와 공유할 필요 없이 형상 관리도 가능할 뿐만이 아니라 서로가 필요로 할 때 직접 원하는 모델을 다운로드 받아서 사용할 수 있는 장점이 있다.

 

 

MLflow Architecture

 

Tracking Server

아래처럼 실행한 Python Code가 실행되는 동안 파라미터, metric, model 등 메타 정보를 파일 또는 DB에 저장되는 것을 tree 명령어를 통해 확인할 수 있다. tree 명령어는 현재 디렉토리의 구조가 어떻게 되어있는지를 보여준다.

 

mlflow server 명령어로 외부 storage를 이용하여 메타 정보를 저장할 Backend Store URI를 지정할 수 있다.

 

mlflow server --backend-store-uri sqlite:///mlflow.db --default-artifact-root $(pwd)/artifacts

 

export MLFLOW_TRACKING_URI="http://127.0.0.1:5000"로 환경변수를 지정한 후, experiment를 생성하여 Run한다.

 

 

Artifact Store

Python Code가 실행되는 동안 생기는 Artifact(Model File, Image 등)를 파일 또는 storage에 저장한다.

 

 

 

MLflow의 실행 흐름

 

MLflow의 실행 흐름을 네 단계로 요약하면 다음과 같다.

  1. mlflow run을 실행한다.
  2. 파이썬 코드가 tracking server에게 기록을 요청한다.
  3. Tracking server가 DB 등 저장소에 기록한다.
  4. 파이썬 코드가 Artifact Store에 요청하여 Artifact를 저장한다.

 

 

출처
1. 네이버 커넥트재단 부스트캠프 AI Tech Level 3 변성윤 마스터님 Product Serving
Contents

글 주소를 복사했습니다

부족한 글 끝까지 읽어주셔서 감사합니다.
보충할 내용이 있으면 언제든지 댓글 남겨주세요.