AI 머신러닝

MLFlow 활용 머신러닝 실험 관리: 재현성 있는 모델 개발 전략

강코의 코딩 일기 2026. 5. 3. 07:25
반응형

MLFlow를 활용해 복잡한 머신러닝 실험을 효율적으로 관리하고, 모델 개발의 재현성과 신뢰성을 확보하는 실무 전략을 공유합니다.

데이터 과학자와 머신러닝 엔지니어라면 누구나 겪는 고민이 있습니다. "이 모델이 왜 이런 성능이 나왔더라?", "지난주에 돌렸던 그 실험, 파라미터가 뭐였지?", "동료가 만든 모델, 내 환경에서 어떻게 재현해야 할까?"

수많은 실험과 모델 학습을 진행하면서, 파라미터, 메트릭, 결과물들을 일일이 수동으로 기록하거나 주피터 노트북 스크롤 압박 속에서 헤매셨던 경험, 다들 있으실 겁니다. 특히 여러 사람이 함께 프로젝트를 진행하거나, 프로덕션 환경에 배포할 모델을 선정해야 할 때면 이런 비효율적인 방식은 재현성협업에 큰 걸림돌이 됩니다.

제가 직접 경험했던 사례를 하나 말씀드리자면, 한참 프로젝트가 진행될 때 모델 성능 개선을 위해 수십 가지의 하이퍼파라미터 조합과 피처 엔지니어링 기법을 시도했습니다. 그때는 스프레드시트에 파라미터와 F1 점수만 기록하고 모델 파일은 날짜별로 저장해두곤 했죠. 결국 최적의 모델을 찾았다고 생각했지만, 나중에 그 모델을 다시 학습시키려니 어떤 전처리 과정을 거쳤는지, 어떤 라이브러리 버전을 썼는지 불분명해서 꽤나 애를 먹었습니다. 결국 상당한 시간을 들여 코드를 다시 분석해야 했고, 모델의 재현성에 대한 신뢰도도 떨어졌습니다.

이런 문제에 직면했을 때, 저희 팀은 MLFlow 도입을 결정했습니다. 그리고 실제로 적용해 본 결과, 머신러닝 개발 워크플로우에 혁신적인 변화를 가져올 수 있었습니다. 이 글에서는 MLFlow가 무엇인지부터 Tracking, Models, Model Registry 기능까지, 제가 직접 MLFlow를 활용하며 느꼈던 점과 실무 팁을 자세히 공유해 드리고자 합니다.

MLFlow를 활용한 머신러닝 실험 관리 및 모델 버전 관리 전략 - construction machine, scoops, shovel, excavator, caterpillar, tracked vehicle, construction site, machine, vehicle, old, bulldozer, rooms, ride, level, excavator, excavator, excavator, caterpillar, construction site, construction site, bulldozer, bulldozer, bulldozer, bulldozer, bulldozer

Image by Tama66 on Pixabay

MLFlow란 무엇이며, 왜 필요한가?

MLFlow는 머신러닝 프로젝트의 전체 생명주기를 관리하기 위한 오픈소스 플랫폼입니다. 단순히 모델 학습 코드를 짜는 것을 넘어, 실험 추적, 모델 패키징, 모델 배포, 그리고 모델 버전 관리까지 머신러닝 개발의 모든 단계를 아우르는 기능을 제공합니다.

MLFlow는 크게 네 가지 핵심 컴포넌트로 구성됩니다.

  • MLFlow Tracking: 머신러닝 실험을 기록하고 비교할 수 있는 API와 UI를 제공합니다. 파라미터, 메트릭, 아티팩트(모델 파일, 데이터 전처리 스크립트 등)를 체계적으로 관리할 수 있습니다.
  • MLFlow Projects: 머신러닝 코드를 재현 가능하고 패키징된 형태로 구성하여 공유하고 실행할 수 있도록 돕습니다. (실무에서는 이 기능의 활용도가 상대적으로 낮았습니다. 대부분 자체적인 파이프라인이나 스크립트 실행 방식을 선호하는 경향이 있습니다.)
  • MLFlow Models: 다양한 ML 라이브러리(Scikit-learn, PyTorch, TensorFlow 등)로 학습된 모델을 표준 형식으로 패키징하여 여러 환경(Docker, Apache Spark, 클라우드 플랫폼 등)에 쉽게 배포할 수 있도록 지원합니다.
  • MLFlow Model Registry: 모델의 수명 주기(Staging, Production, Archived)를 관리하고, 모델 버전 기록 및 전환 기능을 제공하여 프로덕션 모델 관리를 간소화합니다.

