본문 바로가기
AI 도구

🦙Ollama를 활용한 LLAMA3 RAG 시스템 구현하기

by James AI Explorer 2024. 4. 22.

목차

    728x90

    안녕하세요! 오늘은 새로운 오픈소스 언어 모델의 최강자 LLAMA 3를 활용한 RAG 시스템을 구현해 보겠습니다. RAG(Retrieval-Augmented Generation, 검색 강화 생성) 외부 지식소스 검색을 통해 정보를 얻고, 이를 바탕으로 답변을 생성함으로써, 언어모델이 환각현상이나 부정확한 답변을 하지 않도록 보장하는 기술인데요, 이 블로그에서는 사용자가 제공한 URL에서 문서를 검색하고, 임베딩과 Chroma 벡터스토어를 거쳐서 LLAMA 3 모델을 통해 사용자의 질문에 대답하는 Gradio 앱을 만들어보겠습니다. 

    Ollama를 활용한 LLAMA3 RAG 시스템

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

    프로그램 개요

    이 프로그램은 주어진 URL에서 웹 페이지를 로드하고, 분할한 각 문장에 대한 임베딩을 생성하며, 이를 Chroma 벡터스토어에 저장한 후, Ollama에 탑재한 LLAMA 3 모델을 사용하여 질문에 대한 답변을 생성하며, Gradio를 통해 사용자에게 인터페이스를 제공합니다. 다음은 프로그램의 기능별 사용도구를 나타낸 표입니다.

    구분 주요기능  사용 도구
    텍스트 분할 입력된 텍스트를 재귀적으로 분할하여
    더 작은 단위로 나누는 기능을 수행합니다.
    RecursiveCharacterTextSplitter
    임베딩 모델 텍스트나 문장을 고차원 벡터 공간에 매핑하여
    의미론적 정보를 담는 임베딩을 생성하는 모델입니다.
    Ollama: mxbai-embed-large
    벡터 스토어 텍스트에 대한 임베딩을 저장하고 관리하는 저장소로,
    검색과 유사성 측정을 위해 사용됩니다.
    Chroma 벡터스토어
    언어 모델 주어진 텍스트에서 문맥을 이해하고 답변을 생성하는 모델로,
    자연어 처리 작업에 활용됩니다.
    Ollama: LLAMA 3 8B
    사용자 인터페이스 사용자와 시스템 간의 상호작용을 지원하는 인터페이스로,
    사용자의 입력을 받고 결과를 표시합니다.
    Gradio

     

    위 도구 중에서 RecursiveCharacterTextSplitter는 텍스트를 재귀적으로 분할하는 기능을 수행하는 도구인데요, 이 분할 기능은 다음과 같은 특징을 갖습니다:

    • 재귀적 분할: 재귀적 분할이란 주어진 텍스트를 더 작은 단위로 나누고, 각각의 작은 단위에 대해 동일한 과정을 반복하는 것을 말합니다. 이를 통해 매우 긴 텍스트를 작은 단위로 분할하여 처리할 수 있습니다. 
    • 문장 경계 고려: 텍스트를 분할할 때 문장 경계를 고려하므로, 각 분할된 단위는 완전한 문장으로 구성될 수 있습니다.
    • 유연성: 분할할 단위의 크기와 중첩 부분의 크기를 조절할 수 있습니다. 여기서는 1000개의 문자로 분할합니다.
    • 텍스트 전처리: 분할된 텍스트에 대해 특수 문자 제거, 대소문자 변환 등의 필요한 전처리를 수행할 수 있습니다. 

    RecursiveCharacterTextSplitter는 특히 매우 긴 텍스트를 작은 단위로 나누어 처리해야 할 때 유용한 도구입니다. 

     

    이 프로그램에서 사용되는 임베딩 모델인 mxbai-embed-large는 Mixedbread AI에서 개발한 영어 임베딩 모델로, 텍스트를 고차원 벡터 공간에 매핑하여 의미론적 정보를 포함하는 임베딩을 생성하며, 주요 특징은 다음과 같습니다:

    • 최신 고성능 모델: 2024년 3월 기준으로 같은 크기 클래스의 오픈 소스 모델 중에서 Massive Text Embedding Benchmark (MTEB)와 같은 벤치마크에서 최고의 성능을 발휘합니다.
    • 다양한 활용: 정보 검색, 분류, 군집화, 쌍 분류, 재랭킹, 검색 등 다양한 작업에 사용할 수 있습니다.
    • 효율적인 사용: 검색을 위한 별도의 사용자 정의 코드나 원격 코드가 필요하지 않으며, 설치와 사용이 간편합니다.
    • 학습 데이터: 모델은 다양한 주제와 도메인의 학습 데이터를 경험하여, 실제 환경 및 RAG과 관련된 사용 사례에 대해 높은 성능을 발휘합니다.

    RAG(검색 강화 생성) 시스템의 답변 정확도는 사용되는 임베딩 모델의 성능에 직접적으로 영향을 받습니다. 임베딩 모델은 텍스트를 고차원 벡터 공간에 매핑하여 의미론적 정보를 담은 임베딩을 생성하는데, RAG 시스템에서는 이 임베딩을 답변을 생성하는 데 사용됩니다.

     

    임베딩 모델의 성능이 높을수록 텍스트의 의미론적 유사성을 더 잘 파악할 수 있으며, RAG 시스템이 외부 지식소스에서 적합한 정보를 검색하고 답변을 생성하는 데 더욱 정확하고 신속하게 작동할 수 있습니다. 따라서 RAG 시스템을 구현할 때는 임베딩 모델의 성능을 신중하게 고려하여야 하며, 최신이고 고품질의 임베딩 모델을 선택하여 시스템의 정확도와 효율성을 높이는 것이 중요합니다.

     

    환경설정 및 모델 다운로드

    이 블로그에서 사용한 예제코드의 실행환경은 Windows 11 Pro(23H2),  파이썬 버전 3.11, 코드 에디터는 비주얼 스튜디오 코드(이하 VSC)입니다. 먼저 윈도우 명령프롬프트에서 "conda create -n llama3rag python=3.11 -y" 명령으로 가상환경을 생성하고 "conda activate llama3rag" 명령으로 활성화합니다. llama3rag 가상환경 이름은 원하는 이름으로 수정할 수 있습니다. 

    conda를 이용한 가상환경 생성

    다음은 의존성 설치단계입니다. 가상환경이 활성화된 상태에서 아래 코드를 복사하여 실행합니다. 

    pip install ollama langchain beautifulsoup4 chromadb gradio

    가상환경 활성화 및 의존성 설치

    위 단계에서 설치되는 라이브러리의 기능은 다음과 같습니다. 

    라이브러리 주요 기능
    ollama Ollama 라이브러리는 언어 모델 관리 및 자연어 처리 작업을 위한 다양한 모델과 함수를 제공합니다.
    langchain Langchain은 텍스트 분할 및 처리를 위한 라이브러리입니다.
    beautifulsoup4 BeautifulSoup4는 HTML 및 XML 문서를 파싱하고 구문 분석하는 데 사용됩니다.
    chromadb Chromadb는 문서 및 텍스트 데이터를 저장하고 관리하기 위한 벡터 스토어를 구현하는 데 사용됩니다.
    gradio Gradio는 간단하게 웹 브라우저 기반의 사용자 인터페이스를 구축할 수 있는 도구입니다.

     

    다음은  "ollama pull" 명령어를 통해 LLAMA 3 언어 모델과 mxbai-embed-large 임베딩 모델을 다운로드합니다. 

    LLAMA 3  언어모델 다운로드
    mxbai-embed-large 임베딩 모델 다운로드

    반응형

    코드작성 및 실행

    다음은 코드작성 및 실행단계입니다. 이 코드의 출처는 유튜브 "Llama 3 RAG: How to Create AI App using Ollama?"이며, 한국어로 대답하도록 시스템 프롬프트를 수정하고, 임베딩 모델을 mxbai-embed-large로 변경하였습니다. 

    예제코드는 다음과 같은 기능으로 구현됩니다.

    • `load_and_retrieve_docs(url)`: 이 함수는 주어진 URL에서 웹 페이지를 로드하고, 이를 문서로 변환하고, 문서를 적절한 크기로 분할한 후 분할된 문장들에 대해 Ollama의 mxbai-embed-large 임베딩 모델을 사용하여 각각의 문장에 대한 의미론적 임베딩을 생성합니다.
    • Chroma 벡터스토어 생성: Chroma 벡터스토어는 각 문장의 임베딩을 저장하는 데 사용됩니다. 이를 통해 문맥을 이해하고 질문에 적합한 문장을 검색하는 데 사용됩니다.
    • `format_docs(docs)`: 이 함수는 검색된 문서를 올바른 형식으로 포맷합니다. 각 문서의 내용을 하나의 문자열로 결합하여 반환합니다.
    • `rag_chain(url, question)`: 이 함수는 위의 두 함수를 사용하여 주어진 URL과 질문에 대한 답변을 생성합니다. 먼저 `load_and_retrieve_docs` 함수를 사용하여 문서를 검색하고, 그 결과를 `format_docs` 함수를 통해 포맷합니다. 그런 다음, LLAMA 3 모델을 사용하여 포맷된 질문과 문맥을 제공하여 답변을 생성합니다. 이 답변은 시스템 프롬프트에 따라 한국어로 번역되어 이모지와 함께 반환됩니다.
    • Gradio 인터페이스 설정: 위의 함수를 사용하여 Gradio 인터페이스를 설정합니다. 이 인터페이스는 사용자에게 URL과 질문을 입력하고, 그에 대한 답변을 반환합니다.
    • `iface.launch()`: 이 코드는 Gradio를 사용하여 설정된 인터페이스를 실행합니다.

    VSC에서 새 파이썬 파일을 생성하고 아래 코드를 복사하여 붙여 넣습니다. 

    import gradio as gr
    import bs4
    from langchain.text_splitter import RecursiveCharacterTextSplitter
    from langchain_community.document_loaders import WebBaseLoader
    from langchain_community.vectorstores import Chroma
    from langchain_community.embeddings import OllamaEmbeddings
    import ollama
    
    # Function to load, split, and retrieve documents
    def load_and_retrieve_docs(url):
        loader = WebBaseLoader(
            web_paths=(url,),
            bs_kwargs=dict() 
        )
        docs = loader.load()
        text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
        splits = text_splitter.split_documents(docs)
        embeddings = OllamaEmbeddings(model="mxbai-embed-large")
        vectorstore = Chroma.from_documents(documents=splits, embedding=embeddings)
        return vectorstore.as_retriever()
    
    # Function to format documents
    def format_docs(docs):
        return "\n\n".join(doc.page_content for doc in docs)
    
    # Function that defines the RAG chain
    def rag_chain(url, question):
        retriever = load_and_retrieve_docs(url)
        retrieved_docs = retriever.invoke(question)
        formatted_context = format_docs(retrieved_docs)
        formatted_prompt = f"Question: {question}\n\nContext: {formatted_context}"
        response = ollama.chat(model='llama3', 
                               messages=[
                                    {"role": "system",
                                     "content": "You are a helpful assistant. Check the url content and answer the question. Translate the answer in Korean with emoji."
                                    },
                                    {"role": "user", "content": formatted_prompt}])
        return response['message']['content']
    
    # Gradio interface
    iface = gr.Interface(
        fn=rag_chain,
        inputs=["text", "text"],
        outputs="text",
        title="LLAMA 3: RAG Chain Question Answering",
        description="Enter a URL and a query to get answers from the RAG chain."
    )
    
    # Launch the app
    iface.launch()

     

    코드를 실행하면 http://127.0.0.1:7860 주소에서 아래 화면과 같이 Gradio 인터페이스가 열립니다. 

    예제 코드 실행 화면
    예제 코드 실행 초기화면

    다음은 url 텍스트 상자에 웹페이지의 주소를 입력하고, 질문을 입력하면 시스템 프롬프트에 따라 아래 화면과 같이 한국어로 이모지와 함께 응답이 출력됩니다. LLAMA 3의 한국어 번역기능은 일본어가 몇 자 보이지만 문제가 되진 않습니다. 

    url 내용 관련 질문에 대한 LLAMA3의 응답화면 1
    url 내용 관련 질문에 대한 LLAMA3의 응답화면 2
    url 내용 관련 질문에 대한 LLAMA3의 응답화면 3

    위 예시 화면과 같이 Ollama의 윈도우 프리뷰 버전 공개 웹 사이트의 내용에 대해 정확한 답변을 얻을 수 있었습니다. 

     

     

     

     

    맺음말

    이 블로그에서는 새로운 오픈소스 언어 모델인 LLAMA 3를 활용해서 RAG시스템을 구현하는 방법을 살펴보았습니다. RAG는 외부 지식소스 검색을 통해 정보를 얻고, 이를 바탕으로 답변을 생성하여 언어모델이 부정확한 답변을 하지 않도록 보장하는 기술입니다. 이를 위해 웹 페이지에서 문서를 검색하고, 임베딩과 Chroma 벡터스토어를 거쳐 LLAMA 3 모델을 활용하여 사용자의 질문에 대답하는 Gradio 앱을 만들어보았습니다.

     

    RAG 시스템의 정확도는 사용되는 임베딩 모델의 성능에 직접적으로 영향을 받습니다. 임베딩 모델이 높은 성능을 보일수록 시스템은 외부 지식을 더 잘 이해하고 적절한 답변을 생성할 수 있습니다. 따라서 최신의 고품질 임베딩 모델을 선택하는 것이 중요합니다.

     

    오늘 블로그 내용은 여기까지입니다. 저는 다음에 더 유익한 정보를 가지고 다시 찾아뵙겠습니다. 감사합니다. 

     

    https://fornewchallenge.tistory.com/

     

     

    2024.04.21 - [대규모 언어모델] - [Llama 3 70B] Groq을 활용한 함수 호출 및 API 통합! NBA 게임 및 주식 정보 실시간 조회

     

    [Llama 3 70B] Groq을 활용한 함수 호출 및 API 통합! NBA 게임 및 주식 정보 실시간 조회

    안녕하세요! 이번주 가장 핫한 대형 언어 모델은 Llama3인데요. 오늘은 Groq을 활용해서 Llama 3 함수 호출 및 API 통합을 해보겠습니다. 이 프로그램은 사용자가 Gradio 웹 인터페이스를 통해 NBA 게임결

    fornewchallenge.tistory.com

     

    반응형