Julie의 Tech 블로그

Vector Store: Azure Vector Search에 대하여 본문

Tech

Vector Store: Azure Vector Search에 대하여

Julie's tech 2023. 8. 22. 23:29
728x90

이번 글은 Azure에서 LLM기반 어플리케이션의 best-practice 아키텍쳐 중에서 QA엔진에서 주로 사용되는 Azure Vector Search 서비스에 대한 설명과 서비스 이용해본 경험을 바탕으로 내린 한계와 후기를 담으려고 한다.

 

Vector Search 서비스 소개

Vector Search란?

Cognitive Search에서 벡터 Query + 벡터 필드 추가가 가능해진 확장판 버전이다. 즉 Azure 클라우드 리소스 내에서 검색엔진 리소스인 Azure Search (현 Cognitive Search)의 연장선에 있는 서비스라고 생각하면 된다. Index에 벡터 필드를 추가하고, keyword 서치랑 병렬로 vector search를 지원한다는 정도의 차이이다.

Vector Search는 데이터 타입으로 Vector를 받아들여 multi-modal content retrieval이 가능하다는 것이 Azure 측의 소개이다.

따라서 Azure Cognitive Search의 검색 유형은 세 단계로 되어있다.

1) Cognitive Search: 기본적인 search 알고리즘(BM25, TF-IDF)를 사용한다.

2) Semantic Search: 1의 결과에 re-ranking을 적용한다. 1에서의 TOP 50개 문서를 corpus로 사용하여 언어모델이 re-ranking한다. Transformer-based semantic ranking engine을 사용하여 쿼리와 semantically matching하는 결과의 relevance값을 높여준다. 추가적으로 Instant Answer + Caption + Highlight + Spell Correction 기능을 제공한다.

3) Vector Search: vector index를 생성하고 해당 index에 쿼리의 벡터 임베딩 값으로 매칭된 검색결과를 리턴한다. 1,2는 inverted index를 사용하는 반면, vector search는 embedding 모델로 document를 벡터화하여 검색한다. 실제로는 query를 vector query, keyword query 두 개를 던져 각각 index에서의 score 결과를 뽑은 뒤 RRF 알고리즘에 따라 합치게 된다. 만약 Semantic Search도 on해두었다면 RRF 결과에서 Semantic re-ranking을 진행한다.

위 세 가지 유형의 기능을 조합하면 크게 3가지 유형의 검색이 가능하다.

1) Vector Search

2) Hybrid Search

  • vector index + inverted index 모두에서 검색
  • 각각 쿼리문이 다를 수 있는데 다르게되면 OR조건으로 검색
  • 각 index에서의 search score을 RRF(Reciprocal Rank Fusion)으로 weight하여 merge한 검색결과를 제공
    • 이 때 ranking algorithm으로 아래와 같이 두 가지가 있다.
      • Single Vector Search: HNSW(Hierarchical Navigable Small Words)
      • Simple Hybrid Search: RRF(Reciprocal Rank Fusion)

3) Semantic Hybrid Search

  • Hybrid search에서 semantic ranking + caption + answer + spell check를 추가

Embedding Model 선정

Vector store은 당연하게도 임베딩 모델이 있어야한다. 데이터를 벡터화하여 저장하고 있기 때문이다.

Azure에서는 물론 Azure OpenAI Embeddings를 추천한다. 현 기준(23.08) 임베딩 모델 중에서 가장 최신 모델인 text-embedding-ada-002를 가이드 코드에서 사용하고 있다.

그 외에 커스텀화된 모델도 이용 가능하다.

Vector Search 생성 방법

1. Azure Search Service를 우선적으로 생성해야한다.

plan을 먼저 설정해준 후 subscription, resource group을 정의해주어야한다. 이는 정책에 따라서 지정하면 된다.

2. 서비스명을 지어준 후 search service가 동작할 location, 그리고 서비스 scaling과 관련된 pricing tier를 지정해준다.

  • pricing tier: standard 기준으로 Partition당 25GB 사이즈, 최대 12개 replica, 최대 12개 partition, 최대 36개 search unit 생성 가능
  • 그 외에 scale로 replica, partition 수를 지정해서 띄울 수 있는데 이는 서비스가 running하는 동안에도 쉽게 조정이 가능하다. (다만 조정 후 배포까지의 소요시간이 수십분 걸린다.)
  • 엔드포인트 연결도 public / private 지정이 가능하다.

3. 레포에 있는 가이드를 따라서 인덱스를 생성하면 끝이다.

  • 이 때 Cognitive skill을 사용하면 이미지, 오디오, 영상, 텍스트 등 비정형 데이터도 아울러 인덱싱할 수 있다.
  • 인덱싱의 경우 JSON 규격의 데이터를 인풋받아 원격 서버에 API Request PUT 방식으로 동작한다.
  • 제약 사항으로는 데이터를 index에 인풋시 API Request LIMITS에 걸린다는 점이 있고, 대규모+대량의 문서를 인덱싱해야하는 경우 크리티컬한 제약일 수 있다.
    • The maximum document size when calling an Index API is approximately 16 MB.
    • Maximum 1000 documents per batch of index uploads, merges, or deletes
  • Index 필드: 가이드 상으로는 문서의 제목, 카테고리, 컨텐츠 내용, 그리고 각각의 임베딩 벡터값 필드를 추가하였다.
  • 벡터 필드 생성은 따로 함수가 있는 것이 아니라서 아무 임베딩 모델을 사용하여 벡터값을 생성한 뒤 JSON의 Key:Value pair로 추가, 인덱스 메타에 지정해주면 된다.
  • 가이드 코드에서 사용된 임베딩 모델은 text-embedding-ada-002
  • 추가로 Algorithm Configuration을 해주어야한다.
    • Vector Search: HNSW 알고리즘 주요 parameter 값 지정이 필요하다 (m, efConstruction, efSearch, metric)
    • Semantic Search: title, content, keyword field가 있고 의미상 매칭이 되는 데이터 필드를 매핑해주어야한다.
  • Tokenizer / Analyzer

