StoryCode

MLflow.3.Experiments & Runs

인공지능,AI,학습,ML,Tensorflow, Cafee2,MLFlow/MLFlow
반응형

# 참조 : https://dailyheumsi.tistory.com/259?category=980484

 

이번에는 MLflow의 실험(experiments)과 실행(runs)에 대해 알아본다.


사전 준비

다음이 사전에 준비 되어 있어야 한다.

# 파이썬 버전 확인
$ python --version
Python 3.8.7

# mlflow 설치 & 버전 확인
$ pip install mlflow
$ mlflow --version
mlflow, version 1.16.0

# 예제 파일을 위한 mlflow repo clone
$ git clone https://github.com/mlflow/mlflow.git
$ cd mlflow/examples

 


Experiments & Runs

개념

MLflow에는 크게 실험(Experiment)와 실행(Run)이라는 개념이 있다. 실험은 하나의 주제를 가지는 일종의 '프로젝트'라고 보면 된다. 실행은 이 실험 속에서 진행되는 '시행'이라고 볼 수 있다. 하나의 실험은 여러 개의 실행을 가질 수 있다.

직접 눈으로 보며 이해해보자.
examples 에 있는 sklearn_elasticnet_wine MLflow 프로젝트를 실행해본다.

$ mlflow run sklearn_elasticnet_wine --no-conda

실행 결과로 ./mlruns 경로에 다음과 같은 파일들이 생긴다.

여기서 0 은 실험 ID이고, a853debd39fb4de4a61ce3aa6d247c8a 은 실행 ID다.
한번 더 동일한 프로젝트를 실행해보자. 이번에는 파라미터 값을 추가로 넘겨줘본다.

$ mlflow run sklearn_elasticnet_wine -P alpha=0.5 --no-conda

실행 결과로 mlruns 경로를 확인해보면 다음과 같다.

0 이라는 실행에 69c2f00c31044d339344f91ea03ed1f0 이라는 실행이 추가로 생성되었다.
이렇듯 매 실행은 하나의 실험에 속하여 들어간다. 위의 예시가 매우 직관적이라 실험과 실행의 관계와 활용 방안을 바로 알 수 있을 것이다.

 

Experiment 생성 및 조회

위에서 별도의 실험을 생성하지 않았기 때문에 ID가 0 인 실험을 자동으로 생성하고 이 실험에서 실행을 생성하였다.
이번에는 직접 실험을 생성해보자.

실험 생성 은 다음 CLI 명령어로 가능하다.

$ mlflow experiments create -n "실험 이름"

그리고 실험 목록은 다음 CLI 명령어로 가능하다.

$ mlflow experiments list

그 외 mlflow experiments 관련된 명령어는 다음의 것들이 있으니 참고하자.

CLI가 아닌 코드에서 experiments 및 run을 다루는 방법

다음처럼 mlflow.tracking.MlflowClient 를 사용하면 된다.

from mlflow.tracking import MlflowClient

# Create an experiment with a name that is unique and case sensitive.
client = MlflowClient()
experiment_id = client.create_experiment("Social NLP Experiments")
client.set_experiment_tag(experiment_id, "nlp.framework", "Spark NLP")

# Fetch experiment metadata information
experiment = client.get_experiment(experiment_id)
print("Name: {}".format(experiment.name))
print("Experiment_id: {}".format(experiment.experiment_id))
print("Artifact Location: {}".format(experiment.artifact_location))
print("Tags: {}".format(experiment.tags))
print("Lifecycle_stage: {}".format(experiment.lifecycle_stage))

자세한 내용은 공식 docs를 참고하자.

 

Run 생성 및 조회

위에서 실험을 생성했으므로 이번에는 실행을 생성해보자.
먼저 mlruns 내부를 확인해본다.

위에서 새로 만든 1, 2 실험에는 아직 아무런 실행이 없다.
다음 명령어로 실행을 생성한다.

$ mlflow run sklearn_elasticnet_wine -P alpha=0.5 --no-conda --experiment-id 2

끝에 --experiment-id 를 붙여주었다.
다음처럼 실험 이름으로 할 수도 있다.

$ mlflow run sklearn_elasticnet_wine -P alpha=0.25 --no-conda --experiment-name "experiments-2"

잘 실행된걸 확인했으므로, 이제 결과가 잘 나왔는지 ./mlruns 경로에서 확인하자.

2 번 실험에 위에서 생성한 실행들이 잘 생성된 것을 볼 수 있다.

다음처럼 환경 변수로 실험 ID를 잡아줄 수도 있다.

$ export MLFLOW_EXPERIMENT_ID = 2

정리

  • MLflow 에는 실험(Experiments)과 실행(Runs)이란 개념이 있다.
  • 하나의 ML 프로젝트는 하나의 실험으로 구성할 수 있다.
  • 하나의 실험은 여러 개의 실행으로 구성된다.
    • 각 실험마다 ML 모델의 하이퍼 파라미터 조정 등을 다르게 하여 수행할 수 있다.
  • CLI 혹은 코드에서 실험과 실행의 생성, 조회, 삭제 등의 명령을 할 수 있다.
반응형

MLflow.2.Automatic logging

인공지능,AI,학습,ML,Tensorflow, Cafee2,MLFlow/MLFlow
반응형

# 참조 : https://dailyheumsi.tistory.com/258?category=980484

 

 

저번 Quick 리뷰 글에 이어 계속해서 작성한다.
이번 글은 MLflow 에서 제공하는 Automatic Logging 기능 예제들을 살펴본다.

 


사전 준비

다음이 사전에 준비 되어 있어야 한다.

# 파이썬 버전 확인
$ python --version
Python 3.8.7

# mlflow 설치 & 버전 확인
$ pip install mlflow
$ mlflow --version
mlflow, version 1.16.0

# 예제 파일을 위한 mlflow repo clone
$ git clone https://github.com/mlflow/mlflow.git
$ cd mlflow/examples

 


예제 살펴보기

linear_regression.py

