🤖

본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.

⚠️

본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.

이미지 로딩 중...

모델 모니터링 완벽 가이드 - 슬라이드 1/7
A

AI Generated

2025. 12. 7. · 16 Views

모델 모니터링 완벽 가이드

머신러닝 모델을 운영 환경에 배포한 후 성능을 지속적으로 추적하고 관리하는 방법을 알아봅니다. 드리프트 감지부터 Prometheus와 Grafana를 활용한 실시간 모니터링까지 실무에서 바로 적용할 수 있는 내용을 다룹니다.


목차

  1. 모델_드리프트란
  2. 데이터_드리프트_감지
  3. 성능_메트릭_추적
  4. Prometheus_연동
  5. Grafana_대시보드
  6. 알림_설정

1. 모델 드리프트란

김개발 씨는 3개월 전 고객 이탈 예측 모델을 배포했습니다. 처음에는 95%라는 놀라운 정확도를 자랑했는데, 어느 날 마케팅팀에서 연락이 왔습니다.

"요즘 예측이 자꾸 빗나가는 것 같아요. 모델 괜찮은 거 맞죠?"

모델 드리프트는 시간이 지나면서 모델의 예측 성능이 점차 저하되는 현상입니다. 마치 오래된 지도로 새로 생긴 도로를 찾으려는 것과 같습니다.

세상은 변하는데 모델은 과거 데이터로 학습했기 때문에 현실과 괴리가 생기는 것입니다. 이를 감지하고 대응하지 않으면 비즈니스에 큰 손실을 초래할 수 있습니다.

다음 코드를 살펴봅시다.

from dataclasses import dataclass
from datetime import datetime
from typing import List

@dataclass
class DriftMetrics:
    # 드리프트 측정 지표를 담는 클래스
    timestamp: datetime
    accuracy: float
    prediction_distribution: List[float]

def detect_drift(baseline_accuracy: float, current_accuracy: float, threshold: float = 0.05) -> bool:
    # 기준 성능 대비 현재 성능 저하 감지
    drift_amount = baseline_accuracy - current_accuracy
    if drift_amount > threshold:
        print(f"경고: 성능이 {drift_amount:.2%} 하락했습니다!")
        return True
    return False

# 사용 예시
is_drifting = detect_drift(baseline_accuracy=0.95, current_accuracy=0.88)

김개발 씨는 입사 1년 차 ML 엔지니어입니다. 첫 번째 프로젝트로 고객 이탈 예측 모델을 만들었는데, 테스트 결과가 너무 좋아서 큰 칭찬을 받았습니다.

모델은 순조롭게 운영 환경에 배포되었고, 김개발 씨는 다음 프로젝트로 넘어갔습니다. 그런데 3개월 후, 마케팅팀에서 이상한 보고가 들어왔습니다.

모델이 이탈할 것이라고 예측한 고객들이 오히려 더 충성스러운 고객이었고, 이탈하지 않을 것이라던 고객들이 떠나고 있었습니다. 박시니어 씨가 김개발 씨에게 물었습니다.

"혹시 모델 드리프트에 대해 들어본 적 있어요?" 그렇다면 모델 드리프트란 정확히 무엇일까요? 쉽게 비유하자면, 모델 드리프트는 마치 10년 전 네비게이션으로 오늘 길을 찾으려는 것과 같습니다.

10년 전에는 정확했던 지도가 지금은 맞지 않습니다. 새 도로가 생기고, 건물이 들어서고, 교통 패턴이 바뀌었기 때문입니다.

머신러닝 모델도 마찬가지입니다. 학습 당시의 데이터 패턴이 현재와 달라지면 예측력이 떨어집니다.

모델 드리프트가 발생하는 원인은 크게 두 가지입니다. 첫 번째는 데이터 드리프트입니다.

입력 데이터의 분포 자체가 변하는 경우입니다. 예를 들어 코로나19 팬데믹 이후 소비자 행동 패턴이 급격히 변했습니다.

온라인 쇼핑이 폭발적으로 늘었고, 오프라인 매장 방문은 줄었습니다. 팬데믹 이전 데이터로 학습한 모델은 이런 변화를 알 수 없습니다.

