anakib1 commited on
Commit
ed74064
·
1 Parent(s): 4e7b4ba

Added gradio

Browse files
Files changed (8) hide show
  1. .gitignore +1 -1
  2. app.py +31 -0
  3. requirements.txt +3 -1
  4. src/.env +0 -1
  5. src/__init__.py +0 -0
  6. src/chains.py +50 -0
  7. src/clients.py +51 -0
  8. src/complex.ipynb +256 -0
.gitignore CHANGED
@@ -1,2 +1,2 @@
1
- src/.env
2
  .idea/
 
1
+ .env
2
  .idea/
app.py ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from dotenv import load_dotenv
3
+ from src.clients import AcademicClient
4
+
5
+ load_dotenv()
6
+ client = AcademicClient()
7
+
8
+
9
+ def perform_qa(query):
10
+ return client.answer(query)
11
+
12
+
13
+ css = """
14
+ body {
15
+ text-align: center;
16
+ display:block;
17
+ }
18
+ """
19
+
20
+ with gr.Blocks(css=css) as demo:
21
+ gr.Markdown('Wisdom.AI'),
22
+ gr.Image('misc/wisdom.jpg', height=600, width=400)
23
+ with gr.Row():
24
+ inp = gr.Textbox('Що б ви хотіли дізнатися у мудрого?')
25
+ out = gr.Textbox('Мудрий каже...')
26
+
27
+ btn = gr.Button('Спитати')
28
+ btn.click(fn=perform_qa, inputs=inp, outputs=out)
29
+
30
+ if __name__ == "__main__":
31
+ demo.launch()
requirements.txt CHANGED
@@ -5,4 +5,6 @@ langchain-openai
5
  chromadb
6
  openai
7
  sentence_transformers
8
- pypdf
 
 
 
5
  chromadb
6
  openai
7
  sentence_transformers
