
머신러닝 시스템 디자인: 인터뷰를 통과하는 프레임워크
요약
머신러닝 시스템 디자인 인터뷰를 위한 체계적인 프레임워크를 소개합니다. 모델 자체보다 비즈니스 목표를 시스템 아키텍처로 전환하는 능력, 즉 데이터 루프, 피처 관리, 서빙 및 모니터링의 중요성을 강조합니다.
핵심 포인트
- ML 시스템에서 모델은 전체 아키텍처 중 교체 가능한 작은 구성 요소임
- 오프라인 학습 루프와 온라인 서빙 루프의 상호작용 이해가 핵심
- 피처 스큐 방지, 2단계 후보 생성 및 랭킹 패턴 등 실무적 설계 역량 필요
- 지연 시간, 처리량, 모니터링을 포함한 시스템 안정성 확보가 중요
대부분의 사람들에게 머신러닝 (Machine Learning) 시스템을 설계해 보라고 하면 그들은 모델부터 시작합니다. 그들은 Transformer, 혹은 Gradient-boosted tree, 또는 그 분기에 유행하는 어떤 아키텍처 (Architecture)든 손을 뻗으며, 인터뷰 내내 머릿속으로 그것을 튜닝하는 데 시간을 보냅니다. 그러한 본능은 바로 이 질문이 드러내고자 하는 핵심입니다. 왜냐하면 실제 ML 시스템에서 모델은 쉬운 부분이기 때문입니다. 모델은 훨씬 더 큰 다이어그램 (Diagram)의 중간에 있는 작은 상자일 뿐이며, 대개 그 안에서 가장 교체 가능한 구성 요소입니다.
머신러닝 시스템 디자인 인터뷰는 당신에게 새로운 모델을 발명하라고 요구하는 것이 아닙니다. 그것은 당신이 '사람들에게 더 관련성 높은 게시물을 보여준다'와 같은 모호한 비즈니스 목표를 받아들여, 실제 트래픽에서 신뢰할 수 있는 좋은 예측을 생성하고, 세상이 변함에 따라 계속해서 예측을 수행하며, 수십 밀리초 (Milliseconds) 단위로 측정되는 지연 시간 예산 (Latency budget) 내에서 작동하는 시스템으로 전환할 수 있는지를 묻는 것입니다. 흥미로운 작업은 거의 항상 아키텍처가 아닙니다. 그것은 작업을 어떻게 프레임화 (Frame)하는지, 무엇을 최적화하기로 선택하는지, 레이블 (Labels)이 어디에서 오는지, 훈련 (Training)과 서빙 (Serving) 사이에서 피처 (Features)가 어떻게 동일하게 유지되는지, 오프라인 (Offline)에서 어떻게 평가하고 온라인 (Online)에서 어떻게 확인하는지, 그리고 전체 시스템이 조용히 성능이 저하될 때 어떻게 알아차리는지에 관한 것입니다.
이 글은 해당 프레임워크의 긴 버전입니다. 우리는 유능한 후보자가 실제로 진행하는 순서대로 이를 살펴볼 것입니다: 모든 ML 시스템을 구성하는 두 개의 루프 (Loops), 문제를 프레임화하고 지표 (Metrics)를 선택하는 방법, 피처 스토어 (Feature store)와 그것이 해결하고자 하는 스큐 (Skew), 데이터와 레이블이 인터뷰의 승패를 결정짓는 지점, 2단계 후보 생성 및 랭킹 (Candidate-and-ranking) 패턴, 오프라인 평가와 온라인 A/B 테스트 사이의 간극, 두 가지 서빙 방식, 그리고 마지막으로 라이브 시스템이 소리 없이 부패하는 것을 막는 모니터링 (Monitoring)입니다. 여기서 언급되는 특정 지연 시간 (Latency), 처리량 (Throughput), 또는 카탈로그 크기 (Catalog-size) 수치는 특정 회사의 측정된 수치가 아니라, 업계의 전형적인 범위이거나 추론을 위한 예시입니다.
두 개의 루프, 하나의 공유된 시계 문제
훌륭한 답변의 핵심은 ML (Machine Learning) 시스템이 아티팩트 (artifacts)를 공유하지만 완전히 다른 시계(clocks)에 따라 작동하는 두 개의 루프 (loops)라는 점을 파악하는 것입니다.