examples 내에 있는 많은 예제 중, skelarn_autolog 를 사용해보자.
먼저 sklearn 을 설치해준다.

# sklearn 설치 & 버전 확인
$ pip install sklearn
$ python -c "import sklearn; print(sklearn.__version__)"
0.24.2

skelarn_autolog/linear_regression.py 를 보면 다음처럼 생겼다.

# skelarn_autolog/linear_regression.py

from pprint import pprint

import numpy as np
from sklearn.linear_model import LinearRegression

import mlflow
from utils import fetch_logged_data


def main():
    # enable autologging
    mlflow.sklearn.autolog()

    # prepare training data
    X = np.array([[1, 1], [1, 2], [2, 2], [2, 3]])
    y = np.dot(X, np.array([1, 2])) + 3

    # train a model
    model = LinearRegression()
    with mlflow.start_run() as run:
        model.fit(X, y)
        print("Logged data and model in run {}".format(run.info.run_id))

    # show logged data
    for key, data in fetch_logged_data(run.info.run_id).items():
        print("\n---------- logged {} - ---------".format(key))
        pprint(data)


if __name__ == "__main__":
    main()

소스코드가 아주 간결하고 잘 설명되어 있다. 내용은 Linear Regression을 사용하는 간단한 머신러닝 코드다.
여기서는 2가지 코드가 눈에 띈다.

  • mlflow.sklearn.autolog()
    • Automatic Logging 기능을 사용하는 설정이다.
    • 코드 앞부분에 들어가야 한다.
  • with mlflow.start_run() as run:
    • MLflow 의 실행(run) 의 시작을 알리는 컨텍스트 매니저 구문이다.
    • run 에는 실행과 관련된 내용이 들어간다.

이제 다음 명령어로 실행해보자.

$ python sklearn_autolog/linear_regression.py

실행하고 나면 위와같은 출력이 나온다.
warning 은 일단 무시하면 될듯하고.. 로그를 좀 살펴보면, run_id  8f93587bcd384c198daee5aaef6f5c4b 로 생성되었고, 다음 사항들이 자동으로 기록한 것을 알 수 있다.

  • params
    • 모델 생성(위에서는 LinearRegression)에 사용하는 params 를 기록한다.
    • 부연 설명하면... copy_X, fit_intercept 등의 파라미터는 LinearRegression  __init__ 파라미터다.
  • metrics
    • 모델 훈련 중에 평가하는 metrics를 기록한다.
    • 위의 경우, mae, mse, r2_score, rmse, score (이건 뭔지 모르겠다.) 를 모두 기록해주었다.
  • tags
    • 이 실행에 관련된 tag 를 기록한다.
    • 기본적으로 모델의 패키지와 클래스 이름을 기록한다.
  • artifacts
    • 실행에 대한 메타 정보와 모델 파일을 기록한다.

실제로 잘 생성되었는지 mlruns/ 에서 확인해보자.

$ tree mlruns/

8f93587bcd384c198daee5aaef6f5c4b 디렉토리에 각종 내용들이 로깅된 파일들이 있는 것을 볼 수 있다.
실제 어떤 값들이 들어가있는지 쉽게 보기위해 웹서버로 접속해서 봐보자.

$ mlflow ui
[2021-05-01 14:36:15 +0900] [87757] [INFO] Starting gunicorn 20.1.0
[2021-05-01 14:36:15 +0900] [87757] [INFO] Listening at: http://127.0.0.1:5000 (87757)
[2021-05-01 14:36:15 +0900] [87757] [INFO] Using worker: sync
[2021-05-01 14:36:15 +0900] [87759] [INFO] Booting worker with pid: 87759

params , metrics, tags 등을 좀 더 자세히 확인해보기 위해 sklearn 모델을 클릭하여 실행 상세 페이지에 들어가보자.

위에서 출력한 내용들이 모두 잘 들어가있는 것을 볼 수 있다.

 

pipeline.py

이번엔 skelarn_autolog/pipeline.py 예제를 살펴보자.
이 파일은 다음처럼 생겼다.

from pprint import pprint

import numpy as np
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline

import mlflow
from utils import fetch_logged_data


def main():
    # enable autologging
    mlflow.sklearn.autolog()

    # prepare training data
    X = np.array([[1, 1], [1, 2], [2, 2], [2, 3]])
    y = np.dot(X, np.array([1, 2])) + 3

    # train a model
    pipe = Pipeline([("scaler", StandardScaler()), ("lr", LinearRegression())])
    with mlflow.start_run() as run:
        pipe.fit(X, y)
        print("Logged data and model in run: {}".format(run.info.run_id))

    # show logged data
    for key, data in fetch_logged_data(run.info.run_id).items():
        print("\n---------- logged {} ----------".format(key))
        pprint(data)


if __name__ == "__main__":
    main()

sklearn.pipeline.Pipeline 을 사용하는 간단한 머신러닝 코드다.
바로 실행해보자.

$ python sklearn_autolog/pipeline.py

logged_params 를 보면 Pipeline 에 들어가는 모든 파라미터를 기록하는 것을 볼 수 있다.
기록된 값 역시 mlruns/ 에 저장된다.

 

grid_search_cv.py

마지막으로, skelarn_autolog/grid_search_cv.py 예제를 살펴보자.
다음처럼 생겼다.

from pprint import pprint

import pandas as pd
from sklearn import svm, datasets
from sklearn.model_selection import GridSearchCV

import mlflow
from utils import fetch_logged_data


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)

    # show data logged in the parent run
    print("========== parent run ==========")
    for key, data in fetch_logged_data(run.info.run_id).items():
        print("\n---------- logged {} ----------".format(key))
        pprint(data)

    # show data logged in the child runs
    filter_child_runs = "tags.mlflow.parentRunId = '{}'".format(run.info.run_id)
    runs = mlflow.search_runs(filter_string=filter_child_runs)
    param_cols = ["params.{}".format(p) for p in parameters.keys()]
    metric_cols = ["metrics.mean_test_score"]

    print("\n========== child runs ==========\n")
    pd.set_option("display.max_columns", None)  # prevent truncating columns
    print(runs[["run_id", *param_cols, *metric_cols]])


