[LLM] 올라마 모델에 랭체인 적용하기
Ollama 공식 문서의 튜토리얼
python: https://github.com/ollama/ollama/blob/main/docs/tutorials/langchainpy.md
java script: https://github.com/ollama/ollama/blob/main/docs/tutorials/langchainjs.md
llama2에서 호메로스의 오디세이아에 대해 정보를 요청하면 다음과 같은 답변을 얻을 수 있다.
💻 죄송합니다만 저는 언어모델이 큰 관계로 현실에 존재하지 않는 개인이나 가족에 대한 정보를 제공할 수 없습니다.
Neleus는 실제 인물이나 캐릭터가 아니므로 가족이나 기타 개인 정보가 없습니다. 혼란을 드려 죄송합니다. 제가 더 도와드릴 일이 있나요?
해당 답변은 사용자가 원하는 대답이 아닐 것이다.
그렇다면 Ollama와 LangChaing을 사용하여 호메로스의 오디세이아에 관한 질문을 한 뒤, 적합한 답변을 얻을 수 있는 방법을 알아보자.
패키지 설치
먼저 필요한 패키지를 설치해준다.
#랭체인
pip install langchain_community
#웹스크래핑 및 데이터 추출 라이브러리
pip install bs4
모델 생성 및 문서 로드
패키지 설치가 완료됐다면, LangChain 모델을 생성한다.
from langchain_community.llms import Ollama
ollama = Ollama( base_url='http://localhost:11434', model="llama3" )
print(ollama.invoke("why is the sky blue"))
그 후 Project Gurenberg에서 찾을 수 있는 오디세이아 문서를 로드한다.
해당 문서를 로드하기 위해선 모든 웹페이지에서 텍스트를 로드하는 WebBaseLoader가 필요하다. 해당 클래스는 LangChain의 일부이다.
from langchain.document_loaders import WebBaseLoader
loader = WebBaseLoader("https://www.gutenberg.org/files/1727/1727-h/1727-h.htm")
data = loader.load()
임베딩
해당 파일은 서문만 3000토큰이기 때문에, 작은 조각으로 나누어야 한다.
from langchain.text_splitter import RecursiveCharacterTextSplitter
text_splitter=RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=0)
all_splits = text_splitter.split_documents(data)
임베딩 과정이 필요하므로, 벡터 데이터베이스로 Chromadb를 사용하며 임베딩 모델을 가져와야한다.
pip install chromadb
ollama pull nomic-embed-text
분할이 완료되었으면, 분할 된 조각 중 관련된 조각을 모델에 제출해야한다.
임베딩을 생성하고 이를 벡터 데이터베이스에 저장한다.
from langchain.embeddings import OllamaEmbeddings
from langchain.vectorstores import Chroma
oembed = OllamaEmbeddings(base_url="http://localhost:11434", model="nomic-embed-text")
vectorstore = Chroma.from_documents(documents=all_splits, embedding=oembed)
질문하기
이제 문서에 질문을 할 수있다.
"넬레우스는 누구였으며 그의 가족은 누구입니까?"
넬레우스는 오디세이아의 인물이며, 그에 대한 답은 문서에서 찾을 수 있다.
먼저 검색과 유사한 데이터 청크에 대한 일치 항목 수를 확인한다.
question="Who is Neleus and who is in Neleus' family?"
docs = vectorstore.similarity_search(question)
len(docs)
그 후 아래 코드로 문서의 관련 부분을 모델에 전달하여 답변 얻을 수 있다.
해당 코드는 프로세스의 두 부분(LLM 모델과, 벡터 DB)을 함께 연결하고 있으며, 이를 체인이라고 한다.
체인의 의미는 다양하게 쓰이는데, 여기서의 체인은 올라마(LLM 모델)과 검색하고자 하는 벡터 디비와 연결을 의미한다.
from langchain.chains import RetrievalQA
qachain=RetrievalQA.from_chain_type(ollama, retriever=vectorstore.as_retriever())
res = qachain.invoke({"query": question})
print(res['result'])
해당 체인에서 받은 답변은 다음과 같다.
❓ 넬레우스는 누구였으며 그의 가족은 누구입니까?
💻 Neleus는 Homer의 "Odyssey"에 등장하는 인물이며 Penelope의 구혼자들의 맥락에서 언급됩니다. Neleus는 Neleus와 결혼하여 Nestor, Chromius, Periclymenus 및 Pero를 포함한 여러 자녀를 낳은 Chloris의 아버지입니다. 니소스(Nisus)의 아들인 암피노무스(Amphinomus)도 페넬로페의 구혼자로 언급되며 그의 천부적인 성격과 유쾌한 대화로 유명합니다.
텍스트 분할기의 Chunk_overlap을 20으로 업데이트 후 다시 시도하면 더 나은 답변을 얻을 수 있다.
(청크를 자르면 자를 수록 정확도가 높아지지만 연산 수가 늘어난다.)
💻 넬레우스(Neleus)는 호머의 서사시 '오디세이아'에 등장하는 인물입니다. 그는 Iasus의 아들 Amphion의 막내딸이자 Minyan Orchomenus의 왕인 Chloris의 남편입니다. Neleus에는 Nestor, Chromius, Periclymenus 및 Pero를 포함하여 Chloris를 가진 여러 자녀가 있습니다.
'🤖 AI > LLM' 카테고리의 다른 글
[LLM] 도큐먼트 로더(Document Loader) (0) | 2024.07.15 |
---|---|
[LLM] RAG (Retrieval-Augmented Generation) (0) | 2024.07.03 |
[LLM] 랭체인(LangChain) (0) | 2024.06.24 |
[LLM] 올라마(Ollama) (0) | 2024.06.21 |
[LLM] LM Studio (0) | 2024.06.20 |