로컬머신에서 LlamaCpp 로 Llama2를 구동하고 Llama2 가 부족한 정보를 벡터디비로 보완해서 성능을 최적화 하는 과정을 정리해본다.
1. Llama2 설치하기
1) GGUF 버전의 Llama2 모델 다운로드 (LlamaCpp 변경사항 수정)
하위 과정을 진행하기 위해 "TheBloke/Llama-2-7b-Chat-GGUF" 버전을 다운로드 하도록 한다.
2) LlamaCpp 사용하기
llama.cpp의 주요 목표 중 하나는 MacBook에서 4비트 정수 양자화(feat. GGML)를 사용하여 LLaMA 모델을 실행하는 것이라고 한다.
3) Llama2 기본 모델 테스트 하기
from langchain.llms import LlamaCpp
from langchain import PromptTemplate, LLMChain
template = """Question: {question}
Answer: Let's work this out in a step by step way to be sure we have the right answer."""
prompt = PromptTemplate(template=template, input_variables=["question"])
llm = LlamaCpp(
# model_path: 로컬머신에 다운로드 받은 모델의 위치
model_path="./llama-2-7b-chat.Q4_K_M.gguf",
temperature=0.0,
top_p=1,
max_tokens=8192,
verbose=True,
# n_ctx: 모델이 한 번에 처리할 수 있는 최대 컨텍스트 길이
n_ctx=4096
)
llm_chain = LLMChain(prompt=prompt, llm=llm)
prompt = """
Among Korean dramas, please recommend 3 medical dramas about hospital life.
When recommending, classify it by number and title, and describe the release year and cast.
"""
response = llm_chain.run(prompt)
print(response)
3-1) 기본모델에 한국 드라마 관련 질문하기 (영문)
3-2) 기본모델에 한국 드라마 관련 질문하기 (한글)
3-3) 기본모델이 알고 있는 한국드라마의 릴리즈 연도는 어떻게 될까
2. Embedding
드라마 데이터셋 Embedding 하고 VectorDB FAISS 에 저장하기
1) 데이터셋 정의
지난 글에서 사용한 케글에 공개된 한국드라마 250건에 대한 데이터를 Embedding 하기로 했다.
from langchain.document_loaders import CSVLoader
from langchain.text_splitter import CharacterTextSplitter
loader = CSVLoader("./kdrama.csv")
documents = loader.load()
# 데이터를 불러와서 텍스트를 일정한 수로 나누고 구분자로 연결하는 작업
text_splitter = CharacterTextSplitter(
chunk_size=1000,
chunk_overlap=0,
separator="\n"
)
texts = text_splitter.split_documents(documents)
print(len(texts))
2) HuggingFace, Embeding 모델 (feat.intfloat/multilingual-e5-large)
intfloat/multilingual-e5-large Embedding 모델은 94개국어의 텍스트를 임베딩하는 모델이다.
3) Embeding 하고 FAISS VectorDB 에 저장/로드 하기
from langchain.vectorstores import FAISS
from langchain.embeddings import HuggingFaceEmbeddings
# 임베딩 모델 로드
embeddings = HuggingFaceEmbeddings(model_name="intfloat/multilingual-e5-large")
# 문서에 있는 텍스트를 임베딩하고 FAISS 에 인덱스를 구축함
index = FAISS.from_documents(
documents=texts,
embedding=embeddings,
)
# faiss_db 로 로컬에 저장하기
index.save_local("faiss_db")
# faiss_db 로 로컬에 로드하기
docsearch = FAISS.load_local("faiss_db", embeddings)
3. Langchain, RetrievalQA 로 질의하기
VectorDB 로 Embedding 한 Llama2 모델에게 한국 드라마 질문하기
from langchain.retrievers.document_compressors import EmbeddingsFilter
from langchain.retrievers import ContextualCompressionRetriever
from langchain.chains import RetrievalQA
# 유사도 0.7로 임베딩 필터를 저장
# 유사도에 맞추어 대상이 되는 텍스트를 임베딩함
embeddings_filter = EmbeddingsFilter(
embeddings=embeddings,
similarity_threshold=0.70
)
# 압축 검색기 생성
compression_retriever = ContextualCompressionRetriever(
# embeddings_filter 설정
base_compressor=embeddings_filter,
# retriever 를 호출하여 검색쿼리와 유사한 텍스트를 찾음
base_retriever=docsearch.as_retriever()
)
# RetrievalQA 클래스의 from_chain_type이라는 클래스 메서드를 호출하여 질의응답 객체를 생성
qa = RetrievalQA.from_chain_type(llm=llm, chain_type="stuff", retriever=compression_retriever)
3-1) 기본모델에 했던 한국 드라마 관련 질문 다시하기 (영문)
Embedding 한 데이터를 중심으로 20~21년 드라마도 잘 보인다.
3-2) 기본모델에 했던 한국 드라마 관련 질문 다시하기 (한글)
영문 질의와 결과가 조금 다르긴 한데, 한글도 Embedding 한 데이터를 중심으로 20~21년 드라마도 잘 보인다.
3-3) Embedding 된 한국드라마의 릴리즈 연도는 어떻게 될까
Embedding 된 데이터가 2022 가 최신이라 해당 질의에 대한 응답도 2022 년도 작품이 최신으로 나온다.