벡터 데이터베이스 (VectorDB)

RAG를 공부하면서 Vector DB에 대해 자세히 알아볼 필요성을 느껴 포스팅을 진행해보고자 한다.

 

Database 구분

 

Database는 크게 3가지로 구분이 된다.

  • 관계형 데이터베이스(RDBMS)
  • 비관계형 데이터베이스(NoSQL)
  • 벡터 데이터베이스(VectorDB)

 

관계형 데이터베이스(RDBMS)

 

RDBMS는 데이터를 테이블로 구성하여 관리하는 데이터베이스를 의미한다. SQL을 이용하여 데이터를 조작한다. 이는 강력한 데이터 무결성을 가지고 복잡한 쿼리 처리 능력과 트랜젝션 관리 등이 가능한 DB형태를 가진다.

대표적으로 우리가 익숙하게 알고 있는 MySQL, PostgreSQL, Oracle 등이 그 예시다. 주로 금융 시스템이나 고객 관리 시스템, 온라인 상점 등 데이터의 관계가 중요한 애플리케이션 서비스에 RDBMS가 사용이 된다.

 

비관계형 데이터베이스(NoSQL)

 

NoSQL은 스키마가 없거나 유연한 스키마를 가져, 대량의 분산 데이터를 저장하고 관리하는데 최적화된 데이터베이스이다.

키-값 저장소, 문서 저장소, 와이드 컬럼 저장소, 그래프 DB 등 다양한 유형이 존재하고 확장성, 유연한 데이터 모델, 빠른 읽기/쓰기 성능이 그 특징이다.

대표적으로 MongoDB, Redis, Neo4j 등이 그 예시다. 이들은 주로 소셜 네트워크, 실시간 애널리틱스, 빅데이터 처리 등에 사용이 된다.

 

MongoDB 예시

 

벡터 데이터베이스(VectorDB)

 

VectorDB는 벡터 형식의 데이터를 저장하고 쿼리 분석하는데 특화된 데이터베이스다. 벡터는 공간상의 점을 의미하며, 벡터들은 다차원 공간에서의 위치를 나타낸다. VectorDB는 높은 차원의 데이터에서도 빠른 검색 속도와 유사 벡터 검색 기능을 지원한다.

대표적으로 Milvus, Faiss, Chroma, Pinecone과 같은 VectorDB가 그 예시다. (VectorDB는 DB에 따라 지원하는 쿼리 검색 방법이나 특징이 약간씩 다르다) 이는 주로 이미지, 오디오, 텍스트와 같은 다양한 유형의 벡터 데이터를 저장하고, 이를 기반으로 유사한 항목을 검색하거나 분석하는 AI 기반의 애플리케이션에 활용이 된다.

 

VectorDB 톺아보기

 

Vector DB는 벡터 형식으로 데이터를 변환하기 위해 인코딩 작업이 필요하다. 모든 딥러닝 모델은 벡터를 통해서 계산되어지고 특징을 추출할 수 있는데, Vector DB는 이렇게 생성된 벡터값을 저장, 관리, 사용하는데 강점이 있는 데이터베이스다.

 

효과적인 인코딩을 통해 Cotext Vector들을 하나의 Vector Space에 투영하게 되면 하나의 Vector Space 안에서 맥락이 유사한 Vector들은 서로 가까이 위치하게 된다. 우리는 이를 활용하여 유사도 기반 검색 서비스를 제공할 수 있다. 테이블 구조를 가지고 key를 기반으로 데이터를 얻는 관계형데이터베이스에 반해, Vector DB는 전체 데이터들과 쿼리간의 유사도를 계산하고, 가장 유사도가 높은 document를 추출해야한다는 목적성과 특성때문에 '정확하고 빠른' document 추출이 Vector DB 구축에 가장 핵심요소라고 할 수 있다.

 

 

VectorDB 검색 방식

 

브루트 포스 검색 (Brute-Force Search) == 'Flat Indexing'

 

브루트 포스 검색 방식은 모든 데이터포인트를 순회하여 주어진 쿼리 포인트와의 거리를 계산한다. 가장 단순하고 기본적인 방식인데, 데이터셋의 크기가 커질수록 계산량이 기하급수적으로 증가하기에 비효율적이다.

 

Approximate Nearest Neighbor(ANN)

 

ANN 알고리즘은 가장 많이 사용되는 검색방법이다. 이는 완벽한 최근접 이웃을 찾기보다 '근사적'으로 가장 가까운 이웃을 찾는 방법이다. 예를 들어, 데이터를 미리 클러스터링하여 검색공간을 줄이거나, 여러 버킷으로 나눈다음, 주어진 쿼리 포인트가 속할 가능성이 가장 높은 몇 개의 버킷만 검색하는 방식이다.

여기서 거리계산의 '근사적'이라는 표현은 완벽한 정확도를 포기하고, 대신 검색 속도를 크게 향상시키는 트레이드 오프를 찾는 방식을 의미한다.

 

Faiss나 Annoy 등의 검색 방법이 그 예시인데, 해당 내용은 추후에 더 정리해보겠다.

 

고급 인덱싱 기반 검색

 

고급 인덱싱 기반 검색 방법은 데이터를 구조화하여 검색속도를 향상시키는 방법이다. 데이터를 미리 인덱싱하여 검색 시간을 단축시키는 방법이다.

Faiss의 경우, 데이터를 군집화하여 검색범위를 좁히는 방식인 IVF(Inverted File Index)를 통해 검색범위를 좁혀 ANN(최근접 이웃 검색)을 구현하거나, 벡터를 양자화해서 메모리사용을 줄이는 PQ(Product Quantization)방식을 통해 ANN을 구현할 수 있는 것이다. 

아래는 고급 인덱싱 기반 검색 방법들에 대한 설명이다.

 

  • IVF(Inverted File Index)
    • 데이터셋을 미리 정의된 수의 군집(centroid)으로 나누고, 각 벡터를 가장 가까운 centroid에 할당함으로써 검색범위를 제한하는 방식으로 ANN에 공헌한다. 검색 시, 쿼리벡터가 속하는 군집을 먼저 찾고, 해당 군집내에서 가장 유사한 벡터를 찾는 방식이다. 단, 검색속도가 빠르지만, 검색 시 적절한 군집수를 선택해야하고 군집화에 시간이 소요될 수 있다는 점이 단점이다.
  • PQ(양자화 기반 검색, Product Quantization)
    • PQ방식은 고차원 벡터를 여러개의 하위 벡터로 분할하고, 각 하위 벡터를 양자화하여 저장공간을 줄이는 방식이다. 줄어든 공간에서의 검색속도 또한 범위가 줄어들기 때문에 빨라질 수 밖에 없다는 것이 논리이다.
  • HNSW(Hierarchical Navigable Small World)
    • HNSW방식은 다계층 그래프 구조를 사용하여, 고차원 데이터에 대한 효율적인 최근접 이웃 검색을 수행하는 방법이다.
      HNSW방식은 속도도 빠르고, 다른 인덱싱 기법에 비해 정확하다는 강점을 가진다.
  • LSH(Locality-Sensitive Hashing)
    • 데이터 포인트를 해시 테이블에 매핑하여, 쿼리 벡터와 유사한 데이터 포인트들을 빠르게 검색하는 방법이다. LSH는 유사한 객체가 '같은 버킷'에 할당될 확률을 높이는 해시 함수를 사용한다.