두 번째는 콘셉트 드리프트입니다. 입력과 출력 사이의 관계 자체가 변하는 경우입니다.

예전에는 특정 행동을 하는 고객이 이탈했지만, 시장 환경이 바뀌면서 같은 행동을 해도 이탈하지 않게 된 것입니다. 위의 코드를 살펴보겠습니다.

DriftMetrics 클래스는 드리프트를 측정하기 위한 핵심 지표들을 담고 있습니다. 시간, 정확도, 예측 분포를 기록합니다.

detect_drift 함수는 기준 성능과 현재 성능을 비교하여 임계값 이상 하락했는지 확인합니다. 실제 현업에서는 단순한 정확도 비교만으로는 부족합니다.

다양한 통계적 검정을 활용하고, 여러 지표를 종합적으로 분석해야 합니다. 하지만 이 기본 원리를 이해하는 것이 첫걸음입니다.

주의할 점은 모든 성능 저하가 드리프트 때문은 아니라는 것입니다. 버그나 인프라 문제일 수도 있습니다.

따라서 원인을 정확히 파악하는 것이 중요합니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.

박시니어 씨의 설명을 들은 김개발 씨는 고개를 끄덕였습니다. "배포하고 끝이 아니라, 계속 지켜봐야 하는 거군요!"

실전 팁

💡 - 모델 배포 직후 기준 성능을 반드시 기록해 두세요

  • 드리프트 감지는 자동화하여 사람이 놓치지 않도록 하세요
  • 드리프트가 발생하면 재학습 파이프라인을 갖춰두는 것이 좋습니다

2. 데이터 드리프트 감지

김개발 씨는 모델 드리프트의 개념을 이해했습니다. 하지만 문제가 생긴 후에 알게 되면 이미 늦은 것 아닐까요?

박시니어 씨가 말했습니다. "성능이 떨어지기 전에 미리 알 수 있는 방법이 있어요.

바로 입력 데이터의 변화를 먼저 감지하는 거죠."

데이터 드리프트 감지는 모델에 들어오는 입력 데이터의 분포가 학습 시점과 얼마나 달라졌는지 측정하는 기법입니다. 마치 체온계로 열이 나기 전에 미열을 감지하는 것과 같습니다.

데이터 분포의 변화는 곧 성능 저하의 전조 증상이므로, 이를 조기에 발견하면 선제적으로 대응할 수 있습니다.

다음 코드를 살펴봅시다.

import numpy as np
from scipy import stats

def calculate_psi(baseline: np.ndarray, current: np.ndarray, bins: int = 10) -> float:
    """PSI(Population Stability Index)를 계산합니다"""
    # 데이터를 구간으로 나누기
    breakpoints = np.percentile(baseline, np.linspace(0, 100, bins + 1))

    # 각 구간별 비율 계산
    baseline_counts = np.histogram(baseline, bins=breakpoints)[0] / len(baseline)
    current_counts = np.histogram(current, bins=breakpoints)[0] / len(current)

    # 0으로 나누기 방지
    baseline_counts = np.clip(baseline_counts, 0.001, None)
    current_counts = np.clip(current_counts, 0.001, None)

    # PSI 계산: 분포 차이를 수치화
    psi = np.sum((current_counts - baseline_counts) * np.log(current_counts / baseline_counts))
    return psi

# PSI 해석: 0.1 미만 = 안정, 0.1-0.2 = 주의, 0.2 이상 = 심각한 드리프트
psi_score = calculate_psi(baseline_data, current_data)
print(f"PSI Score: {psi_score:.4f}")

김개발 씨에게 새로운 과제가 주어졌습니다. 모델 성능이 떨어지기 전에 미리 경고를 받을 수 있는 시스템을 구축하는 것입니다.

하지만 어떻게 미래를 예측할 수 있을까요? 박시니어 씨가 힌트를 주었습니다.

"모델 성능이 떨어지는 건 결과야. 원인은 뭘까?" 김개발 씨가 생각에 잠겼습니다.

