본문으로 건너뛰기

버그 제보

이상한 점을 알려 주시면 고칠게요. 지금 보고 있는 페이지와 브라우저 정보가 함께 담겨요.

페이지:

AI & Data

딥러닝 추천 시스템: 후보 생성과 랭킹

작성 2026. 10. 31.추가
목차11개 항목
출처와 참고

당근마켓의 「딥러닝 개인화 추천」·「딥러닝 추천 시스템 in production」(2019), 네이버 AiRS·AiTEMS 발표 자료(2017), LINE 「Timeline의 새로운 도전 1편」(2020)을 바탕으로, 이후의 흐름은 2026년 공개 내용으로 보강해 재구성한 노트다. 피드의 다단계 파이프라인은 ByteByteGo의 System Design 101 가이드 「How does Twitter recommend "For You" Timeline」를 바탕으로 덧붙였다. Item2Vec은 최규민의 「Word2Vec 그리고 추천 시스템의 Item2Vec」과 「word2vec이 추천 시스템을 만났을때」(PyCon Korea 2015)로 보강했다.

왜 딥러닝으로 가나

행렬 분해 라이브러리만으로 실시간 개인화 피드를 만들면 세 가지가 막힌다.

  • 학습 데이터가 늘면 메모리 사용량이 급격히 커지고 학습이 느려진다.
  • 사용자를 ID 하나로만 표현해서 지역·시간 같은 다른 정보를 넣기 어렵다.
  • 요청마다 빠르게 추천을 계산하는 구조가 고려돼 있지 않다.

이 문제를 푼 대표 설계가 유튜브의 「Deep Neural Networks for YouTube Recommendations」(2016)다. 이후 대부분의 대형 피드 추천이 같은 뼈대를 쓴다.

2단계 구조

아이템이 많으면 사용자 한 명에 대해 모든 아이템의 점수를 계산할 시간이 없다. 그래서 빠르고 거칠게 추린 뒤, 좁혀진 후보만 정밀하게 정렬한다.

flowchart TB
  all["전체 아이템 (수십만~수억)"]
  cand["후보 수백 개"]
  final["최종 추천 수십 개<br/>(+ 다양성·중복 제거·비즈니스 규칙)"]
  all -->|"1단계 후보 생성(candidate generation)<br/>사용자 벡터 · 아이템 벡터의 내적 → 유사 벡터 검색으로 수백 개"| cand
  cand -->|"2단계 랭킹(ranking)<br/>사용자·아이템·문맥 특성을 모두 이어 붙인 신경망 → 선호도 점수"| final
단계입력출력특징
후보 생성최근 소비 이력, 지역 등 일부 특성사용자 벡터 → 가까운 아이템 수백 개원리는 행렬 분해와 같다. 사용자 벡터를 신경망으로 만든다는 점만 다르다
랭킹사용자·아이템·문맥 특성 전부아이템별 점수내적이 아니라 신경망 출력으로 점수를 내는 회귀 모델이다

피드 추천의 다단계 파이프라인

소셜 피드처럼 후보 풀이 거대하고 응답 시간이 짧아야 하는 서비스는 2단계를 더 잘게 나눈다. 공개된 X(옛 Twitter)의 「For You」 타임라인 알고리즘이 대표 예다.

단계하는 일후보 수 감각
후보 수집(candidate sourcing)팔로우 관계 그래프, 임베딩 유사도 등 여러 소스에서 후보를 모은다수억 → 수천
전역 필터링차단·뮤트, 안전 정책, 이미 본 글을 거른다수천 → 1~2천
점수 매기기·랭킹신경망이 참여(좋아요·답글·재게시) 확률을 예측해 점수를 낸다
다양성 필터한 작성자·한 주제가 몰리지 않게 섞는다
혼합(mixing)광고, 팔로우 추천 같은 다른 모듈과 섞어 최종 피드를 만든다수십

단계마다 계산 비용이 커지는 만큼 후보 수를 줄여서, 전체를 짧은 응답 시간 안에 끝낸다.

후보 모델 학습: 다음 아이템 맞히기

후보 모델은 사용자가 본 아이템 목록을 문장처럼 보고, 다음에 볼 아이템을 예측하는 언어 모델식으로 학습한다.

항목내용
입력최근 본 아이템 ID 수십 개, 지역 같은 맥락, 시간
정답다음에 본 아이템 ID
학습네거티브 샘플링 + 이진 교차 엔트로피 (word2vec과 같은 요령)
평가MAP, Top-K 적중. 며칠 치 로그로 학습하고 다음 날로 시험한다
  • 맥락은 모델을 나누지 말고 조건으로 넣는다. 지역별로 모델을 따로 두면 겹치는 범위와 여러 지역을 오가는 사용자를 다루지 못한다. 조건으로 넣으면 처음 가 본 지역에서도 각자 취향대로 추천을 받는다.
  • 학습 데이터의 소비 패턴이 그대로 추천에 배어든다. 중고 거래처럼 최신 아이템 소비가 압도적인 서비스에서는 모델도 최신 아이템을 추천하는 경향을 띤다.
  • 복잡한 시스템은 단계로 쪼개 빨리 내보낸다. 후보 모델만 먼저 붙여 배포하고 A/B 테스트로 개선한 뒤 랭킹 모델을 더한다.

