Vespa 벡터 검색

Vespa 벡터 검색

Vespa는 임베딩 벡터 기반의 근접 이웃 검색을 지원해요. tensor 타입 필드에 벡터를 저장하고, HNSW 인덱스를 만들어 nearestNeighbor 연산자로 검색해요. 풀텍스트 검색과 함께 쓰는 하이브리드 검색도 자연스럽게 구성할 수 있어요.

출처: https://docs.vespa.ai/en/nearest-neighbor-search.html

텐서 필드 선언

벡터를 저장하려면 스키마에 tensor 타입 필드를 만들고, 벡터 인덱스를 위한 index 설정과 랭킹용 attribute를 지정해요.

schema doc {
  document doc {
    field embedding type tensor<float>(x[384]) {
      indexing: attribute | index
      index: hnsw
    }
  }
}

tensor<float>(x[384])는 384차원 float 텐서를 뜻하고, index: hnsw로 HNSW 인덱스를 만들어요. HNSW 인덱스는 크기와 성능을 조절하는 파라미터를 함께 지정할 수 있어요.

벡터 데이터 넣기

도큐먼트를 넣을 때 벡터 필드도 함께 보내요.

curl -s -X POST -H "Content-Type: application/json" \
  --data-binary '{"fields": {"id": 1, "embedding": {"values": [0.1, 0.2, ...]}}}' \
  http://localhost:8080/document/v1/mynamespace/doc/docid/1

nearestNeighbor 검색

검색 쿼리는 YQL에서 nearestNeighbor(field, query_embedding) 연산자를 쓰고, 쿼리 벡터를 ranking.features.query(embedding)으로 넘겨요.

curl -s 'http://localhost:8080/search/?yql=select%20*%20from%20sources%20*%20where%20nearestNeighbor(embedding,%20query_embedding)%3B&ranking.features.query(embedding)=[0.1,0.2,...]'

기본적으로 nearestNeighbor는 쿼리를 받아 가장 가까운 도큐먼트만 후보로 남기고, 랭킹 프로파일의 closeness(field, query_embedding) 표현식으로 점수를 매겨요.

하이브리드 검색

벡터 검색과 풀텍스트 검색을 OR로 결합하면 하이브리드 검색이 돼요.

...where%20nearestNeighbor(embedding,%20query_embedding)%20or%20title%20contains%20%22hobbit%22%3B

두 결과를 어떻게 섞을지는 랭킹 프로파일에서 결정해요.

더 알아보기