Faiss 는 Facebook AI 에서 개발한 유사도 검색 모델이다.
밀집 벡터의 효율적인 유사성 검색 및 클러스터링을 위한 라이브러리입니다.
Faiss 는 numpy 나 torch 에서 제공해주는 cosine_similarity 보다 훨씬 빠릅니다.
빠른 이유는 벡터들 간의 연관성까지 포함하여 임베딩 정보를 가지고 있기 때문입니다.
즉, 벡터 길이(n)가 고정되어 있을 경우에는 빠른속도를 기대할 수 있지만
매번 다른 벡터들일 경우엔 매번 벡터간 연관성 계산 + 유사도 계산이 필요하기 때문에 기존
numpy 함수를 사용하는 것이 더 빠릅니다.
즉 faiss 는 길이(n)를 제한하는 대신 미리 벡터끼리의 정보를 계산해두고 그것을 이용하여 빠르게 검색합니다.
( 틀리면 마구마구 지적 부탁드립니다. )
실습을 통해 알아보겠습니다.
Faiss 설치 방법
# CPU-only version
$ conda install -c pytorch faiss-cpu
# GPU(+CPU) version
$ conda install -c pytorch faiss-gpu
# or for a specific CUDA version
$ conda install -c pytorch faiss-gpu cudatoolkit=10.2 # for CUDA 10.2
데이터 셋 : https://github.com/songys/Chatbot_data
pairwise 모델 : https://huggingface.co/Huffon/sentence-klue-roberta-base
준비단계
(1). 데이터셋에 질문(Q)를 pairwise 모델로 전부 임베딩
(2). 임베딩 벡터들을 저장 (.npy)
패키지 로드
import pandas as pd
import numpy as np
import faiss
from sentence_transformers import SentenceTransformer , util
데이터 로드
#데이터 불러오기
df = pd.read_csv("./ChatbotData.csv")
#임베딩 벡터 불러오기
embeddings = np.load("./embeddings.npy")
#변환기 불러오기
embedder = SentenceTransformer("Huffon/sentence-klue-roberta-base")
불러온 벡터의 차원이 맞는지 확인합니다.
# 벡터 차원 확인하기
embeddings.shape
(103675, 768)
Faiss 적용하기
# faiss 계산하기
index = faiss.IndexFlatL2(embeddings.shape[1]) # 초기화 : 벡터의 크기를 지정
index.add(embeddings) # 임베딩을 추가
여기서 IndexFlatL2 는 각 벡터의 유사성 또는 각 벡터의 근접성을 측정하는 데 사용하는 거리 메트릭입니다.
여기서 L2 는 유클리드 거리를 의미합니다.
index.is_trained # 추가가 되었는지 확인하기
index.ntotal # 임베딩 수 확인하기
유사도 검색
top_k = 100
query = "사랑했던 사람이 떠났어"
query_embedding = embedder.encode(query, normalize_embeddings=True ,convert_to_tensor=True)
distances, indices = index.search(np.expand_dims(query_embedding,axis=0),top_k)
유사도 검색은 쉽게 index.search 를 사용하면 할 수 있습니다.
결과는 튜플의 형태로 나오게 되는데 앞에(distances)는 각각의 벡터들의 거리가 저장되고,
뒤에(indices)는 해당하는 인덱스를 반환됩니다.
top_k 는 몇개를 추출할 것인지에 대한 옵션이고 자동으로 거리가 가까운 순서로 정렬되어 반환됩니다.
# 결과 확인
temp = df.iloc[indices[0]]
#temp
temp['distances'] = distances[0]
temp[['user','system','distances']].head(10)
#index 저장하기
faiss.write_index(index,"sts.index")
#인덱스 불러오기
index = faiss.read_index("./sts.index")
한번 계산한 index 는 저장하여 다음번에 불러오기만 해서 사용할 수 있습니다.
속도 테스트 결과
총 10만개의 벡터를 전부 cosine_similarity를 했을 경우에는 10초 정도 결렸고
faiss 모델은 0.2~0.3초 소요되었다.
검색기반 챗봇은 검색 성능과 속도가 가장 중요한데 faiss 라이브러리를 사용하여 엄청난 성능향상을 기대할 수 있었습니다.
참고 : https://www.youtube.com/watch?v=sKyvsdEv6rk&t=22s
https://github.com/facebookresearch/faiss/wiki/Getting-started
https://github.com/facebookresearch/faiss/blob/main/INSTALL.md
'Machine learning > Chatbot' 카테고리의 다른 글
[위로봇 프로젝트]. 오복이 육아일기 1일차 - 소개 (0) | 2022.12.06 |
---|---|
[chatbot]. 핑퐁 빌더 API 연동하기 (1) | 2022.12.05 |
[챗봇]. 편집거리 알고리즘을 통한 오타 확인 (0) | 2022.04.29 |
[챗봇]. BERT 임베딩 벡터를(Embedding Vectors) RDBMS의 저장해야하는 이유 (1) | 2022.02.13 |
[챗봇]. 대화 텍스트 길이(length)에 대한 패널티(penalty)를 주는 방법 (0) | 2021.11.14 |