서빙: 네트워크의 뒷부분을 벡터 검색으로 바꾼다

학습 때는 네거티브 샘플링 덕에 계산이 가볍지만, 예측 때는 사용자 벡터와 모든 아이템 벡터의 내적을 구해야 한다. 내적은 결국 가까운 벡터 찾기이므로 근사 최근접 이웃(ANN) 검색으로 바꿀 수 있다.

flowchart TB
  app["앱 서버"] --> rec["추천 서버"]
  rec --> s1["1. 캐시(Redis 등)에서 사용자의 최근 소비 이력 조회"]
  s1 --> s2["2. 모델 서버: 네트워크 앞부분만 실행해 사용자 벡터 생성"]
  s2 --> s3["3. ANN 검색 서버: 사용자 벡터와 가장 가까운 아이템 ID 수백 개"]
  s3 --> res["수십 밀리초 안, CPU만으로도 충분, 오토스케일링"]

ANN 인덱스(faiss 등)는 데이터가 많아지면 느려지고 메모리를 많이 쓰므로 배포 전에 인덱스를 학습(양자화·클러스터링)해 둔다. faiss 외에 ScaNN, HNSW 기반 라이브러리, 벡터 DB가 같은 역할을 한다.

학습·배포 파이프라인

새 아이템이 계속 들어오므로 주기적으로 다시 학습하고 배포해야 한다.

flowchart TB
  log["이벤트 로그"] --> mid["필요한 열만 모은 중간 테이블(비용 절감)"]
  mid --> pre["전처리(ID 사전, 희귀 ID 제거, 학습용 포맷)"]
  pre --> train["학습"] --> emb["아이템 임베딩 추출"]
  emb --> ann["ANN 인덱스 학습"]
  emb --> deploy["모델 파일 배포"]
  ann --> restart["서빙 재시작으로 새 모델 반영"]
  deploy --> restart
  • 워크플로는 Kubeflow Pipelines, Airflow, Vertex AI Pipelines 같은 오케스트레이터로 자동화한다.
  • 전처리를 모델 그래프 안에 넣으면 서빙 때 같은 전처리를 다시 짤 필요가 없다. 학습과 서빙의 전처리 불일치(training-serving skew)를 막는 방법이다.

아이템 시퀀스를 문장처럼: Item2Vec

word2vec은 문장 안에서 가까이 나오는 단어끼리 비슷한 벡터를 갖도록 학습한다. 이 「문장」과 「단어」 자리에 사용자 이력과 아이템을 넣으면 아이템 임베딩이 나온다. 이렇게 아이템을 벡터로 만드는 방법을 통틀어 Item2Vec이라 부른다.

서비스문장단어
방송 추천(Live2Vec)한 시청자의 시청 이력방송
음악(Song2Vec)한 사용자의 플레이리스트곡
쇼핑(Prod2Vec, Meta-Prod2Vec)한 쇼핑 세션상품
from gensim.models import Word2Vec
 
sessions = [["item1", "item2", "item3"], ["item1", "item12", "item23"]]  # 사용자·세션별 아이템 ID 나열
model = Word2Vec(sessions, vector_size=100, window=10, min_count=3, sg=1, negative=5)
model.wv.most_similar("item1")   # 같이 소비되는 아이템
설정의미
구조CBOW(주변으로 가운데를 맞힘) 또는 Skip-gram(가운데로 주변을 맞힘, sg=1)
출력층 근사계층적 소프트맥스 또는 네거티브 샘플링. 출력 계산을 어휘 크기 V에서 log V 수준으로 줄인다
서브샘플링너무 자주 나오는 아이템을 확률적으로 건너뛰어 속도와 품질을 함께 높인다. 인기 아이템이 모든 벡터를 끌어당기는 것을 누그러뜨린다
차원·데이터 양보통 100~수백 차원. 데이터가 적으면 군집만 대충 생기고, 많아져야 의미 있는 관계가 나온다
  • 쓰임: 비슷한 아이템 추천, 아이템 벡터를 k-means로 묶은 세분류(예: 방송 13K개를 500개 군집으로 나누니 지상파 뉴스와 인터넷 뉴스가 갈리고 운세·그림 같은 틈새 분류가 드러났다), 다른 모델의 의미 특징.
  • 장점: 레이블 없는 로그만으로 학습하고 코드가 짧다. 메모리 기반 최근접 이웃은 인기 아이템 쪽으로 쏠리는데, 임베딩은 내용상 가까운 아이템을 더 잘 찾는 경우가 있다.
  • 한계: 벡터 공간을 해석하기 어렵고, 성능을 의도대로 올리려면 시행착오가 많다. 행렬 분해도 이미 잘 동작하므로 단독 대체재보다 앙상블의 한 구성 요소로 쓴다.