8
+ pypdf
9
+ gradio
10
+ gdown
src/.env DELETED
@@ -1 +0,0 @@
1
- OPENAI_API_KEY=
 
 
src/__init__.py ADDED
File without changes
src/chains.py ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from langchain_core.output_parsers import StrOutputParser
2
+ from langchain_core.runnables import RunnablePassthrough, RunnableLambda
3
+
4
+ from langchain_openai import ChatOpenAI
5
+ from langchain.prompts import PromptTemplate
6
+ from langchain_community.utilities import GoogleSerperAPIWrapper
7
+
8
+ CUSTOM_RAG_PROMPT = """
9
+ Використай наступні **надійні** елементи, для того, щоб відповісти на питання в кінці.
10
+ Якщо вони не містять відповіді, зверни увагу на відповідь з інтернету, хоча вона може бути не надійною.
11
+ Якщо ти не знаєш відповіді, використаши всі свої джерела, то просто скажи про це, не потрібно вигадувати відповідь.
12
+ Використовуй не більше трьох речень, та намагайся відповісти коротко та чітко.
13
+
14
+ {context}
15
+
16
+ Відповідь з інтернету: {internet}
17
+
18
+ Питання: {question}
19
+
20
+ Корисна відповідь:"""
21
+
22
+ CUSTOM_RAG_PROMPT = PromptTemplate.from_template(CUSTOM_RAG_PROMPT)
23
+
24
+
25
+ def documents_parser(docs):
26
+ return "\n\n".join(doc.page_content for doc in docs)
27
+
28
+
29
+ class PdfAndGoogleChain:
30
+
31
+ def use_google_search(self, query):
32
+ try:
33
+ return self.search.run(query)
34
+ except Exception as ex:
35
+ return 'NONE'
36
+
37
+ def __init__(self, retriever, llm_name: str = "gpt-3.5-turbo-0125"):
38
+ self.search = GoogleSerperAPIWrapper()
39
+ self.llm = ChatOpenAI(model=llm_name)
40
+
41
+ self.rag_chain = (
42
+ {"context": retriever | documents_parser, "internet": RunnableLambda(self.use_google_search),
43
+ "question": RunnablePassthrough()}
44
+ | CUSTOM_RAG_PROMPT
45
+ | self.llm
46
+ | StrOutputParser()
47
+ )
48
+
49
+ def answer(self, query: str):
50
+ return self.rag_chain.invoke(query)
src/clients.py ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from langchain_openai import OpenAIEmbeddings
2
+ from langchain_community.vectorstores import Chroma
3
+ from langchain.text_splitter import RecursiveCharacterTextSplitter
4
+ from langchain_community.document_loaders import PyPDFLoader
5
+ import pathlib
6
+ import gdown
7
+ from .chains import PdfAndGoogleChain
8
+
9
+
10
+ def embed_pdf(folder: str = 'data', name: str = 'book.pdf'):
11
+ pathlib.Path(folder).mkdir(exist_ok=True)
12
+ path = pathlib.Path(folder).joinpath(name)
13
+ if not path.exists():
14
+ print('Downloading book PDF.')
15
+ gdown.download('https://drive.google.com/file/d/1CwhFM4gInp9xV4G4sdnYE_rN0StmqQ2z/view?usp=sharing',
16
+ str(path))
17
+ loader = PyPDFLoader(str(path))
18
+ documents = loader.load()
19
+ splitter = RecursiveCharacterTextSplitter(
20
+ chunk_size=1000,
21
+ chunk_overlap=100)
22
+ return splitter.split_documents(
23
+ documents
24
+ )
25
+
26
+
27
+ class AcademicClient:
28
+
29
+ def create_vectordb(self):
30
+ if pathlib.Path('db').exists():
31
+ self.vectordb = Chroma(persist_directory='db', embedding_function=OpenAIEmbeddings())
32
+ elif pathlib.Path('src/db').exists():
33
+ self.vectordb = Chroma(persist_directory='src/db', embedding_function=OpenAIEmbeddings())
34
+ else:
35
+ print('Not found cached DB. Rebuilding DB state, could use money from OPENAI!!!!')
36
+ raise Exception('BAAAAAAAAAAd')
37
+ return
38
+ texts = embed_pdf()
39
+ self.vectordb = Chroma.from_documents(
40
+ documents=texts,
41
+ embedding=OpenAIEmbeddings(),
42
+ persist_directory="db"
43
+ )
44
+ self.vectordb.persist()
45
+
46
+ def __init__(self):
47
+ self.create_vectordb()
48
+ self.chain = PdfAndGoogleChain(self.vectordb.as_retriever())
49
+
50
+ def answer(self, query):
51
+ return self.chain.answer(query)
src/complex.ipynb ADDED
@@ -0,0 +1,256 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": 1,
6
+ "outputs": [],
7
+ "source": [
8
+ "import os\n",
9
+ "\n",
10
+ "from langchain_openai import OpenAIEmbeddings\n",
11
+ "from langchain.vectorstores import Chroma\n",
12
+ "from langchain.text_splitter import RecursiveCharacterTextSplitter\n",
13
+ "from langchain_core.output_parsers import StrOutputParser\n",
14
+ "from langchain_core.runnables import RunnablePassthrough, RunnableLambda\n",
15
+ "from langchain.document_loaders import PyPDFLoader\n",
16
+ "from langchain_openai import ChatOpenAI\n",
17
+ "from dotenv import load_dotenv\n",
18
+ "from langchain.prompts import PromptTemplate\n",
19
+ "from langchain_community.utilities import GoogleSerperAPIWrapper"
20
+ ],
21
+ "metadata": {
22
+ "collapsed": false,
23
+ "ExecuteTime": {
24
+ "end_time": "2024-04-09T13:31:50.973351600Z",
25
+ "start_time": "2024-04-09T13:31:48.724776800Z"
26
+ }
27
+ },
28
+ "id": "6ced23bcbc0e28e5"
29
+ },
30
+ {
31
+ "cell_type": "code",
32
+ "execution_count": 2,
33
+ "id": "initial_id",
34
+ "metadata": {
35
+ "collapsed": true,
36
+ "ExecuteTime": {
37
+ "end_time": "2024-04-09T13:31:50.992692600Z",
38
+ "start_time": "2024-04-09T13:31:50.975349700Z"
39
+ }
40
+ },
41
+ "outputs": [
42
+ {
43
+ "data": {
44
+ "text/plain": "True"
45
+ },
46
+ "execution_count": 2,
47
+ "metadata": {},
48
+ "output_type": "execute_result"
49
+ }
50
+ ],
51
+ "source": [
52
+ "load_dotenv()"
53
+ ]
54
+ },
55
+ {
56
+ "cell_type": "code",
57
+ "execution_count": 3,
58
+ "outputs": [],
59
+ "source": [
60
+ "os.environ[\"LANGCHAIN_TRACING_V2\"] = \"true\""
61
+ ],
62
+ "metadata": {
63
+ "collapsed": false,
64
+ "ExecuteTime": {
65
+ "end_time": "2024-04-09T13:31:50.996689600Z",
66
+ "start_time": "2024-04-09T13:31:50.989345500Z"
67
+ }
68
+ },
69
+ "id": "a6de359e6f0e68ac"
70
+ },
71
+ {
72
+ "cell_type": "code",
73
+ "execution_count": 4,
74
+ "outputs": [],
75
+ "source": [
76
+ "llm = ChatOpenAI(model=\"gpt-3.5-turbo-0125\")"
77
+ ],
78
+ "metadata": {
79
+ "collapsed": false,
80
+ "ExecuteTime": {
81
+ "end_time": "2024-04-09T13:31:51.750122200Z",
82
+ "start_time": "2024-04-09T13:31:50.996689600Z"
83
+ }
84
+ },
85
+ "id": "3b45ee8734cc3396"
86
+ },
87
+ {
88
+ "cell_type": "code",
89
+ "execution_count": 5,
90
+ "outputs": [],
91
+ "source": [
92
+ "import pathlib\n",
93
+ "if pathlib.Path('db').exists():\n",
94
+ " vectordb = Chroma(persist_directory='db', embedding_function=OpenAIEmbeddings())\n",
95
+ "else:\n",
96
+ " loader = PyPDFLoader(\"../data/book.pdf\")\n",
97
+ " documents = loader.load()\n",
98
+ " splitter = RecursiveCharacterTextSplitter(\n",
99
+ " chunk_size=1000,\n",
100
+ " chunk_overlap=100)\n",
101
+ " texts = splitter.split_documents(\n",
102
+ " documents\n",
103
+ " )\n",
104
+ " vectordb = Chroma.from_documents(\n",
105
+ " documents=texts,\n",
106
+ " embedding=OpenAIEmbeddings(),\n",
107
+ " persist_directory=\"db\"\n",
108
+ " )\n",
109
+ " vectordb.persist()"
110
+ ],
111
+ "metadata": {
112
+ "collapsed": false,
113
+ "ExecuteTime": {
114
+ "end_time": "2024-04-09T13:31:53.393778600Z",
115
+ "start_time": "2024-04-09T13:31:51.753134200Z"
116
+ }
117
+ },
118
+ "id": "6ecda08560566442"
119
+ },
120
+ {
121
+ "cell_type": "code",
122
+ "execution_count": 6,
123
+ "outputs": [],
124
+ "source": [
125
+ "custom_rag_prompt = \"\"\"\n",
126
+ "Використай наступні **надійні** елементи, для того, щоб відповісти на питання в кінці. \n",
127
+ "Якщо вони не містять відповіді, зверни увагу на відповідь з інтернету, хоча вона може бути не надійною. \n",
128
+ "Якщо ти не знаєш відповіді, використаши всі свої джерела, то просто скажи про це, не потрібно вигадувати відповідь.\n",
129
+ "Використовуй не більше трьох речень, та намагайся відповісти коротко та чітко.\n",
130
+ "\n",
131
+ "{context}\n",
132
+ "\n",
133
+ "Відповідь з інтернету: {internet}\n",
134
+ "\n",
135
+ "Питання: {question}\n",
136
+ "\n",
137
+ "Корисна відповідь:\"\"\"\n",
138
+ "\n",
139
+ "custom_rag_prompt = PromptTemplate.from_template(custom_rag_prompt)"
140
+ ],
141
+ "metadata": {
142
+ "collapsed": false,
143
+ "ExecuteTime": {
144
+ "end_time": "2024-04-09T13:31:53.410090300Z",
145
+ "start_time": "2024-04-09T13:31:53.397777900Z"
146
+ }
147
+ },
148
+ "id": "1827a7ad093fa60a"
149
+ },
150
+ {
151
+ "cell_type": "code",
152
+ "execution_count": 18,
153
+ "outputs": [],
154
+ "source": [
155
+ "retriever = vectordb.as_retriever()\n",
156
+ "\n",
157
+ "search = GoogleSerperAPIWrapper()\n",
158
+ "def use_google_search(query):\n",
159
+ " try:\n",
160
+ " return search.run(query)\n",
161
+ " except Exception as ex:\n",
162
+ " return 'NONE'\n",
163
+ "\n",
164
+ "def documents_parser(docs):\n",
165
+ " return \"\\n\\n\".join(doc.page_content for doc in docs)\n",
166
+ "\n",
167
+ "rag_chain = (\n",
168
+ " {\"context\": retriever | documents_parser, \"internet\" : RunnableLambda(use_google_search), \"question\": RunnablePassthrough()}\n",
169
+ " | custom_rag_prompt\n",
170
+ " | llm\n",
171
+ " | StrOutputParser()\n",
172
+ ")"
173
+ ],
174
+ "metadata": {
175
+ "collapsed": false,
176
+ "ExecuteTime": {
177
+ "end_time": "2024-04-09T13:38:45.242263100Z",
178
+ "start_time": "2024-04-09T13:38:45.221315700Z"
179
+ }
180
+ },
181
+ "id": "64cb22281c854513"
182
+ },
183
+ {
184
+ "cell_type": "code",
185
+ "execution_count": 19,
186
+ "outputs": [
187
+ {
188
+ "data": {
189
+ "text/plain": "'До конституційних засад сучасної політичної системи України входять демократія, принцип верховенства права, гарантії прав та свобод громадян, розділення влади на виконавчу, законодавчу та судову.'"
190
+ },
191
+ "execution_count": 19,
192
+ "metadata": {},
193
+ "output_type": "execute_result"
194
+ }
195
+ ],
196
+ "source": [
197
+ "rag_chain.invoke(\"Які конституційні засади сучасної політичної системи України ви знаєте?\")"
198
+ ],
199
+ "metadata": {
200
+ "collapsed": false,
201
+ "ExecuteTime": {
202
+ "end_time": "2024-04-09T13:38:50.033577300Z",
203
+ "start_time": "2024-04-09T13:38:45.864222300Z"
204
+ }
205
+ },
206
+ "id": "2a36756422b7544"
207
+ },
208
+ {
209
+ "cell_type": "code",
210
+ "execution_count": 16,
211
+ "outputs": [],
212
+ "source": [
213
+ "stuff = search.run('Які конституційні засади сучасної політичної системи України ви знаєте?')"
214
+ ],
215
+ "metadata": {
216
+ "collapsed": false,
217
+ "ExecuteTime": {
218
+ "end_time": "2024-04-09T13:38:33.477869300Z",
219
+ "start_time": "2024-04-09T13:38:32.098891500Z"
220
+ }
221
+ },
222
+ "id": "7c2ec151bf629265"
223
+ },
224
+ {
225
+ "cell_type": "code",
226
+ "execution_count": null,
227
+ "outputs": [],
228
+ "source": [],
229
+ "metadata": {
230
+ "collapsed": false
231
+ },
232
+ "id": "f1006423bcc8b35b"
233
+ }
234
+ ],
235
+ "metadata": {
236
+ "kernelspec": {
237
+ "display_name": "Python 3",
238
+ "language": "python",
239
+ "name": "python3"
240
+ },
241
+ "language_info": {
242
+ "codemirror_mode": {
243
+ "name": "ipython",
244
+ "version": 2
245
+ },
246
+ "file_extension": ".py",
247
+ "mimetype": "text/x-python",
248
+ "name": "python",
249
+ "nbconvert_exporter": "python",
250
+ "pygments_lexer": "ipython2",
251
+ "version": "2.7.6"
252
+ }
253
+ },
254
+ "nbformat": 4,
255
+ "nbformat_minor": 5
256
+ }