이전 내용
그라디오와 랭체인을 활용해 음성 인식봇, 문서 요약봇, 일정 관리봇을 제작해 본다.
문서 요약봇 제작하기
◆ 문서 요약봇 레이아웃 구성하기
탭을 제외한 문서 요약봇의 레이아웃은 아래와 같이 세로로 4블록이 쌓여 있고 각각 하나의 row로 구성되어 있다. 나중을 위해 각각의 row로 컴포넌트를 설정한다.
with.gr.Tab("음성 인식봇"):
....
with gr.Tab("문서 요약봇"):
with gr.Row():
#1
gr.Markdown()
with gr.Row():
#2
gr.File()
with gr.Row():
#3
gr.Button()
with gr.Row():
#4
gr.Textbox()
- 문서 요약봇의 타이틀 및 설명
마크다운을 이용해 문서 요약봇의 헤드라인을 지정해 주고, 하나씩 컴포넌트를 추가하며 레이아웃을 완성시켜 나간다.
gr.Markdown(
value="""
# <center>문서 요약봇</center>
<center> AI 인공지능 비서 DUDE 입니다. PDF를 업로드하면 내용을 번역해 드립니다.</center>
"""
)
- PDF 파일 업로드 컴포넌트 구현
해당 컴포넌트는 앞서 뼈대를 구성하는 코드에서 gr.File()을 통해 추가되었다.
- 버튼 및 요약 결과 출력 구현
PDF 요약된 텍스트 출력을 위한 텍스트 컴포넌트와 [제출] 버튼을 추가한다.
with gr.Row():
#3
gr.Button(value="문서 요약하기")
with gr.Row():
#4
gr.Textbox(
label="PDF 요약",
placeholder="PDF 요약 내용입니다.",
각 컴포넌트를 추가하고 나면 아래와 같이 된다.
◆ 문서 요약봇 레이아웃 구성하기 - 상세 설정
각각의 컴포넌트에 변수명과 구체적인 매개변수를 설정해 준다.
gr.Textbox 에는 lines=8 매개변수도 추가해 준다.
summary=gr.Textbox(
label="PDF 요약",
lines=8,
placeholder="PDF 요약 내용입니다.",
)
◆ 문서 요약봇 기능 구현하기
- 챗봇 기능 추가
- 문서 내용 읽어오기
- 문서 내용 요약하기 - 랭체인 활용
- 이벤트 리스너 추가하기
랭체인의 필요한 모듈을 import 한다.
from langchain.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.prompts import PromptTemplate
from langchain.chains import MapReduceDocumentsChain
[문서 내용 읽어오기]
기본적인 PDF 문서를 불러오는 함수를 구현한다.
def pdf_loader(pdf_path):
loader=PyPDFLoader(pdf_path)
pdf_doc=loader.load()
return pdf_doc
- loader=PyPDFLoader(pdf_path): pdf_path를 통해 loader 설정
- pdf_doc=loader.load(): load()를 통해 pdf 파일의 내용을 읽어온다.
[문서 내용 요약하기 - 랭체인 활용]
def pdf_bot_chatbot(pdf_path):
pages_content=pdf_loader(pdf_path)
text_splitter=RecursiveCharacterTextSplitter.from_tiktoken_encoder(
chunk_size=3000,
chunk_overlap=0,
)
# pages_content 내용 분할
split_docs=text_splitter.split_documents(pages_content)
# 분할된 문서의 수
# map template 설정, {pages_content} 분할된 내용이 입력
map_template=""" 다음은 문서 중 일부 내용입니다.
{pages_content}
이 문서의 주요 내용을 요약해 주세요.
"""
# map 기본 프롬프트
map_prompt=PromptTemplate.from_template(map_template)
# 문서 내용이 길 수 있기 때문에 model을 gpt-3.5-turbo-16k로 설정
llm=ChatOpenAI(temperature=0,
model_name='gpt-3.5-turbo-16k')
map_chain=LLMChain(llm=llm, prompt=map_prompt)
# reduce 단계에서 처리할 프롬프트 정의
reduce_template="""다음은 문서 요약의 집합입니다.
{summaries}
이 내용을 바탕으로 통합된 문서 요약을 작성해 주세요.
"""
# reduce 프롬프트
reduce_prompt=PromptTemplate.from_template(reduce_template)
# reduce에서 수행할 LLMChain 정의
reduce_chain=LLMChain(llm=llm, prompt=reduce_prompt)
from langchain.chains.combine_documents.stuff import StuffDocumentsChain
from langchain.chains import ReduceDocumentsChain
# 문서 목록 통합 체인 설정
combine_doc_chain=StuffDocumentsChain(
llm_chain=reduce_chain,
document_variable_name="summaries" # reduce 프롬프트에 대입되는 변수
)
# 분할된 문서 순차적으로 Reduce 처리
reduce_doc_chain=ReduceDocumentsChain(
combine_documents_chain=combine_doc_chain,
collapse_documents_chain=combine_doc_chain,
token_max=4000, # 토큰 최대 개수 설정
)
# 최종 체인 연결
final_chain=MapReduceDocumentsChain(
llm_chain=map_chain, # 각 문서 맵핑
reduce_documents_chain=reduce_doc_chain,
document_variable_name="pages_content",
return_intermediate_steps=False,
)
# 최종 결과 실행
result_summary=final_chain.run(split_docs)
# 요약 결과 출력
return result_summary
[이벤트 리스너 추가하기]
문서 요약봇의 이벤트 리스너는 '문서 요약 버튼 클릭' 하나이다.
작성 위치는 app.launch() 바로 위에 작성하면 된다.
summary_btn.click(
fn=pdf_bot_chatbot,
inputs=[pdf_input],
outputs=[summary]
)
문서 요약봇 최종 레이아웃 및 전체 코드
(음성 인식봇 포함)
from langchain.chat_models import ChatOpenAI
from langchain.memory import ConversationBufferWindowMemory
from langchain.prompts import(
ChatPromptTemplate,
MessagesPlaceholder,
SystemMessagePromptTemplate,
HumanMessagePromptTemplate,
)
from langchain.chains import LLMChain
import os
import openai
# 환경변수에서 OpenAI API 키를 읽어옴.
openai_api_key = os.getenv('OPENAI_API_KEY')
# API 키가 환경변수에 설정되어 있는지 확인.
if not openai_api_key:
raise ValueError("환경변수 'OPENAI_API_KEY'가 설정되지 않았습니다.")
# OpenAI API 키를 설정.
openai.api_key = openai_api_key
# OpenAI 클라이언트를 생성.
client = openai.OpenAI()
system_ai_ko = "당신은 인공지능 비서야, pdf 일기, 문서 요약하기, 일정 관리, 날씨, 최단 경로 검색, 웹 검색 등 다양한 내용에 답변할 수 있어야 해."
system_setting = SystemMessagePromptTemplate.from_template(system_ai_ko)
# 프롬프트 설정
voice_bot_prompt = ChatPromptTemplate.from_messages([
system_setting,
MessagesPlaceholder(variable_name="DUDE"),
HumanMessagePromptTemplate.from_template("{master_user}")])
# 메모리 설정
voice_bot_memory = ConversationBufferWindowMemory(memory_key="DUDE",
ai_prefix="AI 비서 DUDE",
human_prefix="사용자:",
return_messages=True,
k=10)
# llm 모델 설정
chatgpt = ChatOpenAI(
temperature=0,
max_tokens=2048,
model_name='gpt-3.5-turbo'
)
# llmchain 정의
conversation=LLMChain(
prompt=voice_bot_prompt,
memory=voice_bot_memory,
llm=chatgpt,
verbose=True
)
from pydub import AudioSegment
import numpy as np
def voice_bot_handle_audio(audio_record):
save_file_path="voice.mp3"
frame_rate=audio_record[0]
audio_data=audio_record[1].tobytes()
sample_width=audio_record[1].dtype.itemsize
audio=AudioSegment(
audio_data,
frame_rate=frame_rate,
sample_width=sample_width,
channels=1,
)
audio.export(save_file_path, format="mp3")
def voice_bot_create_stt():
file_path="voice.mp3"
audio_file=open(file_path, "rb")
transcript=client.audio.transcriptions.create(
model="whisper-1",
file=audio_file)
return transcript.text
def voice_bot_create_audio(text):
response=client.audio.speech.create(
model="tts-1",
voice="onyx",
input=text)
speech_file_path="output.mp3"
with open(speech_file_path, "wb") as audio_file:
audio_file.write(response.content)
def voice_bot_chat(message, cb_user_input_audio, chat_history):
if cb_user_input_audio:
message=voice_bot_create_stt()
ai_answer=conversation({"master_user":message})['text']
chat_history.append((message, ai_answer))
audio_file=voice_bot_create_audio(ai_answer)
return "", audio_file, chat_history
def voice_bot_undo(chat_history):
if len(chat_history) > 1:
chat_history.pop()
return chat_history
def voice_bot_reset(chat_history):
global voice_bot_memory
chat_init=[[None, "안녕하세요, 인공지능 비서 DUDE 입니다. 무엇이든 시켜만 주세요."]]
voice_bot_memory.clear() # 메모리 초기화
return "", chat_init
from langchain.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.prompts import PromptTemplate
from langchain.chains import MapReduceDocumentsChain
def pdf_loader(pdf_path):
loader=PyPDFLoader(pdf_path)
pdf_doc=loader.load()
return pdf_doc
def pdf_bot_chatbot(pdf_path):
pages_content=pdf_loader(pdf_path)
text_splitter=RecursiveCharacterTextSplitter.from_tiktoken_encoder(
chunk_size=3000,
chunk_overlap=0,
)
# pages_content 내용 분할
split_docs=text_splitter.split_documents(pages_content)
# 분할된 문서의 수
# map template 설정, {pages_content} 분할된 내용이 입력
map_template=""" 다음은 문서 중 일부 내용입니다.
{pages_content}
이 문서의 주요 내용을 요약해 주세요.
"""
# map 기본 프롬프트
map_prompt=PromptTemplate.from_template(map_template)
# 문서 내용이 길 수 있기 때문에 model을 gpt-3.5-turbo-16k로 설정
llm=ChatOpenAI(temperature=0,
model_name='gpt-3.5-turbo-16k')
map_chain=LLMChain(llm=llm, prompt=map_prompt)
# reduce 단계에서 처리할 프롬프트 정의
reduce_template="""다음은 문서 요약의 집합입니다.
{summaries}
이 내용을 바탕으로 통합된 문서 요약을 작성해 주세요.
"""
# reduce 프롬프트
reduce_prompt=PromptTemplate.from_template(reduce_template)
# reduce에서 수행할 LLMChain 정의
reduce_chain=LLMChain(llm=llm, prompt=reduce_prompt)
from langchain.chains.combine_documents.stuff import StuffDocumentsChain
from langchain.chains import ReduceDocumentsChain
# 문서 목록 통합 체인 설정
combine_doc_chain=StuffDocumentsChain(
llm_chain=reduce_chain,
document_variable_name="summaries" # reduce 프롬프트에 대입되는 변수
)
# 분할된 문서 순차적으로 Reduce 처리
reduce_doc_chain=ReduceDocumentsChain(
combine_documents_chain=combine_doc_chain,
collapse_documents_chain=combine_doc_chain,
token_max=4000, # 토큰 최대 개수 설정
)
# 최종 체인 연결
final_chain=MapReduceDocumentsChain(
llm_chain=map_chain, # 각 문서 맵핑
reduce_documents_chain=reduce_doc_chain,
document_variable_name="pages_content",
return_intermediate_steps=False,
)
# 최종 결과 실행
result_summary=final_chain.run(split_docs)
# 요약 결과 출력
return result_summary
import gradio as gr
with gr.Blocks() as app:
with gr.Tab("음성 인식봇"):
with gr.Column():
#1
gr.Markdown(
value="""
# <center>음성 인식봇</center>
<center>AI 인공지능 비서 DUDE 입니다.
음성으로 묻거나, 문서 요약, 일정 관리를 할 수 있습니다.</center>
"""
)
#2
cb_chatbot=gr.Chatbot(
value=[[None, "안녕하세요, 인공지능 비서 DUDE 입니다. 무엇이든 시켜만 주세요."]],
show_label=False
)
with gr.Row():
#3
cb_user_input=gr.Textbox(
lines=1,
placeholder="입력 창",
container=False,
scale=7
)
#4
cb_audio_record=gr.Audio(
sources=["microphone"],
format="mp3",
scale=1,
min_width=200,
label="음성을 입력해 주세요."
)
# 음성 출력
cb_audio_chatbot=gr.Audio(autoplay=True,
visible=False)
#5
cb_submit_btn=gr.Button(
value="보내기",
scale=1,
visible="primary",
icon="https://cdn-icons-png.flaticon.com/128/12439/12439334.png"
)
# 음성 녹음 완료
cb_audio_record.stop_recording(
fn=voice_bot_handle_audio,
inputs=[cb_audio_record]
)
# [보내기] 버튼 클릭
cb_submit_btn.click(
fn=voice_bot_chat,
inputs=[cb_user_input, cb_audio_record, cb_chatbot],
outputs=[cb_user_input, cb_audio_record, cb_chatbot]
)
# ENTER 제출 입력
cb_user_input.submit(
fn=voice_bot_chat,
inputs=[cb_user_input, cb_audio_record, cb_chatbot],
outputs=[cb_user_input, cb_audio_record, cb_chatbot]
)
with gr.Row():
#6
gr.Button(value="↪️되돌리기").click(
fn=voice_bot_undo,
inputs=[cb_chatbot],
outputs=[cb_chatbot]
)
#7
gr.Button(value="🔄️초기화").click(
fn=voice_bot_reset,
inputs=[cb_chatbot],
outputs=[cb_chatbot]
)
with gr.Tab("문서 요약봇"):
with gr.Row():
#1
gr.Markdown(
value="""
# <center>문서 요약봇</center>
<center> AI 인공지능 비서 DUDE 입니다. PDF를 업로드하면 내용을 번역해 드립니다.</center>
"""
)
with gr.Row():
#2
pdf_input=gr.File()
with gr.Row():
#3
summary_btn=gr.Button(value="문서 요약하기")
with gr.Row():
#4
summary=gr.Textbox(
label="PDF 요약",
lines=8,
placeholder="PDF 요약 내용입니다.",
)
summary_btn.click(
fn=pdf_bot_chatbot,
inputs=[pdf_input],
outputs=[summary]
)
app.launch()
다음에는 일정 관리봇을 제작해 본다.
다음 내용
[출처]
Hey, 파이썬! 생성형 AI 활용 앱 만들어줘
'[파이썬 Projects] > <파이썬 Gen AI>' 카테고리의 다른 글
[Gen AI] 스테이블 디퓨전 API (이 아닌 stability.ai API 사용법) (1) | 2024.12.22 |
---|---|
[Gen AI] 그라디오로 두 번째 챗봇 제작하기-3 (1) | 2024.12.21 |
[Gen AI] 그라디오로 두 번째 챗봇 제작하기-1 (1) | 2024.12.20 |
[Gen AI] 문서 요약 프롬프트 제작 (1) | 2024.12.20 |
[Gen AI] 음성 변환 기술 구현해보기(STT, TTS) (1) | 2024.12.19 |