그렇다면 MLFlow가 왜 필요할까요? 제 경험상 가장 큰 이유는 재현성(Reproducibility)협업(Collaboration), 그리고 MLOps 기반 마련에 있습니다. MLFlow를 사용하기 전에는 "이전 모델의 성능을 재현해봐"라는 요청에 막연함을 느꼈지만, 도입 후에는 몇 번의 클릭만으로 모든 기록을 확인할 수 있게 되었습니다. 팀원 간에도 누가 어떤 실험을 했고, 어떤 결과를 얻었는지 투명하게 공유되어 의사결정 속도가 빨라졌습니다.

MLFlow Tracking: 실험 기록의 A to Z

MLFlow Tracking은 MLFlow의 가장 핵심적인 기능 중 하나입니다. 머신러닝 실험의 모든 과정(입력 파라미터, 출력 메트릭, 생성된 아티팩트)을 기록하고 시각화하며 비교할 수 있도록 돕습니다. 직접 써보니, 복잡한 하이퍼파라미터 튜닝이나 모델 비교 작업에서 MLFlow Tracking이 없었다면 훨씬 더 많은 시간과 노력을 낭비했을 것이라는 확신이 들었습니다.

mlflow.log 제대로 활용하기

MLFlow Tracking은 `mlflow.start_run()`을 통해 새로운 실험 실행(Run)을 시작하고, `mlflow.log_param()`, `mlflow.log_metric()`, `mlflow.log_artifact()` 등의 API를 사용하여 데이터를 기록합니다. 대부분의 경우 `with mlflow.start_run():` 구문을 사용하여 컨텍스트 관리자 형태로 실험을 기록하는 것이 일반적입니다. 이렇게 하면 예외 발생 시에도 Run이 자동으로 종료되어 깔끔하게 관리가 가능합니다.


import mlflow
import mlflow.sklearn
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
import pandas as pd

# 가상의 데이터 생성
data = pd.DataFrame({
    'feature1': [i/100 for i in range(100)],
    'feature2': [i%10 for i in range(100)],
    'target': [1 if i%2 == 0 else 0 for i in range(100)]
})
X = data[['feature1', 'feature2']]
y = data['target']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# MLFlow Tracking 시작
# 로컬 파일 시스템에 'mlruns' 디렉토리가 생성되며, 그 안에 실험 기록이 저장됩니다.
# 원격 서버를 사용하는 경우 mlflow.set_tracking_uri("http://localhost:5000") 등으로 설정합니다.
with mlflow.start_run(run_name="RandomForest_Experiment_A"):
    # 하이퍼파라미터 정의
    n_estimators = 100
    max_depth = 10
    random_state = 42

    # 파라미터 기록
    mlflow.log_param("n_estimators", n_estimators)
    mlflow.log_param("max_depth", max_depth)
    mlflow.log_param("random_state", random_state)

    # 모델 학습
    model = RandomForestClassifier(n_estimators=n_estimators, max_depth=max_depth, random_state=random_state)
    model.fit(X_train, y_train)

    # 예측 및 성능 평가
    y_pred = model.predict(X_test)
    accuracy = accuracy_score(y_test, y_pred)

    # 메트릭 기록
    mlflow.log_metric("accuracy", accuracy)
    print(f"Accuracy: {accuracy}")

    # 모델 저장 (MLFlow Models 형식으로 저장)
    mlflow.sklearn.log_model(
        sk_model=model,
        artifact_path="random_forest_model",
        registered_model_name="RandomForestClassifierModel" # 모델 레지스트리에 등록할 이름 (선택 사항)
    )

    # 추가 아티팩트 (예: 전처리 스크립트, 피처 중요도 플롯 등) 기록
    with open("preprocessing_script.py", "w") as f:
        f.write("# Dummy preprocessing script\n")
    mlflow.log_artifact("preprocessing_script.py", "scripts")

