본문 바로가기
AI 언어 모델

Ollama와 Langchain을 이용한 환각없는 RAG 챗봇 만들기

by James AI Explorer 2023. 12. 19.
    728x90

    안녕하세요. 오늘은 저번시간에 다룬 Ollama와 대규모 언어모델 애플리케이션 개발 프레임워크인 Langchain을 이용해서 요즘 핫한 RAG(Retrieval-Augmented Generation, 검색 강화 생성) 모델을 만들어 보겠습니다. RAG는 외부 지식소스 검색을 통해 정보를 얻고, 이를 바탕으로 답변을 생성함으로써, 언어모델이 환각현상이나 부정확한 답변을 하지 않도록 보장하는 기술입니다. 이 블로그에서는 Ollama와 Langchain 사용방법, Chroma 데이터베이스 구축 및 RAG 구현방법에 대해 알아보실 수 있습니다. 그럼 같이 출발하실까요?

    Ollama와 Langchain을 이용한 환각없는 RAG 챗봇 만들기

    프로젝트 구성도 및 동작순서 

    이 프로젝트의 출처는 https://medium.aiplanet.com입니다. 이 프로젝트의 목표는 RAG 작업을 수행하는 챗봇을 구현하는 것이며, Langchain 프레임워크를 기반으로 Ollama와 Chainlit을 활용하고 있습니다. Chainlit은 Langchain을 사용하는 데 도움을 주는 Python 라이브러리 중 하나입니다. Langchain은 언어 모델을 사용하여 애플리케이션을 개발하는 데 중점을 둔 프레임워크이며, Chroma DB는 데이터를 수치적인 벡터 형태로 표현한 벡터 임베딩(Vector Embedding)을 저장하고 검색하기 위한 오픈 소스 데이터베이스(벡터 스토어, Vector Store)입니다. 

     

    다음은 프로젝트의 구성도와 동작 순서에 대한 간단한 설명입니다.

    프로젝트 구성도

    • 1. 사용자 쿼리 입력: Chainlit을 통해 사용자와 상호작용할 수 있는 챗봇이 준비되면 사용자는 Chatbot 인터페이스를 통해 원하는 주제에 대한 쿼리를 입력합니다.
    • 2. 벡터 검색 및 문맥 검색: 챗봇은 사용자의 쿼리를 받아 Chroma DB에서 벡터 저장소를 검색하고 검색된 벡터를 사용하여 문서에서 관련된 문맥을 검색합니다.
    • 3. Langchain을 통한 모델 실행: 검색된 문맥을 Langchain을 사용하여 백엔드에서 실행 중인 언어모델에 전달하고, 언어모델은 검색된 문맥을 기반으로 응답을 생성합니다.
    • 4. 응답 및 결과 출력: 챗봇은 모델에서 생성된 응답을 받아 사용자에게 제공합니다.

    프로젝트는 사용자의 쿼리를 처리하고, 해당 주제에 대한 정보를 Chroma DB에서 검색하며, Langchain을 사용하여 문맥을 모델에 전달하여 응답을 생성합니다. 이를 통해 사용자에게 신뢰성 있고 정확한 정보를 제공하는 챗봇을 구현하는 것이 목표입니다.

    "이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."

    단계별 설치방법

    RAG 작업을 Ollama와 Langchain을 사용하여 로컬 환경에서 수행하는 단계는 다음과 같습니다. 

    1. Ollama와 WSL2 설치

    대규모 언어 모델을 손쉽게 활용할 수 있도록 도와주는 도구인 Ollama는 현재 Windows에서 지원되지 않으므로, Windows Subsystem for Linux 2(WSL2)를 설치합니다. Ollama와 WSL2의 설치와 세부적인 내용은 저번 시간에 포스트 한 블로그 내용을 참고하시면 되겠습니다.

    2023.12.15 - [AI 도구] - Ollama를 활용한 대규모 언어 모델 웹 인터페이스 만들기: Mistral 7B와의 대화

     

    Ollama를 활용한 대규모 언어 모델 웹 인터페이스 만들기: Mistral 7B와의 대화

    안녕하세요. 오늘은 내 컴퓨터에서 웹 인터페이스로 최신 언어모델과 대화하는 프로젝트에 도전해 보겠습니다. 이 블로그에서는 Ollama라는 오픈소스 도구를 이용해서 최신 인기 대규모 언어모

    fornewchallenge.tistory.com

    2024. 4.17 Update : Ollama에서 윈도우 프리뷰 버전을 제공 중이지만, 각종 파이썬 라이브러리와의 호환성이나 동작 안정성 면에서 아직까지는 리눅스 버전을 사용하시는 것을 추천합니다. 

    2. Ollama 서버 시작 및 언어모델 구동

    위 블로그 내용을 참고하여 "Ollama serve" 명령으로 Ollama 서버를 시작하고, "Ollama run 모델명" 명령으로 언어모델을 구동합니다. 이 단계를 거치면 언어모델이 "localhost:11434"에서 서비스됩니다. 이 블로그에서는 Mistral 7B 모델을 미세조정한 dolphin2.2-mistral 언어모델을 사용해 보겠습니다. dolphin2.2-mistral 언어모델에 대한 내용은 아래 링크를 참고하시면 됩니다. 

    dolphin2.2-mistral 언어모델 다운로드
    dolphin2.2-mistral 언어모델 다운로드 화면

    3. 필요한 종속성 설치

    명령어 프롬프트에서 "conda create -n name"명령을 이용해서 가상환경을 만들고 활성화한 후, Python 패키지 관리자인 pip를 사용하여 Chromadb, Langchain 등 필요한 종속성을 다음과 같은 명령어로 설치합니다. 

    pip install chromadb
    pip install langchain
    pip install BeautifulSoup4
    pip install gpt4all
    pip install langchainhub
    pip install pypdf
    pip install chainlit

     

     

     

     

     

    4. 데이터 전처리

    검색에 참조하기 위해 필요한 PDF 형식 문서를 메인폴더 하위에 data 폴더를 만들어서 저장한 후, 아래 파이썬 코드(load_data_vdb.py)를 실행하면 해당 PDF 문서들이 벡터 임베딩으로 변환돼서 Chroma DB에 저장됩니다. 

    from langchain.text_splitter import RecursiveCharacterTextSplitter
    from langchain.document_loaders import PyPDFLoader, DirectoryLoader
    from langchain.document_loaders.pdf import PyPDFDirectoryLoader
    from langchain.document_loaders import UnstructuredHTMLLoader, BSHTMLLoader
    from langchain.vectorstores import Chroma
    from langchain.embeddings import GPT4AllEmbeddings
    from langchain.embeddings import OllamaEmbeddings  
    
    import os
    
    DATA_PATH = "data/"
    DB_PATH = "vectorstores/db/"
    
    def create_vector_db():
        loader = PyPDFDirectoryLoader(DATA_PATH)
        documents = loader.load()
        print(f"Processed {len(documents)} pdf files")
        text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=50)
        texts = text_splitter.split_documents(documents)
        vectorstore = Chroma.from_documents(documents=texts, embedding=GPT4AllEmbeddings(), persist_directory=DB_PATH)      
        vectorstore.persist()
    
    if __name__ == "__main__":
        create_vector_db()

    5. Langchain RAG 구현

    RAG 구현에 필요한 파이썬 스크립트를 아래 코드를 참조하여 "RAG.py"로 생성해서 파이프라인을 정의하고, "chainlit run RAG.py " 명령을 실행하여 챗봇 Interface를 실행합니다. 명령을 실행하면 자동으로 브라우저가 실행되고 http://localhost:8000/의 주소로 챗봇 화면이 열립니다.

    #import required dependencies
    from langchain import hub
    from langchain.embeddings import GPT4AllEmbeddings
    from langchain.vectorstores import Chroma
    from langchain.llms import Ollama
    from langchain.callbacks.manager import CallbackManager
    from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler
    import chainlit as cl
    from langchain.chains import RetrievalQA, RetrievalQAWithSourcesChain
    
    # Set up RetrievalQA model
    QA_CHAIN_PROMPT = hub.pull("rlm/rag-prompt-mistral")
    
    #load the LLM
    def load_llm():
        llm = Ollama(
            model="mistral",
            verbose=True,
            callback_manager=CallbackManager([StreamingStdOutCallbackHandler()])
        )
        return llm
    
    def retrieval_qa_chain(llm, vectorstore):
        qa_chain = RetrievalQA.from_chain_type(
            llm,
            retriever=vectorstore.as_retriever(),
            chain_type_kwargs={"prompt": QA_CHAIN_PROMPT},
            return_source_documents=True
        )
        return qa_chain
    
    def qa_bot():
        llm = load_llm()
        DB_PATH = "vectorstores/db/"
        vectorstore = Chroma(persist_directory=DB_PATH, embedding_function=GPT4AllEmbeddings())
        qa = retrieval_qa_chain(llm, vectorstore)
        return qa
    
    @cl.on_chat_start
    async def start():
        chain = qa_bot()
        msg = cl.Message(content="Firing up the research info bot...")
        await msg.send()
        msg.content = "Hi, welcome to the research info bot. What is your query?"
        await msg.update()
        cl.user_session.set("chain", chain)
    
    @cl.on_message
    async def main(message):
        chain = cl.user_session.get("chain")
        cb = cl.AsyncLangchainCallbackHandler(
            stream_final_answer=True,
            answer_prefix_tokens=["FINAL", "ANSWER"]
        )
        cb.answer_reached = True
        res = await chain.acall(message.content, callbacks=[cb])
        print(f"response: {res}")
        answer = res["result"]
        answer = answer.replace(".", ".\n")
        sources = res["source_documents"]
    
        if sources:
            answer += f"\nSources: " + str(str(sources))
        else:
            answer += f"\nNo Sources found"
    
        await cl.Message(content=answer).send()

    "chainlit run RAG.py " 명령을 실행하여 챗봇 Interface 실행

    728x90

    Chainlit 챗봇 인터페이스 초기화면

    6. 챗봇 사용

    실행된 챗봇에 사용자 쿼리를 제공하면, 언어모델이 벡터 저장소에서 관련 컨텍스트를 검색하고 이를 바탕으로 응답을 생성하게 됩니다. 모델의 응답속도는 사용자 컴퓨터의 사양에 따라 다를 수 있습니다.

    언어모델의 답변 화면

    위와 같은 단계를 따르면 Ollama와 Langchain을 사용하여 로컬 환경에서 RAG 작업을 수행할 수 있습니다.

    https://fornewchallenge.tistory.com/

    "이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."

     

    마치며

    여기까지 Ollama와 Langchain을 사용하여 RAG 작업을 수행하는 방법에 대해 알아보았습니다. RAG 작업은 외부 지식소스 검색을 통해 정보를 얻고, 이를 바탕으로 답변을 생성함으로써, 언어모델이 환각현상이나 부정확한 답변을 하지 않도록 보장하는 기술입니다.

     

    이 프로젝트를 통해 Ollama와 Chainlit을 사용하여 대규모 언어 모델을 활용한 웹 애플리케이션을 구축하는 방법과 Chroma DB를 사용하여 텍스트와 코드 데이터를 벡터 임베딩으로 변환하는 방법, 그리고 Langchain을 사용하여 RAG 작업을 수행하는 방법을 배울 수 있었습니다. 

     

    앞으로 이러한 기술들을 바탕으로 보다 정확하고 신뢰성 있는 정보를 제공하는 챗봇이 구현되기를 기대하면서 저는 다음에 더욱 유익한 정보를 가지고 다시 찾아뵙겠습니다. 이 블로그가 도움이 되셨기를 바랍니다. 감사합니다.

     

     

    2023.12.15 - [AI 도구] - Ollama를 활용한 대규모 언어 모델 웹 인터페이스 만들기: Mistral 7B와의 대화

     

    Ollama를 활용한 대규모 언어 모델 웹 인터페이스 만들기: Mistral 7B와의 대화

    안녕하세요. 오늘은 내 컴퓨터에서 웹 인터페이스로 최신 언어모델과 대화하는 프로젝트에 도전해 보겠습니다. 이 블로그에서는 Ollama라는 오픈소스 도구를 이용해서 최신 인기 대규모 언어모

    fornewchallenge.tistory.com

     

    728x90