Model Monitor는 4종류의 모니터를 제공한다. 오늘은 앞의 둘, 나머지 둘(편향·설명가능성)은 Day 2에서 다룬다.
모니터 종류
무엇을 감시하나
정답 레이블 필요?
베이스라인 산출물
데이터 품질(Data Quality)
입력 피처의 통계 분포 변화
불필요
피처별 통계 + 제약(Deequ)
모델 품질(Model Quality)
예측 정확도/성능 지표 저하
필요(ground truth)
검증셋 기준 성능 지표
편향 드리프트(Bias Drift)
그룹 간 예측 편향 변화
라벨 필요
Clarify 편향 지표 기준값
피처 기여도 드리프트(Feature Attribution)
피처 중요도 분포 변화
불필요
SHAP 기준 중요도
드리프트는 크게 두 종류로 나뉜다. 데이터 드리프트(data drift, covariate shift)는 입력 피처 X의 분포가 바뀌는 것이고, 개념 드리프트(concept drift)는 입력과 출력의 관계 P(Y|X) 자체가 바뀌는 것이다. 데이터 품질 모니터는 X의 분포 변화(데이터 드리프트)를 라벨 없이 잡고, 모델 품질 모니터는 실제 성능 저하(개념 드리프트의 결과)를 ground truth와 비교해 잡는다. 이 구분이 "어떤 모니터를 써야 하는가" 문제의 핵심이다.
모든 모니터링은 엔드포인트로 들어오고 나가는 요청·응답을 S3에 저장하는 것에서 시작한다. 이를 Data Capture라 한다. 캡처를 켜지 않으면 감시할 데이터가 없다.
from sagemaker.model_monitor import DataCaptureConfigdata_capture_config = DataCaptureConfig( enable_capture=True, sampling_percentage=100, # 들어오는 요청의 몇 %를 캡처할지 destination_s3_uri="s3://my-bucket/datacapture/",)# 엔드포인트 배포 시 이 설정을 함께 전달한다predictor = model.deploy( initial_instance_count=1, instance_type="ml.m5.xlarge", data_capture_config=data_capture_config,)
sampling_percentage로 트래픽이 많을 때 일부만 샘플링해 저장 비용을 줄일 수 있다.
캡처 파일은 시간 단위 경로(엔드포인트/배리언트/연/월/일/시)로 나뉘어 쌓인다. 스케줄 실행은 자기 주기에 해당하는 구간만 읽는다.
저장 형식은 JSON Lines — 한 줄이 한 건의 요청·응답이며 입력(endpointInput)과 출력(endpointOutput)이 함께 들어간다.
기존에 이미 떠 있는 엔드포인트라면 재배포 없이 설정만 갱신할 수도 있다.
import boto3sm = boto3.client("sagemaker")# 이미 운영 중인 엔드포인트에 캡처를 켜는 경로(엔드포인트 구성 변경 → 업데이트)sm.create_endpoint_config( EndpointConfigName="my-endpoint-config-v2", ProductionVariants=[...], DataCaptureConfig={ "EnableCapture": True, "InitialSamplingPercentage": 100, "DestinationS3Uri": "s3://my-bucket/datacapture/", "CaptureOptions": [{"CaptureMode": "Input"}, {"CaptureMode": "Output"}], },)sm.update_endpoint(EndpointName="my-endpoint", EndpointConfigName="my-endpoint-config-v2")
⚠️ 함정: "모니터링을 켰는데 실행 결과가 계속 비어 있다"는 시나리오의 1순위 원인은 Data Capture 미설정 또는 샘플링 비율이 너무 낮음이다. 2순위는 해당 주기에 트래픽이 아예 없었던 경우다. 베이스라인이나 스케줄을 의심하기 전에 캡처 S3 경로에 파일이 쌓이는지부터 확인한다.
드리프트를 감지하려면 "정상이란 무엇인가"의 기준이 있어야 한다. Model Monitor는 학습 데이터(또는 검증 데이터)를 분석해 베이스라인 통계(statistics)와 제약(constraints)을 자동 생성한다.
statistics.json: 각 피처의 평균, 표준편차, 최소/최대, 분포 등 통계 요약
constraints.json: 각 피처가 만족해야 할 규칙(예: not null, 데이터 타입, 값 범위)
내부적으로는 Deequ(아마존이 만든 데이터 품질 검증 라이브러리)를 사용한다.
from sagemaker.model_monitor import DefaultModelMonitorfrom sagemaker.model_monitor.dataset_format import DatasetFormatmonitor = DefaultModelMonitor(role=role, instance_count=1, instance_type="ml.m5.xlarge")# 학습 데이터로 베이스라인 생성 → statistics.json, constraints.json 산출monitor.suggest_baseline( baseline_dataset="s3://my-bucket/train/train.csv", dataset_format=DatasetFormat.csv(header=True), output_s3_uri="s3://my-bucket/baseline/",)
베이스라인은 "한 번 만들고 끝"이 아니다. 모델을 재학습하거나 의도적으로 데이터 분포를 바꿨다면 베이스라인도 다시 생성해야 한다. 오래된 베이스라인을 그대로 두면, 정당한 변화까지 드리프트로 오탐(false positive)하거나 반대로 새 기준에 맞춰 진짜 드리프트를 놓친다. 베이스라인은 "현재 정상이라고 믿는 상태"의 스냅샷이다.
베이스라인이 준비되면 모니터링 스케줄을 만든다. 스케줄은 cron 표현식으로 주기(보통 매시간)를 정하고, 그 주기마다 SageMaker가 Processing Job을 띄워 최근 캡처된 데이터를 베이스라인과 비교한다.
from sagemaker.model_monitor import CronExpressionGeneratormonitor.create_monitoring_schedule( monitor_schedule_name="data-quality-schedule", endpoint_input=predictor.endpoint_name, output_s3_uri="s3://my-bucket/monitor-results/", statistics=monitor.baseline_statistics(), constraints=monitor.suggested_constraints(), schedule_cron_expression=CronExpressionGenerator.hourly(), # 매시간 실행 enable_cloudwatch_metrics=True,)
각 실행이 끝나면 violation report(제약 위반 보고서)가 S3에 생성된다. 위반이 있으면 어떤 피처가 어떤 규칙을 어겼는지 기록된다. 또 enable_cloudwatch_metrics=True로 결과 지표를 CloudWatch로 보내 알람을 걸 수 있다(Day 3 주제).
실행 이력과 위반 여부는 SDK/boto3로 직접 확인한다.
# 최근 스케줄 실행 목록 — 상태가 CompletedWithViolations면 위반이 있었다는 뜻execs = monitor.list_executions()last = execs[-1].describe()print(last["ProcessingJobStatus"])print(last["ProcessingOutputConfig"]) # 위반 리포트가 떨어진 S3 경로
캡처 데이터에 나타나는 대표적인 위반 유형은 다음과 같다. 어떤 이름이 나오느냐가 곧 원인 힌트다.
위반 유형
뜻
흔한 실제 원인
data_type_check
기대한 타입과 다른 값이 들어옴
숫자 컬럼에 문자열·빈 문자열 유입
completeness_check
결측 비율이 기준을 넘음
업스트림 조인 실패, 선택 입력 필드
baseline_drift_check
분포가 베이스라인에서 멀어짐
진짜 데이터 드리프트, 계절성
missing_column_check / extra_column_check
컬럼이 빠지거나 늘어남
전처리 코드 변경, 스키마 변경
categorical_values_check
학습 때 없던 범주값 등장
신규 상품코드·지역코드 추가
위반이 떴다고 곧바로 재학습이 답은 아니다. missing_column_check나 data_type_check는 데이터 파이프라인 버그일 가능성이 크고, 이건 모델을 다시 학습해도 해결되지 않는다. 반대로 baseline_drift_check가 여러 피처에서 지속적으로 뜨면 그때가 재학습을 검토할 시점이다. "스키마 문제인가, 분포 문제인가"를 먼저 갈라라.
problem_type은 문제 유형에 맞춰 고른다 — BinaryClassification, MulticlassClassification, Regression. 유형에 따라 계산되는 지표 집합이 달라진다(분류는 정확도·F1·AUC 계열, 회귀는 오차 계열).
구분
데이터 품질 모니터
모델 품질 모니터
보는 것
입력 X의 분포·스키마
예측이 실제로 맞았는가
ground truth
불필요
필수
감지 시점
즉시(다음 주기)
정답이 모일 때까지 지연
잡는 것
데이터 드리프트, 파이프라인 사고
개념 드리프트의 결과(성능 저하)
한계
분포가 변해도 성능은 멀쩡할 수 있음
이미 손해가 난 뒤에야 안다
⚠️ 함정: "모델 정확도가 실제로 떨어지는지 감시"라고 하면 데이터 품질이 아니라 모델 품질 모니터다. 그리고 모델 품질 모니터는 반드시 ground truth가 필요하다. 시험에서 "정답 레이블을 수집할 수 없는 상황에서 성능 저하를 미리 감지하려면?"이라고 물으면, 모델 품질은 불가능하므로 데이터 품질 드리프트(입력 분포 변화)나 피처 기여도 드리프트로 우회한다.