retvq commited on
Commit
bf4d444
·
verified ·
1 Parent(s): e2b8864

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +129 -0
app.py CHANGED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import os
3
+ from langchain_community.document_loaders import PyPDFLoader
4
+ from langchain_text_splitters import RecursiveCharacterTextSplitter
5
+ from langchain_community.embeddings.fastembed import FastEmbedEmbeddings
6
+ from langchain_community.vectorstores import FAISS
7
+ from langchain_community.llms import LlamaCpp
8
+ from langchain.prompts import ChatPromptTemplate
9
+ from huggingface_hub import hf_hub_download
10
+
11
+ # --- 1. Model Setup (The "Brain") ---
12
+ # We download a "Quantized" (compressed) version of Llama 3 to run on CPU
13
+ MODEL_REPO = "QuantFactory/Meta-Llama-3-8B-Instruct-GGUF"
14
+ MODEL_FILE = "Meta-Llama-3-8B-Instruct.Q4_K_M.gguf"
15
+
16
+ print("Downloading model... this may take a minute on first run.")
17
+ model_path = hf_hub_download(
18
+ repo_id=MODEL_REPO,
19
+ filename=MODEL_FILE,
20
+ repo_type="model"
21
+ )
22
+
23
+ # Initialize the Model
24
+ llm = LlamaCpp(
25
+ model_path=model_path,
26
+ n_ctx=4096, # Context window size
27
+ temperature=0.7, # Creativity
28
+ max_tokens=2000, # Max length of output
29
+ n_batch=512,
30
+ verbose=True
31
+ )
32
+
33
+ # --- 2. The Core Logic ---
34
+ def generate_question_paper(pdf_file, difficulty, num_questions):
35
+ if not pdf_file:
36
+ return "Please upload a PDF file first."
37
+
38
+ try:
39
+ # A. Load PDF
40
+ loader = PyPDFLoader(pdf_file.name)
41
+ pages = loader.load()
42
+
43
+ # B. Split Text
44
+ text_splitter = RecursiveCharacterTextSplitter(
45
+ chunk_size=1000,
46
+ chunk_overlap=100
47
+ )
48
+ chunks = text_splitter.split_documents(pages)
49
+
50
+ # C. Vector Store (FAISS)
51
+ # We use FAISS (Ram-based) instead of Chroma for better Cloud compatibility
52
+ embeddings = FastEmbedEmbeddings()
53
+ vector_store = FAISS.from_documents(chunks, embeddings)
54
+
55
+ # D. Retrieve Context
56
+ # Get the top 7 most relevant chunks
57
+ retriever = vector_store.as_retriever(search_kwargs={"k": 7})
58
+ context_docs = retriever.invoke("Key concepts and definitions")
59
+ context_text = "\n\n".join([doc.page_content for doc in context_docs])
60
+
61
+ # E. Prompt
62
+ template = """
63
+ You are an expert academic examiner. Create a formal Question Paper based ONLY on the context provided below.
64
+
65
+ CONTEXT:
66
+ {context}
67
+
68
+ INSTRUCTIONS:
69
+ - Difficulty: {difficulty}
70
+ - Total Questions: {num_questions}
71
+ - Format:
72
+ Section A: Multiple Choice Questions (MCQs)
73
+ Section B: Short Answer Questions
74
+ Section C: Long Answer/Essay Questions
75
+ - Provide the Answer Key for MCQs at the very end.
76
+
77
+ Do not output conversational text. Output ONLY the exam paper.
78
+ """
79
+
80
+ prompt = ChatPromptTemplate.from_template(template)
81
+
82
+ # F. Generate
83
+ chain = prompt | llm
84
+ response = chain.invoke({
85
+ "context": context_text,
86
+ "difficulty": difficulty,
87
+ "num_questions": num_questions
88
+ })
89
+
90
+ return response
91
+
92
+ except Exception as e:
93
+ return f"Error processing PDF: {str(e)}"
94
+
95
+ # --- 3. The UI ---
96
+ theme = gr.themes.Soft(primary_hue="blue")
97
+
98
+ with gr.Blocks(theme=theme, title="AI Question Paper Generator") as demo:
99
+ gr.Markdown("# 📄 AI Question Paper Generator")
100
+ gr.Markdown("Hosted on Hugging Face • Powered by Llama 3 (GGUF)")
101
+
102
+ with gr.Row():
103
+ with gr.Column(scale=1):
104
+ pdf_input = gr.File(label="Upload Study Material (PDF)")
105
+
106
+ with gr.Group():
107
+ difficulty = gr.Radio(
108
+ ["Easy", "Medium", "Hard"],
109
+ label="Difficulty",
110
+ value="Medium"
111
+ )
112
+ num_questions = gr.Slider(
113
+ 5, 20, value=10, step=1,
114
+ label="Total Questions"
115
+ )
116
+
117
+ btn = gr.Button("Generate Question Paper", variant="primary")
118
+
119
+ with gr.Column(scale=2):
120
+ output = gr.Markdown(label="Generated Paper")
121
+
122
+ btn.click(
123
+ fn=generate_question_paper,
124
+ inputs=[pdf_input, difficulty, num_questions],
125
+ outputs=output
126
+ )
127
+
128
+ if __name__ == "__main__":
129
+ demo.launch()