if __name__ == "__main__":
    main()

iris 데이터셋을 사용하고, svm 모델을 사용하는데, 이 때 GridSearchCV 를 사용하여 최적의 모델 파라미터를 찾는 머신러닝 코드다.
# show data logged in the parent run 아래 부분은 뭔가 양이 많은데, 그냥 로깅된 내용을 출력해주는 부분이므로, 여기서는 주의 깊게 봐지 않아도 된다.

아무튼 이 코드도 실행해보자.

$ python sklearn_autolog/grid_search_cv.py

출력된 내용을 보면 크게 parent run  child runs 으로 구성해볼 수 있다.
parent run 에서는 전체 파이프라인에 들어간 파라미터 값들을 기록하고, 또 이 GridSearch 를 통해 찾은 최적의 파라미터 값을 기록한다. (best_C, best_kernel ).
child runs 에서는 GridSearch 진행할 때 각각 파라미터 경우의 수대로 run 들을 실행하고 기록한 모습을 볼 수 있다. 이 때 child runs 들도 각각 하나의 run 이 되므로 run_id 를 가지게 된다. 즉 GridSearch 에서 파라미터 조합의 경우의 수가 많아지면, 그만큼의 실행(run) 이 생기게 된다.

실제 mlruns 를 확인해보면 이 child run 들이 생긴 것을 볼 수 있다.
(다만 parent run 과 별다른 디렉토리 구분은 없다. 즉 누가 child run 인지 디렉토리 구조로는 파악이 잘 안된다.)

그렇다면 웹서버에서는 어떻게 보여줄까?
웹서버에서도 child run 들을 parent run 들과 구분 없이 보여줄까?
이를 확인하기 위해 웹서버로 접속해서 확인해보자.

재밌게도 웹서버에서는 parent run 만 보인다.
grid_search_cv.py 가 있는 행에 + 버튼을 눌러보면 아래와 같이 child runs 가 나온다.

run 자체는 GridSearch 에 맞게 독립적으로 여러 개로 생성하되, run 간에 Parent, Child 관계를 가질 수 있는 것이다.
parent_run_id  mlruns 디렉토리를 검색해보면, 이러한 관계가 어떻게 구성될 수 있는지 알 수 있다.

mlruns 에서 child run 의 디렉토리 구조를 살펴보면 tags/mlflow.parentRunId 가 있는 것을 볼 수 있다.
그리고 이 파일에 위 사진처럼 부모 run_id 가 기록되어 있다. (b09de55d441e4a6ea0386f45c58dd96c  dc302019f7fb45ffa82165fcd679b84a  parent run 이다.)

그리고 child run  artifact 과 관련하여 어떤 것도 기록하지 않고, metrics, params, tags 만 기록한다. artifacts 는 최종적으로 최적화된 모델을 사용하는 parent run 에서만 기록한다.


정리

  • mlflow.sklearn.autolog() 기능으로 로깅 함수를 쓰지 않아도 자동 로깅을 사용할 수 있다.
    • autolog() 는 머신러닝 프레임워크별로 지원한다. 이에 대한 내용은 여기에서 확인하자.
    • artifacts ,params, metrics, tags 등을 모두 기록한다.
  • GridSearch 를 쓰는 경우 여러 개의 run 들을 만들어 실행하고 기록한다.
    • run  parent run  child run 으로 구성된다.
    • child run  GridSearch 에 사용되는 파라미터 별로 실행한다.
    • parent run  child run 중 가장 최적화된 파라미터를 가지고 실행한다.
    • parent run  artifacts 를 기록한다.
    • 웹서버에서도 parent - child 구조를 확인할 수 있다.

이전 글에서 모델러가 로깅을 위해 mlflow 를 알고 써야하는 의존성에 대해서 걱정했었는데, 자동 로깅 기능을 사용하면 이러한 걱정이 좀 많이 내려가지 않을까 싶다.

반응형

MLflow.1.Quick Review ( 오작동 일부 수정 )

인공지능,AI,학습,ML,Tensorflow, Cafee2,MLFlow/MLFlow
반응형

# 참조 : https://dailyheumsi.tistory.com/257?category=980484

 

사전 준비

  • 파이썬 3.8.7과 가상환경
$ python --version
Python 3.8.7

Quick Start

설치

$ pip install mlflow
$ mlflow --version
mlflow, version 1.15.0

 

기본 동작 이해하기

예제 코드를 받기 위해 mlflow 공식 github 코드도 다운받자.
이후 examples/quickstart 경로로 들어가자

$ git clone https://github.com/mlflow/mlflow
$ cd mlflow/examples/quickstart
$ ls -al
total 8
drwxr-xr-x   5 heumsi  staff  160  4 24 14:20 .
drwxr-xr-x  31 heumsi  staff  992  4 24 14:18 ..
-rw-r--r--   1 heumsi  staff  494  4 24 14:18 mlflow_tracking.py

mlflow_tracking.py 라는 파일이 보이는데, 이 파일은 이렇게 생겼다.

# mlflow_tracking.py

import os
from random import random, randint

from mlflow import log_metric, log_param, log_artifacts

if __name__ == "__main__":
    print("Running mlflow_tracking.py")

    log_param("param1", randint(0, 100))

    log_metric("foo", random())
    log_metric("foo", random() + 1)
    log_metric("foo", random() + 2)

    if not os.path.exists("outputs"):
        os.makedirs("outputs")
    with open("outputs/test.txt", "w") as f:
        f.write("hello world!")

    log_artifacts("outputs")

mlflow 패키지로부터 다음 세 개를 가져와 사용하는 것을 알 수 있다.

  • log_param
  • log_metric
  • log_artifacts

log 라는 이름만 봐도 뭔가를 기록하는 동작을 하는구나하고 감이온다.

