개발자의 개발괴발

[mlflow] mlflow 설치하고 간단히 사용해보기 본문

AI

[mlflow] mlflow 설치하고 간단히 사용해보기

휘발성 기억력 2025. 6. 14. 21:52
반응형

mlflow는 머신러닝 Experiment를 관리하고 재현성 있게 만들기 위한 오픈소스 플랫폼이다.

머신러닝 모델을 학습하다보면 모델 저장도 하고 저장된 모델의 성능같은 부가 정보들을 같이 기록해야한다.

아무 도구 없이 파일로 기록하다보면 기록하기도 힘들고 다시 찾아보기도 힘든데 mlflow를 사용하면 쉽게 기록하고 쉽게 찾아볼 수 있다.

mlflow 설치하기

설치하기는 매우 쉽다.

pip install mlflow

pip로 간단하게 설치할 수 있다.

 

이렇게하면 로컬PC에 바로 설치가 되지만 Docker를 이용해 로컬PC와 환경을 분리하고 싶다.(가상환경을 써도 분리할 수 있지만 dockerfile로 분리해보겠다.)

 

Dockerfile

# 베이스 이미지 (Python 포함된 경량 이미지)
FROM python:3.13-slim

# 환경 변수 설정
ENV MLFLOW_HOME=/app
ENV MLFLOW_TRACKING_URI=http://0.0.0.0:5000

# 작업 디렉토리 생성
WORKDIR $MLFLOW_HOME