Vector Store 관련 필요한 고민사항

  • Document Chunking: 긴 text 데이터로 벡터 필드를 생성하게 될 경우 chunk를 하게 된다. chunk는 당연하게도 trade-off가 있는데 문서 간의 연속성을 떨어뜨리는 반면 단일 문서 사이즈를 줄여 임베딩 혹은 검색 속도를 향상시킨다. 이에 따라 어떤 token splitter를 쓸 것인지, overlap 길이는 어떻게 해야하는지에 대한 고민이 있을텐데, Vector Search 가이드라인상으로는 하나의 문서를 다중으로 나누게 될 경우 문서의 제목이나 카테고리 정보 등 메타를 내용 상에 추가해주어 문서의 연속성을 유지하도록 안내하였다. Overlap 길이는 언어에 따라 다르겠지만 평균 구/절/문장 단위로 사용하는 것이 좋다. 혹은 Recursive splitter를 사용하여 문단 단위로 문맥이 유지될 수 있도록 하는 방법도 있다.
  • 임베딩 모델 선정: 영문으로 된 문서라면 다른 적절한 오픈소스형 모델을 사용해도 좋을 것 같은데, 한글로 된 문서라면 OpenAI Embedding을 사용하는 것이 제일 최선의 선택일 것 같다. 혹여나 동일한 문서 데이터로부터 검색 최적화된 학습 모델이 있다면 그를 대신하여 임베딩 모델로 사용하는 것이 좋을 것 같다.

Vector Search 관련 팁

  • Query시 벡터 서치를 이용하게 될 경우 생각보다 예민한 편이라 스페이스 하나 추가에도 검색 결과가 확연히 달라지게 된다. 따라서 유저에게 검색어를 받는 등의 어플리케이션 개발이 엮여있다면 strip으로 앞뒤 스페이스나 무의미한 토큰들은 전처리해주는 것이 좋다.
  • filter 기능을 사용하여 검색성능을 향상시키거나 보안과 같은 기본적인 검색 기능을 추가로 구현할 수 있다. 문서 조회 권한 등이 담겨있는 필드에 filter를 이용하여 유저의 정보에 따라 조회 가능한 문서들만을 검색 결과로 뱉도록 구현할 수 있다. 혹은 검색 결과에 꼭 포함되어야하는 단어가 있다면 마찬가지로 filter기능을 통해 반드시 특정 term을 포함하는 문서만을 결과로 줄 수 있다.
  • 최신순 혹은 조회수 등으로 문서의 우선순위를 sorting을 통해 조정할 수 있다. 혹여나 문서 간 우선순위가 모종의 규칙으로 정해져있는게 있거나 좀 더 복잡한 우선순위를 주고 싶다면 scoring profile을 활용하면 된다.
  • 만약 사전(dictionary)가 있어 주요 term에 대해 임의의 weight를 주어 검색결과를 개선하고 싶다면 아래와 같이 두 가지 정도의 간단한 기능이 있다. 이들은 Query 전처리에 포함된다.

한계점 / 보완점

  • (한국어) 자연어 Query 검색이 가능하다는 점이 의심된다. “A 알려줘”의 검색결과와 “A”의 검색결과가 서로 다르다. 그리고 스페이스 하나만 포함/비포함되더라도 검색결과가 달라지는 경우도 있다.
  • index 정기 업데이트가 필요할 경우 삭제 후 재생성이 아닌 업데이트가 가능하다고 되어있는데, 그 기준이 모호한 부분이 있다.
    • An upload action is similar to an "upsert" where the document will be inserted if it is new and updated/replaced if it exists. All fields are replaced in the update case.
  • Semantic Search 등 전반적으로 search score에 대한 threshold 정의가 되지 않는다. 공식 문서에 따르면 search.score의 range값이 고정이 아니라고 하며 따로 thresholding하는 기능을 지원하지 않는다고 되어있다.
  • Azure vector search의 임베딩 모델을 자체 모델을 사용하지 않는 이상 어떤 term이 더 중요한 의미를 지니는지에 대해 파악하지 못하기 때문에 Query문에 조건 혹은 조사와 같이 무의미한 검색어가 많이 붙게 되면 검색결과가 좋지 않다.
  • 아주 간단한 예를 들어 “치약” 중에서도 “불소 치약”에 대해서 검색하고 싶을 경우 “불소”에 대한 weight값이 높게 매겨저 검색결과가 나오는 경우
  • memory store로만 사용할 수도 있다. 비정형 문서들(PDF, 이미지 등)도 text화하는 cognitive skills 기능으로 통합된 indexing이 가능하기 때문이다. 하지만 가성비가 좋지 않다는 후기
  • 벡터서치 관련한 한계사항으로는 다중 필드 쿼리가 불가능하다. 그리고 다중 벡터 쿼리도 지원하지 않는다. 검색결과는 단일 벡터 쿼리만을 받는다.
  • Hybrid query (vector + cognitive/semantic)인 경우 sorting($orderby)과 pagination($skip)을 지원하지 않는다.
  • 벡터 쿼리와 Hybrid query에는 facet ($facet)과 count ($count)를 지원하지 않는다.
반응형