print("MLFlow run completed.")
    

위 코드 예시처럼, `mlflow.log_param`으로 파라미터를, `mlflow.log_metric`으로 성능 지표를, 그리고 `mlflow.log_artifact`로 모델 파일이나 전처리 스크립트와 같은 결과물을 기록할 수 있습니다. 특히 `mlflow.sklearn.log_model`과 같이 특정 라이브러리용 `log_model` 함수를 사용하면 해당 라이브러리에 최적화된 형식으로 모델을 저장하고, 나중에 쉽게 로드할 수 있게 됩니다.

제가 직접 수십 번의 실험을 진행했을 때, 단순히 코드를 실행하는 것만으로 모든 파라미터와 메트릭이 자동으로 기록되고 UI에서 한눈에 비교할 수 있다는 점이 정말 놀라웠습니다. 이전에는 각 실험마다 파라미터 세팅을 변경하며 주석을 달거나, 별도의 CSV 파일에 기록해야 했지만, MLFlow 덕분에 100번의 실험 중 최적의 하이퍼파라미터 조합을 단 5분 만에 시각적으로 찾아낼 수 있었습니다. 이처럼 직관적인 UI는 실험 결과 분석 시간을 획기적으로 줄여주었습니다.

Runs와 Artifacts 관리

MLFlow UI에 접속하면 각 Run별로 상세한 정보를 확인할 수 있습니다.

  • Parameters: 모델 학습에 사용된 모든 하이퍼파라미터.
  • Metrics: 학습 과정에서 기록된 성능 지표 (정확도, F1-score, 손실값 등). 시간 경과에 따른 변화도 그래프로 시각화됩니다.
  • Artifacts: 학습된 모델 파일, 전처리 스크립트, 학습 로그, 시각화 이미지 등 모든 결과물.

이러한 정보는 MLFlow Tracking 서버(로컬 파일 시스템, PostgreSQL, MySQL 등의 DB, S3, Azure Blob Storage 등의 아티팩트 스토어)에 저장됩니다. 특히 Artifacts는 모델의 재현성을 위해 매우 중요합니다. 모델 파일뿐만 아니라 해당 모델을 학습시키는 데 사용된 전처리 코드나 데이터셋 샘플까지 함께 저장해두면, 나중에 모델을 재현하거나 디버깅할 때 큰 도움이 됩니다. 제가 직접 해보니, 모델과 관련된 모든 것을 한곳에 모아두는 습관이 얼마나 중요한지 깨달았습니다.

MLFlow Models: 모델 패키징 및 배포 표준화

머신러닝 모델을 프로덕션 환경에 배포하는 과정은 생각보다 복잡합니다. 모델을 학습시킨 환경과 배포될 환경이 다를 수 있고, 모델을 서비스하기 위한 API 래핑, 의존성 관리 등 고려해야 할 사항이 많습니다. MLFlow Models는 이러한 배포 과정을 표준화하고 간소화하는 데 중점을 둡니다.

MLFlow Model Flavor 이해하기

MLFlow Models는 다양한 머신러닝 라이브러리(Scikit-learn, PyTorch, TensorFlow, XGBoost 등)에 대한 'Flavor'를 제공합니다. 각 Flavor는 해당 라이브러리의 모델을 저장하고 로드하는 데 필요한 특정 로직을 캡슐화합니다. 예를 들어, `mlflow.sklearn.log_model()`을 사용하여 Scikit-learn 모델을 저장하면, MLFlow는 모델 파일과 함께 `MLmodel`이라는 메타데이터 파일을 생성합니다.


# MLmodel 파일 예시
artifacts:
  python_model:
    pickled_model: model.pkl
    env: conda.yaml
run_id: 1234abcd...
signature:
  inputs: '[{"type": "double", "name": "feature1"}, {"type": "double", "name": "feature2"}]'
  outputs: '[{"type": "long"}]'
utc_time_created: 2023-01-01T12:00:00.000000Z
flavors:
  python_function:
    loader_module: mlflow.sklearn
    model_path: model.pkl
    python_version: 3.9.7
  sklearn:
    pickled_model: model.pkl
    sklearn_version: 1.0.2
    serialization_format: pickle
    conda_env: conda.yaml
    