오프라인 학습 루프 (offline training loop)와 온라인 서빙 루프 (online serving loop)는 하나의 피처 스토어 (feature store)를 공유합니다.
오프라인 학습 루프 (offline training loop)는 정해진 일정에 따라 실행됩니다. 데이터 레이크 (data lake)나 데이터 웨어하우스 (data warehouse)에서 로그로 기록된 원시 이벤트(raw logged events), 노출 (impressions), 클릭 (clicks), 시청 (watches), 구매 (purchases) 등을 읽어옵니다. 그런 다음 각 이벤트가 발생했던 시점의 피처 (features)와 결합하고, 라벨링된 학습 세트 (labeled training set)를 구축하며, 모델을 학습시키고, 오프라인에서 평가합니다. 만약 통과하면 모델 레지스트리 (model registry)에 등록합니다. 이 루프는 느려도 괜찮습니다. 시간 단위, 일 단위, 또는 주 단위로 실행되며, 아무도 실시간으로 이를 기다리지 않습니다.
온라인 서빙 루프 (online serving loop)는 모든 개별 요청마다 실행됩니다. 실시간 컨텍스트 (live context)를 가져와 관련 피처 (features)를 불러오고, 후보군을 생성 (generates candidates)하고, 순위를 매기며 (ranks them), 비즈니스 및 정책 필터 (business and policy filters)를 적용한 뒤, 결과를 반환하고, 방금 수행한 모든 작업을 로그로 남깁니다. 이 루프는 사용자 대상 응답의 크리티컬 패스 (critical path)에 존재하므로, 밀리초 (milliseconds) 단위로 측정됩니다.
두 루프는 로그 (logs)에서 만납니다. 서빙 루프가 보여주는 모든 것은 내일 오프라인 루프를 위한 학습 데이터가 됩니다. 이는 우아한 방식이지만, 동시에 모든 ML에서 발생하는 가장 미묘한 버그의 근원이기도 하며, 이에 대해서는 나중에 다루겠습니다. 지금 내재화해야 할 핵심은 이 두 루프를 명확히 구분하고, 피처 계산 (feature computation) 방식을 동일하게 유지하는 것이 '프로덕션 (production) 환경처럼 들리는 답변'과 '노트북 (notebook) 환경처럼 들리는 답변'을 가르는 차이라는 점입니다.
프레이밍 (Framing): 정직한 첫 번째 질문은 ML을 사용할 것인가 자체이다
그 모든 과정에 앞서, 모호한 비즈니스 목표를 정밀한 ML 태스크 (ML task)로 전환해야 합니다. 그리고 가장 정직한 첫 번째 질문은 머신러닝 (machine learning)을 사용하는 것이 과연 타당한가 하는 것입니다.
만약 문제를 규칙(rule)으로 해결할 수 있다면—예를 들어 최신 항목을 먼저 보여주거나, 알려진 악성 IP를 차단하는 것과 같은 경우—휴리스틱 베이스라인 (heuristic baseline)이 올바른 시작점입니다. 이는 비용이 더 저렴하고, 디버깅이 쉬우며, 설명하기가 매우 간단합니다. 또한 머신러닝 (ML) 모델이 그 복잡성을 정당화하기 위해 넘어서야 할 기준점을 제공합니다. 인터뷰에서 이렇게 말하는 것은 회피가 아니라 강점입니다. 이는 당신이 단순히 모델이 이야기하기에 더 인상적인 것이기 때문에 머신러닝을 선택하는 것이 아니라, 중요한 지표에서 베이스라인을 능가하기 때문에 머신러닝을 활용한다는 신호를 줍니다.
머신러닝 (ML) 사용이 타당할 때는, 이를 구체적인 예측 작업 (prediction task)으로 프레임화해야 합니다. 이것이 분류 (classification)인가(사용자가 클릭할 것인가?), 회귀 (regression)인가(얼마나 오래 시청할 것인가?), 아니면 랭킹 (ranking)인가(가치에 따라 항목들을 정렬하는가?)와 같은 식입니다. 이러한 프레임화를 명확히 하는 것은 손실 함수 (loss function)부터 평가 지표 (evaluation metric)에 이르기까지 이후의 모든 과정을 결정짓습니다.
그다음, 초보자들이 끊임없이 혼동하는 두 가지 종류의 지표를 분리해야 합니다.

