Spaces:
Sleeping
Sleeping
File size: 12,553 Bytes
1205120 5b55b54 1205120 50d2989 1205120 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
import gradio as gr
import time
import networkx as nx
import speech_recognition as sr
import edge_tts
import asyncio
from transformers import (
AutoTokenizer,
AutoModelForSequenceClassification,
pipeline,
)
model_names = [
'wangchanberta-base-att-spm-uncased',
]
tokenizers = {
'wangchanberta-base-att-spm-uncased': AutoTokenizer,
}
public_models = ['xlm-roberta-base', 'bert-base-multilingual-cased']
#Choose Pretrained Model
model_name = "wangchanberta-base-att-spm-uncased"
#create tokenizer
tokenizer = tokenizers[model_name].from_pretrained(
f'airesearch/{model_name}' if model_name not in public_models else f'{model_name}',
revision='main',
model_max_length=416,)
#pipeline
zero_classify = pipeline(task='zero-shot-classification',
tokenizer=tokenizer,
model=AutoModelForSequenceClassification.from_pretrained(
f'airesearch/{model_name}' if model_name not in public_models else f'airesearch/{model_name}-finetuned',
revision='finetuned@xnli_th')
)
def intent_classifier(text_input, candidate_labels, zero_classify=zero_classify):
output_label = zero_classify(text_input, candidate_labels=candidate_labels)
return output_label['labels'][0]
customer_name = "จิรานุวัฒน์"
bot_identity = 'female'
bot_name = 'ท้องฟ้า'
pronoun = 'ดิฉัน' if bot_identity == 'female' else 'กระผม'
sentence_ending = ['ค่ะ','คะ'] if bot_identity == 'female' else ['ครับ','ครับ']
comany_name = 'แมวเหมียว'
# Create a directed graph
A = nx.DiGraph(section='A')
# Add nodes and edges
A.add_node("START A", response=f"สวัสดี{sentence_ending[0]} ขอเรียนสายคุณ {customer_name}{sentence_ending[0]}")
A.add_node("A1", response=f"{pronoun} ต้องกราบขอประทานโทษเป็นอย่างสูงที่โทรมารบกวนนะ{sentence_ending[1]} {pronoun} ชื่อ {bot_name} ใบอนุญาตนายหน้าประกันวินาศภัยเลขที่ XXXXXXXXXX ติดต่อจากบริษัท {comany_name} จำกัด โทรมาเพื่อขออนุญาตนำเสนอสิทธิประโยชน์สำหรับลูกค้าของธนาคาร{comany_name} ไม่ทราบว่าจะสะดวกหรือไม่{sentence_ending[1]}", intent_classify= lambda x :intent_classifier(x,["ได้","ไม่ได้ ไม่ตกลง ยังไม่ตกลง ยังไม่ได้"]))
A.add_node("A2", response=f"{pronoun} ขออนุญาตติดต่อกลับคุณ{customer_name} อีกครั้งในวันที่....ไม่ทราบว่า คุณ{customer_name} สะดวกไหม{sentence_ending[1]} ")
A.add_node("END", response=f"ต้องกราบขอประทานโทษเป็นอย่างสูงที่โทรมารบกวนนะ{sentence_ending[1]} {pronoun} หวังเป็นอย่างยิ่งว่าทางบริษัท {comany_name} จะได้ให้บริการคุณ{customer_name} ในโอกาสถัดไปนะ{sentence_ending[1]} หากคุณ{customer_name} ไม่ประสงค์ที่จะให้บริษัท {comany_name} ติดต่อเพื่อนำเสนอบริการของ บริษัท {comany_name} สามารถแจ้งผ่าน Call Center โทร 02-123-4567 ได้{sentence_ending[0]} ขอขอบพระคุณ ที่สละเวลาในการฟังข้อมูลของ บริษัท {comany_name} ขออนุญาตวางสาย{sentence_ending[0]} สวัสดี{sentence_ending[0]}")
A.add_node("A3", response=f"ขอบพระคุณ{sentence_ending[0]} และเพื่อเป็นการปรับปรุงคุณภาพในการให้บริการ ขออนุญาตบันทึกเสียงการสนทนาในครั้งนี้ด้วยนะ{sentence_ending[1]}", intent_classify= lambda x :intent_classifier(x,["ได้","ไม่ได้ ไม่ตกลง ยังไม่ตกลง ยังไม่ได้"]))
A.add_node("END A1", response=f"ขอบพระคุณ{sentence_ending[0]} ดิฉันจะไม่บันทึกเสียงการสนทนาในครั้งนี้{sentence_ending[0]}")
A.add_node("END A2", response=f"ขอบพระคุณ{sentence_ending[0]} ขณะนี้ได้เริ่มบันทึกการสนทนาแล้วนะ{sentence_ending[1]}")
A.add_edges_from((("START A","A1"),("A1","A2"),("A2","END"),("A1","A3"),("A3","END A1"),("A3","END A2")))
# Create a directed graph
B = nx.DiGraph(section='B')
# Add nodes and edges
B.add_node("START B", response=f"เนื่องในโอกาสที่ ธนาคาร{comany_name} ได้จัดตั้งบริษัท {comany_name} จำกัด เข้าเป็นบริษัทในกลุ่มธุรกิจการเงินของธนาคาร โดยมีวัตถุประสงค์ประกอบกิจการเป็นนายหน้าประกันวินาศภัย {pronoun} {bot_name} จึงติดต่อมาเพื่อขออนุญาตนำเสนอแผนประกันภัยรถยนต์แบบพิเศษเฉพาะลูกค้าของธนาคาร{comany_name}เท่านั้น {pronoun}ขอชี้แจงรายละเอียดนะ{sentence_ending[1]} ")
B.add_node("B1", response=f"เพื่อให้ท่านสมาชิกได้รับประโยชน์สูงสุด จึงขออนุญาตสอบถามข้อมูลรถยนต์ของคุณ{customer_name} นะ{sentence_ending[1]}")
B.add_node("B2", response=f"รถยนต์มีประกันประเภทใด (1,2,3,2+,3+) รับประกันภัยโดยบริษัทฯใด สิ้นสุดความคุ้มครองเมื่อใด")
B.add_node("END B", response=f"{comany_name}ได้คัดสรรค์แบบประกัน เพื่อเป็นทางเลือกที่คุ้มค่าไว้บริการสำหรับลูกค้าของธนาคาร{comany_name} ดังนี้")
B.add_edges_from((("START B","B1"),("B1","B2"),("B2","END B")))
Bot_dialog = nx.compose(A, B)
Bot_dialog.add_edges_from((("END A1","START B"),("END A2","START B")))
def addfile(filepath):
return filepath
def submit_file(filepath):
return filepath
def clear_audio():
return None
def speech_to_text(audiofile_path):
recognizer = sr.Recognizer()
try:
with sr.WavFile(audiofile_path) as source:
audio = recognizer.record(source)
transcription = recognizer.recognize_google(audio,language = "th-TH")
return transcription
except:
return "Could not understand audio"
#bot response
current_node = "START A"
def user(user_input, history):
global current_node, Bot_dialog
next_nodes = list(Bot_dialog.successors(current_node))
if next_nodes != []:
if "intent_classify" in Bot_dialog.nodes[current_node]:
intent = Bot_dialog.nodes[current_node]["intent_classify"](user_input)
if len(next_nodes) == 1:
current_node = next_nodes[0]
else:
if intent == "ไม่ได้ ไม่ตกลง ยังไม่ตกลง ยังไม่ได้":
current_node = next_nodes[0]
else:
current_node = next_nodes[1]
return user_input, history + [[user_input, None]]
def bot(history):
global current_node, Bot_dialog
history[-1][1] = ""
bot_message = Bot_dialog.nodes[current_node]["response"]
if current_node == "END B" or current_node == "END":
bot_message += """<span style="color:red"> \n**Conversation Endded** </span>"""
for character in bot_message:
history[-1][1] += character
time.sleep(0.01)
yield history
async def text_to_speech(inputtext_history: list[str], filename: str = "tts_temp.wav"):
input_text = inputtext_history[-1][1]
communicate = edge_tts.Communicate(input_text, "th-TH-PremwadeeNeural")
with open(filename, "wb") as file:
async for chunk in communicate.stream():
if chunk["type"] == "audio":
file.write(chunk["data"])
elif chunk["type"] == "WordBoundary":
pass
return filename
async def restart(history):
global current_node, Bot_dialog
current_node = "START A"
await text_to_speech([[None, Bot_dialog.nodes["START A"]["response"]]])
return [history[0]], '', 'tts_temp.wav'
async def main():
current_node = "START A"
# init first audio greeting
await text_to_speech([[None, Bot_dialog.nodes["START A"]["response"]]])
# Create a Gradio interface
with gr.Blocks(title='Chatbot Demo') as demo:
chatbot = gr.Chatbot(
[[None, Bot_dialog.nodes["START A"]["response"]]],
elem_id="chatbot",
bubble_full_width=False,
avatar_images=('https://aui.atlassian.com/aui/9.3/docs/images/avatar-person.svg',
'https://avatars.githubusercontent.com/u/51063788?s=200&v=4')
)
with gr.Row():
txt = gr.Textbox(
scale=3,
show_label=False,
placeholder="transcription is Here.",
container=False,
interactive=True,
)
voice_btn = gr.Audio(sources="microphone",type="filepath", scale=4)
voicesubmit_btn = gr.Button(value="Submit Voice✔️", scale=1,variant='primary')
with gr.Row():
sentence = gr.Textbox(visible=False)
audio = gr.Audio(
value="tts_temp.wav",
label="Generated audio response",
streaming=True,
autoplay=False,
interactive=False,
show_label=True,
)
restart_btn = gr.Button(value='Restart🔄')
gr.Markdown(
"""
<div style="text-align: center;">
<h1 style="font-weight: bold; font-size: 30px;">Insurance Voicebot Demo</h1>
</div>
<div style="text-align: left;">
<p style="font-weight: bold; font-size: 20px;"><strong>To try this demo follow these steps.</strong></p>
</div>
"""
)
gr.Markdown("""
- From **Audio** block, click **Record** button and speak something to the bot.
- When finished recording, click **Stop** button.
- Click **Submit Voice✔️** button.
- Wait until bot generate text and audio response.
- From **Generated audio response** block, click play button to play bot's audio response.
- Continue these steps until you want to restart.
"""
)
voice_btn.stop_recording(addfile, inputs=voice_btn, outputs=txt)
voicesubmit_btn.click(submit_file, inputs=voice_btn, outputs=txt).then(speech_to_text, inputs=voice_btn, outputs=txt).then(user, [txt, chatbot], [txt, chatbot], queue=False).then(bot, chatbot, chatbot).then(clear_audio, outputs=voice_btn).then(text_to_speech, inputs=chatbot, outputs=audio)
restart_btn.click(restart, chatbot, [chatbot,txt,audio])
demo.launch(debug=False)
if __name__ == "__main__":
loop = asyncio.get_event_loop_policy().get_event_loop()
try:
loop.run_until_complete(main())
finally:
loop.close() |