이제 이 파일을 파이썬으로 실행해보자.

$ python mlflow_tracking.py
Running mlflow_tracking.py

실행하고 나면 다음과 mlruns  outputs 디렉토리가 생겨있다.

$ ls -al
total 8
drwxr-xr-x   5 heumsi  staff  160  4 24 14:20 .
drwxr-xr-x  31 heumsi  staff  992  4 24 14:18 ..
-rw-r--r--   1 heumsi  staff  494  4 24 14:18 mlflow_tracking.py
drwxr-xr-x   4 heumsi  staff  128  4 24 14:20 mlruns
drwxr-xr-x   3 heumsi  staff   96  4 24 14:20 outputs

어떻게 생겨있는지 tree 로 확인해보면

디렉토리를 보면 다음 세 디렉토리가 눈에 띈다.

  • artifacts
  • metrics
  • params

음.. 아까 log_param 등의 함수로 기록했던게 여기 있을거 같다.
위 디렉토리들 내부에 있는 파일을 까서 확인해보자.,

역시 그렇다.
log_param, log_metric 함수로 넘겼던 값들이 위 파일들에 기록된다.
특히 metric 의 경우 (위에서 metrics/foo, 왼쪽에서 두 번째 파일) 타임스탬프가 같이 기록되는 것을 알 수 있다.

 

웹 대시보드

mlflow ui 명령어로 대시보드용 웹서버를 띄울 수 있다고 한다.

$ mlflow ui
# 주의 : "mlflow ui" 를 실행하는 디렉토리는 mlruns 가 생성되어 있는 곳이어야 한다.

[2021-04-24 15:57:58 +0900] [59547] [INFO] Starting gunicorn 20.1.0
[2021-04-24 15:57:58 +0900] [59547] [INFO] Listening at: http://127.0.0.1:5000 (59547)
[2021-04-24 15:57:58 +0900] [59547] [INFO] Using worker: sync
[2021-04-24 15:57:58 +0900] [59549] [INFO] Booting worker with pid: 59549

http://127.0.0.1:5000 로 들어가보면

방금 파일로 기록된 내용들이 대시보드에 등장하는 것을 알 수 있다.
Artifact Location 을 보면 웹 서버가 파일을 어느 디렉토리에 마운트해서 읽어오는지 알 수 있다.

 

MLflow 프로젝트

이번엔 실제 ML 모델에 mlflow 를 적용해보자.
mlflow/examples/ 에 예제가 꽤 많이 있는데, 여기서는 scikit-learn 모델을 사용해본다.

먼저 scikit-learn 을 설치한다.

$ pip install sklearn
$ python -c "import sklearn; print(sklearn.__version__)"
0.24.1

mlflow/examples 에 가보면 중간에 이렇게 sklearn 모델 예제들이 있다.

$ ls -al
...
drwxr-xr-x   5 heumsi  staff   160  4 24 14:18 sklearn_elasticnet_diabetes
drwxr-xr-x   7 heumsi  staff   224  4 24 14:18 sklearn_elasticnet_wine
drwxr-xr-x   5 heumsi  staff   160  4 24 14:18 sklearn_logistic_regression

이 중에서 우리는 sklearn_elasticnet_wine 을 사용해본다.

sklearn_elasticnet_wine 의 패키지 구조는 다음과 같다.

$ tree sklearn_elasticnet_wine
sklearn_elasticnet_wine
├── MLproject
├── conda.yaml
├── train.ipynb
├── train.py
└── wine-quality.cs

핵심이 되는 MLproject 를 먼저 확인해보면

# MLProject

name: tutorial

conda_env: conda.yaml

entry_points:
  main:
    parameters:
      alpha: {type: float, default: 0.5}
      l1_ratio: {type: float, default: 0.1}
    command: "python train.py {alpha} {l1_ratio}"

MLProject  sklearn_elasticnet_wine 에 대한 전체적인 소개와 설정 값들을 담은 프로젝트 파일이라 볼 수 있다.

다음으로 train.py 를 확인해보면

# train.py

import os
import warnings
import sys

import pandas as pd
import numpy as np
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
from sklearn.model_selection import train_test_split
from sklearn.linear_model import ElasticNet
from urllib.parse import urlparse
import mlflow
import mlflow.sklearn

import logging

logging.basicConfig(level=logging.WARN)
logger = logging.getLogger(__name__)


def eval_metrics(actual, pred):
    rmse = np.sqrt(mean_squared_error(actual, pred))
    mae = mean_absolute_error(actual, pred)
    r2 = r2_score(actual, pred)
    return rmse, mae, r2


if __name__ == "__main__":
    warnings.filterwarnings("ignore")
    np.random.seed(40)

    # Read the wine-quality csv file from the URL
    csv_url = (
        "http://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-red.csv"
    )
    try:
        data = pd.read_csv(csv_url, sep=";")
    except Exception as e:
        logger.exception(
            "Unable to download training & test CSV, check your internet connection. Error: %s", e
        )

    # Split the data into training and test sets. (0.75, 0.25) split.
    train, test = train_test_split(data)

    # The predicted column is "quality" which is a scalar from [3, 9]
    train_x = train.drop(["quality"], axis=1)
    test_x = test.drop(["quality"], axis=1)
    train_y = train[["quality"]]
    test_y = test[["quality"]]

    alpha = float(sys.argv[1]) if len(sys.argv) > 1 else 0.5
    l1_ratio = float(sys.argv[2]) if len(sys.argv) > 2 else 0.5

    with mlflow.start_run():
        lr = ElasticNet(alpha=alpha, l1_ratio=l1_ratio, random_state=42)
        lr.fit(train_x, train_y)

        predicted_qualities = lr.predict(test_x)

        (rmse, mae, r2) = eval_metrics(test_y, predicted_qualities)

        print("Elasticnet model (alpha=%f, l1_ratio=%f):" % (alpha, l1_ratio))
        print("  RMSE: %s" % rmse)
        print("  MAE: %s" % mae)
        print("  R2: %s" % r2)

        mlflow.log_param("alpha", alpha)
        mlflow.log_param("l1_ratio", l1_ratio)
        mlflow.log_metric("rmse", rmse)
        mlflow.log_metric("r2", r2)
        mlflow.log_metric("mae", mae)

        tracking_url_type_store = urlparse(mlflow.get_tracking_uri()).scheme

        # Model registry does not work with file store
        if tracking_url_type_store != "file":

            # Register the model
            # There are other ways to use the Model Registry, which depends on the use case,
            # please refer to the doc for more information:
            # https://mlflow.org/docs/latest/model-registry.html#api-workflow
            mlflow.sklearn.log_model(lr, "model", registered_model_name="ElasticnetWineModel")
        else:
            mlflow.sklearn.log_model(lr, "model")