모델은 데이터를 입력받아 예측을 출력합니다. 모델 자체는 변하지 않았는데 결과가 달라졌다면, 결국 입력 데이터가 변한 것입니다.

바로 이것이 데이터 드리프트 감지의 핵심 아이디어입니다. 쉽게 비유하자면, 데이터 드리프트 감지는 마치 의사가 혈압을 정기적으로 측정하는 것과 같습니다.

심장마비가 오기 전에 혈압이 먼저 높아집니다. 마찬가지로 모델 성능이 추락하기 전에 입력 데이터의 분포가 먼저 변합니다.

데이터 드리프트를 감지하는 대표적인 방법 중 하나가 **PSI(Population Stability Index)**입니다. 이 지표는 원래 금융권에서 신용 점수 모델의 안정성을 평가하기 위해 개발되었습니다.

PSI는 두 분포가 얼마나 다른지를 숫자로 나타냅니다. 0에 가까울수록 분포가 비슷하고, 값이 커질수록 분포가 많이 달라졌다는 뜻입니다.

일반적으로 0.1 미만이면 안정적, 0.1에서 0.2 사이면 주의 필요, 0.2 이상이면 심각한 드리프트로 판단합니다. 위의 코드를 살펴보겠습니다.

먼저 기준 데이터를 여러 구간으로 나눕니다. 그다음 각 구간에 현재 데이터가 얼마나 분포되어 있는지 계산합니다.

마지막으로 두 분포의 차이를 PSI 공식으로 계산합니다. 또 다른 방법으로는 **KS 검정(Kolmogorov-Smirnov Test)**이 있습니다.

이것은 두 분포가 같은 분포에서 왔는지를 통계적으로 검정합니다. scipy 라이브러리의 ks_2samp 함수를 사용하면 쉽게 계산할 수 있습니다.

실제 현업에서는 모든 입력 피처에 대해 드리프트를 모니터링합니다. 수십 개에서 수백 개의 피처를 매일 검사하고, 이상이 감지되면 알림을 보냅니다.

이런 작업을 수동으로 하는 것은 불가능하므로 자동화가 필수입니다. 주의할 점은 모든 데이터 변화가 나쁜 것은 아니라는 것입니다.

비즈니스 성장으로 인해 자연스럽게 변할 수도 있습니다. 중요한 것은 변화를 인지하고, 그것이 모델에 어떤 영향을 미치는지 파악하는 것입니다.

김개발 씨는 이제 데이터 드리프트 감지 시스템을 구축했습니다. 매일 아침 출근하면 대시보드에서 모든 피처의 PSI 점수를 확인합니다.

빨간불이 켜지면 즉시 조사에 들어갑니다.

실전 팁

💡 - 중요한 피처부터 우선순위를 정해서 모니터링하세요

  • PSI와 KS 검정을 함께 사용하면 더 신뢰할 수 있습니다
  • 임계값은 비즈니스 특성에 맞게 조정하세요

3. 성능 메트릭 추적

데이터 드리프트 감지 시스템을 구축한 김개발 씨. 하지만 박시니어 씨가 말했습니다.

"데이터 변화를 보는 것도 중요하지만, 결국 우리가 관심 있는 건 모델 성능 자체야. 실제 예측이 얼마나 맞는지를 추적해야 해."

성능 메트릭 추적은 모델의 예측 결과를 실제 정답과 비교하여 다양한 성능 지표를 계산하고 기록하는 과정입니다. 마치 시험 성적표를 주기적으로 받아보는 것과 같습니다.

정확도, 정밀도, 재현율, F1 점수 등 다양한 관점에서 모델을 평가해야 전체적인 건강 상태를 파악할 수 있습니다.

다음 코드를 살펴봅시다.

from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
from datetime import datetime
import json