순서를 보는 모델: 세션 추천

협업 필터링은 과거 클릭을 근거로 하므로 방금 나온 뉴스를 추천하기 어렵고, 한 이슈를 깊게 파고드는 소비도 잘 못 잡는다. 그래서 순서를 보는 모델을 붙인다.

  • 문서마다 벡터(Doc2Vec 등)를 만든다.
  • 사용자가 읽은 순서대로 벡터를 이어 시퀀스를 만든다. 몇 분 안에 이어 읽은 문서는 같은 맥락(세션)으로 본다.
  • 순환 신경망(RNN)이 다음에 읽을 문서를 예측한다. 같은 맥락의 새 문서가 들어오면 바로 추천할 수 있다.
  • CF가 다양성을, 순서 모델이 깊이와 최신성을 맡는 하이브리드가 된다.

지금은 RNN 자리를 트랜스포머 기반 순차 추천(SASRec, BERT4Rec 계열)이 주로 차지한다. 「다음 아이템 예측」이라는 문제 설정은 같다.

여러 신호를 합치는 추천

방식무엇을 합치나효과
크로스오버 추천같은 회사의 다른 서비스 이용 이력(검색, 뉴스, 영상, 스포츠)과 상품명·카테고리·가격·판매자·이미지 벡터해당 서비스 이력이 없어도 추천한다(야구 영상을 본 사용자에게 야구 용품). 인기 대신 취향과 속성을 맞추므로 신규 판매자·비인기 상품도 노출되고, 써 봐야 아는 경험재에서 효과가 크다
멀티모달 유사도아이템마다 텍스트·이미지·비디오·소비 이력 벡터각 벡터의 코사인 유사도로 비슷한 아이템을 찾고 하나로 정렬한다. 구독 관계 밖의 좋은 콘텐츠를 꺼내는 탐색 공간에 쓴다
맥락 인식 추천현재 위치·시간대·인구 통계·관심사 + 사용자 생성 콘텐츠로 만든 아이템 프로필맥락과 프로필이 맞는 것을 고른다. 같은 장소·시간이라도 사용자 집단마다 다른 장소를 권한다

지금의 흐름

후보 생성 → 랭킹 뼈대는 유지되고, 그 위에서 다음 방향으로 옮겨 간다.

방향내용
다단계 구조후보를 여러 단계로 좁히고, 사용자·아이템을 대조 학습(contrastive learning)으로 임베딩하는 투 타워 후보 모델을 쓴다. 랭킹 파이프라인은 서비스별로 설정만 바꿔 공유한다
장기 가치 목표클릭만 보지 않고 최신성, 관심도, 대화·거래 시작, 체류 시간을 함께 보고 부정 피드백은 내린다
파운데이션 추천 모델여러 서비스가 하나의 큰 추천 모델을 공유하고, 의외의 발견(serendipity)을 목표에 넣는다. LLM은 아이템·사용자 표현과 학습 데이터 생성에 쓴다. 모델이 커지면서 서빙은 실시간에서 준실시간으로 옮겨 간다

추천 대상이 반경 몇 km 안으로 제한되는 지역 서비스는 후보 풀이 작아 정교한 개인화가 더 어렵다.

정리

  • 아이템이 많으면 후보 생성(빠르게 수백 개) → 랭킹(정밀하게) 2단계로 나눈다.
  • 후보 모델은 「최근 본 것으로 다음 것 맞히기」로 학습하고, 맥락은 조건으로 넣고, 서빙은 사용자 벡터 + ANN 검색으로 바꾼다.
  • 추천은 한 번 만들고 끝나지 않는다. 수집 → 전처리 → 학습 → 인덱스 → 배포를 자동으로 반복하는 파이프라인이 본체다.
  • 순서 모델은 최신 콘텐츠와 세션 맥락을, 크로스오버·멀티모달 신호는 콜드 스타트를 푼다.
  • 복잡한 시스템은 후보 모델만 먼저 내보내고 A/B 테스트로 키운다.

관련 노트: 추천 시스템, 추천 시스템 기초, 실시간 추천과 실험, 딥러닝 직관으로 이해하기, LLM은 무엇을 하고 왜 작동하나

원본 기록10

댓글

GitHub 계정으로 댓글을 남길 수 있어요.