RAG(Retrieva Augmented Generation, 검색 증강 생성)
이해하기
검생 증강 생성은 LLM모델에게 외부 데이터를 알려주고 싶을 때 사용하는 방법입니다.
시작하기
%%time
import os
from langchain_community.document_loaders import PyMuPDFLoader, Docx2txtLoader, TextLoader, UnstructuredExcelLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain.vectorstores import Chroma
# 임베딩 설정
embeddings = HuggingFaceEmbeddings(
model_name="BAAI/bge-m3",
model_kwargs={'device': 'cpu'}, # 또는 'cuda'로 변경하여 GPU를 사용할 수 있음
encode_kwargs={'normalize_embeddings': True} # 임베딩 정규화
)
# Chroma 클라이언트 초기화
collection_name = 'chromaTest'
db = Chroma(
persist_directory='./chroma',
collection_name=collection_name
)
# Chroma 데이터베이스 컬렉션 삭제
db.delete_collection()
# PDF
files = [file for file in os.listdir('./dataset')]
for file in files:
file_path = os.path.join('./dataset', file)
print('>>> file_path', file_path)
try:
''''''
if file.endswith('.pdf') :
# print('>>> pdf', file)
loader = PyMuPDFLoader(file_path)
if file.endswith('.docx') or file.endswith('.doc') :
# print('>>> docx', file)
loader = Docx2txtLoader(file_path)
if file.endswith('.txt') :
# print('>>> docx', file)
loader = TextLoader(file_path)
if file.endswith('.xlsx') or file.endswith('.xls') :
# print('>>> docx', file)
loader = UnstructuredExcelLoader(file_path, mode="elements")
pages = loader.load()
text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
texts = text_splitter.split_documents(pages)
# 텍스트와 임베딩 확인
print(f"텍스트 수 : {len(texts)}")
if len(texts) > 0 :
''''''
# 컬렉션 이름
# collection_name = 'test_' + str(len(texts))
# Chroma 데이터베이스 생성
db.from_documents(
texts,
embeddings,
persist_directory='./chroma',
)
except Exception as e:
print(f"Error {file} : {e}")
import os
from dotenv import load_dotenv
from langchain.vectorstores import Chroma
from langchain_community.embeddings import HuggingFaceEmbeddings
load_dotenv()
# 임베딩 설정
embeddings = HuggingFaceEmbeddings(
model_name="BAAI/bge-m3",
model_kwargs={'device': 'cpu'}, # 또는 'cuda'로 변경하여 GPU를 사용할 수 있음
encode_kwargs={'normalize_embeddings': True} # 임베딩 정규화
)
# 컬렉션 이름
collection_name = 'langchain'
# Chroma 클라이언트 초기화
db = Chroma(
persist_directory='./chroma',
embedding_function=embeddings,
collection_name=collection_name
)
# similarity_search 검색 (가장 유사한 벡터 검색)
query = "이상미의 직업은?"
result1 = db.similarity_search(query, k=3)
# result = db.get()
print('>>> result1', result1)
# 검색 결과를 저장할 데이터프레임 생성
results_list = []
for doc in result1:
results_list = {
'filename': doc.metadata.get('source', 'unknown'),
'page': doc.metadata.get('page', 'unknown'),
'text': doc.page_content
}
print('>>> filename : ', results_list['filename'])
print('>>> page : ', results_list['page'])
print('>>> text : ', results_list['text'])
# as_retriever 검색
# 벡터 저장소를 기반으로 벡터스토어리트리버를 생성합니다.
retriever = db.as_retriever(search_type="mmr", search_kwargs={"k": 3, "fetch_k": 10})
# 검색
query = "이상미의 직업은?"
result2 = retriever.get_relevant_documents(query)
print('>>> result2', result2)
# 결과 출력
for idx, doc in enumerate(result2):
# print(f"Result {idx + 1}:")
print(f" filename: {doc.metadata.get('source', 'unknown')}")
print(f" Page: {doc.metadata.get('page', 'unknown')}")
print(f" Text: {doc.page_content}")
print()