기존에 구현했던 RAG 성능을 개선하는 PoC 느낌의 업무를 받아서 처음부터 db나 chunker를 새로 모색하기보다는 기존에 사용한 라이브러리를 그대로 사용했다.
chunk, retrieval 쪽은 대게 langchain+FAISS로 구현되어 있었는데 retrieval 성능이 어떻게 해도 좋아지지 않아서 이것저것 찾아봤는데 점수 쪽에서 뭔가 이상하다고 느꼈다.
FAISS로 vector DB를 만들 때 보통 vectorDB.from_documents( )를 사용했는데 이를 이용한 similarity_search는 L2 거리 기반임을 알 수 있었다. vector 거리 비교에 cosine similarity를 사용하지 않아 성능이 낮은 것이라 판단했다.
그렇다고 다른 라이브러리나 벡터 db를 쓰기에는 관련 지식이 전무해 최대한 기존 langchain+FAISS 조합을 유지하고 싶어 일단은 그냥 눈 감고 사용했다.
퇴근하고 너무 열받아 조금 검색하니 바로 해답이(거기다 한국어로 친철하게)나와서 공유해보려 한다.
FAISS.from_documets( )에서 distance_metric 지정하기
db = FAISS.from_documents(doc_texts, embedding=embeddings, distance_strategy = DistanceStrategy.MAX_INNER_PRODUCT)
위의 코드를 사용하면 cosine similarity를 사용해 index를 생성할 수 있다.
이를 사용하지 않았을 때와 사용했을 때 retrieval 결과가 다른 걸 알 수 있다. 이 예제는 Dacon의 예시 데이터라 semantic search를 하기에는 적합하지 않아 검증 코드를 덧붙이겠다.
def l2_distance(vec1, vec2):
return np.sqrt(np.sum((vec1 - vec2) ** 2))
def cosine_similarity(vec1, vec2):
return np.dot(vec1, vec2) / (norm(vec1) * norm(vec2))
print(doc_texts[-1].page_content)
###'The mitochondria are known as the powerhouse of the cell, providing energy for cellular activities.'
db = FAISS.from_documents(doc_texts, embedding=embeddings, distance_strategy = DistanceStrategy.MAX_INNER_PRODUCT, normalize_L2 = True)
db.similarity_search_with_score_by_vector(embeddings.embed_query("The mitochondria"), k=1)
###[(Document(metadata={'source': 'Biology Notes'}, page_content='The mitochondria are known as the powerhouse of the cell, providing energy for cellular activities.'),
0.72040486)]
print(cosine_similarity(embeddings.embed_query(doc_texts[-1].page_content), embeddings.embed_query("The mitochondria")))
###0.7204048870290206
넘파이로 구현한 코사인 거리와 값이 동일한 걸 알 수 있다. 한 가지 주의점으로는 index 생성 시 "normalize_L2 = True" 인자를 설정하지 않으면 같은 거리가 재현되지 않는다. " normalize_L2 = False"(default)를 사용하면 코사인 유사도의 분모로 나눠주는 연산을 수행하지 않기 때문이다.
한 마디로 normalize해도 scailing으로 인한 값의 차가 존재하지만 retrieval 결과는 동일하다.
'Deep Learning' 카테고리의 다른 글
[Pytorch] ImageFolder label기준으로 split하기 (0) | 2023.04.10 |
---|---|
[Pytorch]Datasets and dataloaders (0) | 2023.03.23 |
[Pytorch]Autograd (0) | 2023.03.19 |
[Pytorch]Pytorch Basic (0) | 2023.03.19 |