이 `MLmodel` 파일은 모델의 타입, 의존성(conda 환경 정의), 시그니처(입력/출력 스키마) 등 모델에 대한 모든 중요한 정보를 담고 있습니다. 제가 직접 경험해본 바로는, 이 `MLmodel` 파일 덕분에 개발 환경에서 저장한 모델을 프로덕션 Docker 컨테이너나 클라우드 SageMaker 엔드포인트에서 별다른 코드 수정 없이 바로 로드하고 사용할 수 있었습니다. 이는 모델 배포 시 발생할 수 있는 호환성 문제를 크게 줄여주었습니다.

MLFlow Models는 또한 `mlflow.pyfunc` Flavor를 제공하여, 복잡한 전처리 로직이나 후처리 로직이 포함된 모델도 파이썬 함수 형태로 래핑하여 표준화된 방식으로 배포할 수 있도록 합니다. 이는 특히 커스텀 모델이나 복잡한 파이프라인을 가진 모델을 배포할 때 유용했습니다.

MLFlow를 활용한 머신러닝 실험 관리 및 모델 버전 관리 전략 - algorithm, pictures, by machine, to learn, deep learning, photos, cats, human, neuronal, artificially, generation, template, pattern recognition, intelligence, laws, monitor, machine learning, the flood of images, recognize, algorithm, algorithm, deep learning, machine learning, machine learning, machine learning, machine learning, machine learning

Image by geralt on Pixabay

MLFlow Model Registry: 모델 버전 관리의 완성

MLFlow Model Registry는 MLFlow Tracking에서 기록된 모델들을 중앙 집중식으로 관리하고, 모델의 버전과 수명 주기를 체계적으로 관리하는 기능을 제공합니다. 제가 직접 팀 프로젝트에 적용해 본 결과, 모델 배포 프로세스의 투명성과 안정성을 비약적으로 향상시킬 수 있었습니다.

스테이징에서 프로덕션까지

Model Registry는 각 모델에 대해 여러 버전을 관리하고, 각 버전별로 "None", "Staging", "Production", "Archived"와 같은 스테이지를 할당할 수 있습니다.

  • None: 기본 상태.
  • Staging: 개발 및 테스트 환경에서 검증 중인 모델.
  • Production: 실제 서비스에 배포되어 사용 중인 모델.
  • Archived: 더 이상 사용되지 않거나 폐기된 모델.

이러한 스테이지 관리는 팀 내에서 모델 배포 정책을 수립하고 준수하는 데 큰 도움을 줍니다. 예를 들어, 새로운 모델이 개발되면 먼저 Staging으로 등록하여 QA 팀이나 다른 개발자가 충분히 테스트할 수 있도록 합니다. 검증이 완료되면 Production으로 전환하고, 기존 Production 모델은 Archived로 전환하는 방식으로 워크플로우를 구축할 수 있습니다.

제가 직접 경험한 사례로는, 프로덕션에 배포된 모델에서 갑작스러운 성능 저하가 발생했을 때, Model Registry를 통해 단 30초 만에 이전 Production 버전의 모델로 롤백하여 서비스 장애 시간을 최소화할 수 있었습니다. 이는 수동으로 모델 파일을 찾아 배포하던 이전 방식으로는 상상하기 어려웠던 속도와 안정성이었습니다.

모델 이력 추적 및 롤백 전략

Model Registry는 각 모델 버전별로 누가 언제 등록했고, 어떤 Run ID에서 생성되었는지 등 상세한 이력을 기록합니다. 이 덕분에 "이 모델은 왜 Production으로 올라갔지?", "이전 버전과 현재 버전의 차이는 무엇이지?"와 같은 질문에 명확하게 답할 수 있게 됩니다.

Git과 코드 버전 관리가 소스 코드의 변경 이력을 추적하고 롤백하는 데 필수적인 것처럼, MLFlow Model Registry는 학습된 모델의 변경 이력을 관리하고 필요할 때 특정 버전으로 되돌릴 수 있는 기능을 제공합니다. 이는 특히 A/B 테스트나 점진적인 모델 업데이트 전략을 구현할 때 매우 유용합니다.