class ModelPerformanceTracker:
    def __init__(self, model_name: str):
        self.model_name = model_name
        self.metrics_history = []

    def log_metrics(self, y_true, y_pred):
        # 다양한 성능 지표를 한 번에 계산
        metrics = {
            "timestamp": datetime.now().isoformat(),
            "accuracy": accuracy_score(y_true, y_pred),
            "precision": precision_score(y_true, y_pred, average="weighted"),
            "recall": recall_score(y_true, y_pred, average="weighted"),
            "f1": f1_score(y_true, y_pred, average="weighted"),
            "sample_count": len(y_true)
        }
        self.metrics_history.append(metrics)
        return metrics

    def get_trend(self, metric_name: str, window: int = 7):
        # 최근 N개 기록의 추세 확인
        recent = [m[metric_name] for m in self.metrics_history[-window:]]
        return {"mean": sum(recent) / len(recent), "values": recent}

김개발 씨는 데이터 드리프트만 보면 될 줄 알았습니다. 그런데 박시니어 씨가 흥미로운 사례를 들려주었습니다.

"작년에 데이터 분포는 거의 변하지 않았는데 성능이 급락한 적이 있어. 왜 그랬을까?" 이유는 간단했습니다.

외부 환경이 바뀌어서 같은 데이터라도 결과가 달라진 것입니다. 이것이 바로 콘셉트 드리프트입니다.

데이터 드리프트 감지만으로는 이런 상황을 놓칠 수 있습니다. 그래서 성능 메트릭 추적이 필요합니다.

쉽게 비유하자면, 데이터 드리프트 감지가 체온 측정이라면, 성능 메트릭 추적은 종합 건강검진입니다. 체온이 정상이어도 다른 곳에 문제가 있을 수 있으니까요.

성능을 측정할 때는 하나의 지표만 보면 안 됩니다. **정확도(Accuracy)**가 높아도 클래스 불균형이 있으면 의미가 없을 수 있습니다.

99%의 정상 거래와 1%의 사기 거래가 있을 때, 모든 것을 정상이라고 예측해도 정확도는 99%가 됩니다. 그래서 **정밀도(Precision)**와 **재현율(Recall)**을 함께 봅니다.

정밀도는 모델이 사기라고 예측한 것 중 실제 사기의 비율입니다. 재현율은 실제 사기 중 모델이 찾아낸 비율입니다.

이 둘의 조화 평균이 F1 점수입니다. 위의 코드를 살펴보겠습니다.

ModelPerformanceTracker 클래스는 모델의 성능을 추적합니다. log_metrics 메서드는 실제 정답과 예측 결과를 받아 여러 지표를 한 번에 계산합니다.

get_trend 메서드는 최근 기록을 분석하여 성능 추세를 파악합니다. 실제 현업에서는 레이블 딜레이 문제를 고려해야 합니다.

예측은 즉시 이루어지지만, 실제 정답을 알기까지는 시간이 걸립니다. 고객 이탈 예측의 경우 고객이 정말 이탈했는지 확인하려면 몇 주에서 몇 달이 걸릴 수 있습니다.

이런 경우 프록시 메트릭을 활용합니다. 최종 결과 대신 중간 지표를 추적하는 것입니다.

예를 들어 이탈 예측 대신 앱 사용 빈도 감소를 먼저 추적할 수 있습니다. 주의할 점은 메트릭에 집착하여 숫자 놀음에 빠지지 않는 것입니다.

비즈니스 맥락을 항상 염두에 두어야 합니다. F1 점수가 0.01 떨어졌다고 무조건 문제인 것은 아닙니다.

그 변화가 비즈니스에 미치는 영향을 생각해야 합니다. 김개발 씨는 이제 매일 성능 메트릭을 기록합니다.

일간, 주간, 월간 리포트를 자동으로 생성하고, 이상한 패턴이 보이면 즉시 조사합니다.

실전 팁

💡 - 단일 지표가 아닌 여러 지표를 종합적으로 확인하세요

  • 레이블 딜레이를 고려한 모니터링 전략을 수립하세요
  • 비즈니스 KPI와 연결된 메트릭을 정의하세요

4. Prometheus 연동

김개발 씨는 성능 메트릭을 열심히 추적하고 있습니다. 하지만 매번 수동으로 확인하는 것이 번거로웠습니다.

박시니어 씨가 말했습니다. "프로메테우스를 써봐.

메트릭 수집의 업계 표준이야. 한번 설정해 두면 알아서 데이터를 긁어가거든."

