티스토리 뷰

 

첫번째 섹션

간단한 챗봇 만들기

 

RAG구현은 방식이 아닌

챗GPT모델을 가져와서 만드는 챗봇입니다

 

!pip install langchain
!pip install streamlit
!pip install openai
!pip install langchain_community

 

 

먼저

아나콘다 가상환경에 langchain, streamlit, openai 를 설치해줍니다

 

 

 

그리고 챗봇 코드 작성

 

import streamlit as st
from langchain.chat_models import ChatOpenAI
st.set_page_config(page_title="무엇이든 질문하세요~")
st.title('무엇이든 질문하세요~')

import os
os.environ["OPENAI_API_KEY"] = "sk-"

def generate_response(input_text): # llm 답변 생성
    llm = ChatOpenAI(temperature=0.5,
                     model_name='gpt-4')
    st.info(llm.predict(input_text))

with st.form('Question'):
    text = st.text_area('질문 입력:', 'What types of text models does OpenAI provode?') # 첫페이지에서의 질문
    submitted = st.form_submit_button('보내기')
    generate_response(text)

 

 

temperature - 답변의 유연성 (0.5~0.7이 좋다고함)

 

 

e.g. My favorite animal is ___  를 여러번 시도했을때

 

temperature가 0 인 경우

My favorite animal is dog.

My favorite animal is dog.

My favorite animal is dog.

 

temperature가 1 인 경우

My favorite animal is dragon.

My favorite animal is tiger.

My favorite animal is cat.

 

https://algowriting.medium.com/gpt-3-temperature-setting-101-41200ff0d0be

 

 

 

그리고 streamlit은 주피터 노트북이 아닌 아래의 방법으로 실행해야함

 

 

 

 

 

해당 파일을 anaconda 가상환경 설치된 경로에 위치시킴 (제 경우 /Users/jh 여기 있었음)

 

그리고 터미널에서 아래 코드로 실행하면

streamlit run 파일이름.py

 

 

 

streamlit로 실행하는 Chat GPT 챗봇

잘 나오는 모습

 

 


 

 

 

두번째 섹션

랭체인과 챗GPT로 RAG기반의 챗봇 서비스 만들기

 

 

먼저 라이브러리 설치를 합니다

 

!pip install unstructured # 텍스트 파일 같은 구조화 되지 않은 데이터를 다룸
!pip install sentence-transformers # 문장을 벡터로 변환, 텍스트 유사성 계산
!pip install chromadb # 벡터를 저장하고 유사도 검색 지원
!pip install openai

 

 

 

그리고 https://github.com/gilbutITbook/080413 여기서 텍스트파일 가져옵니다.

 

from langchain.document_loaders import TextLoader
documents = TextLoader("/Users/jh/AI.txt").load()

 

가져온 텍스트 파일을 불러오고,

 

 

RecursiveCharacterTextSplitter를 사용하여 문장을 청크로 분할합니다.

from langchain.text_splitter import RecursiveCharacterTextSplitter

# 문서를 청크로 분할
def split_docs(documents,chunk_size=1000,chunk_overlap=20):
  text_splitter = RecursiveCharacterTextSplitter(chunk_size=chunk_size, chunk_overlap=chunk_overlap)
  docs = text_splitter.split_documents(documents)
  return docs

# docs 변수에 분할 문서를 저장
docs = split_docs(documents)

 

 

 

벡터 디비에 임베딩 처리된 벡터를 저장해줍니다.

#OpenAI의 임베딩 모델 사용
from langchain_openai import OpenAIEmbeddings
api_key="sk-"
embeddings = OpenAIEmbeddings(model="text-embedding-ada-002", api_key=api_key)

# Chromdb에 벡터 저장, /Users/jh/verctorDB -> 저장장소 알아서 설정
from langchain.vectorstores import Chroma
db = Chroma.from_documents(docs, embeddings, persist_directory="/Users/jh/verctorDB")

 

 

 

그리고

AI.txt 를 벡터화 한 벡터 디비를 가져와서 질문을 던집니다.  -> db.similarity_search(query) 

 

 

