본문 바로가기

Database

pincone이 조건부 벡터 검색을 빠르게 수행하는 방법

  Pincone이란?

  • AI 어플리케이션을 위한 벡터 데이터를 저장하는 벡터 데이터베이스
  • 왜 벡터를 저장해야하는가?
    • 다양한 콘텐츠에 대한 내용을 벡터화하여 원본에 대한 정보와 함께 저장
    • 나중에 유사한 콘텐츠를 찾기 위해 임베딩으로 DB를 검색할 수 있음

 

 

FAISS(Facebook AI Similarity Search) 와의 차이점은?

  • FAISS도 벡터 임베딩 검색을 지원하지만 DB의 기능을 가지고 있지 않음

 

  벡터 검색에서 문제점: 필터링

  • 검색이나 추천시스템에서는 거의 항상 필터를 적용해야함
    • Google은 카테고리(예: 뉴스 또는 쇼핑), 날짜 또는 언어 및 지역별로 검색을 필터링
    • Netflix, Amazon 및 Spotify는 유사한 지역의 사용자를 비교하기 위해 필터링을 사용
    • 그 외에도 애플리케이션 내에서 특정 부서 내에서만 검색을 하고싶다거나, 특정 날짜 범위로 검색을 제한하고 싶을 수 있음
  • 그러나 벡터 검색에 있어 필터링은 단순해보이지만 해결하기 어려운 문제점임
  • 벡터 검색에 필터를 추가하는 두 가지 일반적인 방법
    • 사전 필터링
    • 사후 필터링
  • 이러한 접근 방식에는 일반적으로 벡터 인덱스메타데이터 인덱스 라는두 개의 인덱스가 필요함

 

 

  🔎 사전 필터링

  1. 메타데이터 인덱스를 가져와서 조건부 필터링
  2. 필터링 이후에 남은 데이터에서 벡터 검색

 

문제점

  • 문제는 사전필터링이 ANN의 작동방식을 방해한다는 것
  • 벡터 검색은 ANN 알고리즘으로 이루어지는데 이를 위해서는 전체 데이터의 인덱스가 필요하기 때문
    • ANN: Approximate Nearest Neighbor 기법
    • 정확도를 조금 포기하고 아주 빠른 속도로 주어진 vector의 근접이웃을 찾는 기법
    • 정확한 근접 이웃이 아닌 근사적으로 구한 근접이웃이어서 Approximate NN이다.

 

대안

따라서 위의 문제를 해결하기 위해서는 두 가지 옵션이 있다.

  1. 모든 필터에 대해 벡터 인덱스를 만들거나
  2. 필터링 이후의 나머지 벡터에서 kNN 검색을 수행하거나

옵션 (1)은 실용적이지 않다. 필터링은 무수한 조합이 있을 수 있기 때문이다. 옵션 (2)는 남은 모든 벡터 임베딩에 대해 쿼리 임베딩과 비교해야하기 때문에 검색 속도가 크게 느려진다.

그렇다면 사후 필터링은 어떨까?

 

 

  🔎 사후 필터링

  1. 벡터 검색을 먼저 수행
  2. 검색된 데이터에서 조건부 필터링

 

문제점

  • 만약 k=10 으로 10개의 매칭된 데이터를 가져왔을 경우
  • 조건을 충족하는 결과가 몇 개 밖에 없거나 아예 없을 수도 있다.

 

대안

위의 문제를 해결하기 위해 애초에 k 를 높은 숫자로 해서 매칭 데이터를 많이 가져온 후 필터링을 진행하여 너무 적은 결과를 반환하는 위험을 제거할 수는 있다.

그러나 이제 지나치게 높은 k 검색으로 인해 검색 시간이 느려지고 이는 사전 필터링의 느린 검색시간과 상황이 비슷해질 수 있다.

 

 

  pinecone의 솔루션: 단일 단계 필터링

  • 앞서 사전/사후 필터링과 같은 2단계에 거친 과정이 아닌 단일 단계에서 필터링을 수행하고자 하는 방식
  • 벡터 및 메타데이터 인덱스를 단일 인덱스로 병합하여 작동
  • 실험 결과 사전 필터의 정확도를 유지하면서 검색 속도가 크게 개선된 것을 확인할 수 있음
  • 데이터 셋이 커질수록 검색 속도에서 큰 이득을 볼 수 있음

 

테스트

  • SQuAD 데이터셋: 질문 및 답변의 세트가 있음
  • 해당 데이터의 languagetitle 을 pincone의 metadata 태그로 추가하여 인덱스 생성
{
 'id': '573387acd058e614000b5cb5en',
 'context': 'One of the main driving forces in the growth of the University was its football team, the ... against the New York Giants in New York City.',
 'metadata': {
 'lang': 'en',
 'title': 'University_of_Notre_Dame'
 }
}
  • 파인콘에서 메타 데이터로 필터링 시 아래와 같은 연산자를 사용할 수 있음

 

Ex)

  • 영어 결과만 반환받기 위해 langen 과 같은지를 기준으로 필터링 수행할 경우
results = index.query(queries=[xq.tolist()], top_k=3, filter={'lang': {'$eq': 'en'}})
  • lang 필터를 유지하면서 제목이 켄자스 대학교 또는 노틀담 대학교 가 아닌 것을 반환받고자 하는경우
conditions = {
    'lang': {'$eq': 'en'},
    'title': {'$nin': ['University_of_Kansas', 'University_of_Notre_Dame']}
}

results = index.query(queries=[xq.tolist()], top_k=3, filter=conditions)
%%timeit
index.query(queries=[xq.tolist()], top_k=3, filter=conditions)

>>>
38.3 ms ± 244 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

 

파인콘의 단일 단계 필터링이 작동 원리에 대해서는 다음 글에서 작성하고자 한다.

'Database' 카테고리의 다른 글

[Redis] redis 클러스터 모드 설치 및 multi command test  (2) 2022.11.05