전체적으로 머신러닝 모델을 학습하고 테스트하는 코드다. 다만 중간 중간에 다음 함수들이 눈에 띈다.

  • mlflow.log_param
  • mlflow.log_metric
  • mlflow.sklearn.log_model
  • mlflow 의 이 함수들을 사용하여 파라미터 값이나 결과 값을 기록하는 것을 알 수 있다.

이제 이 MLflow 프로젝트를 실행해보자.
mlflow run 명령어를 사용한다. (참고로 나는 conda 사용안할거기 때문에 --no-conda 옵션을 주었다)

$ mlflow run sklearn_elasticnet_wine -P alpha=0.5 --no-conda

2021/04/24 14:40:43 INFO mlflow.projects.utils: === Created directory /var/folders/nr/8lrr92zn1rbbsrtm7nnzfp800000gn/T/tmpbdfgejik for downloading remote URIs passed to arguments of type 'path' ===
2021/04/24 14:40:43 INFO mlflow.projects.backend.local: === Running command 'python train.py 0.5 0.1' in run with ID 'f2bec5126785418b9ba84a67a9a86d92' ===
Elasticnet model (alpha=0.500000, l1_ratio=0.100000):
  RMSE: 0.7460550348172179
  MAE: 0.576381895873763
  R2: 0.21136606570632266
2021/04/24 14:40:48 INFO mlflow.projects: === Run (ID 'f2bec5126785418b9ba84a67a9a86d92') succeeded ===

위 명령어를 실행하고 나면 동일 경로에 다음처럼 mlruns 디렉토리가 생기고, 다음처럼 생겼다.

$ ls -al
...
drwxr-xr-x   4 heumsi  staff   128  4 24 14:37 mlruns
...

$ tree mlruns -L 3
mlruns
└── 0
    ├── e36ebff4f2444161af4472b3a11d408b
    │   ├── artifacts
    │   ├── meta.yaml
    │   ├── metrics
    │   ├── params
    │   └── tags
    └── meta.yaml

전체적인 구성은 위에서 본 예제와 거의 같다.
다시 mlflow ui 명령어로 대시보드 웹서버를 실행시킨 뒤 접속해서 이를 확인해보자

$ mlflow ui
# 주의 : "mlflow ui" 를 실행하는 디렉토리는 mlruns 가 생성되어 있는 곳이어야 한다.

[2021-04-24 15:57:58 +0900] [59547] [INFO] Starting gunicorn 20.1.0
[2021-04-24 15:57:58 +0900] [59547] [INFO] Listening at: http://127.0.0.1:5000 (59547)
[2021-04-24 15:57:58 +0900] [59547] [INFO] Using worker: sync
[2021-04-24 15:57:58 +0900] [59549] [INFO] Booting worker with pid: 59549

방금 돌린 모델이 잘 들어가있는 것을 알 수 있다.

 

모델 서빙

이번엔 mlflow/examples 내에 있는 sklearn_logistic_regression MLflow 프로젝트를 살펴보자.
sklearn_logistic_regression 의 내부 구조는 이렇다.

$ tree sklearn_logistic_regression
sklearn_logistic_regression
├── MLproject
├── conda.yaml
└── train.py

train.py 는 이렇게 생겼다.

# 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])
    lr = LogisticRegression()
    lr.fit(X, y)
    score = lr.score(X, y)
    print("Score: %s" % score)
    mlflow.log_metric("score", score)
    mlflow.sklearn.log_model(lr, "model")
    print("Model saved in run %s" % mlflow.active_run().info.run_uuid)

위 예제들과 별반 다른바 없는 코드다.
이제 이 파일을 파이썬으로 실행한다.

$ python sklearn_logistic_regression/train.py --no-conda
Score: 0.6666666666666666
Model saved in run 40cfabcdc6d2439fa97ca3d98bfe1ea1

결과물은 역시 ./mlruns 에 추가된다.
40cfabcdc6d2439fa97ca3d98bfe1ea1 라는 id 를 가지고 새로운 디렉토리가 추가되었음을 알 수 있다.

mlruns
└── 0
    ├── 40cfabcdc6d2439fa97ca3d98bfe1ea1
    │   ├── artifacts
    │   ├── meta.yaml
    │   ├── metrics
    │   ├── params
    │   └── tags
    ├── e36ebff4f2444161af4472b3a11d408b
    │   ├── artifacts
    │   ├── meta.yaml
    │   ├── metrics
    │   ├── params
    │   └── tags
    └── meta.yaml

웹 대시보드에도 역시 추가가 되어있는걸 확인할 수 있다.

이제 이 MLflow 프로젝트를 서빙하는 서버를 띄워보자.
mlflow models serve -m runs:/<RUN_ID>/model 명령어로 가능하다.
이 때 RUN_ID 는 위에서 확인한 40cfabcdc6d2439fa97ca3d98bfe1ea1 를 넣어주면 된다.

$ mlflow models serve -m runs:/40cfabcdc6d2439fa97ca3d98bfe1ea1/model --no-conda --port 5001 --host 0.0.0.0
...

