오프라인 AUC 0.95는 허상입니다: 추천 시스템이 프로덕션에서 무너지는 3가지 지점

오프라인 AUC 0.95는 허상입니다: 추천 시스템이 프로덕션에서 무너지는 3가지 지점

Precision@K가 아무리 높아도 클릭률이 바닥을 치는 이유—오프라인 지표와 온라인 지표 사이의 구조적 괴리를 피처 드리프트, 서빙 레이턴시, 평가 설계 세 축으로 해부합니다.

추천 시스템 오프라인 평가 온라인 평가 AUC A/B 테스트 피처 드리프트 서빙 레이턴시 MLOps
광고

근거는 있나요? 오프라인 지표의 달콤한 함정

추천 모델을 하나 만들었다고 합시다. 오프라인 테스트셋에서 AUC 0.95, Precision@10이 0.82. 팀 내 분위기는 축제입니다. 그런데 A/B 테스트를 돌리는 순간, 클릭률은 기존 규칙 기반 시스템 대비 통계적으로 유의미한 차이가 없습니다. p-value 0.38. 샴페인은 일찍 열었습니다.

이건 드문 사례가 아닙니다. velog에 정리된 머신러닝 시스템 설계 6장 내용을 보면, 추천 시스템의 오프라인 평가(Precision@K, 다양성 지표)와 온라인 평가(클릭률, 총시청 시간, 명시적 피드백 수)가 명시적으로 분리되어 있습니다. 문제는 이 두 세계 사이의 괴리를 대부분의 팀이 과소평가한다는 것입니다.

첫 번째 지점: 피처 드리프트와 '정적 임베딩'의 한계

해당 설계 문서에서 소개하는 행렬 인수분해(Matrix Factorization) 모델의 장점 중 하나는 "학습된 임베딩이 정적이므로 서빙 시 바로 재사용 가능"하다는 것입니다. 서빙 레이턴시 관점에서는 매력적이죠. 하지만 데이터 분석가로서 즉시 물어야 할 질문이 있습니다: 이 임베딩은 언제 학습된 건가요?

100억 개 동영상 풀에서 사용자 취향은 매일 드리프트합니다. 월요일에 교육 콘텐츠를 보던 개발자가 금요일 밤에는 게임 영상을 봅니다. 오프라인 평가 시점의 피처 분포와 서빙 시점의 분포가 다르면, 아무리 높은 AUC도 과거의 스냅샷에 대한 성적표일 뿐입니다. 투-타워(Two-Tower) 모델은 사용자 임베딩을 실시간으로 계산할 수 있어 이 문제를 일부 완화하지만, 그 대가로 서빙 속도가 느려지고 훈련 비용이 증가합니다. 결국 trade-off입니다.

두 번째 지점: 서빙 파이프라인의 레이턴시가 지표를 삼킨다

Python이 ML을 지배하는 이유를 분석한 dev.to의 글이 정확히 이 맥락과 만납니다. Python 자체는 느리지만, NumPy·PyTorch·TensorFlow가 C/C++와 CUDA로 연산을 위임하기 때문에 학습 단계에서는 문제가 없습니다. 그런데 프로덕션 서빙은 다른 이야기입니다.

추천 시스템의 서빙 구조는 보통 3단계—후보 생성(Candidate Generation) → 랭킹(Ranking) → 리랭킹(Re-ranking)—로 이루어집니다. 각 단계의 레이턴시가 누적되면, 사용자가 피드를 새로고침한 뒤 결과를 보기까지의 시간이 길어집니다. AWS 프리티어 환경에서 심방세동 예측 서비스를 구축한 velog 사례를 보면, EC2 단일 인스턴스에서 ML 예측 서버와 챗봇 서버를 분리 운영하면서도 메모리 우회와 CloudWatch 모니터링으로 버텼다는 기록이 나옵니다. 오프라인 노트북에서 0.95였던 AUC가, t2.micro 위에서 타임아웃으로 fallback 로직을 타면 사실상 의미가 없어지는 거죠.

세 번째 지점: 평가 지표 자체의 설계 결함

가장 근본적인 문제입니다. 오프라인에서 Precision@K를 측정할 때, 우리는 이미 상호작용이 발생한 데이터로 평가합니다. 하지만 추천 시스템은 본질적으로 "사용자가 아직 보지 않은 것"을 제안하는 시스템입니다. 이건 correlation이지 causation이 아닙니다—과거에 클릭한 패턴이 미래의 만족을 보장하지 않습니다.

설계 문서에서 참여율을 정의하는 부분이 이를 잘 보여줍니다. 클릭 수를 목표로 잡으면 낚시성 콘텐츠가 올라오고, 시청 완료 수를 잡으면 짧은 영상만 추천됩니다. 총시청 시간을 잡으면 또 다른 편향이 생깁니다. 오프라인 지표가 높다는 것은, 우리가 정의한 라벨이 비즈니스 목표와 정렬되어 있다는 뜻이 아닙니다. 라벨링 자체가 프록시(proxy)일 뿐이라는 사실을 먼저 인정해야 합니다.

시사점: 숫자를 의심하는 프로토콜이 필요하다

그렇다면 어떻게 해야 할까요? 세 가지를 제안합니다.

첫째, 오프라인-온라인 지표 간 상관계수를 먼저 측정하세요. 과거 실험 로그가 있다면, 오프라인 Precision@K 개선폭과 온라인 CTR 개선폭 사이의 Spearman 상관을 계산해보세요. 상관이 낮다면, 오프라인 지표를 아무리 올려도 비즈니스 임팩트는 없습니다.

둘째, 서빙 환경의 P99 레이턴시를 평가 리포트에 포함시키세요. 모델 성능 보고서에 latency budget을 명시하지 않는 팀이 아직도 많습니다. Grafana+Prometheus 조합으로 서빙 레이턴시를 모니터링하는 것은 이제 선택이 아니라 기본입니다.

셋째, A/B 테스트의 샘플 사이즈를 사전에 계산하세요. 효과 크기(effect size) 0.5%를 탐지하려면 트래픽이 얼마나 필요한지, 실험 기간은 며칠인지. 이걸 계산하지 않고 "일주일 돌려보자"는 건 동전 던지기와 다를 바 없습니다.

전망: 오프라인 지표는 '출발점'이지 '도착점'이 아니다

추천 시스템은 ML 시스템 중에서도 오프라인-온라인 괴리가 가장 큰 도메인입니다. 사용자의 의도는 실시간으로 변하고, 서빙 환경은 늘 제약이 있으며, 비즈니스 목표 자체가 다층적이기 때문입니다. AUC 0.95를 달성했다면, 축하하기 전에 먼저 물어보세요: 이 숫자가 프로덕션에서도 유효하다는 근거는 있나요? 실제 운영 환경에서도 이 성능이 나올까요? 재현 가능한가요? Ablation study로 어떤 피처가 이 성능에 기여하는지 분리해봤나요?

결국 추천 시스템의 진짜 평가는 Jupyter Notebook이 아니라, 사용자의 스크롤이 멈추는 그 순간에 이루어집니다.

출처

더 많은 AI 트렌드를 Seedora 앱에서 확인하세요