`MlflowClient`를 사용하면 파이썬 코드에서 Model Registry를 프로그래밍 방식으로 제어할 수 있습니다.


from mlflow.tracking import MlflowClient

client = MlflowClient()

# 등록된 모델의 새 버전 생성 (예: Tracking에서 저장한 모델을 등록)
# run_id = "이전에 모델을 저장했던 Run의 ID"
# model_uri = f"runs:/{run_id}/random_forest_model" # 위 예시에서 artifact_path="random_forest_model"
# registered_model = client.create_model_version(
#     name="RandomForestClassifierModel",
#     source=model_uri,
#     run_id=run_id,
#     description="Initial version of Random Forest Classifier"
# )
# print(f"Registered model version: {registered_model.version}")

# 특정 모델 버전의 스테이지 변경 (예: Staging -> Production)
model_name = "RandomForestClassifierModel"
version = 1 # 변경하고자 하는 모델 버전
client.transition_model_version_stage(
    name=model_name,
    version=version,
    stage="Production",
    archive_existing_versions=True # 기존 Production 모델을 Archived로 전환
)
print(f"Model {model_name} version {version} transitioned to Production.")

# Production 스테이지에 있는 모델 로드
model_uri = f"models:/{model_name}/Production"
loaded_model = mlflow.sklearn.load_model(model_uri)
print(f"Loaded model from Production: {loaded_model}")
    

이처럼 `MlflowClient`를 활용하면 CI/CD 파이프라인과 연동하여 모델 배포 과정을 자동화하고, 모델 검증 후 자동으로 스테이지를 전환하는 등의 MLOps 워크플로우를 구축할 수 있습니다.

MLFlow를 활용한 머신러닝 실험 관리 및 모델 버전 관리 전략 - drill, milling, milling machine, tool, metal, metal processing, industry, cnc, rotate, machine, cnc machine, production, lathe, to cut, metal construction, drill head, engineering, rounding, drilling machine, mechanics, technology, cutting tools, machining, industry, cnc, cnc, machine, machine, machine, machine, machine, engineering, engineering

Image by blickpixel on Pixabay

MLFlow 적용, 실제로 해보니 좋았던 점과 주의할 점

MLFlow를 저희 팀에 도입하고 나서, 머신러닝 개발 및 운영 방식에 많은 긍정적인 변화를 가져왔습니다. 하지만 모든 도구가 그렇듯, 주의해야 할 점도 분명 있었습니다.

좋았던 점

  • 확실한 재현성 확보: 가장 큰 장점입니다. "모델 A가 왜 이 성능이 나왔지?"라는 질문에 더 이상 추측이 아닌 명확한 데이터(파라미터, 메트릭, 아티팩트)로 답할 수 있게 되었습니다. 이는 모델의 신뢰도를 높이고 디버깅 시간을 단축시키는 데 결정적인 역할을 했습니다.
  • 협업 효율 증대: 팀원들이 각자 진행한 실험 결과를 MLFlow UI를 통해 쉽게 공유하고 비교할 수 있게 되면서, 중복 실험을 줄이고 효율적인 의사결정을 내릴 수 있었습니다. 마치 Git으로 코드 변경 이력을 공유하듯이, MLFlow로 실험 이력을 공유하는 것이 자연스러워졌습니다.
  • 모델 배포 간소화 및 표준화: MLFlow Models를 통해 모델을 표준 형식으로 패키징하면서, 모델 배포 스크립트가 훨씬 간결해지고 다양한 환경에 유연하게 대응할 수 있게 되었습니다.
  • MLOps 기반 마련: MLFlow Tracking과 Model Registry는 MLOps 파이프라인의 핵심 구성 요소가 됩니다. 모델 학습 자동화, 지속적인 통합(CI), 지속적인 배포(CD) 등 MLOps의 기본적인 틀을 구축하는 데 큰 도움을 받았습니다.

