FAISS vector db의 자료의 최소단위인 chunk는 page_content(내용)과 metadata(chunk 정보)로 구성된다.
기본적으로 vector db에서 search를 진행하면 입력된 문장과 page_content의 내용을 비교하여 유사한 chunk 순으로 반환을 해준다. 하지만 metadata에 필터링을 걸어 검색을 하고 싶을 때가 있다. 예를 들어 특정 출처의 자료에서만 내용을 검색한다던지 특정 시기의 자료에서 검색을 위해 요구될 수 있다.
기본적인 metadata 필터링과 맞춤형으로 custom 필터 함수를 만들어 사용하는 방법에 대해 알아보자
0. vector db load
from langchain_community.vectorstores import FAISS
from langchain_huggingface import HuggingFaceEmbeddings
embeddings = HuggingFaceEmbeddings(model_name=embedding_model_name) # embedding에 사용할 모델
db = FAISS.load_local("저장된 vector db", embeddings=embeddings) # vector db load
1. 기본적인 vector db 검색
metadata 필터링을 확인하기 위해 검색된 chunk들의 metadata만 비교해보자.
result = db.similarity_search('전기를 아껴쓰는 방법')
metadatas = [content.metadata for content in result]
metadatas
result
[{'id': 176,
'사내외구분': '사내',
'과제구분': '연구과제무관',
'주제분야': '공통',
'기술관리등급': '공개(C)',
'등록일': '2011-04-18',,
'확장자': '.pdf',
'문서종류': '논문, 보고서'},
{'id': 145,
'주제분야': '배전',
'실제발표일자': '2022-03-18',
'논문성격': '연구과제성과물',
'확장자': '.pdf',
'사내외구분': '사내',
'문서종류': '논문'},
{'id': 145,
'주제분야': '배전',
'실제발표일자': '2022-03-18',
'논문성격': '연구과제성과물',
'확장자': '.pdf',
'사내외구분': '사내',
'문서종류': '논문'}]
2. 기본 filter 사용법
similarity_search method 에는 filter 인자를 받을 수 있다.
이때 dictonary 형태로 metadata 필터링을 진행할 수 있다. 이때 완벽하게 일치하는 값을 가진 chunk들만 출력된다. 예를 들어 위에 결과에서 문서 종류가 논문인 chunk만 출력하고 싶다면 아래와 같이 사용가능하다.
result = db.similarity_search('전기를 아껴쓰는 방법', filter={'문서종류':'논문'})
metadatas = [content.metadata for content in result]
metadatas
result
[{'id': 145,
'주제분야': '배전',
'확장자': '.pdf',
'사내외구분': '사내',
'문서종류': '논문'},
{'id': 145,
'주제분야': '배전',
'논문성격': '연구과제성과물',
'확장자': '.pdf',
'사내외구분': '사내',
'문서종류': '논문'},
{'id': 1895,
'학술저널': '전기학회논문지',
'저널종류': '학술저널',
'사내외구분': '사외',
'문서종류': '논문'}]
3. custom filter 사용법
2번의 사용법은 완전일치를 조건으로 한다. 1에서 결과 중 첫 번째 나왔던 chunk는 문서종류가 "논문, 보고서"로 되어 있어 2에서 검색되지 않았다. 이번에는 filter 인자에 직접 함수를 넣어 "논문"과 완전 일치가 아닌 "논문"이라는 단어가 들어 있다면 검색되도록 함수를 짜준다. 함수는 True, False를 반환해야 한다.
custom 함수
from typing import Any, Dict
fillter = {"문서종류": "논문"}
def filter_func(metadata: Dict[str, Any]) -> bool:
return all(
metadata.get(key) in value # in 연산자로 포함관계 적용
if isinstance(value, list)
else value in metadata.get(key)
for key, value in filter.items() # type: ignore
)
함수 적용 검색
result = db.similarity_search('전기를 아껴쓰는 방법', filter=filter_func)
metadatas = [content.metadata for content in result]
metadatas
result
[{'id': 176,
'사내외구분': '사내',
'과제구분': '연구과제무관',
'주제분야': '공통',
'기술관리등급': '공개(C)',
'등록일': '2011-04-18',,
'확장자': '.pdf',
'문서종류': '논문, 보고서'},
{'id': 145,
'주제분야': '배전',
'실제발표일자': '2022-03-18',
'논문성격': '연구과제성과물',
'확장자': '.pdf',
'사내외구분': '사내',
'문서종류': '논문'},
{'id': 145,
'주제분야': '배전',
'실제발표일자': '2022-03-18',
'논문성격': '연구과제성과물',
'확장자': '.pdf',
'사내외구분': '사내',
'문서종류': '논문'}]
함수가 적용되어 "논문, 보고서"를 metadata로 가진 chunk도 반환된 것을 알 수 있다.
'python > 딥러닝' 카테고리의 다른 글
langchain에서 VLLM 사용하기 (with lora) (1) | 2024.08.12 |
---|---|
vLLM 사용방법 with LoRA (0) | 2024.06.18 |
llama.cpp GPU 가속 설치 error : which is required to install pyproject.toml-based projects (0) | 2024.02.22 |
llama.cpp 설치 방법 및 사용방법 with LoRA (2) | 2024.02.22 |
[컴퓨터 비전] SSD 개요 (0) | 2021.05.06 |
댓글