from langchain.chat_models import ChatOpenAI
model_name = "gpt-3.5-turbo"  #GPT-3.5-turbo 모델 사용
llm = ChatOpenAI(model_name=model_name, api_key=api_key)

# Q&A 체인을 사용하여 쿼리에 대한 답변 얻기
from langchain.chains.question_answering import load_qa_chain
chain = load_qa_chain(llm, chain_type="stuff",verbose=True)

# 쿼리를 작성하고 유사성 검색을 수행하여 답변을 생성,따라서 txt에 있는 내용을 질의해야 합니다
query = "AI란?"
matching_docs = db.similarity_search(query)
answer =  chain.run(input_documents=matching_docs, question=query)
answer

 

 

그러고 코드를 실행해주면,

 

 

 

 

'AI란 어쩌고 저쩌고' 답변이 나오는 모습

 

 

 


 

 

 

세번째 섹션

PDF 요약해주는 웹 사이트 만들기

 

 

 

먼저 라이브러리 설치 갈겨줍니다

 

!pip install langchain
!pip install streamlit
!pip install PyPDF2 # pdf 읽기, 분할, 병합, 순서변경, 추가, 암호화 작업 하는 라이브러리
!pip install langchain-openai
!pip install sentence-transformers
!pip install faiss-cpu # 대용량 벡터 검색 라이브러리

 

 

 

그리고

사용자가 업로드한 PDF 파일을

청크로 분할 -> 임베딩 처리

이후 LLM에게 요약하라고 쿼리를 던지는 코드를 작성하여 실행합니다

 

 

import os
from PyPDF2 import PdfReader
import streamlit as st
from langchain.text_splitter import CharacterTextSplitter
from langchain_openai import OpenAIEmbeddings
from langchain import FAISS
from langchain.chains.question_answering import load_qa_chain
from langchain.chat_models import ChatOpenAI
from langchain.callbacks import get_openai_callback
api_key="sk-"

def process_text(text): 
#CharacterTextSplitter를 사용하여 텍스트를 청크로 분할
    text_splitter = CharacterTextSplitter(
        separator="\n",
        chunk_size=1000,
        chunk_overlap=200,
        length_function=len
    )
    chunks = text_splitter.split_text(text)

    #임베딩 처리(벡터 변환), 임베딩은 OpenAI 모델을 사용합니다.
    embeddings = OpenAIEmbeddings(model="text-embedding-ada-002", api_key=api_key)
    documents = FAISS.from_texts(chunks, embeddings)
    return documents

def main():  #streamlit을 이용한 웹사이트 생성
    st.title("📄PDF 요약하기")
    st.divider()

    pdf = st.file_uploader('PDF파일을 업로드해주세요', type='pdf')

    if pdf is not None:
        pdf_reader = PdfReader(pdf)
        text = ""   # 텍스트 변수에 PDF 내용을 저장
        for page in pdf_reader.pages:
            text += page.extract_text()

        documents = process_text(text)
        query = "업로드된 PDF 파일의 내용을 약 3~5문장으로 요약해주세요."  # LLM에 PDF파일 요약 요청

        if query:
            docs = documents.similarity_search(query)
            llm = ChatOpenAI(model="gpt-3.5-turbo-16k", api_key=api_key, temperature=0.1)
            chain = load_qa_chain(llm, chain_type='stuff')

            with get_openai_callback() as cost:
                response = chain.run(input_documents=docs, question=query)
                print(cost)

            st.subheader('--요약 결과--:')
            st.write(response)

if __name__ == '__main__':
    main()

 

 

 

streamlit 기반 실행 방법은 맨위 참고

 

 

 

streamlit run 파일이름.py 실행해주면

 

 

 

 

 

2장짜리 pdf를 4줄로 요약해주는 모습

 

 

 


 

 

 

네번째 섹션

독립형 질문 챗봇 만들기 (PDF읽고 답변해줌)

 

 

 

우선 pdf를 읽는 라이브러리를 포함하여

 

!pip install langchain
!pip install streamlit
!pip install PyPDF2
!pip install langchain-openai

 

 