주의할 점

  • 초기 설정 비용: MLFlow Tracking 서버와 아티팩트 저장소를 구축해야 합니다. 로컬에서 간단히 시작할 수 있지만, 팀 단위로 사용하거나 프로덕션 환경에서는 데이터베이스(PostgreSQL 등)와 클라우드 스토리지(S3, Azure Blob Storage 등)를 연동해야 하므로 초기 인프라 구성에 일정 시간이 소요됩니다.
  • 학습된 모델 크기 관리: 모델의 크기가 매우 크거나, 학습 과정에서 생성되는 아티팩트가 많다면 아티팩트 저장소의 용량을 효율적으로 관리해야 합니다. 불필요한 아티팩트를 제거하거나, S3와 같은 비용 효율적인 클라우드 스토리지를 활용하는 전략이 필요합니다.
  • MLFlow Projects 활용도: 제 경험상 MLFlow Projects 기능은 다른 컴포넌트에 비해 상대적으로 활용도가 낮았습니다. 많은 팀이 이미 Docker나 KubeFlow 등 자체적인 워크플로우 오케스트레이션 도구를 사용하고 있기 때문인 것 같습니다.

MLFlow의 실험 관리 기능을 다른 인기 있는 도구인 TensorBoard와 비교해보면 다음과 같습니다.

특징 MLFlow TensorBoard
주요 목적 ML 생명주기 관리 (실험 추적, 모델 관리, 레지스트리, 배포) 딥러닝 모델 학습 과정 시각화 및 디버깅
지원 라이브러리 모든 ML 라이브러리 (Scikit-learn, PyTorch, TensorFlow 등) 주로 TensorFlow, PyTorch 등 딥러닝 프레임워크
데이터 저장 방식 DB (메타데이터) + Artifact Store (파일) 로컬 파일 시스템 (이벤트 로그 파일)
주요 기능 파라미터/메트릭 기록, 모델 버전 관리, 모델 배포 스칼라, 히스토그램, 이미지, 그래프, 임베딩 시각화
협업 용이성 중앙 서버 기반으로 팀 협업에 매우 적합 로컬 파일 기반이라 공유 및 협업에 추가 설정 필요

표에서 볼 수 있듯이, TensorBoard는 딥러닝 모델의 학습 과정을 상세히 시각화하는 데 특화되어 있다면, MLFlow는 전체 머신러닝 생명주기를 관리하고 협업 및 배포를 용이하게 하는 데 강점을 가집니다. 프로젝트의 성격과 팀의 필요에 따라 두 도구를 함께 사용하거나, MLFlow를 메인으로 사용하는 전략을 고려해 볼 수 있습니다.

MLFlow와 함께 더 체계적인 ML 개발을 시작하세요

MLFlow는 머신러닝 실험의 재현성을 높이고, 협업을 효율적으로 만들며, 모델 배포 과정을 간소화하고, 궁극적으로 MLOps의 기반을 다지는 데 필수적인 도구입니다. 제가 직접 MLFlow를 도입하고 사용하면서 겪었던 비효율적인 문제들이 상당 부분 해결되었고, 훨씬 더 체계적이고 신뢰할 수 있는 머신러닝 개발 프로세스를 구축할 수 있었습니다.

혹시 아직도 스프레드시트와 폴더 구조에 의존하여 머신러닝 실험을 관리하고 계시다면, MLFlow를 도입하여 새로운 경험을 해보시는 것을 강력히 추천합니다. 초기 설정에 약간의 노력이 필요할 수 있지만, 장기적으로는 개발 생산성과 모델 품질 향상에 지대한 영향을 미칠 것이라고 확신합니다.

MLFlow를 사용하시면서 겪었던 특별한 경험이나 팁이 있다면 댓글로 자유롭게 공유해 주세요! 함께 더 나은 머신러닝 개발 문화를 만들어갈 수 있기를 바랍니다.

📌 함께 읽으면 좋은 글

  • [클라우드 인프라] 클라우드 비용 최적화 전략: 불필요한 지출을 줄이고 효율적인 인프라 운영하기
  • [이슈 분석] IT 경기 둔화 속 개발자 채용 시장 변화와 커리어 성장 전략
  • [AI 머신러닝] MLOps 모델 성능 모니터링과 드리프트 감지 전략: 프로덕션 환경에서 모델 신뢰성 유지

이 글이 도움이 되셨다면 공감(♥)댓글로 응원해 주세요!
궁금한 점이나 다루었으면 하는 주제가 있다면 댓글로 남겨주세요.

반응형