본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.
본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.
이미지 로딩 중...
AI Generated
2025. 11. 30. · 16 Views
MLflow 완벽 가이드 - 실험 추적부터 모델 레지스트리까지
머신러닝 실험 관리의 혼란에서 벗어나고 싶은 분들을 위한 MLflow 입문서입니다. 실험 추적, 모델 패키징, 레지스트리까지 실무에서 바로 활용할 수 있는 내용을 담았습니다.
목차
- MLflow_설치_및_환경_설정
- Tracking_Server_구성하기
- 실험_로깅_메트릭_파라미터
- MLflow_Projects_사용법
- MLflow_Models_패키징
- Model_Registry_기본_사용
- REST_API_서빙_설정
1. MLflow 설치 및 환경 설정
데이터 사이언티스트 김개발 씨는 오늘도 머신러닝 모델을 학습시키고 있습니다. 그런데 문제가 생겼습니다.
"어제 학습시킨 모델이 더 좋았던 것 같은데, 그때 하이퍼파라미터가 뭐였지?" 엑셀에 기록해둔 것 같기도 하고, 주피터 노트북 어딘가에 적어둔 것 같기도 합니다. 이런 혼란, 익숙하지 않으신가요?
MLflow는 머신러닝 실험의 전 과정을 관리해주는 오픈소스 플랫폼입니다. 마치 실험실의 연구 노트처럼 모든 실험 기록을 체계적으로 저장하고 비교할 수 있게 해줍니다.
설치는 pip 한 줄이면 충분하며, 기존 코드에 몇 줄만 추가하면 바로 사용할 수 있습니다.
다음 코드를 살펴봅시다.
# MLflow 설치
# pip install mlflow
import mlflow
# MLflow 버전 확인
print(f"MLflow version: {mlflow.__version__}")
# 기본 tracking URI 설정 (로컬 파일 시스템)
mlflow.set_tracking_uri("file:./mlruns")
# 실험 생성 및 설정
mlflow.set_experiment("my-first-experiment")
# 현재 설정 확인
print(f"Tracking URI: {mlflow.get_tracking_uri()}")
print(f"Artifact URI: {mlflow.get_artifact_uri()}")
김개발 씨는 입사 6개월 차 데이터 사이언티스트입니다. 매일 다양한 모델을 실험하고 결과를 비교하는 것이 주된 업무입니다.
처음에는 엑셀에 실험 결과를 정리했습니다. 학습률, 배치 크기, 정확도를 한 줄씩 기록했습니다.
하지만 실험이 100개를 넘어가자 상황이 복잡해졌습니다. 어떤 실험은 기록이 누락되었고, 어떤 실험은 파라미터 값이 잘못 적혀 있었습니다.
선배 박시니어 씨가 지나가다 한마디 합니다. "MLflow 써봤어요?
실험 관리가 훨씬 편해질 거예요." 그렇다면 MLflow란 정확히 무엇일까요? 쉽게 비유하자면, MLflow는 마치 과학자의 실험 노트와 같습니다.
과학자가 실험할 때마다 날짜, 조건, 결과를 꼼꼼히 기록하듯이, MLflow는 머신러닝 실험의 모든 정보를 자동으로 기록합니다. 언제 실험했는지, 어떤 파라미터를 사용했는지, 결과는 어땠는지 한눈에 볼 수 있습니다.
설치 방법은 놀라울 정도로 간단합니다. 터미널에서 pip install mlflow 한 줄이면 됩니다.
추가적인 설정 파일도, 복잡한 환경 구성도 필요 없습니다. Python 환경만 있다면 바로 시작할 수 있습니다.
설치 후 가장 먼저 해야 할 일은 tracking URI를 설정하는 것입니다. 이것은 실험 기록이 저장될 위치를 지정하는 것입니다.
위 코드에서 file:./mlruns라고 설정했는데, 이는 현재 디렉토리 아래 mlruns 폴더에 모든 기록을 저장하겠다는 의미입니다. 다음으로 set_experiment 함수로 실험 이름을 지정합니다.
이것은 마치 실험 노트의 제목을 붙이는 것과 같습니다. 관련 있는 실험들을 하나의 실험 이름 아래 모아두면 나중에 비교하기가 훨씬 수월합니다.
실무에서는 프로젝트마다 별도의 실험을 만드는 것이 좋습니다. 예를 들어 "고객이탈예측-v1", "상품추천-baseline" 처럼 의미 있는 이름을 붙이면 나중에 찾기가 쉽습니다.
김개발 씨는 설치를 마치고 터미널에서 mlflow ui 명령어를 실행해봤습니다. 브라우저에서 localhost:5000에 접속하니 깔끔한 대시보드가 나타났습니다.
아직 실험 기록은 없지만, 곧 이 화면이 소중한 실험 데이터로 가득 찰 것입니다. 박시니어 씨가 다가와 화면을 보더니 고개를 끄덕입니다.
"좋아요, 이제 본격적으로 실험 추적을 시작해볼까요?"
실전 팁
💡 - 가상환경을 만들어서 MLflow를 설치하면 프로젝트별로 독립적인 환경을 유지할 수 있습니다
- mlflow ui 명령어로 웹 대시보드를 실행할 수 있으며, 기본 포트는 5000번입니다
2. Tracking Server 구성하기
김개발 씨가 MLflow를 열심히 사용하기 시작했습니다. 그런데 팀원들과 실험 결과를 공유하려니 문제가 생겼습니다.
"내 컴퓨터에 저장된 실험 기록을 다른 사람이 어떻게 봐요?" 로컬에서 혼자 사용하는 것은 쉬웠지만, 팀 단위로 협업하려면 중앙 서버가 필요했습니다.
Tracking Server는 팀 전체가 공유하는 MLflow의 중앙 저장소입니다. 마치 회사의 공용 파일 서버처럼, 모든 팀원이 하나의 서버에 실험을 기록하고 서로의 결과를 조회할 수 있습니다.
백엔드 저장소로 SQLite, MySQL, PostgreSQL 등을 선택할 수 있으며, 모델 파일은 별도의 스토리지에 저장합니다.
다음 코드를 살펴봅시다.
# Tracking Server 실행 (터미널에서)
# mlflow server \
# --backend-store-uri sqlite:///mlflow.db \
# --default-artifact-root ./mlartifacts \
# --host 0.0.0.0 \
# --port 5000
import mlflow
# 원격 Tracking Server에 연결
mlflow.set_tracking_uri("http://your-server-ip:5000")
# 연결 확인
print(f"Connected to: {mlflow.get_tracking_uri()}")
# 실험 목록 조회
client = mlflow.tracking.MlflowClient()
experiments = client.search_experiments()
for exp in experiments:
print(f"Experiment: {exp.name}, ID: {exp.experiment_id}")
김개발 씨의 팀은 5명의 데이터 사이언티스트로 구성되어 있습니다. 각자 자기 컴퓨터에서 실험을 진행하다 보니 같은 모델을 중복으로 학습시키는 일이 잦았습니다.
누군가 이미 시도해본 하이퍼파라미터 조합을 다른 사람이 또 시도하는 비효율이 발생한 것입니다. 팀장인 이매니저 씨가 회의에서 제안했습니다.
"MLflow Tracking Server를 구축해서 모든 실험을 한곳에서 관리합시다." Tracking Server란 무엇일까요? 비유하자면 도서관의 중앙 카탈로그 시스템과 같습니다.
각자 책을 빌려가서 읽더라도, 누가 어떤 책을 빌렸는지는 중앙 시스템에 기록됩니다. 마찬가지로 각자의 컴퓨터에서 실험을 진행하더라도, 모든 기록은 중앙 서버에 저장됩니다.
서버 구성의 핵심은 두 가지 저장소를 설정하는 것입니다. 첫 번째는 backend-store-uri로, 실험의 메타데이터가 저장되는 곳입니다.
파라미터, 메트릭, 태그 같은 가벼운 정보들이 여기에 기록됩니다. SQLite는 간단한 설정에 적합하고, 대규모 팀이라면 PostgreSQL이나 MySQL을 권장합니다.
두 번째는 default-artifact-root로, 학습된 모델 파일이나 그래프 이미지 같은 무거운 파일들이 저장됩니다. 로컬 디렉토리를 사용할 수도 있고, AWS S3나 Azure Blob Storage 같은 클라우드 스토리지를 연결할 수도 있습니다.
서버를 실행하는 명령어를 살펴보겠습니다. --host 0.0.0.0은 모든 네트워크 인터페이스에서 접속을 허용한다는 의미입니다.
이렇게 설정해야 다른 컴퓨터에서도 서버에 접근할 수 있습니다. --port 5000은 서버가 사용할 포트 번호입니다.
클라이언트 측에서는 set_tracking_uri 함수로 서버 주소를 지정합니다. 이 한 줄만 바꾸면 로컬 저장에서 원격 서버 저장으로 전환됩니다.
기존 코드를 거의 수정하지 않아도 됩니다. MlflowClient 클래스를 사용하면 서버와 직접 통신할 수 있습니다.
실험 목록을 조회하거나, 특정 실험의 상세 정보를 가져오거나, 프로그래밍 방식으로 다양한 작업을 수행할 수 있습니다. 실무에서 주의할 점이 있습니다.
서버를 외부에 노출할 때는 보안 설정을 반드시 해야 합니다. 기본 설정으로는 인증 없이 누구나 접근할 수 있기 때문입니다.
프록시 서버를 앞에 두거나, 클라우드 제공업체의 인증 기능을 활용하는 것이 좋습니다. 김개발 씨는 팀 서버에 접속해서 동료들의 실험 목록을 살펴봤습니다.
"오, 박시니어 씨가 어제 학습률 0.001로 실험했네요. 저는 0.01로 해봐야겠다."
실전 팁
💡 - 프로덕션 환경에서는 PostgreSQL이나 MySQL을 백엔드로 사용하는 것이 안정적입니다
- 아티팩트 저장소로 S3나 GCS를 사용하면 대용량 모델도 안전하게 보관할 수 있습니다
3. 실험 로깅 메트릭 파라미터
Tracking Server도 구축했겠다, 이제 본격적으로 실험을 기록할 차례입니다. 김개발 씨가 모델 학습 코드를 작성하던 중 고민이 생겼습니다.
"학습률, 배치 크기, 에폭 수... 기록해야 할 게 너무 많은데, 이걸 어떻게 체계적으로 남기지?"
MLflow의 로깅 기능은 실험의 모든 정보를 기록하는 핵심 기능입니다. 파라미터는 실험 전에 설정하는 값이고, 메트릭은 실험 결과로 나오는 측정값입니다.
마치 요리할 때 레시피(파라미터)를 기록하고 맛 평가 점수(메트릭)를 남기는 것과 같습니다. 한 번 설정하면 자동으로 모든 것이 추적됩니다.
다음 코드를 살펴봅시다.
import mlflow
# 실험 시작
mlflow.set_experiment("house-price-prediction")
with mlflow.start_run(run_name="xgboost-baseline"):
# 파라미터 로깅 (실험 설정값)
mlflow.log_param("learning_rate", 0.1)
mlflow.log_param("max_depth", 6)
mlflow.log_param("n_estimators", 100)
# 여러 파라미터를 한번에 로깅
mlflow.log_params({"subsample": 0.8, "colsample_bytree": 0.8})
# 메트릭 로깅 (실험 결과)
mlflow.log_metric("rmse", 0.234)
mlflow.log_metric("mae", 0.189)
# 단계별 메트릭 로깅 (학습 곡선)
for epoch in range(5):
mlflow.log_metric("train_loss", 0.5 - epoch * 0.08, step=epoch)
김개발 씨는 주택 가격 예측 모델을 개발하고 있습니다. XGBoost를 사용해서 다양한 하이퍼파라미터 조합을 시험해보는 중입니다.
예전 같았으면 노트북 셀 출력 결과를 캡처하거나 수동으로 적어뒀겠지만, 이제는 MLflow가 있습니다. 실험 로깅의 핵심 개념은 두 가지입니다.
파라미터와 메트릭입니다. 파라미터는 실험을 시작하기 전에 결정하는 값들입니다.
학습률, 배치 크기, 모델 구조 같은 것들이 여기에 해당합니다. 요리에 비유하면 레시피에 적힌 재료의 양과 같습니다.
"소금 한 스푼, 설탕 두 스푼"처럼 미리 정해두는 것입니다. 메트릭은 실험 결과로 얻어지는 측정값입니다.
정확도, 손실값, F1 스코어 같은 것들입니다. 요리 결과물의 맛 평가 점수와 같습니다.
실험을 돌려봐야 알 수 있는 값입니다. 코드를 살펴보겠습니다.
mlflow.start_run은 하나의 실험 실행을 시작합니다. 파이썬의 with 문과 함께 사용하면 실행이 끝났을 때 자동으로 정리됩니다.
run_name 파라미터로 실행에 이름을 붙일 수 있어서 나중에 찾기가 쉽습니다. log_param 함수는 하나의 파라미터를 기록합니다.
키-값 쌍으로 저장되며, 나중에 이 값으로 실험들을 필터링할 수 있습니다. 여러 파라미터를 한꺼번에 기록하고 싶다면 log_params 함수에 딕셔너리를 전달하면 됩니다.
log_metric 함수는 메트릭을 기록합니다. 특별한 점은 step 파라미터입니다.
이것을 사용하면 학습 과정에서 메트릭이 어떻게 변화하는지 추적할 수 있습니다. 에폭마다 손실값을 기록하면 MLflow UI에서 학습 곡선 그래프를 볼 수 있습니다.
실무에서 유용한 팁이 있습니다. 모델 학습 코드에 로깅을 추가할 때, 기존 코드 구조를 크게 바꾸지 않아도 됩니다.
with mlflow.start_run()으로 감싸고, 중요한 지점에 log 함수를 추가하면 됩니다. 주의할 점도 있습니다.
파라미터는 한 번 기록하면 변경할 수 없습니다. 같은 키로 다시 로깅하면 덮어쓰지 않고 오류가 발생합니다.
반면 메트릭은 같은 키로 여러 번 기록할 수 있으며, 이때 step 값으로 구분됩니다. 김개발 씨는 코드에 로깅을 추가하고 실험을 실행했습니다.
MLflow UI를 열어보니 방금 실행한 실험이 목록에 나타났습니다. 파라미터와 메트릭이 깔끔하게 정리되어 있었습니다.
"이제 실험 조건을 까먹을 일이 없겠네요."
실전 팁
💡 - 딕셔너리 형태의 설정 파일이 있다면 log_params에 통째로 전달하면 편리합니다
- 메트릭 이름은 팀 내에서 통일된 규칙을 정해두면 비교가 쉬워집니다
4. MLflow Projects 사용법
김개발 씨가 작성한 모델이 좋은 성능을 보였습니다. 팀원 이주니어 씨가 "저도 그 코드로 실험해보고 싶은데, 실행 방법 좀 알려주세요"라고 요청했습니다.
그런데 막상 코드를 공유하려니 "이 코드는 Python 3.9에서 돌려야 하고, pandas 버전은 1.3이어야 하고..." 의존성 설명만 한참이 걸렸습니다.
MLflow Projects는 머신러닝 코드를 재현 가능한 형태로 패키징하는 표준입니다. 마치 레고 블록처럼 누구든지 동일한 방식으로 조립할 수 있게 해줍니다.
MLproject 파일에 실행 환경과 진입점을 정의해두면, 한 줄의 명령어로 누구나 같은 환경에서 코드를 실행할 수 있습니다.
다음 코드를 살펴봅시다.
# MLproject 파일 내용
# name: house-price-model
#
# conda_env: conda.yaml
#
# entry_points:
# main:
# parameters:
# learning_rate: {type: float, default: 0.1}
# max_depth: {type: int, default: 6}
# command: "python train.py --lr {learning_rate} --depth {max_depth}"
import mlflow
# 로컬 프로젝트 실행
mlflow.projects.run(
uri="./my_project",
entry_point="main",
parameters={"learning_rate": 0.05, "max_depth": 8}
)
# Git 저장소에서 직접 실행
mlflow.projects.run(
uri="https://github.com/team/ml-project.git",
entry_point="main",
parameters={"learning_rate": 0.01}
)
이주니어 씨는 김개발 씨의 코드를 받아서 실행해봤습니다. 그런데 오류가 났습니다.
"ModuleNotFoundError: No module named 'xgboost'" 라이브러리 버전이 맞지 않아서 생긴 문제였습니다. 의존성을 하나씩 맞추다 보니 한 시간이 훌쩍 지나갔습니다.
이런 문제를 해결하기 위해 MLflow Projects가 등장했습니다. 쉽게 비유하자면, MLflow Projects는 마치 이케아 가구 설명서와 같습니다.
설명서에 필요한 부품 목록과 조립 순서가 적혀 있듯이, MLproject 파일에는 필요한 라이브러리 목록과 실행 방법이 정의되어 있습니다. 누구든지 이 설명서만 따라하면 같은 결과물을 만들 수 있습니다.
MLproject 파일의 구조를 살펴보겠습니다. name은 프로젝트 이름입니다.
conda_env는 환경 정의 파일을 가리킵니다. 여기에 Python 버전과 필요한 라이브러리가 명시됩니다.
entry_points가 핵심입니다. 이것은 프로젝트의 진입점을 정의합니다.
하나의 프로젝트에 여러 진입점을 둘 수 있습니다. 예를 들어 main은 학습용, evaluate는 평가용으로 분리할 수 있습니다.
각 진입점에는 받을 수 있는 파라미터와 실행할 명령어를 지정합니다. mlflow.projects.run 함수로 프로젝트를 실행합니다.
uri 파라미터에는 로컬 경로를 넣을 수도 있고, Git 저장소 URL을 넣을 수도 있습니다. Git URL을 사용하면 코드를 따로 다운받지 않아도 바로 실행할 수 있습니다.
놀라운 점은 환경 격리입니다. MLflow는 conda_env에 정의된 대로 새로운 환경을 만들고 그 안에서 코드를 실행합니다.
사용자의 기존 환경을 건드리지 않습니다. 실험이 끝나면 환경을 정리할 수도 있습니다.
실무에서 이 기능은 특히 유용합니다. 연구팀에서 실험한 코드를 엔지니어링팀에 전달할 때, MLproject 파일만 있으면 "이렇게 실행하세요"라는 복잡한 설명이 필요 없습니다.
한 줄의 명령어면 충분합니다. 주의할 점이 있습니다.
conda 환경을 새로 만드는 데 시간이 걸릴 수 있습니다. 첫 실행 시에는 조금 기다려야 합니다.
반복 실행 시에는 캐시된 환경을 사용하므로 빨라집니다. 이주니어 씨는 김개발 씨의 프로젝트를 MLflow로 실행했습니다.
명령어 한 줄에 모든 환경이 자동으로 설정되고 코드가 실행됐습니다. "와, 이렇게 간단할 줄이야!"
실전 팁
💡 - conda 대신 docker_env를 사용하면 더 완벽한 환경 격리가 가능합니다
- 프로젝트 루트에 MLproject 파일이 있으면 mlflow run . 명령어로 간단히 실행할 수 있습니다
5. MLflow Models 패키징
모델 학습이 완료됐습니다. 이제 이 모델을 저장해서 나중에 사용해야 합니다.
김개발 씨가 pickle로 모델을 저장하려는 순간, 박시니어 씨가 말합니다. "잠깐, MLflow Models를 써보는 건 어때요?
나중에 배포할 때 훨씬 편할 거예요."
MLflow Models는 머신러닝 모델을 표준화된 형식으로 저장하는 기능입니다. 마치 USB 포트가 어떤 기기든 연결할 수 있듯이, MLflow Models로 저장한 모델은 다양한 환경에서 동일하게 동작합니다.
sklearn, pytorch, tensorflow 등 대부분의 프레임워크를 지원하며, 저장된 모델은 바로 서빙에 사용할 수 있습니다.
다음 코드를 살펴봅시다.
import mlflow
import mlflow.sklearn
from sklearn.ensemble import RandomForestRegressor
from sklearn.datasets import make_regression
# 샘플 데이터 생성 및 모델 학습
X, y = make_regression(n_samples=100, n_features=4, noise=0.1)
model = RandomForestRegressor(n_estimators=100)
model.fit(X, y)
with mlflow.start_run():
# 모델 로깅 (자동으로 패키징됨)
mlflow.sklearn.log_model(
sk_model=model,
artifact_path="model",
registered_model_name="house-price-model"
)
# 입력 예시도 함께 저장 (추론 시 스키마 검증용)
mlflow.sklearn.log_model(
model, "model_with_signature",
signature=mlflow.models.infer_signature(X, model.predict(X))
)
# 저장된 모델 로드
loaded_model = mlflow.sklearn.load_model("runs:/<run_id>/model")
predictions = loaded_model.predict(X[:5])
김개발 씨는 RandomForest 모델을 학습시켰습니다. 성능도 괜찮고 팀원들에게 공유하고 싶습니다.
예전 같았으면 pickle.dump로 저장하고, 사용법을 문서로 작성했을 겁니다. 하지만 이번에는 MLflow Models를 사용해보기로 했습니다.
MLflow Models가 특별한 이유가 있습니다. 비유하자면 국제 표준 규격의 컨테이너와 같습니다.
전 세계 어느 항구에서든 같은 규격의 컨테이너를 싣고 내릴 수 있듯이, MLflow로 저장한 모델은 어떤 환경에서든 동일하게 로드하고 실행할 수 있습니다. 모델을 저장할 때 MLflow는 여러 가지를 함께 패키징합니다.
모델 가중치뿐만 아니라 MLmodel 파일, conda.yaml 파일, 그리고 requirements.txt가 포함됩니다. 이것들이 있어야 나중에 같은 환경을 재현할 수 있습니다.
코드를 살펴보겠습니다. mlflow.sklearn.log_model은 sklearn 모델을 저장하는 함수입니다.
다른 프레임워크도 마찬가지로 mlflow.pytorch, mlflow.tensorflow 등의 모듈이 있습니다. artifact_path는 실행(run) 내에서 모델이 저장될 하위 경로입니다.
registered_model_name을 지정하면 Model Registry에 자동으로 등록됩니다. 이 부분은 다음 장에서 자세히 다루겠습니다.
signature는 중요한 개념입니다. 모델의 입력과 출력 스키마를 정의합니다.
infer_signature 함수에 실제 데이터를 넣으면 자동으로 스키마를 추론합니다. 이 정보가 있으면 나중에 잘못된 형식의 데이터가 들어왔을 때 미리 오류를 잡을 수 있습니다.
저장된 모델을 불러올 때는 load_model 함수를 사용합니다. runs:/<run_id>/model 형식의 URI로 특정 실행의 모델을 지정합니다.
로드된 모델은 원래 프레임워크의 객체로 복원되어 predict 메서드를 바로 사용할 수 있습니다. 실무에서 이 표준화가 빛을 발하는 순간이 있습니다.
데이터 사이언티스트가 Jupyter에서 개발한 모델을 DevOps 엔지니어가 배포할 때입니다. pickle 파일이라면 "이거 어떻게 로드해요?"라는 질문이 나올 수 있지만, MLflow Models라면 문서화된 표준 방식으로 로드하면 됩니다.
김개발 씨는 모델을 저장하고 MLflow UI에서 확인해봤습니다. Artifacts 탭에 모델 파일들이 깔끔하게 정리되어 있었습니다.
"이제 다른 사람이 이 모델을 쓰고 싶으면 load_model 한 줄이면 되겠네요."
실전 팁
💡 - signature를 정의해두면 서빙 시 입력 데이터 검증이 자동으로 이루어집니다
- 모델과 함께 전처리 파이프라인도 저장하려면 sklearn의 Pipeline을 통째로 저장하세요
6. Model Registry 기본 사용
프로젝트가 진행되면서 모델 버전이 늘어나기 시작했습니다. v1, v2, v3...
어느 것이 현재 프로덕션에 배포된 건지, 어느 것이 테스트 중인지 헷갈립니다. 김개발 씨가 투덜거립니다.
"모델 버전 관리가 코드 버전 관리보다 더 복잡해요."
Model Registry는 MLflow의 모델 버전 관리 시스템입니다. Git이 코드의 버전을 관리하듯이, Model Registry는 모델의 버전을 관리합니다.
모델에 스테이지(Staging, Production, Archived)를 부여하여 현재 상태를 명확히 하고, 버전 간 전환을 쉽게 할 수 있습니다.
다음 코드를 살펴봅시다.
import mlflow
from mlflow.tracking import MlflowClient
client = MlflowClient()
# 모델 등록 (log_model에서 이미 했다면 생략)
# mlflow.register_model("runs:/<run_id>/model", "house-price-model")
# 모델 버전 정보 조회
model_name = "house-price-model"
latest_versions = client.get_latest_versions(model_name)
for version in latest_versions:
print(f"Version: {version.version}, Stage: {version.current_stage}")
# 모델 스테이지 변경 (Staging → Production)
client.transition_model_version_stage(
name=model_name,
version="2",
stage="Production"
)
# Production 스테이지의 모델 로드
prod_model = mlflow.pyfunc.load_model(f"models:/{model_name}/Production")
# 특정 버전의 모델 로드
v1_model = mlflow.pyfunc.load_model(f"models:/{model_name}/1")
김개발 씨의 팀은 주택 가격 예측 모델을 운영 중입니다. 처음에는 모델이 하나뿐이라 문제가 없었습니다.
하지만 시간이 지나면서 개선된 모델들이 계속 나왔습니다. 어느 날 문제가 터졌습니다.
"지금 프로덕션에 어떤 모델이 올라가 있는 거예요?" 아무도 정확히 대답하지 못했습니다. 슬랙에 공유된 파일?
S3에 올라간 최신 파일? 혼란이 컸습니다.
Model Registry는 이런 혼란을 해결합니다. 비유하자면 출판사의 원고 관리 시스템과 같습니다.
작가가 원고를 여러 번 수정하면 v1, v2, v3로 버전이 매겨집니다. 편집 중인 원고는 "편집 중", 인쇄된 원고는 "출간됨"으로 상태가 표시됩니다.
Model Registry도 마찬가지입니다. MLflow의 스테이지는 크게 네 가지입니다.
None은 방금 등록된 상태, Staging은 테스트 중인 상태, Production은 실제 서비스에 배포된 상태, Archived는 더 이상 사용하지 않는 상태입니다. 코드를 살펴보겠습니다.
MlflowClient를 통해 Registry와 상호작용합니다. get_latest_versions 함수는 각 스테이지별 최신 버전을 반환합니다.
이를 통해 현재 Production에 어떤 버전이 있는지 바로 확인할 수 있습니다. transition_model_version_stage 함수로 모델의 스테이지를 변경합니다.
새 모델을 Production으로 올리면 기존 Production 모델은 자동으로 Archived로 이동시킬 수 있습니다. 이 과정이 기록으로 남아서 나중에 "언제 누가 모델을 교체했는지" 추적할 수 있습니다.
모델을 로드할 때 스테이지 이름을 사용할 수 있습니다. models:/house-price-model/Production 형식으로 지정하면 현재 Production 스테이지의 모델을 가져옵니다.
버전 번호가 아니라 스테이지로 지정하면 모델이 업데이트되어도 코드를 수정할 필요가 없습니다. 특정 버전이 필요할 때는 models:/house-price-model/1 처럼 버전 번호를 직접 지정합니다.
이전 버전으로 롤백해야 할 때 유용합니다. 실무에서 Model Registry는 거버넌스의 기초가 됩니다.
모델을 프로덕션에 올리기 전에 승인 절차를 추가할 수 있습니다. 누가, 언제, 왜 모델을 변경했는지 모든 기록이 남습니다.
김개발 씨는 팀 회의에서 Model Registry 도입을 제안했습니다. "이제부터 모델 배포는 Registry를 통해서만 하는 걸로 정했으면 좋겠어요." 팀원들이 고개를 끄덕였습니다.
실전 팁
💡 - CI/CD 파이프라인과 연동하면 Staging 테스트 통과 후 자동으로 Production 전환이 가능합니다
- 모델 설명과 태그를 추가해두면 나중에 버전 선택할 때 도움이 됩니다
7. REST API 서빙 설정
모델도 만들었고, Registry에도 등록했습니다. 이제 마지막 관문이 남았습니다.
이 모델을 실제 서비스에서 사용하려면 어떻게 해야 할까요? 백엔드 개발자 최엔지니어 씨가 찾아왔습니다.
"이 모델을 API로 호출하고 싶은데, 어떻게 하면 돼요?"
MLflow Models로 저장한 모델은 한 줄의 명령어로 REST API 서버가 됩니다. 마치 마법처럼 학습된 모델이 웹 서비스로 변신합니다.
/invocations 엔드포인트로 JSON 데이터를 보내면 예측 결과가 돌아옵니다. Docker 이미지로 만들어서 쿠버네티스에 배포하는 것도 가능합니다.
다음 코드를 살펴봅시다.
# 터미널에서 모델 서빙 시작
# mlflow models serve -m "models:/house-price-model/Production" -p 5001
# 또는 특정 run의 모델을 서빙
# mlflow models serve -m "runs:/<run_id>/model" -p 5001
import requests
import json
# API 호출 예시
url = "http://localhost:5001/invocations"
# pandas split 형식
data = {
"dataframe_split": {
"columns": ["feature1", "feature2", "feature3", "feature4"],
"data": [[0.5, 1.2, -0.3, 0.8], [1.0, 0.5, 0.2, -0.1]]
}
}
response = requests.post(
url,
headers={"Content-Type": "application/json"},
data=json.dumps(data)
)
print(f"Predictions: {response.json()}")
# Docker 이미지 빌드
# mlflow models build-docker -m "models:/house-price-model/1" -n "house-price-api"
최엔지니어 씨는 웹 애플리케이션을 개발하고 있습니다. 사용자가 주택 정보를 입력하면 예상 가격을 보여주는 기능을 만들어야 합니다.
머신러닝 모델은 김개발 씨가 이미 만들어뒀습니다. 이제 이 모델을 API로 제공해야 합니다.
예전 같았으면 Flask나 FastAPI로 서버를 직접 구현해야 했습니다. 모델 로딩 코드, 입력 검증 코드, 응답 포맷팅 코드...
꽤 많은 작업이 필요합니다. 하지만 MLflow가 있으면 이야기가 달라집니다.
mlflow models serve 명령어 한 줄이면 REST API 서버가 실행됩니다. -m 옵션으로 모델 URI를 지정하고, -p 옵션으로 포트를 지정하면 끝입니다.
Model Registry에 등록된 모델이라면 models:/모델이름/스테이지 형식으로, 특정 실행의 모델이라면 runs:/실행ID/경로 형식으로 지정합니다. 서버가 실행되면 /invocations 엔드포인트가 활성화됩니다.
이 엔드포인트에 JSON 형식으로 데이터를 POST 하면 예측 결과가 반환됩니다. 입력 데이터 형식이 중요합니다.
MLflow는 여러 형식을 지원하는데, 가장 많이 쓰이는 것은 dataframe_split 형식입니다. columns에 컬럼 이름 배열을, data에 실제 데이터 배열을 넣습니다.
여러 건의 예측을 한 번에 요청할 수 있어서 효율적입니다. 실제 프로덕션 환경에서는 Docker를 사용하는 것이 좋습니다.
mlflow models build-docker 명령어로 Docker 이미지를 만들 수 있습니다. 이 이미지에는 모델, 의존성, 서빙 코드가 모두 포함되어 있습니다.
쿠버네티스나 ECS 같은 컨테이너 오케스트레이션 환경에 바로 배포할 수 있습니다. 주의할 점이 있습니다.
기본 제공되는 서버는 개발과 테스트 용도입니다. 실제 대규모 트래픽을 처리하려면 gunicorn 같은 WSGI 서버를 앞에 두거나, 클라우드 제공업체의 모델 서빙 서비스를 활용하는 것이 좋습니다.
성능 최적화도 고려해야 합니다. 모델이 클 경우 첫 번째 요청에서 로딩 시간이 걸릴 수 있습니다.
워밍업 요청을 보내거나, 헬스체크 엔드포인트(/health)를 활용하여 서버 상태를 확인할 수 있습니다. 최엔지니어 씨는 서버를 실행하고 테스트 요청을 보내봤습니다.
예측 결과가 JSON으로 깔끔하게 돌아왔습니다. "오, 이렇게 쉬울 줄이야.
백엔드 코드에서 이 API만 호출하면 되겠네요." 김개발 씨와 최엔지니어 씨는 협업의 경계가 명확해져서 좋았습니다. 데이터 사이언티스트는 모델 개선에 집중하고, 백엔드 개발자는 서비스 통합에 집중할 수 있게 되었습니다.
실전 팁
💡 - 프로덕션 배포 시에는 Docker 이미지를 사용하고, 로드밸런서 뒤에 여러 인스턴스를 두는 것이 좋습니다
- 입력 데이터 검증을 위해 모델 저장 시 signature를 반드시 정의해두세요
이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!
댓글 (0)
함께 보면 좋은 카드 뉴스
Helm 마이크로서비스 패키징 완벽 가이드
Kubernetes 환경에서 마이크로서비스를 효율적으로 패키징하고 배포하는 Helm의 핵심 기능을 실무 중심으로 학습합니다. Chart 생성부터 릴리스 관리까지 체계적으로 다룹니다.
보안 아키텍처 구성 완벽 가이드
프로젝트의 보안을 처음부터 설계하는 방법을 배웁니다. AWS 환경에서 VPC부터 WAF, 암호화, 접근 제어까지 실무에서 바로 적용할 수 있는 보안 아키텍처를 단계별로 구성해봅니다.
AWS Organizations 완벽 가이드
여러 AWS 계정을 체계적으로 관리하고 통합 결제와 보안 정책을 적용하는 방법을 실무 스토리로 쉽게 배워봅니다. 초보 개발자도 바로 이해할 수 있는 친절한 설명과 실전 예제를 제공합니다.
AWS KMS 암호화 완벽 가이드
AWS KMS(Key Management Service)를 활용한 클라우드 데이터 암호화 방법을 초급 개발자를 위해 쉽게 설명합니다. CMK 생성부터 S3, EBS 암호화, 봉투 암호화까지 실무에 필요한 모든 내용을 담았습니다.
AWS Secrets Manager 완벽 가이드
AWS에서 데이터베이스 비밀번호, API 키 등 민감한 정보를 안전하게 관리하는 Secrets Manager의 핵심 개념과 실무 활용법을 배워봅니다. 초급 개발자도 쉽게 따라할 수 있도록 실전 예제와 함께 설명합니다.