비즈니스 목표에서 머신러닝 작업으로, 그리고 오프라인 지표와 온라인 지표의 분리로.
오프라인 지표 (offline metric)는 로그 데이터 (logged data)를 통해 학습하고 평가하는 대상입니다: AUC, 로그 손실 (log loss), k에서의 정밀도 (precision at k), 랭킹을 위한 NDCG 등이 이에 해당합니다. 이는 계산이 빠르고 반복 가능하며, 빠르게 반복 실험 (iterate)할 수 있게 해줍니다. 온라인 지표 (online metric)는 비즈니스가 실제로 관심을 갖는 것입니다: 참여도 (engagement), 시청 시간 (watch time), 매출 (revenue), 유지율 (retention) 등입니다. 이는 실제 트래픽 (live traffic)에서만 측정될 수 있습니다. 이 두 지표는 완벽하게 함께 움직이지 않습니다. 모델이 오프라인 AUC를 개선하더라도 온라인 지표에는 아무런 영향을 주지 못하거나, 심지어 해를 끼칠 수도 있습니다.
훌륭한 답변을 가르는 차이는 오프라인 지표(offline metric) 하나만으로 승리를 선언하기를 거부하고, 승리를 확인하기 위해 사용할 온라인 지표(online metric)를 항상 명시하는 절제력에 있습니다. Google의 'Rules of Machine Learning'은 바로 이 점을 강조합니다. 모델을 영리하게 만들기 전에 인프라와 지표를 올바르게 설정하고, 최적화할 수 있는 지표와 실제로 원하는 결과 사이의 간극에 대해 정직해지라는 것입니다.
피처 스토어(Feature Store)와 그것이 해결하고자 하는 스큐(Skew)
만약 이 설계에서 머신러닝(ML) 전용 인프라 중 가장 중요한 단 하나를 꼽아야 한다면, 그것은 모델이 아닐 것입니다. 바로 피처 스토어(feature store)이며, 이는 특정한 치명적인 버그를 해결함으로써 그 자리를 차지합니다.

