이번 프로젝트에서 Faiss 라이브러리를 사용해볼까 하여 Faiss에 대해 정리해보고자 한다.
Faiss
Faiss는 Facebook AI Research에서 개발한 라이브러리로 대량의 고차원 벡터에서 효율적인 유사성 검색 및 클러스터링을 처리를 위해 개발된 라이브러리다. 딥러닝에서는 복잡한 이미지, 텍스트, 사운드 데이터들을 벡터화하는 작업이 우선적으로 처리되어야 하는데 Faiss는 특히 딥러닝에서 생성된 대량의 벡터 데이터에 대한 연산을 처리하는데 최적화되어 있는 라이브러리이다.
딥러닝 문제를 해결함에 있어서 벡터 간 유사성을 찾는 상황이 일반적으로 많이 발생한다. 벡터 간 유사성을 찾는 방법으로 유클리드 거리나, 코사인 유사도 같은 방법을 사용할 수 있지만 이는 고차원&대용량 벡터 데이터로 넘어가게 되면 계산량이 많아져 굉장히 비효율적이게 된다. 반면 Faiss는 양자화 및 압축, 색인 생성 등의 최적화 기법을 사용하여 대량의 고차원 벡터에서 유사 벡터를 빠르게 찾을 수 있다는 장점을 가지고 있어 딥러닝에 자주 사용된다.
Faiss 기능
Faiss는 크게 유사성 검색, 벡터 양자화의 2가지 기능을 제공한다.
유사성 검색의 경우 코사인 유사도와 비슷한 로직을 생각하면 되는데, 벡터 공간에서 가장 가까운 이웃 벡터를 효과적으로 찾아내는 기능을 제공하는 것을 의미한다. 이전에 언급했듯 딥러닝에 사용되는 이미지, 텍스트, 사운드 등 다양한 데이터 유형에 대한 유사성 기반 검색에 꽤나 빠르고 정확한 성능을 제공한다.
두 번째 기능인 벡터 양자화 이전에 개념부터 정리해보자.
벡터 양자화의 정의는 N개의 특징 벡터 집합 x를 K개의 특징 벡터들의 집합 Y로 mapping하는 것이다. 예를 들어 아래 X, Y 벡터가 있다고 생각해보자.
$$ X = (소녀시대, 한예슬, 코드브이, 얀, 이영애, 한석규, 안성기, 유재석, 강호동) $$
$$ Y = (가수, 영화배우, 개그맨, 연예인) $$
이 때 X -> Y로 mapping을 진행하면 아래와 같이 매핑할 수 있다.
$$ 가수 = (소녀시대, 코드브이, 얀) $$
$$ 영화배우 = (한석규, 안성기) $$
$$ 개그맨 = (유재석, 강호동) $$
$$ 연예인 = (한예슬) $$
이 때 위와 같이 매핑 하는 방법을 사상함수라고 하며, $y=f(x) $라고 했을 때 $f()$를 양자화 연산자라고 한다.
여기서 중요하게 알아봐야 할 점은 벡터 Y의 각 특징(원소)들은 벡터 X의 원소가 매핑이 되는 큰 카테고리라고 보면 되고 이를 코드워드, 코드벡터, 클러스터 등이라고 부른다. 그리고 Y 집합은 코드북이라고 부른다.
다시 Faiss의 기능으로 돌아와서 핵심을 살펴보면, Faiss는 벡터 데이터를 압축하고 저장하는데 사용이 되는 벡터 양자화 기능도 제공한다는 것이다. (대량의 데이터를 효율적으로 저장하고 메모리 사용량을 줄이는 데 도움을 준다. -> 속도 향상!!)
Faiss 사용법
사용법 이전에 Faiss 작동 원리에 대해 간략히 짚고 넘어가보면 아래와 같다.
Faiss의 핵심 개념은 인덱스 생성이다. 인덱스는 벡터 데이터의 구조를 나타내는 메타데이터라고 보면 된다. 먼저 데이터를 양자화하여 인덱스를 생성하고 이후 인덱스를 활용해서 유사성 검색을 수행하는 구조다. 이 때 Faiss는 복잡한 벡터 공간을 작은 클러스터로 분할하며 각 클러스터는 그 안에 벡터들이 서로 유사하다는 점에서 차별성을 가진다. 클러스터링은 원본 벡터 공간을 더 작고 이해하기 쉽게, 계산하기 편한 공간으로 변환하는 역할을 한다. 이렇게 만들어진 클러스터는 원래 대량 데이터 대신 사용되며 각 클러스터는 원본 데이터의 '대표', '중심'을 나타내게 된다.
Faiss를 사용하기 위해선 아래의 4단계로 요약할 수 있을 것 같다.
- 필요한 벡터 데이터 로드
- 로드한 벡터 데이터를 파시스 인덱스에 추가
- 인덱스 학습
- 전역 클러스터링
- 로컬 클러스터링
- 유사성 검색 수행
인덱스 학습(3)의 경우 위와 같이 두 단계로 나뉘게 되는데 가장 먼저 전체 데이터 셋에 대한 전역 클러스터링을 수행한다. (이 전역 클러스터는 벡터 공간을 광범위하게 커버) 다음으로 전역 클러스터 내에서 로컬 클러스터링을 수행하며 이 때 클러스터의 수를 늘리고 벡터 공간을 더욱 세밀하게 나누어 계산 속도 및 정확성을 향상시킨다.
유사성 검색 수행(4)의 경우 쿼리 벡터를 입력으로 받아 가장 유사한 벡터들을 인덱스에서 찾아 반환한다. 이 때 인덱스 내의 각 클러스터에 대해 계산되고 가장 유사도가 높은 클러스터들이 반환 결과로 선택된다.
위를 기능적으로 요약하면, Faiss의 컴포넌트를 2가지(인덱싱, 검색)로 쪼갤 수 있다. 인덱싱에서는 대량의 고차원 벡터 데이터를 관리 및 인덱스 구축에 기능을 담당하며 검색 부분에서는 구축된 인덱스를 통해 특정 쿼리 벡터와 가장 유사한 벡터를 찾아내는 기능을 한다.
더불어 Faiss는 크게 3가지 인덱스 유형을 지원한다. 크게 아래와 같은 3가지 유형을 지원한다.
- 플랫(flat) 인덱스: 간단히 모든 벡터 간의 거리를 계산하는 방식이다. (가장 비효율적인 인덱스)
- 계층적(hierarchical) 인덱스: 벡터 공간을 여러 계층으로 나누어 검색을 최적화한다.
- 제품 인덱스(product): 여러 벡터를 조합하여 더 복잡한 벡터를 생성하고 이를 인덱스화 한다.
Faiss 장/단점
Faiss의 장점은 앞서 언급했듯 굉장히 빠르고 효율적인 유사성 검색 기능을 제공한다는 것이다. 또한 벡터 데이터를 효과적으로 압축하여 저장하기에 메모리 효율성 및 검색 성능 향상을 이끌 수 있다.
그러나, Faiss의 경우 비벡터형 데이터에 대해 직접적으로 처리할 수 없기 때문에 라이브러리 사용 이전에 반드시 데이터를 벡터로 임베딩해주는 작업이 필요하다. (단점이라면 단점이지만, 이 정도 단점은 충분히 수용할 수 있을 것 같다.)
그럼에도 불구하고 단점이 주는 거부감보다 장점이 주는 이점이 더욱 크게 다가오기에 앞으로 더 좋은 라이브러리가 만들어질 때까지 Faiss를 자주 사용해볼 예정이다.
Reference
https://github.com/facebookresearch/faiss
https://east-rain.github.io/docs/Deep%20Learning/vector%20search/
https://dajeblog.co.kr/16-faiss%EC%97%90-%EB%8C%80%ED%95%9C-%EB%AA%A8%EB%93%A0-%EA%B2%83/
https://blog.naver.com/chrhdhkd/220949908720
'Analytics' 카테고리의 다른 글
[Data] 텐서(Tensor) 구조와 연산 (0) | 2024.05.08 |
---|---|
[ML/DL] Activation function(활성화 함수)의 쓸모 (0) | 2024.05.05 |
[RecSys] 연관 규칙(Association Rule) (0) | 2024.04.30 |
[Data] 정규화(Normalization) / 표준화(Standardization) (0) | 2024.04.30 |
[ML/DL] Trade-Off(bias - variance) (1) | 2024.04.18 |