danny042 commited on
Commit
7557345
โ€ข
1 Parent(s): fc69640

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +196 -0
app.py ADDED
@@ -0,0 +1,196 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import tiktoken
3
+ from loguru import logger
4
+
5
+ from langchain.chains import ConversationalRetrievalChain
6
+ from langchain.chat_models import ChatOpenAI
7
+
8
+ from langchain.document_loaders.pdf import (PyPDFLoader, PyMuPDFLoader)
9
+
10
+ from langchain.text_splitter import RecursiveCharacterTextSplitter
11
+ from langchain.embeddings import HuggingFaceEmbeddings
12
+
13
+ from langchain.memory import ConversationBufferMemory
14
+ from langchain.vectorstores import FAISS
15
+
16
+ # from streamlit_chat import message
17
+ from langchain.callbacks import get_openai_callback
18
+ from langchain.memory import StreamlitChatMessageHistory
19
+ from gtts import gTTS
20
+ from IPython.display import Audio, display
21
+
22
+ from io import BytesIO
23
+ import speech_recognition as sr
24
+
25
+ from langchain.callbacks import get_openai_callback
26
+ from langchain.memory import StreamlitChatMessageHistory
27
+
28
+ def main():
29
+ st.set_page_config(
30
+ page_title="์ฐจ๋Ÿ‰์šฉ Q&A ์ฑ—๋ด‡",
31
+ page_icon=":car:"
32
+ )
33
+
34
+ st.title("์ฐจ๋Ÿ‰์šฉ Q&A ์ฑ—๋ด‡ :car:")
35
+
36
+ if "conversation" not in st.session_state:
37
+ st.session_state.conversation = None
38
+
39
+ if "chat_history" not in st.session_state:
40
+ st.session_state.chat_history = None
41
+
42
+ if "processComplete" not in st.session_state:
43
+ st.session_state.processComplete = None
44
+
45
+ with st.sidebar:
46
+ uploaded_files = st.file_uploader("์ฐจ๋Ÿ‰ ๋ฉ”๋‰ด์–ผ PDF ํŒŒ์ผ์„ ๋„ฃ์–ด์ฃผ์„ธ์š”.", type=['pdf'], accept_multiple_files=True)
47
+ openai_api_key = st.text_input("OpenAI API Key", key="chatbot_api_key", type="password")
48
+ process = st.button("์‹คํ–‰")
49
+
50
+ if process:
51
+ if not openai_api_key:
52
+ st.info("Open AIํ‚ค๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.")
53
+ st.stop()
54
+ files_text = get_text(uploaded_files)
55
+ text_chunks = get_text_chunks(files_text)
56
+ vector_store = get_vectorstore(text_chunks)
57
+
58
+ st.session_state.conversation = get_conversation_chain(vector_store, openai_api_key)
59
+
60
+ st.session_state.processComplete = True
61
+
62
+ if 'messages' not in st.session_state:
63
+ st.session_state['messages'] = [{"role": "assistant",
64
+ "content": "์•ˆ๋…•ํ•˜์„ธ์š”! ์ฃผ์–ด์ง„ ๋ฌธ์„œ์— ๋Œ€ํ•ด ๊ถ๊ธˆํ•˜์‹  ๊ฒƒ์ด ์žˆ์œผ๋ฉด ์–ธ์ œ๋“  ๋ฌผ์–ด๋ด์ฃผ์„ธ์š”!"}]
65
+
66
+ for message in st.session_state.messages:
67
+ with st.chat_message(message["role"]):
68
+ st.markdown(message["content"])
69
+
70
+ history = StreamlitChatMessageHistory(key="chat_messages")
71
+
72
+ # Chat logic
73
+ if query := st.chat_input("์งˆ๋ฌธ์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”."):
74
+ st.session_state.messages.append({"role": "user", "content": query})
75
+
76
+ with st.chat_message("user"):
77
+ st.markdown(query)
78
+
79
+ with st.chat_message("assistant"):
80
+ # STT ์ฝ”๋“œ ์ถ”๊ฐ€
81
+ user_voice_input = stt()
82
+ if user_voice_input:
83
+ # Add user's voice input to chat history
84
+ st.session_state.messages.append({"role": "user", "content": user_voice_input})
85
+
86
+ # Continue with the rest of the conversation logic...
87
+ chain = st.session_state.conversation
88
+
89
+ with st.spinner("Thinking..."):
90
+ result = chain({"question": query})
91
+ with get_openai_callback() as cb:
92
+ st.session_state.chat_history = result['chat_history']
93
+ response = result['answer']
94
+ source_documents = result['source_documents']
95
+
96
+ st.markdown(response)
97
+ with st.expander("์ฐธ๊ณ  ๋ฌธ์„œ ํ™•์ธ"):
98
+ st.markdown(source_documents[0].metadata['source'], help=source_documents[0].page_content)
99
+ st.markdown(source_documents[1].metadata['source'], help=source_documents[1].page_content)
100
+ st.markdown(source_documents[2].metadata['source'], help=source_documents[2].page_content)
101
+
102
+ # TTS ์ฝ”๋“œ ์ถ”๊ฐ€
103
+ tts("์ด๊ฒƒ์€ ์Œ์„ฑ์œผ๋กœ ๋ณ€ํ™˜๋œ ๋‹ต๋ณ€์ž…๋‹ˆ๋‹ค.")
104
+
105
+ # Add assistant message to chat history
106
+ st.session_state.messages.append({"role": "assistant", "content": response})
107
+
108
+ # ...
109
+
110
+ # STT ํ•จ์ˆ˜ ์ถ”๊ฐ€
111
+ def stt():
112
+ recognizer = sr.Recognizer()
113
+
114
+ with sr.Microphone() as source:
115
+ st.write("๋งํ•ด๋ณด์„ธ์š”...")
116
+ recognizer.adjust_for_ambient_noise(source)
117
+ audio = recognizer.listen(source, timeout=5)
118
+
119
+ try:
120
+ text = recognizer.recognize_google(audio, language="ko-KR")
121
+ st.write("์ธ์‹๋œ ํ…์ŠคํŠธ: {}".format(text))
122
+ return text
123
+ except sr.UnknownValueError:
124
+ st.write("์Œ์„ฑ์„ ์ธ์‹ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.")
125
+ return None
126
+ except sr.RequestError as e:
127
+ st.write("Google Speech Recognition ์„œ๋น„์Šค์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค; {0}".format(e))
128
+ return None
129
+
130
+ # TTS ํ•จ์ˆ˜ ์ถ”๊ฐ€
131
+ def tts(text):
132
+ st.write("์Œ์„ฑ์œผ๋กœ ๋ณ€ํ™˜ ์ค‘...")
133
+ tts = gTTS(text=text, lang='ko')
134
+ audio_stream = BytesIO()
135
+ tts.save(audio_stream)
136
+ st.audio(audio_stream, format='audio/wav')
137
+
138
+ def tiktoken_len(text):
139
+ tokenizer = tiktoken.get_encoding("cl100k_base")
140
+ tokens = tokenizer.encode(text)
141
+ return len(tokens)
142
+
143
+
144
+ def get_text(docs):
145
+ doc_list = []
146
+
147
+ for doc in docs:
148
+ file_name = doc.name # doc ๊ฐ์ฒด์˜ ์ด๋ฆ„์„ ํŒŒ์ผ ์ด๋ฆ„์œผ๋กœ ์‚ฌ์šฉ
149
+ with open(file_name, "wb") as file: # ํŒŒ์ผ์„ doc.name์œผ๋กœ ์ €์žฅ
150
+ file.write(doc.getvalue())
151
+ logger.info(f"Uploaded {file_name}")
152
+ if '.pdf' in doc.name:
153
+ loader = PyMuPDFLoader(file_name)
154
+ documents = loader.load_and_split()
155
+
156
+ doc_list.extend(documents)
157
+ return doc_list
158
+
159
+
160
+ def get_text_chunks(text):
161
+ text_splitter = RecursiveCharacterTextSplitter(
162
+ chunk_size=1000,
163
+ chunk_overlap=100,
164
+ length_function=tiktoken_len
165
+ )
166
+ chunks = text_splitter.split_documents(text)
167
+ return chunks
168
+
169
+
170
+ def get_vectorstore(text_chunks):
171
+ embeddings = HuggingFaceEmbeddings(
172
+ model_name="jhgan/ko-sroberta-multitask",
173
+ model_kwargs={'device': 'cpu'},
174
+ encode_kwargs={'normalize_embeddings': True}
175
+ )
176
+ vectordb = FAISS.from_documents(text_chunks, embeddings)
177
+ return vectordb
178
+
179
+
180
+ def get_conversation_chain(vetorestore, openai_api_key):
181
+ llm = ChatOpenAI(openai_api_key=openai_api_key, model_name='gpt-3.5-turbo', temperature=0)
182
+ conversation_chain = ConversationalRetrievalChain.from_llm(
183
+ llm=llm,
184
+ chain_type="stuff",
185
+ retriever=vetorestore.as_retriever(search_type='mmr', vervose=True),
186
+ memory=ConversationBufferMemory(memory_key='chat_history', return_messages=True, output_key='answer'),
187
+ get_chat_history=lambda h: h,
188
+ return_source_documents=True,
189
+ verbose=True
190
+ )
191
+
192
+ return conversation_chain
193
+
194
+
195
+ if __name__ == '__main__':
196
+ main()