Prometheus는 오픈소스 모니터링 시스템으로, 시계열 데이터베이스에 메트릭을 저장하고 쿼리할 수 있게 해줍니다. 마치 자동으로 움직이는 CCTV처럼 지정한 엔드포인트에서 주기적으로 메트릭을 수집합니다.

클라우드 네이티브 환경에서 사실상 표준으로 자리 잡았으며, 특히 쿠버네티스와의 연동이 뛰어납니다.

다음 코드를 살펴봅시다.

from prometheus_client import Counter, Gauge, Histogram, start_http_server
import time

# 메트릭 정의: 예측 요청 수, 현재 정확도, 응답 시간
prediction_requests = Counter(
    "ml_prediction_requests_total",
    "Total prediction requests",
    ["model_name", "status"]
)
model_accuracy = Gauge(
    "ml_model_accuracy",
    "Current model accuracy",
    ["model_name"]
)
prediction_latency = Histogram(
    "ml_prediction_latency_seconds",
    "Prediction latency in seconds",
    ["model_name"],
    buckets=[0.01, 0.05, 0.1, 0.5, 1.0, 5.0]
)

def predict_with_metrics(model, input_data):
    start_time = time.time()
    try:
        result = model.predict(input_data)
        prediction_requests.labels(model_name="churn_model", status="success").inc()
        return result
    finally:
        latency = time.time() - start_time
        prediction_latency.labels(model_name="churn_model").observe(latency)

# 메트릭 서버 시작 (포트 8000에서 /metrics 엔드포인트 제공)
start_http_server(8000)

김개발 씨가 만든 성능 추적 시스템은 잘 작동했습니다. 하지만 한 가지 문제가 있었습니다.

로그 파일에 기록하고 있었기 때문에 데이터를 분석하려면 매번 파일을 열어봐야 했습니다. 여러 서버에 분산된 로그를 합치는 것도 번거로웠습니다.

박시니어 씨가 제안했습니다. "프로메테우스를 도입하면 이런 고민이 사라져." Prometheus는 무엇일까요?

쉽게 비유하자면, 프로메테우스는 마치 여러 곳에 설치된 CCTV 영상을 한곳에 모아서 보여주는 중앙 관제 시스템과 같습니다. 각 서버에서 메트릭을 수집해서 중앙 데이터베이스에 저장하고, 원할 때 언제든 조회할 수 있습니다.

프로메테우스의 동작 방식은 독특합니다. 대부분의 모니터링 시스템은 애플리케이션이 데이터를 밀어 넣는 푸시(Push) 방식입니다.

하지만 프로메테우스는 직접 데이터를 가져가는 풀(Pull) 방식입니다. 애플리케이션은 /metrics 엔드포인트만 열어두면 됩니다.

프로메테우스에서 사용하는 메트릭 타입은 세 가지입니다. Counter는 누적 카운터입니다.

절대 감소하지 않고 계속 증가합니다. 총 예측 요청 수, 에러 발생 횟수 등에 사용합니다.

Gauge는 현재 값을 나타냅니다. 올라갈 수도, 내려갈 수도 있습니다.

현재 모델 정확도, 메모리 사용량 등에 사용합니다. Histogram은 값의 분포를 측정합니다.

응답 시간처럼 값이 어떤 범위에 분포하는지 볼 때 사용합니다. 미리 정의한 버킷에 값들을 분류합니다.

위의 코드를 살펴보겠습니다. 먼저 세 가지 메트릭을 정의합니다.

prediction_requests는 예측 요청 수를 세는 카운터입니다. model_accuracy는 현재 정확도를 나타내는 게이지입니다.

prediction_latency는 응답 시간 분포를 측정하는 히스토그램입니다. predict_with_metrics 함수는 예측을 수행하면서 메트릭을 기록합니다.

성공하면 카운터를 증가시키고, 응답 시간은 항상 기록합니다. 마지막으로 **start_http_server(8000)**을 호출하면 8000번 포트에서 /metrics 엔드포인트가 열립니다.

프로메테우스가 이 엔드포인트를 주기적으로 호출하여 데이터를 수집합니다. 실제 운영 환경에서는 프로메테우스 설정 파일에 스크레이프 대상을 지정해야 합니다.

