신규 사용자가 회원가입한 직후에는 아무것도 안 보여요!

추천시스템 콜드스타트 트러블 슈팅
MLOps추론
avatar
2025.07.13
·
5 min read

문제 상황

프로젝트 상품 추천 모델 서빙을 끝낸 후, 문제 상황이 발생했습니다. 현재 추천 모델은 기존 사용자 데이터를 기반으로 작동하는데, 오프라인 추론으로 구성했기 때문에 하루에 한 번 00시에 배치 재학습하는 구조로 설계되어 있습니다. 그렇기 때문에 이 방식은 신규 사용자가 회원가입한 직후에는 추천 결과를 바로 제공할 수 없었습니다.

그럼 신규 사용자는 어떻게 해야할까요? 처음에는 신규 사용자가 회원가입을 할 때, 관심 카테고리(1개)로 선택한 상품들만 추천으로 띄우게 하는 것을 생각했습니다. 그런데 그럼 동일한 관심 카테고리를 선택한 모든 유저들은 나이나 성별에 상관없이 회원가입 직후 모두 동일한 상품을 추천받게 된다는 단점이 있었습니다.

해결 방법

나이와 성별도 맞춤으로 추천해주고 싶다는 생각을 했고, 추천 모델을 모듈화하면서 작동 방식을 확인해 보니 룰 기반과 FAISS를 사용하고 있었습니다. 그래서 사용자 임베딩 벡터를 사용자 요청 시 바로 생성하는 온라인 추론 방식을 부분적으로 적용했습니다.

  1. 추천 요청 전달

    • 사용자가 선호 카테고리를 입력하면, 백엔드에서 아래와 같은 JSON 형식으로 ML팀의 추천 API에 요청을 보냅니다.

    [POST]
    
    {
    	"user_id" : 201,
    	"birth" : "2000-12-11",
    	"gender" : "FEMALE",
    	"address" : "서울특별시 서대문구 신촌로 134",
    	"interestCategory" : "식품"
    }
    
  2. 신규 사용자 상품 추천

    • 상품 데이터는 사전에 벡터로 임베딩해 OpenSearch 3.0 인덱스에 저장합니다.

    • 백엔드에서 받은 성별, 생일, 관심 카테고리를 기반으로 사용자 임베딩 벡터를 실시간으로 생성합니다.

    • OpenSearch에 저장된 아이템 벡터와 사용자 벡터 간 유사도 검색 쿼리를 실행합니다.

    • Top-K 유사도 기반 추천 결과를 도출합니다.

    • S3와 Opensearch에 추천 결과를 저장합니다.

고민 방식

저는 핵심 추천 결과를 저장하고, 검색 및 추천 LLM을 위한 벡터 DB로 OpenSearch 3.0을 선택했습니다. 그 이유는 여기서 확인해주세요 😄 추천 모델은 룰 기반과 내부 Vector DB FAISS를 활용하고 있었는데, 내부 Vector DB는 CI/CD 환경에서 Docker 컨테이너가 재시작될 때마다 인덱스가 초기화됩니다. 따라서 서버가 재가동될 때마다 인덱스를 다시 메모리에 로드해야하는 단점이 있기 때문에 내부 FAISS 대신 외부 Vector DB 기능을 갖춘 OpenSearch에서 유사도 계산을 수행하는 방안을 선택했습니다.







- 컬렉션 아티클