어제 파이프라인이 만들어낸 모델은 체계적으로 보관되고 승인을 거쳐 프로덕션으로 넘어가야 한다. "이 모델은 어떤 데이터로 학습됐고, 성능은 얼마고, 누가 승인했고, 지금 어느 버전이 배포돼 있는가?"에 답할 수 없다면 그건 MLOps가 아니라 그냥 파일 더미다.
학습된 모델들을 버전 관리되는 카탈로그에 등록·정리하는 서비스.
코드에 Git이 있듯 모델에도 버전·메타데이터·승인 이력이 필요하다는 발상.
구조는 두 계층이다.
개념
역할
Model Package Group
동일 목적의 모델들을 묶는 컨테이너 (예: "사기탐지-모델")
Model Package (Version)
그룹 안의 개별 버전 (1, 2, 3...) — 각각 아티팩트·메트릭·승인 상태를 가짐
하나의 그룹 안에 모델을 등록할 때마다 버전이 1씩 자동 증가한다. 사용자가 번호를 붙이지 않는다.
각 버전이 담는 것: 모델 아티팩트(S3의 model.tar.gz), 추론 컨테이너 이미지 URI, 평가 메트릭, 승인 상태, 설명.
비교 축
그냥 S3에 모델 저장
Model Registry
버전
파일명·경로 규칙에 의존(사람 실수)
시스템이 자동 부여
메트릭
별도 파일로 따로 관리
버전에 함께 첨부
승인
없음(문서·구두 합의)
상태값으로 명시, 이력 남음
배포 연결
수동
승인 이벤트 → 자동 트리거
감사
추적 어려움
Lineage와 연결해 역추적
💡 관련 이론: Model Registry의 핵심 가치는 추적성(traceability)과 거버넌스다. 규제 산업(금융·의료)에서는 "프로덕션에 배포된 모델이 정확히 무엇이고 누가 승인했는가"를 감사(audit)할 수 있어야 한다. Registry는 모델 버전과 SageMaker 계보(lineage)를 연결해 데이터→학습→모델→배포의 전 과정을 기록으로 남긴다. 시험에서 "모델 버전 추적·승인·감사"라는 키워드가 보이면 Model Registry다.
먼저 모델들을 담을 그룹을 만든다. 그룹은 보통 "한 가지 문제를 푸는 모델 계열"을 의미한다.
import boto3sm = boto3.client("sagemaker")# 동일 목적 모델들을 묶는 패키지 그룹 생성sm.create_model_package_group( ModelPackageGroupName="fraud-detection-models", ModelPackageGroupDescription="사기 탐지 모델 버전 카탈로그",)
그룹을 문제 단위로 자르는 것이 원칙이다. "사기탐지"와 "이탈예측"은 서로 다른 그룹이어야 버전 번호가 의미를 갖는다.
같은 문제의 알고리즘만 바꾼 실험은 같은 그룹의 다른 버전으로 두는 편이 비교·롤백에 유리하다.
[파이프라인 RegisterModel] │ ▼ ┌────────────────────────┐ │ PendingManualApproval │ ← 등록 직후 기본 상태 └───────┬────────────┬───┘ 검토 통과 │ │ 검토 탈락 ▼ ▼ ┌──────────────┐ ┌──────────┐ │ Approved │ │ Rejected │ └──────┬───────┘ └──────────┘ │ │ │ └──▶ (배포 없음 · 재학습 후 새 버전 등록) ▼ EventBridge "SageMaker Model Package State Change" │ ▼ CodePipeline(Deploy) → 스테이징 → 수동 승인 → 프로덕션
전형적 흐름: 파이프라인이 PendingManualApproval로 등록 → 검토자(또는 자동 검증)가 메트릭 확인 → Approved로 변경 → 그 이벤트가 배포를 트리거.
즉 승인 상태 변경 자체가 배포의 게이트다.
Rejected는 되돌리는 상태가 아니라 "이 버전은 안 쓴다"는 기록이다. 고쳤다면 새 버전을 등록하는 것이 정석이다.
# 검토 후 모델 버전을 승인 처리sm.update_model_package( ModelPackageArn=model_package_arn, ModelApprovalStatus="Approved", ApprovalDescription="오프라인 평가 통과, 프로덕션 승인",)
승인 상태 변경은 EventBridge 이벤트를 발생시킨다. 이를 받아 CodePipeline이나 Lambda가 자동으로 엔드포인트 배포를 수행하도록 연결하는 것이 내일 다룰 CI/CD의 핵심 트리거다.
승인 워크플로는 "누가 책임지고 프로덕션에 내보내는가"를 명시화한다. 자동 평가가 통과해도 사람이 최종 Approved를 누르게 하면 책임 소재와 통제권이 명확해진다(human-in-the-loop). 반대로 신뢰가 쌓이면 ConditionStep으로 자동 승인까지 갈 수 있다. 시험에서 "모델 승인 시 자동 배포"라는 흐름이 나오면 Model Registry 승인 → EventBridge → CodePipeline 연결이 답이다.
⚠️ 함정: 등록 단계에서 approval_status="Approved"로 바로 박아 버리면 사람 검토 없이 곧장 배포가 굴러간다. "품질 게이트는 통과했지만 사람이 한 번 더 확인해야 한다"는 요구가 있으면 반드시 PendingManualApproval로 등록해야 한다. 반대로 완전 자동 재학습 루프를 원하면 자동 승인이 답이다 — 요구사항의 방향을 먼저 읽어야 한다.
승인을 사람이 누를 것인가, 파이프라인이 대신 눌러 줄 것인가는 조직의 신뢰 수준에 달렸다. 시험은 요구 문장에서 이 방향을 흘린다.
비교 축
수동 승인 (human-in-the-loop)
자동 승인
등록 시 상태
PendingManualApproval
조건 통과 시 곧장 Approved
판단 근거
검토자가 메트릭·리포트를 눈으로 확인
ConditionStep의 임계값 비교
속도
사람 대기만큼 느림
즉시 배포까지 연결
책임 소재
승인자가 명확히 남음
임계값을 정한 규칙에 위임
맞는 상황
규제 산업, 초기 도입, 영향이 큰 모델
잦은 재학습, 리스크가 낮은 모델
요구 문장의 신호
"검토를 거쳐", "감사 대응", "책임자 확인"
"완전 자동", "야간 재학습", "사람 개입 없이"
두 방식은 배타적이지 않다. Registry 승인은 자동으로 두고, 프로덕션 직전에 CodePipeline 수동 승인을 남기는 절충이 흔하다.
자동 승인을 쓰더라도 ApprovalDescription에 근거(어떤 지표가 얼마였는지)를 남겨 두면 나중에 감사에 대응할 수 있다.
# 평가 결과를 근거로 남기며 승인 상태를 바꾸는 형태sm.update_model_package( ModelPackageArn=model_package_arn, ModelApprovalStatus="Approved", ApprovalDescription="AUC 0.91 (기준 0.88 초과), 야간 자동 검증 통과",)
Registry는 "모델을 저장하는 곳"이 아니라 "모델의 상태를 선언하는 곳" 이다. 아티팩트 자체는 여전히 S3에 있고, Registry가 관리하는 건 그 아티팩트에 붙은 버전·메트릭·승인이라는 메타데이터다. 그래서 승인 상태 하나만 바꿔도 배포 파이프라인 전체가 움직인다.
내일은 이 승인 이벤트를 받아 실제로 배포를 굴리는 CI/CD — SageMaker Projects와 CodePipeline/CodeBuild를 다룬다.