undefined102 commited on
Commit
4d12558
·
1 Parent(s): 5b227e5

Upload folder using huggingface_hub

Browse files
Files changed (3) hide show
  1. README.md +2 -8
  2. app.py +212 -0
  3. requirements.txt +7 -0
README.md CHANGED
@@ -1,12 +1,6 @@
1
  ---
2
- title: QuestionPDF
3
- emoji: 🏃
4
- colorFrom: red
5
- colorTo: blue
6
  sdk: gradio
7
  sdk_version: 3.42.0
8
- app_file: app.py
9
- pinned: false
10
  ---
11
-
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: questionPDF
3
+ app_file: app.py
 
 
4
  sdk: gradio
5
  sdk_version: 3.42.0
 
 
6
  ---
 
 
app.py ADDED
@@ -0,0 +1,212 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import urllib.request
2
+ import fitz
3
+ import re
4
+ import numpy as np
5
+ import tensorflow_hub as hub
6
+ import openai
7
+ import gradio as gr
8
+ import os
9
+ from sklearn.neighbors import NearestNeighbors
10
+
11
+ def download_pdf(url, output_path):
12
+ urllib.request.urlretrieve(url, output_path)
13
+
14
+ def preprocess(text):
15
+ text = text.replace('\n', ' ')
16
+ text = re.sub('\s+', ' ', text)
17
+ return text
18
+
19
+
20
+ def pdf_to_text(path, start_page=1, end_page=None):
21
+ doc = fitz.open(path)
22
+ total_pages = doc.page_count
23
+
24
+ if end_page is None:
25
+ end_page = total_pages
26
+
27
+ text_list = []
28
+
29
+ for i in range(start_page-1, end_page):
30
+ text = doc.load_page(i).get_text("text")
31
+ text = preprocess(text)
32
+ text_list.append(text)
33
+
34
+ doc.close()
35
+ return text_list
36
+
37
+
38
+ def text_to_chunks(texts, word_length=150, start_page=1):
39
+ text_toks = [t.split(' ') for t in texts]
40
+ page_nums = []
41
+ chunks = []
42
+
43
+ for idx, words in enumerate(text_toks):
44
+ for i in range(0, len(words), word_length):
45
+ chunk = words[i:i+word_length]
46
+ if (i+word_length) > len(words) and (len(chunk) < word_length) and (
47
+ len(text_toks) != (idx+1)):
48
+ text_toks[idx+1] = chunk + text_toks[idx+1]
49
+ continue
50
+ chunk = ' '.join(chunk).strip()
51
+ chunk = f'[Page no. {idx+start_page}]' + ' ' + '"' + chunk + '"'
52
+ chunks.append(chunk)
53
+ return chunks
54
+
55
+
56
+ class SemanticSearch:
57
+
58
+ def __init__(self):
59
+ self.use = hub.load('https://tfhub.dev/google/universal-sentence-encoder/4')
60
+ self.fitted = False
61
+
62
+
63
+ def fit(self, data, batch=1000, n_neighbors=5):
64
+ self.data = data
65
+ self.embeddings = self.get_text_embedding(data, batch=batch)
66
+ n_neighbors = min(n_neighbors, len(self.embeddings))
67
+ self.nn = NearestNeighbors(n_neighbors=n_neighbors)
68
+ self.nn.fit(self.embeddings)
69
+ self.fitted = True
70
+
71
+
72
+ def __call__(self, text, return_data=True):
73
+ inp_emb = self.use([text])
74
+ neighbors = self.nn.kneighbors(inp_emb, return_distance=False)[0]
75
+
76
+ if return_data:
77
+ return [self.data[i] for i in neighbors]
78
+ else:
79
+ return neighbors
80
+
81
+
82
+ def get_text_embedding(self, texts, batch=1000):
83
+ embeddings = []
84
+ for i in range(0, len(texts), batch):
85
+ text_batch = texts[i:(i+batch)]
86
+ emb_batch = self.use(text_batch)
87
+ embeddings.append(emb_batch)
88
+ embeddings = np.vstack(embeddings)
89
+ return embeddings
90
+
91
+
92
+
93
+ def load_recommender(path, start_page=1):
94
+ global recommender
95
+ texts = pdf_to_text(path, start_page=start_page)
96
+ chunks = text_to_chunks(texts, start_page=start_page)
97
+ recommender.fit(chunks)
98
+ return 'Corpus Loaded.'
99
+
100
+ def generate_text(openAI_key, prompt, model):
101
+ openai.api_key = openAI_key
102
+ temperature=0.7
103
+ max_tokens=1500
104
+ top_p=1
105
+ frequency_penalty=0
106
+ presence_penalty=0
107
+ message = openai.ChatCompletion.create(
108
+ model=model,
109
+ messages=[
110
+ {"role": "system", "content": "You are a question generator."},
111
+ {"role": "assistant", "content": "Here is some initial assistant message."},
112
+ {"role": "user", "content": prompt}
113
+ ],
114
+ temperature=.3,
115
+ max_tokens=max_tokens,
116
+ top_p=top_p,
117
+ frequency_penalty=frequency_penalty,
118
+ presence_penalty=presence_penalty,
119
+ )
120
+ print(message.choices[0])
121
+ message = message.choices[0].message['content']
122
+ return message
123
+
124
+
125
+ def generate_answer(question, openAI_key, model, difficulty):
126
+ topn_chunks = recommender(question)
127
+ prompt = 'search results:\n\n'
128
+ for c in topn_chunks:
129
+ prompt += c + '\n\n'
130
+
131
+ prompt += "Create 4 " + difficulty +" level content complexity multiple-choice questions with 4 options each, providing the correct answer for each question-option pair based on the search results. \n"\
132
+ "Cite each reference using [ Page Number] notation. Citation should be done at the end of each question."\
133
+ "Only answer what is asked. The answer should be short and concise. \n\nQuery: "
134
+
135
+ prompt += f"{question}\nAnswer:"
136
+ answer = generate_text(openAI_key, prompt, model)
137
+ answer = answer.replace("\n", "<br>")
138
+ print(answer)
139
+ return answer
140
+
141
+
142
+ def question_answer(chat_history, url, file, question, difficulty):
143
+ openAI_key = "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"
144
+ model = "gpt-4"
145
+ try:
146
+ if openAI_key.strip()=='':
147
+ return '[ERROR]: Please enter your Open AI Key. Get your key here : https://platform.openai.com/account/api-keys'
148
+ if url.strip() == '' and file is None:
149
+ return '[ERROR]: Both URL and PDF is empty. Provide at least one.'
150
+ if url.strip() != '' and file is not None:
151
+ return '[ERROR]: Both URL and PDF is provided. Please provide only one (either URL or PDF).'
152
+ if model is None or model =='':
153
+ return '[ERROR]: You have not selected any model. Please choose an LLM model.'
154
+ if url.strip() != '':
155
+ glob_url = url
156
+ download_pdf(glob_url, 'corpus.pdf')
157
+ load_recommender('corpus.pdf')
158
+ else:
159
+ old_file_name = file.name
160
+ file_name = file.name
161
+ # file_name = file_name[:-12] + file_name[-4:]
162
+ # os.rename(old_file_name, file_name)
163
+ load_recommender(file_name)
164
+ if question.strip() == '':
165
+ return '[ERROR]: Question field is empty'
166
+ answer = generate_answer(question, openAI_key, model, difficulty)
167
+ chat_history.append([question, answer])
168
+ print(chat_history)
169
+ return chat_history
170
+ except openai.error.InvalidRequestError as e:
171
+ return f'[ERROR]: Either you do not have access to GPT4 or you have exhausted your quota!'
172
+
173
+
174
+
175
+ recommender = SemanticSearch()
176
+
177
+ title = 'Skillwise GAN'
178
+ description = """ Analyze your pdf to generate questions and answers. """
179
+
180
+ with gr.Blocks(css="""#chatbot { font-size: 14px; height: 780px!important; }""") as demo:
181
+
182
+ gr.Markdown(f'<center><h3>{title}</h3></center>')
183
+ gr.Markdown(description)
184
+
185
+ with gr.Row():
186
+
187
+ with gr.Group():
188
+ with gr.Accordion(""):
189
+ url = gr.Textbox(label='Enter PDF URL here (Example: https://arxiv.org/pdf/1706.03762.pdf )')
190
+ gr.Markdown("<center><h4>OR<h4></center>")
191
+ file = gr.File(label='Upload your PDF/ Research Paper / Book here', file_types=['.pdf'])
192
+
193
+ difficulty = gr.Textbox(label='Enter difficulty level')
194
+
195
+ question = gr.Textbox(label='Enter your question title here')
196
+ btn = gr.Button(value='Submit')
197
+
198
+ btn.style(full_width=True)
199
+
200
+ with gr.Group():
201
+ chatbot = gr.Chatbot(placeholder="Chat History", label="Chat History", lines=500, elem_id="chatbot")
202
+
203
+
204
+
205
+ # Bind the click event of the button to the question_answer function
206
+ btn.click(
207
+ question_answer,
208
+ inputs=[chatbot, url, file, question, difficulty],
209
+ outputs=[chatbot],
210
+ )
211
+
212
+ demo.launch(debug=True, share=True)
requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ gradio
2
+ PyMuPDF
3
+ numpy
4
+ scikit-learn
5
+ tensorflow
6
+ tensorflow-hub
7
+ openai