MLflow 해부 (4) Model Registry: 버전, alias, 서빙
run에 흩어진 모델을 이름과 버전으로 관리하는 Model Registry를 다룹니다. register_model 등록, alias 기반 승격과 롤백, models URI 로딩, mlflow models serve까지의 흐름입니다.
MLflow 해부 시리즈의 4편입니다. 전체 목차는 0편에 있습니다.
Registry가 푸는 문제
3편까지의 모델은 run 아래에 있습니다. “지난주 화요일에 돌린 run의 모델”은 재현에는 충분하지만 배포 기준으로는 부족합니다. 배포 파이프라인에 필요한 것은 “지금 운영에 나가야 하는 모델은 어느 것인가”라는 질문의 답이고, Model Registry가 그 답을 이름, 버전, alias로 관리합니다.
등록과 버전
1
2
result = mlflow.register_model("runs:/<run_id>/model", "demand-model")
print(result.version) # 1
같은 이름으로 다시 등록하면 버전이 2, 3으로 올라갑니다. run과 registry의 관계가 핵심입니다. 등록은 모델 복사가 아니라 “이 run의 이 모델을 demand-model 버전 N으로 부른다”는 포인터 생성이라서, registry의 모든 버전은 원본 run으로 거슬러 올라갈 수 있습니다. 어떤 파라미터와 데이터로 만든 모델인지가 끊기지 않습니다.
log_model만 하고 등록됐다고 착각하는 것이 흔한 사고입니다. log_model은 run에 저장까지이고, registry 등록은 register_model이라는 별도 단계입니다. 배포 파이프라인이 registry를 바라보고 있다면, 이 단계가 빠졌을 때 새 모델이 조용히 배포되지 않습니다.
alias: 승격과 롤백의 단위
버전에 이름표를 붙이는 것이 alias입니다. 예전 방식인 stage(Staging, Production)는 deprecated 상태이고 alias가 현재 표준입니다.
1
2
3
4
from mlflow import MlflowClient
client = MlflowClient()
client.set_registered_model_alias("demand-model", "champion", version=3)
배포 코드는 버전 번호가 아니라 alias만 바라봅니다.
1
model = mlflow.pyfunc.load_model("models:/demand-model@champion")
이 구조가 만드는 운영 절차는 단순합니다.
- 승격: 새 버전 4가 검증을 통과하면 champion alias를 4로 옮깁니다. 배포 코드는 수정하지 않습니다
- 롤백: 문제가 생기면 alias를 3으로 되돌립니다. 역시 코드 수정이 없습니다
- 후보 관리: 평가 중인 버전에 challenger alias를 붙여 champion과 나란히 두는 패턴이 일반적입니다
로컬 서빙으로 확인
등록한 모델은 CLI 한 줄로 REST API가 됩니다.
1
mlflow models serve -m "models:/demand-model@champion" --port 5002
1
2
3
curl -X POST http://127.0.0.1:5002/invocations \
-H "Content-Type: application/json" \
-d '{"inputs": [[0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]]}'
3편의 signature가 여기서 동작합니다. 입력 컬럼 수나 dtype이 어긋나면 예측 대신 스키마 에러가 돌아옵니다. 프로덕션 서빙을 이 명령으로 하는 것은 아니고, 등록한 모델이 서빙 가능한 상태인지 배포 전에 확인하는 용도로 씁니다. 실제 서빙 구성은 머신러닝 실전 워크플로 9편의 영역입니다.
이 편의 요약
- 등록은 포인터 생성입니다. 모든 버전이 원본 run과 연결됩니다
- 배포 코드는
models:/이름@alias만 바라보고, 승격과 롤백은 alias 이동으로 처리합니다 log_model과register_model은 별도 단계입니다
다음 편에서는 기록을 코드로 조회해서 승격을 자동화합니다.