임베딩 안정화로 검색 리랭킹의 콜드 스타트 문제를 해결하다: LINE Part Time Jobs 적용 사례 (새 탭에서 열림)
LINE Part Time Jobs는 기존 2타워 임베딩 기반 리랭킹의 콜드 스타트와 검색 쿼리 미반영 문제를 해결하기 위해, 임베딩 공간을 날짜별로 안정화하는 후처리 방식을 도입했습니다. 저차원 SVD와 직교 Procrustes 정렬을 통해 매일 재학습되는 임베딩의 연속성을 유지했고, 그 결과 오프라인 전환 nDCG가 약 9%, 클릭 nDCG가 약 4.5% 향상되었습니다. A/B 테스트에서도 서비스 전체 KPI 4.7%, 매출 6.5% 증가를 달성했습니다.
LINE Part Time Jobs 검색 리랭킹 구조
- 검색 시스템은 다음 두 단계로 구성됩니다.
- 검색(retrieval): 사용자의 쿼리에 맞는 구인 공고 후보를 수집
- 리랭킹(reranking): 수집된 후보를 사용자별로 재정렬
- 기존에는 별도 배치 파이프라인에서 생성한 사용자·아이템 2타워 임베딩을 활용했습니다.
- 사용자 임베딩과 아이템 임베딩의 코사인 유사도를 계산해 검색 결과 순위를 정했습니다.
- 이 방식은 실시간 연산 부담을 줄일 수 있지만 다음 한계가 있었습니다.
- 검색 쿼리와 역, 거리 같은 화면별 정보가 임베딩에 충분히 반영되지 않음
- 검색 외 추천 모듈이나 LINE 공식 계정에서 발생한 행동까지 함께 포함됨
- 검색 화면에 특화된 사용자 의도를 정밀하게 반영하기 어려움
전용 리랭킹 모델 도입 과정의 문제
공고 교체로 인한 콜드 스타트
- LINE Part Time Jobs의 공고는 월초에 대부분 교체됩니다.
- 새로운 공고에 대한 클릭·지원 데이터가 충분히 쌓이기 전에는 전용 리랭킹 모델이 학습할 데이터가 부족합니다.
- 그 결과 공고 교체 직후 모델 성능이 크게 저하되는 콜드 스타트 문제가 발생했습니다.
매일 변하는 임베딩 공간
- 2타워 모델은 성능 유지를 위해 주기적으로 랜덤 가중치에서 처음부터 재학습됩니다.
- 재학습할 때마다 임베딩 공간의 방향과 좌표계가 달라질 수 있습니다.
- 따라서 오늘 생성한 임베딩과 어제 생성한 임베딩은 실제 의미가 비슷해도 벡터 좌표상 직접 비교하기 어렵습니다.
- 학습 시점과 추론 시점에 서로 다른 버전의 임베딩을 사용하면 다운스트림 리랭킹 모델의 입력 분포가 달라져 성능이 떨어질 수 있습니다.
임베딩 안정화 방식
- 각 날짜의 임베딩을 전날 안정화된 임베딩 공간에 맞춰 정렬합니다.
- 첫날 임베딩은 별도 변환 없이 기준으로 사용합니다.
- 이후에는 전날 결과를 다음 날의 기준으로 삼아 임베딩 공간을 순차적으로 연결합니다.
- 이 방식은 특정 기준일에 모든 임베딩을 맞추는 대신, 시간에 따른 공간의 연속성을 유지합니다.
- 결과적으로 임베딩 피처와 다운스트림 모델의 업데이트 시점을 엄격히 일치시키지 않아도 됩니다.
저차원 SVD와 직교 Procrustes
저차원 SVD
- 아이템 임베딩과 사용자 임베딩을 각각 행렬 (T), (W)로 표현합니다.
- 2타워 모델의 점수는 (TW^\top)로 계산되지만, 이 대규모 행렬을 직접 분해하지는 않습니다.
- 대신 저차원 SVD를 사용해 변환 행렬 (M_T), (M_W)를 구합니다.
- 변환 결과는 다음과 같습니다.
- 아이템 임베딩: (T' = TM_T)
- 사용자 임베딩: (W' = WM_W)
- 이를 통해 각 학습에서 생성된 임베딩을 보다 표준화된 저차원 표현으로 변환합니다.
직교 Procrustes 정렬
- 당일 임베딩과 전날 안정화된 임베딩이 최대한 일치하도록 직교 변환을 계산합니다.
- 직교 변환은 회전과 반전만 수행하므로 벡터 간 거리와 내적 구조를 보존합니다.
- 따라서 임베딩의 유사도 기반 점수 계산 특성을 유지하면서 일별 공간 차이를 보정할 수 있습니다.
대규모 데이터 처리를 위한 구현
- 데이터 규모가 크기 때문에 알고리즘을 Apache Spark 기반 분산 처리로 구현했습니다.
- 저차원 SVD에서는 원 논문의 QR 분해 대신 숄레스키 분해를 사용했습니다.
- Gramian 행렬 (G = A^\top A)를 계산
- (G = R^\top R) 형태로 숄레스키 분해
- QR 분해에서 필요한 상삼각 행렬 (R)을 효율적으로 획득
- 직교 Procrustes에서는 다음과 같이 처리했습니다.
- 대규모 행렬곱 (M = B^\top A)는 Spark로 분산 계산
- (M)은 임베딩 차원 (e \times e)의 작은 행렬이므로 SVD는 단일 노드에서 NumPy로 계산
- 대규모 벡터 데이터와 소규모 변환 행렬을 구분해 계산 자원을 효율적으로 배분했습니다.
안정화 효과와 평가 결과
- 안정화 전에는 서로 다른 날짜의 임베딩 상관관계가 거의 0에 가까웠습니다.
- 안정화 후에는 다음 수준의 유사도를 유지했습니다.
- 일주일 후: 약 0.88
- 한 달 후: 약 0.87
- 안정화하지 않은 임베딩을 다운스트림 모델에 추가하면 공간 불일치로 nDCG가 약 1~5% 하락했습니다.
- 안정화된 임베딩을 사용한 경우:
- 전환 nDCG 약 9.0% 향상
- 클릭 nDCG 약 4.5% 향상
A/B 테스트 결과와 해석
- 안정화된 임베딩과 콜드 스타트 대응책을 결합한 모델을 온라인 실험했습니다.
- 검색 화면 단독 KPI에서는 통계적으로 유의미한 개선이 뚜렷하지 않았습니다.
- 그러나 서비스 전체 기준으로는 다음 성과를 얻었습니다.
- KPI 4.7% 향상
- 매출 6.5% 향상
- 이는 임베딩이 검색 화면뿐 아니라 서비스 전반의 사용자 행동과 장기적인 선호를 반영했기 때문으로 분석됩니다.
- 검색 이후 다른 페이지로 이동하거나 다른 추천 모듈에서 지원하는 행동까지 긍정적인 영향을 받은 것으로 보입니다.
- 기존 2타워 모델 구조나 학습 파이프라인을 변경하지 않고 임베딩 후처리만 추가했다는 점도 운영상 중요한 장점입니다.
실용적인 결론
재학습마다 좌표계가 달라지는 임베딩을 다운스트림 모델의 피처로 사용할 때는 날짜별 공간 정렬이 효과적인 해결책이 될 수 있습니다. 특히 저차원 SVD와 직교 Procrustes를 결합하면 임베딩의 유사도 구조를 유지하면서 버전 불일치와 드리프트를 줄일 수 있으므로, 기존 모델을 크게 변경하기 어려운 대규모 추천·검색 시스템에 적용하기 적합합니다.