쿠버네티스를 사용한다면 서비스 디스커버리가 자동으로 처리됩니다. 주의할 점은 메트릭 이름과 레이블을 일관성 있게 유지하는 것입니다.

나중에 쿼리할 때 편리하도록 네이밍 컨벤션을 미리 정해두세요. 김개발 씨는 프로메테우스를 도입한 후 훨씬 편해졌습니다.

여러 서버의 메트릭을 한곳에서 조회하고, PromQL이라는 쿼리 언어로 복잡한 분석도 할 수 있게 되었습니다.

실전 팁

💡 - 메트릭 이름은 snake_case를 사용하고 단위를 접미사로 붙이세요

  • 레이블 카디널리티가 너무 높으면 성능 문제가 발생합니다
  • 프로메테우스 오퍼레이터를 사용하면 쿠버네티스 연동이 쉬워집니다

5. Grafana 대시보드

프로메테우스로 메트릭 수집 체계를 갖춘 김개발 씨. 하지만 PromQL로 터미널에서 데이터를 조회하는 것은 불편했습니다.

박시니어 씨가 말했습니다. "그라파나를 연동해봐.

그래프로 보면 패턴이 한눈에 들어와."

Grafana는 메트릭 데이터를 시각화하는 오픈소스 대시보드 도구입니다. 마치 자동차 계기판처럼 중요한 정보를 한눈에 볼 수 있게 해줍니다.

Prometheus, InfluxDB, Elasticsearch 등 다양한 데이터 소스를 연결할 수 있으며, 아름다운 그래프와 알림 기능을 제공합니다.

다음 코드를 살펴봅시다.

# Grafana 대시보드 JSON 설정 예시 (dashboard.json)
{
  "dashboard": {
    "title": "ML Model Performance Dashboard",
    "panels": [
      {
        "title": "Prediction Requests per Second",
        "type": "graph",
        "targets": [{
          "expr": "rate(ml_prediction_requests_total[5m])",
          "legendFormat": "{{model_name}} - {{status}}"
        }]
      },
      {
        "title": "Model Accuracy Trend",
        "type": "graph",
        "targets": [{
          "expr": "ml_model_accuracy",
          "legendFormat": "{{model_name}}"
        }],
        "alert": {
          "name": "Low Accuracy Alert",
          "conditions": [{
            "evaluator": {"type": "lt", "params": [0.85]},
            "operator": {"type": "and"},
            "query": {"params": ["A", "5m", "now"]}
          }]
        }
      }
    ]
  }
}

김개발 씨는 프로메테우스에 쌓인 데이터를 분석하고 있었습니다. PromQL을 사용해서 정확도 추이를 조회했습니다.

숫자들이 주르륵 나왔습니다. 하지만 이 숫자들이 좋은 건지 나쁜 건지 한눈에 파악하기 어려웠습니다.

박시니어 씨가 김개발 씨의 화면을 보더니 말했습니다. "사람 눈은 숫자보다 그래프에서 패턴을 더 잘 찾아내.

그라파나를 써볼래?" Grafana는 무엇일까요? 쉽게 비유하자면, 그라파나는 마치 자동차 계기판과 같습니다.

엔진 회전수, 연료량, 속도 같은 정보를 숫자로만 보여준다면 운전이 어려울 것입니다. 하지만 계기판은 바늘과 게이지로 직관적으로 상태를 알려줍니다.

빨간 영역에 들어가면 위험하다는 것을 바로 알 수 있습니다. 그라파나는 여러 데이터 소스를 연결할 수 있습니다.

프로메테우스뿐 아니라 MySQL, PostgreSQL, Elasticsearch, CloudWatch 등 수십 가지 데이터 소스를 지원합니다. 하나의 대시보드에서 여러 소스의 데이터를 함께 볼 수 있습니다.

대시보드는 여러 개의 패널로 구성됩니다. 각 패널은 그래프, 게이지, 테이블, 히트맵 등 다양한 형태로 데이터를 표시할 수 있습니다.

