벡터 데이터베이스

벡터 임베딩과 벡터 검색

텍스트는 토크나이저와 임베딩을 거쳐 벡터가 됩니다. 토큰화와 임베딩을 합해서 그냥 임베딩이라고 이야기하기도 합니다. 벡터를 이용한 검색 과정에 대해 생각해봅시다. 문서를 문단, 문장 등 작은 단위(chunk)로 분리하고 각각을 벡터로 만들어 저장해 놓습니다. 질문이 들어왔을 때 질문도 임베딩 벡터로 만들면 저장된 벡터와 질문의 임베딩 벡터 사이의 거리를 계산할 수 있습니다. 거리가 가까운 벡터는 질문과 관련된 내용을 포함할 가능성이 높습니다. 이렇게 질문과 관련된 벡터를 찾는 과정이 벡터 검색입니다.

검색 후에는 거리가 가장 가까운 벡터 K개를 추출하여 거대 언어 모델의 프롬프트에 포함시킵니다. 이 방법을 Retrieval-Augmented Generation (RAG)라고 합니다.

벡터 거리 측정

검색을 위해 벡터 사이의 거리를 측정하는 방법에는 여러 가지가 있습니다.

  • 코사인 유사도
  • 해밍
  • 유클리드 거리 (L2)
  • 맨하탄 거리 (L1)
  • 내적

이 외에도 여러 가지가 있는데, LLM과 관련해서 코사인 유사도를 많이 사용합니다. 보통 질문의 임베딩 벡터와 가장 가까운 벡터를 하나만 찾는게 아니라 K개를 찾습니다. K-Nearest Neighbor (KNN)라고 하죠.

이 때 문서가 짧으면 벡터도 많지 않고 거리를 구하는 계산이 금방 끝나지만 문서가 길어지게 되면 벡터 검색 시간이 크게 증가하게 됩니다. 그래서 보통 Approximate Nearest Neighbor (ANN) 기법을 사용해 근사적으로 가장 가까운 벡터들을 찾습니다. 정확도를 약간 희생하고 검색 속도를 높이는 방법입니다. ANN 관련 기술도 여러 가지가 있습니다.

  • Locality Sensitive Hashing (LSH)
  • Random Projection
  • Hierarchical Navigable Small World (HNSW) Graphs
  • Product Quantization

벡터 라이브러리

ANN 기법은 검색 범위를 좁히거나 벡터의 길이를 짧게 만들어 벡터 검색 계산량을 줄이는데, 그렇게 하기 위해서는 미리 벡터를 인덱싱하는 과정이 필요합니다. 이렇게 인덱스를 만들고 벡터간의 거리를 계산해서 검색하는 프로그램을 벡터 라이브러리라고 합니다. 다음은 많이 사용하는 벡터 라이브러리들입니다.

  • 메타에서 개발한 FAISS (Facebook AI Similarity Search)
  • 스포티파이에서 개발한 Annoy (Approximate Nearest Neighbors Oh Yeah)
  • 구글에서 개발한 ScaNN (Scalable Nearest Neighbors)
  • NMSLIB
  • HNSWLIB

벡터 데이터베이스

실제 LLM에서 벡터 임베딩을 이용한 검색을 위해서는 벡터 라이브러리의 기능 외에도 추가 기능들이 필요합니다. 벡터 외에 벡터의 원본 텍스트와 같은 메타 정보를 포함하는 기능, 메타 정보를 이용한 필터링, 벡터의 손쉬운 추가/제거/업데이트, 병렬 연산 지원, 백업이나 보안 지원 등과 같은 기능을 추가한 벡터 라이브러리가 벡터 데이터베이스입니다. 최근에는 기존 데이터베이스에서 벡터 검색을 지원하기도 하는데, 많이 사용하는 벡터 전용 데이터베이스는 다음과 같습니다.

  • Pinecone
  • Milvus
  • Chroma
  • Weaviate
  • Deep Lake
  • Qdrant
  • Vespa

LLM을 이용해 RAG를 구현할 때 위 내용들을 몰라도, 벡터 데이터베이스 사용법만 알면 구현이 가능합니다^^ 하지만, 어느 정도의 배경 지식은 알고 만들면 더 좋겠죠?

댓글 남기기