2021/04/24 15:32:49 INFO mlflow.models.cli: Selected backend for flavor 'python_function'
2021/04/24 15:32:49 INFO mlflow.pyfunc.backend: === Running command 'gunicorn --timeout=60 -b 127.0.0.1:5001 -w 1 ${GUNICORN_CMD_ARGS} -- mlflow.pyfunc.scoring_server.wsgi:app'
[2021-04-24 15:32:49 +0900] [58843] [INFO] Starting gunicorn 20.1.0
[2021-04-24 15:32:49 +0900] [58843] [INFO] Listening at: http://127.0.0.1:5001 (58843)
[2021-04-24 15:32:49 +0900] [58843] [INFO] Using worker: sync
[2021-04-24 15:32:49 +0900] [58845] [INFO] Booting worker with pid: 58845
[2021-04-24 15:32:49 +0900] [58843] [INFO] Handling signal: winch

서버가 제대로 잘 동작 하는지 다음처럼 curl 로 요청을 날려보자. 엔드포인트는 /invocations 다.

https://www.mlflow.org/docs/latest/tutorials-and-examples/tutorial.html

Linux>
curl -X POST -H "Content-Type:application/json; format=pandas-split" --data '{"columns":["alcohol", "chlorides", "citric acid", "density", "fixed acidity", "free sulfur dioxide", "pH", "residual sugar", "sulphates", "total sulfur dioxide", "volatile acidity"],"data":[[12.8, 0.029, 0.48, 0.98, 6.2, 29, 3.33, 1.2, 0.39, 75, 0.66]]}' http://192.168.202.133:5001/invocations

Windows>
curl -X POST -H "Content-Type:application/json; format=pandas-split" --data "{\"columns\":[\"alcohol\", \"chlorides\", \"citric acid\", \"density\", \"fixed acidity\", \"free sulfur dioxide\", \"pH\", \"residual sugar\", \"sulphates\", \"total sulfur dioxide\", \"volatile acidity\"],\"data\":[[12.8, 0.029, 0.48, 0.98, 6.2, 29, 3.33, 1.2, 0.39, 75, 0.66]]}" http://192.168.202.133:5001/invocations

[4.132771301547059]

# 아래는 에러 나서 안됨.
# $ curl -d '{"columns":["x"], "data":[[1], [-1]]}' -H 'Content-Type: application/json; format=pandas-split' -X POST localhost:5001/invocations
# [1, 0]

응답이 잘 오는 것을 확인할 수 있다.

 

그 외

여기서 살펴보지 않았지만, CLI 커맨드만 보면 대략 어떤 기능들이 더 있는지 알 수 있다.

후기

  • MLflow는 머신러닝 모델을 train, test, validation 할 때마다 그 값들을 기록해주는 툴이다.
    • 웹 대시보드가 좀 이쁘네.
    • 아직 뭔가 컨텐츠가 많이는 없는거 같은데, 개발이 더 되거나 플러그인이 더 있지 않을까?
    • 일단 간단하게 시작할 때 써먹기 좋을듯 하다!
  • 다만 모델러가 MLflow를 알아야 하는 의존성이 생기긴 하네.
    • 모델러의 코드 파일에 MLflow 코드가 일부 들어갈텐데, 이는 감안해야 하는걸까?
  • 변수, 함수명, 프로젝트 패키지 등에서 네이밍이 아주 직관적이고 간단 명료해서 좋았다.
  • 서빙까지 지원해주는 것도 인상적이다. 내부적으로 어떻게 돌아가는 걸까?
반응형

'인공지능,AI,학습,ML,Tensorflow, Cafee2,MLFlow > MLFlow' 카테고리의 다른 글

MLflow.5.Model Registry  (0) 2021.12.27
MLflow.4.Tracking Server  (0) 2021.12.27
MLflow.3.Experiments & Runs  (0) 2021.12.24
MLflow.2.Automatic logging  (0) 2021.12.24
MLFlow.DB.확인방법  (0) 2021.08.31

MLFlow.DB.확인방법

인공지능,AI,학습,ML,Tensorflow, Cafee2,MLFlow/MLFlow
반응형

1) docker mlflow> ps auxwwwe | grep postgres

호스트와 계정 / 비번, 디비 확인

 

2) docker mlflow> psql -d mlflow mlops

 

3) table목록

mlflow postgre console>=#\dt

 

4) select

mlflow postgre console> select * from alembic_version;

 

9) exit

mlflow postgre console>=#\q

 

 

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND


root         1  0.0  0.7 435336 129752 ?       Ss   Aug19   0:02 /opt/conda/bin/python /opt/conda/bin/mlflow server --backend-store-uri postgresql+psycopg2://mlops:mlops@postgres/mlflow --host 0.0.0.0:5000 --default-artifact-root artifacts HOSTNAME=62861bafe828 POSTGRES_PASSWORD=mlops PWD=/mlflow MLFLOW_S3_ENDPOINT_URL=http://minio:9001 HOME=/root LANG=C.UTF-8 MLFLOW_TRACKING_URI=postgresql+psycopg2://mlops:mlops@postgres/mlflow AWS_SECRET_ACCESS_KEY=minioadmin SHLVL=0 POSTGRES_USER=mlops AWS_ACCESS_KEY_ID=minioadmin LC_ALL=C.UTF-8 PATH=/opt/conda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin POSTGRES_DB=mlflow _=/opt/conda/bin/mlflow

 

root        15  0.0  0.0  15852  4248 ?        Ss   Aug19   0:01 /usr/sbin/sshd LANGUAGE= LC_TIME= LC_CTYPE= LC_MONETARY= TERM= LC_COLLATE= PATH=/opt/conda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/sbin:/sbin LC_ADDRESS= LANG=C.UTF-8 LC_TELEPHONE= LC_MESSAGES= LC_NAME= LC_MEASUREMENT= LC_IDENTIFICATION= LC_ALL=C.UTF-8 PWD=/ LC_NUMERIC= LC_PAPER= HOME=/root

 