패널을 자유롭게 배치하고 크기를 조절하여 원하는 레이아웃을 만들 수 있습니다. 위의 JSON 설정을 살펴보겠습니다.

첫 번째 패널은 초당 예측 요청 수를 그래프로 보여줍니다. rate 함수는 카운터의 증가율을 계산합니다.

5분 간격으로 평균 요청률을 구합니다. 두 번째 패널은 모델 정확도 추이를 보여줍니다.

여기에는 알림 설정도 포함되어 있습니다. 정확도가 0.85 미만으로 떨어지면 알림이 발생합니다.

실제 ML 모니터링 대시보드에는 어떤 정보가 필요할까요? 먼저 트래픽 관련 지표입니다.

예측 요청 수, 에러율, 응답 시간 분포 등입니다. 다음으로 모델 성능 지표입니다.

정확도, 정밀도, 재현율, AUC 등입니다. 마지막으로 인프라 지표입니다.

CPU 사용률, 메모리 사용량, GPU 활용률 등입니다. 그라파나의 강력한 기능 중 하나는 **변수(Variable)**입니다.

대시보드 상단에 드롭다운을 만들어서 모델 이름이나 환경을 선택하게 할 수 있습니다. 하나의 대시보드로 여러 모델을 모니터링할 수 있습니다.

또 다른 유용한 기능은 **어노테이션(Annotation)**입니다. 배포 시점, 롤백 시점 등 중요한 이벤트를 그래프 위에 표시할 수 있습니다.

성능 변화가 언제 발생했는지 이벤트와 연관 지어 분석할 수 있습니다. 주의할 점은 대시보드가 너무 복잡해지지 않게 하는 것입니다.

한 화면에 너무 많은 정보를 담으면 오히려 중요한 것을 놓칩니다. 목적에 따라 대시보드를 분리하는 것이 좋습니다.

김개발 씨는 그라파나 대시보드를 팀원들과 공유했습니다. 매일 아침 스탠드업 미팅에서 대시보드를 함께 보며 모델 상태를 점검합니다.

문제가 생기면 그래프에서 바로 보이기 때문에 빠르게 대응할 수 있습니다.

실전 팁

💡 - 중요한 대시보드는 TV 모니터에 띄워두세요

  • 시간 범위 선택기를 활용하여 과거 데이터와 비교하세요
  • 대시보드를 코드로 관리하면 버전 관리가 가능합니다

6. 알림 설정

아름다운 대시보드가 완성되었습니다. 하지만 김개발 씨는 고민이 생겼습니다.

24시간 대시보드를 쳐다보고 있을 수는 없으니까요. 박시니어 씨가 말했습니다.

"문제가 생기면 대시보드가 널 찾아오게 만들어. 알림을 설정해."

**알림(Alerting)**은 특정 조건이 충족되면 자동으로 담당자에게 통보하는 시스템입니다. 마치 가스 누출 경보기처럼 위험 상황을 자동으로 감지하고 알려줍니다.

Prometheus의 Alertmanager나 Grafana의 알림 기능을 활용하여 Slack, 이메일, PagerDuty 등 다양한 채널로 알림을 보낼 수 있습니다.

다음 코드를 살펴봅시다.

# Prometheus Alertmanager 알림 규칙 (alert_rules.yml)
groups:
  - name: ml_model_alerts
    rules:
      # 모델 정확도 저하 알림
      - alert: ModelAccuracyDegraded
        expr: ml_model_accuracy < 0.85
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "모델 정확도 저하 감지"
          description: "{{ $labels.model_name }} 정확도가 {{ $value }}로 하락했습니다."

      # 예측 에러율 급증 알림
      - alert: HighPredictionErrorRate
        expr: rate(ml_prediction_requests_total{status="error"}[5m]) > 0.1
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "예측 에러율 급증"
          description: "에러율이 10%를 초과했습니다. 즉시 확인이 필요합니다."

      # 데이터 드리프트 알림
      - alert: DataDriftDetected
        expr: ml_data_drift_psi > 0.2
        for: 30m
        labels:
          severity: warning
        annotations:
          summary: "데이터 드리프트 감지"
          description: "{{ $labels.feature_name }}의 PSI가 {{ $value }}입니다."