# 필수 패키지 설치
RUN pip install --upgrade pip && \
    pip install mlflow && \
    apt-get update && apt-get install -y curl && \
    apt-get clean && rm -rf /var/lib/apt/lists/*

# 기본 포트 오픈 (MLflow UI용)
EXPOSE 5000

# 기본 명령어: mlflow 서버 실행
CMD ["mlflow", "server", "--host", "0.0.0.0", "--port", "5000"]

 

docker로 띄우기

shell에서 아래 명령어 실행

# Docker 이미지 빌드
docker build -t mlflow-server .

# Docker 컨테이너 실행
docker run -p 5000:5000 mlflow-server

# 실행 후 로그
[2025-06-14 11:16:18 +0000] [20] [INFO] Starting gunicorn 23.0.0
[2025-06-14 11:16:18 +0000] [20] [INFO] Listening at: http://0.0.0.0:5000 (20)
[2025-06-14 11:16:18 +0000] [20] [INFO] Using worker: sync
[2025-06-14 11:16:18 +0000] [21] [INFO] Booting worker with pid: 21
[2025-06-14 11:16:18 +0000] [22] [INFO] Booting worker with pid: 22
[2025-06-14 11:16:18 +0000] [23] [INFO] Booting worker with pid: 23
[2025-06-14 11:16:18 +0000] [24] [INFO] Booting worker with pid: 24

 

간단히 실행이 되었고 localhost:5000으로 접속하면 mlflow 화면을 볼 수 있다.

 

docker compose로 띄우기

docker-compose.yaml

(--backend-store-uri 인자 입력시 sqlite://// 에서 슬래쉬가 4개임)

version: "3"
services:
  mlflow:
    image: mlflow-server
    container_name: mlflow-server
    working_dir: /app
    ports:
      - "5000:5000"
    volumes:
      - ./mlruns:/mlruns
      - ./mlflow.db:/mlflow.db
    command:
      - sh
      - -c
      - |
        pip install mlflow && \
        mlflow server \
          --backend-store-uri sqlite:////mlflow.db/mlflow.db \
          --default-artifact-root /mlruns \
          --host 0.0.0.0 \
          --port 5000

 

docker compose 명령어 실행

docker compose up
[+] Running 1/0
 ✔ Container mlflow-server  Recreated                                                                                                                                                      0.0s 
Attaching to mlflow-server...
mlflow-server  | Requirement already satisfied: h11>=0.8 in /usr/local/lib/python3.13/site-packages (from uvicorn<1->mlflow-skinny==3.1.0->mlflow) (0.16.0)
mlflow-server  | WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager, possibly rendering your system unusable. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv. Use the --root-user-action option if you know what you are doing and want to suppress this warning.
mlflow-server  | INFO  [alembic.runtime.migration] Context impl SQLiteImpl.
mlflow-server  | INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
mlflow-server  | [2025-06-14 11:33:33 +0000] [25] [INFO] Starting gunicorn 23.0.0
mlflow-server  | [2025-06-14 11:33:33 +0000] [25] [INFO] Listening at: http://0.0.0.0:5000 (25)
mlflow-server  | [2025-06-14 11:33:33 +0000] [25] [INFO] Using worker: sync
mlflow-server  | [2025-06-14 11:33:33 +0000] [26] [INFO] Booting worker with pid: 26
mlflow-server  | [2025-06-14 11:33:33 +0000] [27] [INFO] Booting worker with pid: 27
mlflow-server  | [2025-06-14 11:33:33 +0000] [28] [INFO] Booting worker with pid: 28
mlflow-server  | [2025-06-14 11:33:33 +0000] [29] [INFO] Booting worker with pid: 29
mlflow-server  | 2025/06/14 11:33:43 INFO mlflow.store.db.utils: Creating initial MLflow database tables...
mlflow-server  | 2025/06/14 11:33:43 INFO mlflow.store.db.utils: Updating database tables
mlflow-server  | INFO  [alembic.runtime.migration] Context impl SQLiteImpl.
mlflow-server  | INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
mlflow-server  | INFO  [alembic.runtime.migration] Context impl SQLiteImpl.
mlflow-server  | INFO  [alembic.runtime.migration] Will assume non-transactional DDL.

 

똑같이 http://localhost:5000으로 접속하면 같은 화면을 볼 수 있다.

 

Model 저장하기

https://mlflow.org/docs/latest/ml/tracking/quickstart

 

MLflow Tracking Quickstart | MLflow

Welcome to MLflow!

mlflow.org

여기에 있는걸 그대로 따라해보면 쉽다.

따라하기 전에 uv를 이용해 가상환경을 만들고 실행해보겠다.

uv venv --python 3.13
uv init

uv add pandas scikit-learn mlflow

 

전체 코드를 하나의 파일로 만들어주고 실행해보자.

mlflow-trainig.py

(코드 중간에 set_tracking_uri에서 포트를 아까 설정했던 5000번 포트로 변경)

import mlflow
from mlflow.models import infer_signature

import pandas as pd
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score


# Load the Iris dataset
X, y = datasets.load_iris(return_X_y=True)

# Split the data into training and test sets
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)

# Define the model hyperparameters
params = {
    "solver": "lbfgs",
    "max_iter": 1000,
    "multi_class": "auto",
    "random_state": 8888,
}

# Train the model
lr = LogisticRegression(**params)
lr.fit(X_train, y_train)

# Predict on the test set
y_pred = lr.predict(X_test)

# Calculate metrics
accuracy = accuracy_score(y_test, y_pred)


# Set our tracking server uri for logging
mlflow.set_tracking_uri(uri="http://127.0.0.1:5000")

# Create a new MLflow Experiment
mlflow.set_experiment("MLflow Quickstart")

# Start an MLflow run
with mlflow.start_run():
    # Log the hyperparameters
    mlflow.log_params(params)

    # Log the loss metric
    mlflow.log_metric("accuracy", accuracy)

    # Infer the model signature
    signature = infer_signature(X_train, lr.predict(X_train))

    # Log the model, which inherits the parameters and metric
    model_info = mlflow.sklearn.log_model(
        sk_model=lr,
        name="iris_model",
        signature=signature,
        input_example=X_train,
        registered_model_name="tracking-quickstart",
    )

    # Set a tag that we can use to remind ourselves what this model was for
    mlflow.set_logged_model_tags(
        model_info.model_id, {"Training Info": "Basic LR model for iris data"}
    )

 

이걸 내 PC에서 돌리면 아래처럼 에러가 난다.

OSError: [Errno 30] Read-only file system: '/mlruns'

에러가 나는 이유는 위의 mlflow-trainig.py 파일을 로컬에서 실행시켰는데 로컬에서 /mlruns를 생성하려고해서 에러가 난다.

mlflow는 artifact를 /mlruns에 기본으로 저장하려고 한다.

아마도 mlflow가 training을 같은 환경(docker container 내에서)이라고 생각해서 /mlruns로 저장을 시도해서 그런것 같다.

mlflow를 실행할때 주는 인자 중 --default-artifact-root를 local 파일이 아닌 s3같은 다른 공유 스토리지로하면 로컬에서도 문제없이 트레이닝하고 mlflow에 저장할 수 있다.

# uv 설치
curl -LsSf https://astral.sh/uv/install.sh | sh
. $HOME/.local/bin/env # source가 없어서 .로 대신하면 된다.

uv add pandas scikit-learn mlflow

apt update && apt install vim -y

위 처럼 환경설정을 해주고 저 코드를 docker container 내에서 실행하면 정상적으로 된다.

 

다시 mlflow에 접속해서 보면 실험들이 저장된게 보인다.

 

mlruns dir을 보면 아래처럼 여러가지가 생겼다.

mlruns
└── 1
    └── models
        └── m-1c4616bc82b040f4ba733d37be617bf3
            └── artifacts
                ├── conda.yaml
                ├── input_example.json
                ├── MLmodel
                ├── model.pkl
                ├── python_env.yaml
                ├── requirements.txt
                └── serving_input_example.json
반응형

'AI' 카테고리의 다른 글

[MCP] MCP 서버 만들어보기  (0) 2025.04.10