root        21  0.0  0.1  27780 23100 ?        S    Aug19   2:32 /opt/conda/bin/python /opt/conda/bin/gunicorn -b 0.0.0.0:5000:5000 -w 4 mlflow.server:app HOSTNAME=62861bafe828 POSTGRES_PASSWORD=mlops PWD=/mlflow MLFLOW_S3_ENDPOINT_URL=http://minio:9001 HOME=/root LANG=C.UTF-8 MLFLOW_TRACKING_URI=postgresql+psycopg2://mlops:mlops@postgres/mlflow AWS_SECRET_ACCESS_KEY=minioadmin SHLVL=0 POSTGRES_USER=mlops AWS_ACCESS_KEY_ID=minioadmin LC_ALL=C.UTF-8 PATH=/opt/conda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin POSTGRES_DB=mlflow _=/opt/conda/bin/mlflow _MLFLOW_SERVER_FILE_STORE=postgresql+psycopg2://mlops:mlops@postgres/mlflow _MLFLOW_SERVER_ARTIFACT_ROOT=artifacts

 

root      2394  0.0  0.7 435480 127108 ?       Sl   Aug26   0:06 /opt/conda/bin/python /opt/conda/bin/gunicorn -b 0.0.0.0:5000:5000 -w 4 mlflow.server:app HOSTNAME=62861bafe828 POSTGRES_PASSWORD=mlops PWD=/mlflow MLFLOW_S3_ENDPOINT_URL=http://minio:9001 HOME=/root LANG=C.UTF-8 MLFLOW_TRACKING_URI=postgresql+psycopg2://mlops:mlops@postgres/mlflow AWS_SECRET_ACCESS_KEY=minioadmin SHLVL=0 POSTGRES_USER=mlops AWS_ACCESS_KEY_ID=minioadmin LC_ALL=C.UTF-8 PATH=/opt/conda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin POSTGRES_DB=mlflow _=/opt/conda/bin/mlflow _MLFLOW_SERVER_FILE_STORE=postgresql+psycopg2://mlops:mlops@postgres/mlflow _MLFLOW_SERVER_ARTIFACT_ROOT=artifacts


root      7767  0.0  0.0  16500  7712 ?        Ss   Aug19   0:00 sshd: root@notty                                                                                                                                                                                                                                                                                                                  t
root      9785  0.0  0.6 410012 102144 ?       Sl   Aug27   0:04 /opt/conda/bin/python /opt/conda/bin/gunicorn -b 0.0.0.0:5000:5000 -w 4 mlflow.server:app HOSTNAME=62861bafe828 POSTGRES_PASSWORD=mlops PWD=/mlflow MLFLOW_S3_ENDPOINT_URL=http://minio:9001 HOME=/root LANG=C.UTF-8 MLFLOW_TRACKING_URI=postgresql+psycopg2://mlops:mlops@postgres/mlflow AWS_SECRET_ACCESS_KEY=minioadmin SHLVL=0 POSTGRES_USER=mlops AWS_ACCESS_KEY_ID=minioadmin LC_ALL=C.UTF-8 PATH=/opt/conda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin POSTGRES_DB=mlflow _=/opt/conda/bin/mlflow _MLFLOW_SERVER_FILE_STORE=postgresql+psycopg2://mlops:mlops@postgres/mlflow _MLFLOW_SERVER_ARTIFACT_ROOT=artifacts


root     13482  0.0  0.6 409756 102000 ?       Sl   Aug28   0:03 /opt/conda/bin/python /opt/conda/bin/gunicorn -b 0.0.0.0:5000:5000 -w 4 mlflow.server:app HOSTNAME=62861bafe828 POSTGRES_PASSWORD=mlops PWD=/mlflow MLFLOW_S3_ENDPOINT_URL=http://minio:9001 HOME=/root LANG=C.UTF-8 MLFLOW_TRACKING_URI=postgresql+psycopg2://mlops:mlops@postgres/mlflow AWS_SECRET_ACCESS_KEY=minioadmin SHLVL=0 POSTGRES_USER=mlops AWS_ACCESS_KEY_ID=minioadmin LC_ALL=C.UTF-8 PATH=/opt/conda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin POSTGRES_DB=mlflow _=/opt/conda/bin/mlflow _MLFLOW_SERVER_FILE_STORE=postgresql+psycopg2://mlops:mlops@postgres/mlflow _MLFLOW_SERVER_ARTIFACT_ROOT=artifacts


root     16465  0.0  0.0      0     0 ?        Zs   Aug29   0:04 [ipython] <defunct>


root     20899  0.0  0.0   5752  3628 pts/0    Ss   08:23   0:00 bash PATH=/opt/conda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOSTNAME=62861bafe828 TERM=xterm POSTGRES_USER=mlops POSTGRES_PASSWORD=mlops POSTGRES_DB=mlflow AWS_ACCESS_KEY_ID=minioadmin AWS_SECRET_ACCESS_KEY=minioadmin MLFLOW_TRACKING_URI=postgresql+psycopg2://mlops:mlops@postgres/mlflow MLFLOW_S3_ENDPOINT_URL=http://minio:9001 LANG=C.UTF-8 LC_ALL=C.UTF-8 HOME=/root


root     20931  0.0  0.0   9392  3080 pts/0    R+   08:42   0:00 ps auxwwwe CONDA_EXE=/opt/conda/bin/conda _CE_M= HOSTNAME=62861bafe828 POSTGRES_PASSWORD=mlops PWD=/mlflow CONDA_PREFIX=/opt/conda MLFLOW_S3_ENDPOINT_URL=http://minio:9001 HOME=/root LANG=C.UTF-8 MLFLOW_TRACKING_URI=postgresql+psycopg2://mlops:mlops@postgres/mlflow CONDA_PROMPT_MODIFIER=(base)  AWS_SECRET_ACCESS_KEY=minioadmin TERM=xterm _CE_CONDA= CONDA_SHLVL=1 SHLVL=1 POSTGRES_USER=mlops AWS_ACCESS_KEY_ID=minioadmin CONDA_PYTHON_EXE=/opt/conda/bin/python CONDA_DEFAULT_ENV=base LC_ALL=C.UTF-8 PATH=/opt/conda/bin:/opt/conda/condabin:/opt/conda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin POSTGRES_DB=mlflow _=/bin/ps


