FAISS 사용법 및 예제 코드
다양한 인덱싱 방법을 제공하는 faiss 라이브러리에 대해서 알아보고 사용법을 정리합니다.
FAISS 란
FAISS(Facebook AI Similarity Search)는 페이스북에서 개발한 라이브러리로, 효율적인 유사도 검색과 대량의 벡터 클러스터링을 목적으로 개발되었다. 특히 고차원 공간에서의 벡터 검색에 최적화되어 있기에 이미지, 비디오, 텍스트 등의 데이터에서 유사한 아이템을 빠르게 찾을 수 있다.
FAISS의 주요 특징은 다음과 같다.
- 효율성: 고차원 벡터의 유사성 검색을 빠르고 메모리 효율적으로 수행할 수 있도록 설계
- 확장성: 억 단위의 벡터와 같은 매우 큰 데이터셋도 처리할 수 있으며, 이는 대규모 시스템에서 유용하다.
- 유연성: 다양한 유사도 분석 방법과 인덱싱 방법을 제공한다.
- 이식성: C++로 작성되었으며 Python 인터페이스도 제공한다. 또한 GPU 버전을 설치하면 GPU에서도 사용 가능하다.
FAISS의 동작 원리
벡터 데이터를 기반으로 FAISS가 동작하는 방식은 다음과 같다.
- 임베딩을 통해 유사도를 검색할 전체 데이터를 벡터 형태로 생성한다.
- 인덱스를 구축하고, 전체 데이터 벡터를 인덱스에 추가한다.
- 검색문장을 임베딩하고 유사도 검색을 진행한다.
인덱싱 방법
인덱싱(Indexing)이란 벡터 데이터를 효율적으로 관리하고 검색하기 위해 어떻게 구성하고 저장할지에 대한 방법론이다. 즉, 데이터를 어떻게 분할하고 어떤 구조로 저장할지에 대한 전략이다. 따라서 인덱싱은 "정확한" 유사 데이터를 반환하는 것보다는 빠르게 검색 결과를 반환할 수 있도록 검색 성능을 높이는 데 초점이 맞춰져 있다. faiss에서 제공하는 인덱싱 방법은 크게 flat, Quantization 2가지이다.
이름 | 설명 |
---|---|
Flat Index | - 데이터를 아무런 압축이나 구조 변경 없이 메모리에 그대로 저장한다. - 검색 시 모든 벡터와의 거리를 계산(브루트-포스 방식)하여 가장 가까운 벡터를 찾는다. - 정확도는 가장 높지만 벡터의 양이 많을 때는 매우 성능이 매우 떨어질 수 있다. - 규모가 작고 정확도가 중요한 경우 사용 |
Product Quantization(PQ) | - 고차원 벡터를 여러 개의 하위 벡터로 분할하고, 각 하위 벡터를 독립적으로 양자화한다. - 각 하위 벡터에 대해 독립적인 양자화 코드북을 생성한다. - 벡터를 압축하여 메모리 사용을 줄이면서 검색 속도를 높인다. - 대규모 고차원 데이터셋의 유사도 검색에서 많이 사용 |
Scalar Quantization(SQ) | - 각 차원의 데이터를 독립적으로 양자화한다. - 벡터를 스칼라로 전부 분해한 후 미리 정의한 더 작은 구간(bin)에 맞춰 값들을 변경한다. - 신호 처리에서 많이 사용 |
Vector Quantization(VQ) | - 전체 데이터 공간을 여러 개의 벡터 클러스터로 나눈다. - 각 클러스터는 하나의 대표 벡터(코드워드)로 표현된다. - 이미지 압축, 음성 인식 등에서 많이 사용 |
검색 알고리즘
검색 알고리즘은 저장되어 있는 수많은 벡터 중에서 가장 유사한 벡터를 어떻게 찾을지에 대한 논리구조이다.
이름 | 설명 |
---|---|
유클리디안 거리 (L2) | - 두 점 사이의 최단 직선 거리를 측정하는 방식. - 직관적이고 간단하여 이해하기 쉽다. - 고차원에서의 성능 저하(차원의 저주) 존재한다. |
내적 (IP, Inner Product) | - 두 벡터의 각 성분의 곱을 모두 더하는 방식. - 각도와 방향성을 기반으로 한 유사성 측정에 적합하다. - 벡터 크기를 고려하지 않아 스케일링에 민감할 수 있다. |
유사도 분석에서 사용되는 검색 알고리즘에 대한 자세한 내용은 해당 글에서 확인할 수 있다.
인덱싱 + 검색 알고리즘
faiss에서는 특정 상황에 최적화된 인덱싱 구조와 검색 알고리즘을 결합하여 제공한다.
이름 | 설명 |
---|---|
IVF (Inverted File) | - 전체 벡터를 중심점을 가진 여러 개의 클러스터로 나누어 저장하는 방식. - 검색 시 가장 유사한 클러스터를 먼저 검색 후 클러스터 내 데이터로만 유사도 검색을 수행한다. - 대규모 데이터셋에서 효율적인 검색이 가능하지만 초반의 클러스터링을 통해 검색 범위가 제한된다. - 따라서 클러스터링의 품질에 크게 의존하며, 초기 인덱싱 시간이 많이 소요될 수 있다. |
HNSW (Hierarchical Navigable Small World) | - 그래프 기반의 접근 방식. - 계층적 그래프 구조를 통해 고차원 데이터에서 효과적으로 근접 이웃을 찾아서 반환한다. - 고차원 데이터에서 뛰어난 검색 성능을 가지며, 복잡한 데이터 분포에도 강하다. - 메모리 사용량이 상대적으로 높으며, 구현과 튜닝이 복잡할 수 있다. |
결론
FAISS에서 제공되는 방법들은 보통 인덱싱 방법과 검색 알고리즘을 최적화하여 결합된 형태이다. 더 많은 종류와 자세한 내용은 공식 깃허브 페이지에서 확인할 수 있다.
기초 사용법 및 예제 코드
이제부터 간단한 예제를 통해 기초 사용법을 알아보자.
faiss 설치
이번 글에서는 CPU 버전을 사용하여 예제를 진행할 예정이다. 설치하는 코드는 다음과 같다.
1 |
|
설치가 완료되었다면 python에서 faiss 라이브러리를 임포트한다.
1 |
|
따로 예제 데이터가 없다면 아래 라이브러리도 설치 및 임포트하자.
1 |
|
1 |
|
예제 데이터 준비
다음으로는 인덱싱에 사용할 예제 데이터를 준비한다. 당연히 데이터 구조는 벡터여야 한다. 따라서 텍스트 데이터를 임베딩해주자.
1 |
|
데이터 준비는 끝났다.
인덱싱 작업
이 단계에서 인덱싱 방법과 검색 알고리즘을 골라야 한다. 예제 케이스는 개수가 적어 편하게 flat + 내적 조합을 사용한다.
1 |
|
유사도 검색
이제 위에서 만든 벡터 DB에 유사도 검색을 테스트해보자.
1 |
|
밥과 관련된 문장들을 반환하였다.