김개발 씨는 대시보드를 만들고 뿌듯해했습니다. 하지만 일주일이 지나자 현실적인 문제에 부딪혔습니다.

회의도 가야 하고, 코드도 짜야 하고, 점심도 먹어야 합니다. 대시보드를 계속 쳐다보고 있을 수 없었습니다.

어느 날 마케팅팀에서 연락이 왔습니다. "오늘 오전부터 예측이 이상해요." 김개발 씨가 대시보드를 확인하니 4시간 전부터 문제가 있었습니다.

더 일찍 알았다면 피해를 줄일 수 있었을 텐데. 박시니어 씨가 조언했습니다.

"문제가 생기면 모니터가 널 찾아오게 해야 해." 알림 시스템은 무엇일까요? 쉽게 비유하자면, 알림 시스템은 집에 설치된 화재 경보기와 같습니다.

우리가 자고 있어도, 외출해도, 화재가 나면 경보기가 울립니다. 24시간 집을 지켜보지 않아도 됩니다.

Prometheus 생태계에서는 Alertmanager라는 컴포넌트가 알림을 담당합니다. Prometheus가 알림 규칙을 평가하고, 조건이 충족되면 Alertmanager에게 알립니다.

Alertmanager는 알림을 그룹화하고, 중복을 제거하고, 적절한 채널로 발송합니다. 위의 YAML 설정을 살펴보겠습니다.

세 가지 알림 규칙이 정의되어 있습니다. ModelAccuracyDegraded는 모델 정확도가 0.85 미만으로 떨어지면 발생합니다.

for: 10m은 조건이 10분 동안 지속되어야 알림이 발송된다는 뜻입니다. 일시적인 변동으로 인한 오탐을 방지합니다.

HighPredictionErrorRate는 에러율이 10%를 넘으면 발생합니다. 심각도가 critical로 설정되어 있어 더 긴급하게 처리됩니다.

DataDriftDetected는 PSI가 0.2를 넘으면 발생합니다. 30분 동안 지속되어야 알림이 발송됩니다.

알림을 설정할 때 가장 중요한 것은 적절한 임계값을 찾는 것입니다. 너무 민감하면 알림 피로가 생깁니다.

매일 수십 개의 알림이 오면 결국 무시하게 됩니다. 반대로 너무 느슨하면 정작 중요한 문제를 놓칩니다.

심각도 수준도 잘 정의해야 합니다. 모든 알림이 critical이면 어떤 것을 먼저 처리해야 할지 모릅니다.

일반적으로 info, warning, critical 세 단계를 사용합니다. 알림 라우팅도 고려해야 합니다.

심각도에 따라 다른 채널로 보낼 수 있습니다. info는 Slack에만, warning은 Slack과 이메일에, critical은 PagerDuty로 직접 전화까지 걸리게 할 수 있습니다.

또 하나 중요한 것은 온콜(On-Call) 로테이션입니다. 한 사람이 계속 알림을 받으면 번아웃됩니다.

팀원들이 돌아가며 당번을 서는 시스템을 갖추어야 합니다. 주의할 점은 알림과 함께 **대응 절차(Runbook)**를 문서화하는 것입니다.

새벽 3시에 알림을 받았는데 무엇을 해야 할지 모르면 곤란합니다. 각 알림에 대해 어떤 조치를 취해야 하는지 미리 정리해 두세요.

김개발 씨는 알림 시스템을 구축한 후 마음이 편해졌습니다. 주말에도 모델 걱정 없이 쉴 수 있습니다.

문제가 생기면 알림이 오니까요. 물론 알림이 안 오는 게 가장 좋지만요.

실전 팁

💡 - 알림을 받으면 반드시 조치하고 기록을 남기세요

  • 오탐이 많은 알림은 임계값을 조정하거나 제거하세요
  • 조용한 시간에는 긴급하지 않은 알림을 억제할 수 있습니다

이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!

#Python#MLOps#Prometheus#Grafana#ModelMonitoring#Monitoring,MLOps,Observability

댓글 (0)

댓글을 작성하려면 로그인이 필요합니다.