이렇게 install 합니다.

 

 

 

import streamlit as st 
from PyPDF2 import PdfReader
from langchain_openai import OpenAIEmbeddings
from langchain.chat_models import ChatOpenAI
from langchain.chains import ConversationalRetrievalChain, RetrievalQA
from langchain.memory import ConversationBufferWindowMemory
from langchain.vectorstores import FAISS
from langchain.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter

api_key="sk-"

 

 

설치한 라이브러리를 가져오도록 합니다

 

 

 

 

#PDF 문서에서 텍스트를 추출
def get_pdf_text(pdf_docs):
    text = ""
    for pdf in pdf_docs:
        pdf_reader = PdfReader(pdf)
        for page in pdf_reader.pages:
            text += page.extract_text()
    return text

#지정된 조건에 따라 주어진 텍스트를 더 작은 덩어리로 분할
def get_text_chunks(text):
    text_splitter = RecursiveCharacterTextSplitter(
        separators="\\n",
        chunk_size=1000,
        chunk_overlap=200,
        length_function=len
    )
    chunks = text_splitter.split_text(text)
    return chunks

#주어진 텍스트 청크에 대한 임베딩을 생성하고 FAISS를 사용하여 벡터 저장소를 생성
def get_vectorstore(text_chunks):
    embeddings = OpenAIEmbeddings(model="text-embedding-ada-002", api_key=api_key)
    vectorstore = FAISS.from_texts(texts=text_chunks, embedding=embeddings)
    return vectorstore

 

1. pdf에서 텍스트를 추출하는 코드

2. 추출한 text를 작은 덩어리로 분할합니다

3. 분할한 텍스트 데이터들을 임베딩하고 FAISS로 벡터DB에 저장하는 코드를 작성합니다

 

 

 

 

#주어진 벡터 저장소로 대화 체인을 초기화
def get_conversation_chain(vectorstore):
    memory = ConversationBufferWindowMemory(memory_key='chat_history', return_message=True)  #ConversationBufferWindowMemory에 이전 대화 저장
    conversation_chain = ConversationalRetrievalChain.from_llm(
        llm=ChatOpenAI(temperature=0, model_name='gpt-4o', api_key=api_key),
        retriever=vectorstore.as_retriever(),
        get_chat_history=lambda h: h,
        memory=memory
    ) #ConversationalRetrievalChain을 통해 langchain 챗봇에 쿼리 전송
    return conversation_chain

 

주고 받은 대화를 ConversationBufferWindowMemory에 저장하고

저장한 chain 형태의 대화를 쿼리에 전송합니다.

 

 

 

 

PDF 업로드 기능 + 버튼(st.button), 그리고 업로드 된 PDF를 처리하는 코드

user_uploads = st.file_uploader("파일을 업로드해주세요~", accept_multiple_files=True)
if user_uploads is not None:
    if st.button("Upload"):
        with st.spinner("처리중.."):
            # PDF 텍스트 가져오기
            raw_text = get_pdf_text(user_uploads)
            # 텍스트에서 청크 검색
            text_chunks = get_text_chunks(raw_text)
            # PDF 텍스트 저장을 위해 FAISS 벡터 저장소 만들기
            vectorstore = get_vectorstore(text_chunks)
            # 대화 체인 만들기
            st.session_state.conversation = get_conversation_chain(vectorstore)

 

 

 

그리고 스트림 릿 라이브러리로 웹화면을 구성해줍니다

if user_query := st.chat_input("질문을 입력해주세요~"):
    # 대화 체인을 사용하여 사용자의 메시지를 처리
    if 'conversation' in st.session_state:
        result = st.session_state.conversation({
            "question": user_query, 
            "chat_history": st.session_state.get('chat_history', [])
        })
        response = result["answer"]
    else:
        response = "먼저 문서를 업로드해주세요~."
    with st.chat_message("assistant"):
        st.write(response)

 

 

그리고 streamlit run pdf_query.py 하면

 

 

 

 

잘 나오는 모습

 

pdf 업로드 이후 질문도 잘 되네요

 

댓글