피처 스토어는 훈련(training)과 서빙(serving) 모두에 동일한 하나의 피처 정의를 제공하여, 훈련-서빙 스큐(train-serve skew)를 제거합니다.
훈련-서빙 스큐(Train-serve skew)는 프로덕션 ML 환경에서 가장 흔하면서도 비용이 많이 드는 실패 사례입니다. 설정 자체는 악의가 없습니다. 데이터 사이언티스트가 훈련 파이프라인(training pipeline)에서 웨어하우스(warehouse)에 작성된 SQL을 사용하여 지난 30일간의 평균 세션 길이와 같은 피처를 한 가지 방식으로 계산합니다. 그러면 엔지니어가 서빙 코드(serving code)에서 약간 다른 소스와 약간 다른 윈도우(window)를 사용하여 실시간으로 동일한 피처를 다른 방식으로 재구현합니다. 이 두 정의는 서로 어긋나게 됩니다. 이제 모델은 하나의 분포로 훈련되었으나 다른 분포로 서빙되며, 오프라인 평가(offline evaluation)는 훈련 시점의 계산 방식을 사용하기 때문에 품질 저하가 오프라인 평가에서는 완전히 보이지 않는 방식으로 발생합니다.
이보다 더 미묘한 변종으로는 타임 트래블 리키지(time-travel leakage)가 있습니다. 이는 이벤트가 발생한 후에야 알 수 있었던 피처 값에 이벤트를 조인(join)하는 것입니다. 이는 오프라인 지표를 매우 아름답게 부풀려 놓지만, 서빙 시점에는 미래의 값이 아직 존재하지 않기 때문에 프로덕션 환경에서는 성능이 급락하게 됩니다.
피처 스토어 (Feature Store)는 각 피처의 정의를 단일한 진실의 원천 (Source of Truth)으로 만듦으로써 이 두 가지 문제를 모두 해결합니다. 피처 스토어는 보통 데이터 웨어하우스 내의 컬럼형 (Columnar) 구조로 이루어진 오프라인 스토어 (Offline Store)를 보유하며, 이는 훈련 (Training)을 위해 시점별로 정확한 (Point-in-time-correct) 값, 즉 이벤트 발생 당시의 실제 값을 제공합니다. 또한, 보통 저지연 키-값 저장소 (Low-latency Key-value Store)인 온라인 스토어 (Online Store)를 보유하여 요청 시점 (Request time)에 랭커 (Ranker)에게 동일한 값을 제공합니다. 훈련 파이프라인 (Training pipeline)은 오프라인 측에서 읽고, 서빙 경로 (Serving path)는 온라인 측에서 읽지만, 두 경로 모두 동일한 정의로부터 계산된 동일한 피처를 읽습니다.
면접관이 당신이 훈련-서빙 왜곡 (Train-serve skew)을 방지하기 위해 구체적으로 피처 스토어를 사용하겠다고 자발적으로 언급하는 것을 듣는다면, 이는 당신이 단순히 모델을 훈련하기만 한 사람이 아니라 ML 시스템을 실제로 운영해 본 사람이라는 인상을 줍니다. 이는 전체 인터뷰 과정에서 가장 깔끔한 신호 중 하나입니다.
데이터와 레이블: 인터뷰의 승패가 실제로 결정되는 곳
모델의 성능은 그 뒤에 있는 레이블 (Labels)의 품질만큼만 좋아질 수 있습니다. 이것이 바로 데이터 섹션이 보통 이러한 인터뷰에서 승패가 갈리는 지점인 이유입니다. 역량 있는 후보자는 항상 다음 세 가지 사항을 다룹니다.
첫째, 레이블이 어디에서 오는가입니다. 구매나 평점과 같은 명시적 신호 (Explicit signals)는 깨끗하지만 희소합니다 (Sparse). 클릭이나 체류 시간 (Dwell time)과 같은 암시적 신호 (Implicit signals)는 풍부하지만 노이즈가 많고 편향되어 있습니다 (Biased). 클릭은 실수로 인한 클릭일 수 있고, 클릭하지 않은 것은 단순히 해당 아이템을 보지 못했음을 의미할 수도 있습니다. 이는 클릭뿐만 아니라 임프레션 (Impressions)을 로그로 남겨야 한다는 규칙으로 직결됩니다. 만약 클릭된 것들로만 훈련한다면, 당신의 훈련 세트는 시스템이 이미 선호했던 아이템에 편향될 것이며 실제 부정 사례 (Negatives)를 포함하지 않게 됩니다.
둘째, 누수 (Leakage)입니다. 예측 시점 (Prediction time)에는 사용할 수 없는 정보를 인코딩하는 모든 피처, 즉 이벤트 이후에 업데이트된 값이나 미래를 기준으로 계산된 집계값은 오프라인 지표를 훌륭해 보이게 만들지만 프로덕션 환경에서는 실패하게 만듭니다. 피처는 반드시 시점별로 정확하게 (Point-in-time-correct) 계산되어야 하며, 이는 다시 말해 오프라인 피처 스토어가 제공하는 핵심 기능입니다.
셋째, 불균형 (imbalance) 문제입니다. 클릭률 (Click-through) 및 전환 (conversion) 문제는 양성 (positive) 사례보다 음성 (negative) 사례가 훨씬 더 많으며, 단순한 (naive) 모델은 다수 클래스 (majority class)를 예측함으로써 높은 점수를 받을 수 있지만 실제로는 쓸모가 없을 수 있습니다. 해결책이 중요합니다: 보정 (calibration) 수정을 동반한 음성 다운샘플링 (negative downsampling), 클래스 가중치 (class weighting), 그리고 단순 정확도 (raw accuracy) 대신 정밀도-재현율 (precision-recall) 및 보정 (calibration)과 같은 지표를 선택하는 것입니다. 마찬가지로 중요한 점은, 스스로를 속이지 않도록 평가 세트 (evaluation set)를 실제 클래스 분포 (true class distribution)로 유지하는 것입니다.
실제로 제품을 출시해 본 사람과 공부만 한 사람을 구분 짓는 한 가지가 더 있습니다: 시간 의존적 (time-dependent)인 모든 것에 대한 훈련/테스트 분할 (train/test split)은 무작위 (random)가 아닌 시간 순서에 따라 이루어져야 합니다. 모델이 실제로 사용될 방식과 동일하게 미래의 데이터로 평가해야 하며, 내일의 정보가 오늘로 유출되는 (leak) 무작위 슬라이스 (random slice)로 평가해서는 안 됩니다.
후보 생성 (Candidate generation), 그 다음 랭킹 (ranking)
가장 흔한 ML 디자인 프롬프트인 추천 (recommendation), 피드 (feed), 검색 (search)의 경우, 지연 시간 예산 (latency budget) 내에서 수백만 개의 아이템에 대해 정밀한 모델을 실행할 수는 없습니다. 따라서 표준적인 해결책은 서로 반대되는 목표를 가진 두 단계로 구성됩니다.