root     27460  0.0  0.6 410012 102000 ?       Sl   Aug23   0:09 /opt/conda/bin/python /opt/conda/bin/gunicorn -b 0.0.0.0:5000:5000 -w 4 mlflow.server:app HOSTNAME=62861bafe828 POSTGRES_PASSWORD=mlops PWD=/mlflow MLFLOW_S3_ENDPOINT_URL=http://minio:9001 HOME=/root LANG=C.UTF-8 MLFLOW_TRACKING_URI=postgresql+psycopg2://mlops:mlops@postgres/mlflow AWS_SECRET_ACCESS_KEY=minioadmin SHLVL=0 POSTGRES_USER=mlops AWS_ACCESS_KEY_ID=minioadmin LC_ALL=C.UTF-8 PATH=/opt/conda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin POSTGRES_DB=mlflow _=/opt/conda/bin/mlflow _MLFLOW_SERVER_FILE_STORE=postgresql+psycopg2://mlops:mlops@postgres/mlflow _MLFLOW_SERVER_ARTIFACT_ROOT=artifacts

반응형

2021-139.아나콘다, 쥬피터 노트북 설치

인공지능,AI,학습,ML,Tensorflow, Cafee2,MLFlow
반응형

아나콘다는 파이썬과 머신러닝에 필요한 라이브러리( Numpy, SciPy, TensorFlow, PyTorch, Jupyter Notebook 등) 들을 호환성 최적화되어 있다.

개인은 무료이나 상용은 유료다.

 

- 아나콘다 사이에서 Individual Edition 설치 ( 기본설치, 왠만한건 다 해제하고 설치 )

- 크롬 기본 브라우저 추천

- 기존에 깔려있는 파이썬 충돌 고려해서 설치 필요.

반응형

docker-compose, models.config, http 테스트 호출

인공지능,AI,학습,ML,Tensorflow, Cafee2,MLFlow/Tensorflow
반응형

docker-compose.yml

    tfsservice:
        build:
            context: .
            dockerfile: Dockerfile.tfs
        image: tensorflow/serving
        container_name: tfs
        hostname: tfs
        command:
            - '--model_config_file=/models/models.config'
            - '--model_config_file_poll_wait_seconds=60'
        volumes:
            - ./volume.tfs/models:/models/
        ports:
            - 8500:8500
            - 8501:8501
        networks:
            - backend

 

models.config

git clone https://github.com/tensorflow/serving


model_config_list:
{
    config:
    {
        name:"serving"
        base_path:"/models/serving/tensorflow_serving/servables/tensorflow/testdata/saved_model_half_plus_two_cpu"
        model_platform: "tensorflow"
    }
}

 

command line >

curl -d '{"instances": [1.0, 2.0, 5.0]}' -X POST http://localhost:8501/v1/models/serving:predict 
{ 
    "predictions": [2.5, 3.0, 4.5 
    ] 
}


v1/models 는 디폴트로 입력
serving 은 models.config 의 name

 

반응형

MachineLearningCheatSheet

인공지능,AI,학습,ML,Tensorflow, Cafee2,MLFlow/AI, TensorFlow, AzureMLMachineLearning
반응형

 

 

https://docs.microsoft.com/ko-kr/azure/machine-learning/algorithm-cheat-sheet

 

https://download.microsoft.com/download/3/5/b/35bb997f-a8c7-485d-8c56-19444dafd757/azure-machine-learning-algorithm-cheat-sheet-nov2019.pdf?WT.mc_id=docs-article-lazzeri

 

반응형

AttributeError: 'module' object has no attribute 'pack'

인공지능,AI,학습,ML,Tensorflow, Cafee2,MLFlow/Tensorflow
반응형

Attribute tf.pack 이 tf.stack 으로 변경됨.

반응형

NotFoundError: Key ... not found in checkpoint

인공지능,AI,학습,ML,Tensorflow, Cafee2,MLFlow/Tensorflow
반응형

오류 상황) 변수를 저장후 출력해보면, 변수명 끝에 _1 이 붙는다.

실행을 한 번더 하면 _2 가 된다.


해결) 커널 리스타트 를 해야 한다. 중간부터 다시 실행하면 "오류상황" 과 같은 문제가 발생한다.

쥬피터에서는 동그란 화살표의 Restart 버튼을 클릭하면 된다.

반응형

Saver 에서 save 후, CheckpointVariables 변수 보기

인공지능,AI,학습,ML,Tensorflow, Cafee2,MLFlow/Tensorflow
반응형

1) 아래 소스 추가


inspect_checkpoint.py


2) Traine 소스에서, 


임포트후,

from tensorflow.python.tools.inspect_checkpoint import print_tensors_in_checkpoint_file


저장하고,

ckpt_path = saver.save(sess, 'saved1/train1')


출력하면

print_tensors_in_checkpoint_file(ckpt_path, all_tensors=True, tensor_name='', all_tensor_names=False)


결과가 나온다.

tensor_name:  b_h1_3

[ 1.5395054e-03  0.0000000e+00  1.7294792e-02 -1.9801984e-05

 -3.9077952e-04  1.9007076e-07  2.1687772e-02  1.2043750e-05

  2.5410240e-04  0.0000000e+00]











PS) print_tensors_in_checkpoint_file 파라미터 설명


file_name: not a physical file, just the prefix of filenames

If no tensor_name is provided, prints the tensor names and shapes in the checkpoint file. If tensor_name is provided, prints the content of the tensor.(inspect_checkpoint.py)

If all_tensor_names is True, Prints all the tensor names

If all_tensor is 'True`, Prints all the tensor names and the corresponding content.

N.B. all_tensor and all_tensor_names will override tensor_name

반응형