본문으로 건너뛰기

로컬 실험 환경

로컬에서 model을 개발하고 실험을 추적하기 위한 환경을 구축합니다. Docker 기반 개발환경으로 MLflow와 storage를 간편하게 실행할 수 있습니다.

사전 요구사항

이 가이드를 진행하기 전에 사전 요구사항을 완료하세요:

  • Docker 설치
  • NVIDIA Container Toolkit 설치 (GPU 사용 시)

Docker 개발 환경 구성

로컬에서 실험 추적과 artifact 저장을 위한 개발환경을 Docker로 구성합니다. MLflow와 MinIO를 사용하여 완전한 ML 개발 인프라를 구축할 수 있습니다.

MLflow와 MinIO
  • MLflow: Experiment 추적, model 버전 관리, artifact 저장을 제공하는 open-source platform입니다.
  • MinIO: S3 호환 object storage로, model artifact와 dataset을 로컬에서 관리할 수 있습니다.

Dockerfile 생성

Dockerfile 파일을 생성합니다:

Dockerfile
FROM python:3.9-slim

# Working directory 설정
WORKDIR /mlflow

# MLflow와 S3 의존성 설치
# - mlflow==3.1.1: 재현 가능하도록 버전 고정
# - boto3: S3/MinIO artifact storage 지원
RUN pip install --no-cache-dir \
mlflow==3.1.1 \
boto3==1.34.162

# 보안을 위해 non-root user 생성
RUN useradd -m -u 1000 mlflow && \
chown -R mlflow:mlflow /mlflow

# Non-root user로 전환
USER mlflow

# MLflow port 노출
EXPOSE 5000

# Health check 설정
HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \
CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:5000/health').read()" || exit 1

# Default command
CMD ["mlflow", "server", "--host", "0.0.0.0", "--port", "5000"]

Docker Compose 설정

docker-compose.yaml 파일을 생성합니다:

docker-compose.yaml
services:
# MinIO server for artifact storage
# Stable 2024-07 release, tested with MLflow 3.1.1
minio:
image: minio/minio:RELEASE.2024-07-15T19-02-30Z
container_name: mlflow-minio
ports:
- '9000:9000' # API port
- '9001:9001' # Web console port
environment:
MINIO_ROOT_USER: ${MINIO_ROOT_USER:-minio}
MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:-miniostorage}
volumes:
- minio-data:/data
command: server /data --console-address ":9001"
healthcheck:
test: mc ready local || exit 1
interval: 30s
timeout: 5s
retries: 3
start_period: 10s

# MinIO bucket 생성 (일회성 설정)
minio-create-bucket:
image: minio/mc:RELEASE.2024-07-15T17-46-06Z
container_name: mlflow-minio-setup
depends_on:
minio:
condition: service_healthy
environment:
MINIO_ROOT_USER: ${MINIO_ROOT_USER:-minio}
MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:-miniostorage}
entrypoint: >
/bin/sh -c "
mc alias set mlflowminio http://minio:9000 $${MINIO_ROOT_USER} $${MINIO_ROOT_PASSWORD} &&
if ! mc ls mlflowminio/mlflow >/dev/null 2>&1; then
mc mb mlflowminio/mlflow &&
echo 'Bucket mlflow created successfully';
else
echo 'Bucket mlflow already exists';
fi
"

# MLflow tracking server
mlflow:
build:
context: .
dockerfile: Dockerfile
container_name: mlflow-server
ports:
- '5000:5000'
environment:
MLFLOW_S3_ENDPOINT_URL: http://minio:9000
AWS_ACCESS_KEY_ID: ${MINIO_ROOT_USER:-minio}
AWS_SECRET_ACCESS_KEY: ${MINIO_ROOT_PASSWORD:-miniostorage}
depends_on:
minio:
condition: service_healthy
minio-create-bucket:
condition: service_completed_successfully
volumes:
- mlflow-data:/mlflow
command:
- mlflow
- server
- --backend-store-uri
- sqlite:////mlflow/mlflow.db
- --artifacts-destination
- s3://mlflow/
- --host
- 0.0.0.0
- --port
- '5000'

volumes:
minio-data:
mlflow-data:

Container 실행

# 현재 디렉토리 확인 (Dockerfile과 docker-compose.yaml이 있는 위치)
pwd

# Image 빌드 및 서비스 시작
docker compose up -d --build

처음 실행 시 image 빌드에 1~2분 소요됩니다.

출력 예시:

[+] Building 47.2s
=> [mlflow] ...
[+] Running 5/5
✔ Network mlflow_default Created
✔ Volume mlflow_minio-data Created
✔ Volume mlflow_mlflow-data Created
✔ Container mlflow-minio Started
✔ Container mlflow-minio-setup Started (자동 bucket 생성)
✔ Container mlflow-server Started

서비스 상태 확인

# Container 상태 확인
docker compose ps

정상 실행 시:

NAME                 IMAGE                                        STATUS
mlflow-minio minio/minio:RELEASE.2024-07-15T19-02-30Z Up (healthy)
mlflow-server mlflow-mlflow Up (healthy)
참고

mlflow-minio-setup은 bucket 생성 후 자동으로 종료됩니다 (Exited).

Container 관리

# 중지
docker compose down

# 로그 확인
docker compose logs -f mlflow

# 완전 초기화 (데이터 삭제)
docker compose down -v

MLflow UI 접속

웹 브라우저에서 접속:

http://localhost:5000

기능:

  • Experiment 추적 및 비교
  • Model 버전 관리
  • Metric과 parameter 시각화
  • Artifact 저장 및 조회

MinIO Console 접속

웹 브라우저에서 접속:

http://localhost:9001

로그인 정보:

  • 사용자명: minio
  • 비밀번호: miniostorage

mlflow bucket이 자동으로 생성되어 있습니다. 수동 생성 불필요!

MLflow 사용 예시

MLflow tracking server가 실행되면 Python 코드에서 연결하여 experiment를 추적할 수 있습니다.

프로젝트 환경 설정

# 프로젝트 디렉토리 생성
mkdir example
cd example

# Python 3.12 가상환경 생성 (uv 권장)
uv venv --python 3.12

# 가상환경 활성화
source .venv/bin/activate

# MLflow 클라이언트 설치
uv pip install mlflow==3.1.1

MLflow 테스트 코드

다음 코드를 test_mlflow.py로 저장하고 실행하여 MLflow 연결을 테스트할 수 있습니다:

test_mlflow.py
import mlflow
import random

# MLflow tracking server에 연결
mlflow.set_tracking_uri("http://localhost:5000")

# Experiment 생성 또는 선택
mlflow.set_experiment("test-experiment")

# Training 실행 및 추적 시작
with mlflow.start_run():
# Hyperparameter logging
learning_rate = 0.001
batch_size = 32
epochs = 10

mlflow.log_param("learning_rate", learning_rate)
mlflow.log_param("batch_size", batch_size)
mlflow.log_param("epochs", epochs)

# 간단한 training loop 시뮬레이션
for epoch in range(1, epochs + 1):
# Training loss 시뮬레이션 (감소하는 패턴)
train_loss = 1.0 / (epoch + 1) + random.random() * 0.1

# Validation accuracy 시뮬레이션 (증가하는 패턴)
val_acc = 0.5 + (epoch / epochs) * 0.4 + random.random() * 0.05

# Metric logging (step별로 기록)
mlflow.log_metric("train_loss", train_loss, step=epoch)
mlflow.log_metric("val_accuracy", val_acc, step=epoch)

print(f"Epoch {epoch}: loss={train_loss:.4f}, acc={val_acc:.4f}")

# 최종 결과 저장
mlflow.log_metric("final_accuracy", val_acc)

print("\n✅ MLflow tracking 테스트 완료!")
print(f"📊 MLflow UI에서 확인: http://localhost:5000")

실행:

python test_mlflow.py

출력 예시:

Epoch 0: loss=1.0234, acc=0.5234
Epoch 1: loss=0.5432, acc=0.6123
...
Epoch 9: loss=0.1123, acc=0.8901

✅ MLflow tracking 테스트 완료!
📊 MLflow UI에서 확인: http://localhost:5000

저장된 experiment와 metric은 MLflow UI (http://localhost:5000)에서 확인할 수 있습니다.

문제 해결

포트가 이미 사용 중인 경우 (macOS)

5000 포트는 macOS의 AirPlay Receiver가 사용합니다.

# AirPlay Receiver 비활성화
# 시스템 설정 → 일반 → AirDrop 및 Handoff → "AirPlay 수신기" 체크 해제

또는 docker-compose.yaml에서 다른 포트 사용:

ports:
- '5001:5000' # 예: 5001 포트로 변경

이상 동작 시 완전 초기화

# 모든 volume 삭제 후 재시작
docker compose down -v
docker compose up -d --build

다음 단계

로컬 실험 환경이 준비되었습니다. 이제:

  1. 로컬에서 첫 학습 실행 - 간단한 model로 전체 workflow 경험하기
  2. Docker로 첫 학습 실행 - 재현 가능한 컨테이너 환경에서 학습