이전 내용
그라디오로 두 번째 챗봇 제작하기
위스퍼(Whisper) 음성 인식봇과 문서 요약봇, 일정 관리봇을 만들어 본다.
진행 순서는 레이아웃 구성 ▶ 기능 구성 ▶ 최종 컴포넌트 연결 순으로 진행된다.
레이아웃 구성
제일 상단에 공통적으로 등장하는 음성 인식봇, PDF 문서 요약, 일정 관리봇은 탭, 각 탭을 클릭하면 해당 탭과 일치하는 기능을 가진 메인 화면으로 레이아웃이 변경될 수 있도록 구성한다.
1. 음성 인식봇
음성 인식봇에는 음성을 입력하는 입력 창이 있고, 출력은 텍스트와 음성으로 출력되도록 한다. 상단에는 메시지를 주고받는 듯한 메시지 화면을 구성하고 아래에는 문의를 하기 위한 입력 창, 문의 내용을 보내기 위한 버튼, 답변 삭제, 채팅 내역 초기화 기능들을 배치한다.
2. 문서 요약봇
문서는 PDF 문서 요약을 기본으로 입력받을 수 있도록 하고 문서 요약에 필요한 부분만 구성한다. 문서 요약 내용을 하단에 배치하여 문서 요약 결과를 얻을 수 있도록 배치한다.
3. 일정 관리봇
채팅으로 일정을 추가하거나 전체 일정을 확인할 수 있도록 구성한다. 하단에 사용자의 엑셀 파일을 업로드하여 전체 일정을 추가한 상태로 진행할 수 있다.
음성 인식봇 제작하기
◆ 레이아웃 구성하기
import gradio as gr
with gr.Blocks() as app:
with gr.Tab("음성 인식봇"):
with gr.Column():
#1
gr.Markdown()
#2
gr.Chatbot()
with gr.Row():
#3
gr.Textbox()
#4
gr.Audio()
#5
gr.Button()
with gr.Row():
#6
gr.Button()
#7
gr.Button()
app.launch()
그리고 컴포넌트를 하나씩 추가한다.
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
gr.Chatbot(
value=[[None, "안녕하세요, 인공지능 비서 DUDE 입니다. 무엇이든 시켜만 주세요."]],
show_label=False
)
with gr.Row():
#3
gr.Textbox(
lines=1,
placeholder="입력 창",
container=False,
scale=7
)
#4
gr.Audio(
sources=["microphone"],
format="mp3",
scale=1,
min_width=200,
label="음성을 입력해 주세요."
)
#5
gr.Button(
value="보내기",
scale=1,
visible="primary",
icon="https://cdn-icons-png.flaticon.com/128/12439/12439334.png"
)
with gr.Row():
#6
gr.Button(value="↪️되돌리기"
)
#7
gr.Button(value="🔄️초기화")
app.launch()
◆ 레이아웃 상세 설정
기본적인 레이아웃 구성이 끝났으므로, 각각의 컴포넌트에 구체적인 매개변수를 작성하여 최종 레이아웃을 구성해 본다.
- #4: gr.Audio()의 매개변수 source에는 리스트의 형태로 입력받을 수 있는 음성의 형태를 정할 수 있다. microphone은 마이크를 통해 음성 입력을 받을 수 있도록 하였다.
- format은 mp3, wav 같은 파일의 확장자를 선택할 수 있다.
- # 음성출력: autoplay=True 는 추후 인공지능의 답변이 완성되었을 때 변환된 인공지능 음성 결과가 있을 경우, 자동 재생되도록 설정하였다.
◆ 기능 구현하기
채팅 내역은 랭체인을 통해 다음과 같이 구성된다.
- 프롬프트 설정
- 메모리 설정
- llm 모델 설정
- langchain 설정
- 프롬프트 설정
프롬프트에서는 시스템 프롬프트 설정과 메시지 내용을 저장할 메모리 변수를 설정하게 되며, 입력받는 유저의 메시지 변수명도 설정하게 된다.
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}")])
- system_ai_ko: 시스템 메시지로 사용될 프롬프트 설정. 이 부분을 통해 인공지능 비서의 역할과 능력을 설정하는 역할 수행
- system_setting: 최종적인 시스템 메시지. 역할 부여 기능 수행
- MessagesPlaceholder: 앞으로 사용될 메모리 설정. variable_name="DUDE" 와 같이 추후 나올 ConversationBufferMemory의 memory_key와 동일하게 설정해야 한다.
- HumanMessagePromptTemplate: master_user 변수는 추후 설정할 input 변수명과 동일해야 한다.
- 메모리 설정
# 메모리 설정
voice_bot_memory = ConversationBufferWindowMemory(memory_key="DUDE",
ai_prefix="AI 비서 DUDE",
human_prefix="사용자:",
return_messages=True,
k=10)
- memory_key: 앞서 MessagesPlaceholder의 값과 일하게 설정해야 채팅 내역을 메모리에 저장할 수 있다.
- ai_prefix: 인공지능의 명칭 설정
- user_prefix: 사용자의 명칭 설정
- llm 모델 설정
# llm 모델 설정
chatgpt = ChatOpenAI(
temperature=0,
max_tokens=2048,
model_name='gpt-3.5-turbo'
)
- conversaion 객체 생성
프롬프트와 메모리 설정, llm 모델 설정을 이용한다.
# llmchain 정의
conversation=LLMChain(
prompt=voice_bot_prompt,
memory=voice_bot_memory,
llm=chatgpt,
verbose=True
)
◆ 챗봇 기능추가
- 입력 음성을 음성 파일로 저장하기
- 음성 입력 텍스트 변환하기
- 인공지능 답변 음성 변환하기
- 이벤트 리스너 추가하기
- 음성 인식봇 음성 답변 구현하기
- 챗봇 되돌리기 구현하기
- 챗봇 초기화 구현하기
- 입력 음성을 음성 파일로 저장하기
먼저 pydub과 numpy 라이브러리가 필요하므로 해당 라이브러리가 없다면 이를 먼저 설치한다.
pip install pydub
pip install numpy
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")
- audio_record: 입력으로 받게 되는 auido_record는 [frame_rate, numpy_array] 리스트 형태를 가짐
- save_file_path: 임시 음성 파일 저장 경로
- frame_rate, audio_data, sample_width: 각 음성 파일의 프레임 수와 데이터 그리고 그 길이 의미. 파일을 저장하기 위해 필요한 매개변수
- AudioSegment(): 각각의 오디오 파일 데이터를 입력값으로 받아 저장할 수 있는 객체 생성
- audio.export(): 오디오 파일 객체를 오디오 파일로 저장
- 음성 입력 텍스트 변환하기
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
- audio_file=open(file_path, "rb"): 변환하고자 하는 파일 저장
- transcript=client.audio.transcriptions.create(model="whisper-1", file=audio_file): transcriptions.create 메서드를 통해 음성 변환 작업을 할 수 있다. model과 오디오 파일을 저장하여 변환 (위스퍼 모델 사용)
- return transcript.text: 최종 결과는 transcript 객체의 변환된 텍스트를 결괏값으로 받음.
- 인공지능 답변 음성 변환하기
텍스트를 오디오로 변환하는 작업은 OpenAI의 TTS 모델을 사용한다.
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
- if cb_user_input_audio: message=voice_bot_create_stt(): 만약 음성 입력값이 있을 때는 입력값을 voice_bot_create_stt()를 통해 음성을 입력으로 받고, 음성 입력 값이 없을 때는 채팅으로 입력한 값을 받는다.
- ai_answer=conversation({"master_user":message})['text']: 인공지능 답변을 받아 ai_answer 변수로 지정한다.
- 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
- 이벤트 리스너 추가하기
각각의 이벤트가 일어났을 때 실행되는 함수와 요소들을 연결한다.
- 음성 녹음 완료
- [보내기] 버튼 클릭
- ENTER 제출
- 되돌리기
- 초기화
# 음성 녹음 완료
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]
)
음성 인식봇 전체 코드
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
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]
)
app.launch()
다음에는 문서 요약봇을 제작해보도록 한다.
다음 내용
[출처]
Hey, 파이썬! 생성형 AI 활용 앱 만들어줘
'[파이썬 Projects] > <파이썬 Gen AI, LLM>' 카테고리의 다른 글
[Gen AI] 그라디오로 두 번째 챗봇 제작하기-3 (1) | 2024.12.21 |
---|---|
[Gen AI] 그라디오로 두 번째 챗봇 제작하기-2 (1) | 2024.12.21 |
[Gen AI] 문서 요약 프롬프트 제작 (1) | 2024.12.20 |
[Gen AI] 음성 변환 기술 구현해보기(STT, TTS) (1) | 2024.12.19 |
[Gen AI] 그라디오 챗봇 업그레이드 (2) | 2024.12.19 |