2단계 디자인: 저비용의 고재현율 (high-recall) 후보 생성 (candidate generation), 그 다음 선정된 목록 (shortlist)에 대한 정밀한 랭킹 (ranking).
후보 생성 (Candidate generation)은 재현율 (recall)과 속도를 최적화합니다. 수백만 개의 카탈로그로부터, 학습된 임베딩 (embeddings)에 대한 근사 최근접 이웃 탐색 (approximate nearest neighbor search), 최근/인기/사용자 참여 유사 항목과 같은 여러 소스로부터의 검색 (retrieval), 그리고 가벼운 규칙 기반 필터 (rule-based filters)와 같은 저비용 방법을 사용하여 적절해 보이는 수백 개의 아이템을 생성합니다. 다음 단계에서 정렬될 것이기 때문에 이 단계는 부정확해도 괜찮습니다. 하지만 반드시 하지 말아야 할 것은 정말 좋은 아이템을 누락시키는 것입니다. 왜냐하면 랭킹 (ranking)은 생성 (generation) 단계에서 넘겨준 것들의 순서만 바꿀 수 있기 때문입니다.
랭킹 (Ranking)은 정밀도 (precision)를 최적화합니다. 랭킹은 수백 개의 후보군만을 대상으로 하며, 각 후보에 대해 사용자 (user), 아이템 (item), 컨텍스트 (context) 특징을 결합하여 풍부한 특징 벡터 (feature vector)를 구성하고, 더 무거운 모델 (heavier model)로 각 후보의 점수를 매겨 순서를 정합니다. 결정적으로, 성숙한 시스템은 단일 클릭 확률 (click probability)이 아닌 혼합된 목적 함수 (blended objective)를 기준으로 랭킹을 매기는데, 이는 순수한 클릭 최적화가 클릭베이트 (clickbait)로 직결되기 때문입니다. 일부 시스템은 비즈니스 규칙 (business rules), 다양성 (diversity), 그리고 신선도 (freshness)를 위해 세 번째 재랭킹 (re-ranking) 단계를 추가하기도 합니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기