geekydraco commited on
Commit
9fa84ea
·
verified ·
1 Parent(s): fae8722

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +215 -0
app.py ADDED
@@ -0,0 +1,215 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import time
2
+ from pathlib import Path
3
+ import sys
4
+ import os
5
+ import logging
6
+
7
+ # ==========================================
8
+ # 0. Fix sys.path BEFORE importing anything from src/
9
+ # (src/generators/__init__.py etc. do bare "from generators.xxx import ..."
10
+ # imports that require the src/ folder itself to already be on sys.path)
11
+ # ==========================================
12
+ project_root = Path(__file__).parent.resolve()
13
+ sys.path.insert(0, str(project_root))
14
+ sys.path.insert(0, str(project_root / "src"))
15
+
16
+ import gradio as gr
17
+ import torch
18
+ from src.config import load_config
19
+ from src.models.load_model import ModelLoader
20
+ from src.generators.program_generator import GenerationPipeline
21
+ from src.generators.text_to_mongo_generator import TextToMongoGenerator
22
+ from src.vectorDB.index_manager import IndexManager
23
+ from src.rag.rag_pipeline import RAGPipeline
24
+
25
+ # Configure logging
26
+ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
27
+ logger = logging.getLogger(__name__)
28
+
29
+ # Environment variables to suppress warnings
30
+ os.environ["TOKENIZERS_PARALLELISM"] = "false"
31
+ os.environ["PYTORCH_MPS_HIGH_WATERMARK_RATIO"] = "0.0"
32
+ os.environ["PYTORCH_ENABLE_MPS_FALLBACK"] = "1"
33
+
34
+ # ==========================================
35
+ # 1. Load Configuration & Models
36
+ # ==========================================
37
+ logger.info("Loading configuration...")
38
+ config = load_config("configs/config.yaml")
39
+
40
+ logger.info("Initializing Model Loader...")
41
+ model_loader = ModelLoader(config)
42
+ tokenizer = model_loader.load_tokenizer()
43
+ base_model = model_loader.load_base_model()
44
+
45
+ # Try to load the Fine-Tuned (LoRA) model if it exists
46
+ lora_path = Path(config.lora.output_dir)
47
+ if lora_path.exists() and (lora_path / "adapter_config.json").exists():
48
+ logger.info(f"✅ Found LoRA adapter at {lora_path}. Loading Fine-Tuned model...")
49
+ finetuned_model = model_loader.autodetect_saved_model(str(lora_path))
50
+ else:
51
+ logger.warning("⚠️ No LoRA adapter found. Fine-Tuned model will fallback to Base model.")
52
+ finetuned_model = base_model
53
+
54
+ # ==========================================
55
+ # 2. Setup Generation Pipelines
56
+ # ==========================================
57
+ logger.info("Setting up generation pipelines...")
58
+ base_pipeline = GenerationPipeline(base_model, tokenizer, config.generation)
59
+ finetuned_pipeline = GenerationPipeline(finetuned_model, tokenizer, config.generation)
60
+
61
+ base_generator = TextToMongoGenerator(base_pipeline, config)
62
+ finetuned_generator = TextToMongoGenerator(finetuned_pipeline, config)
63
+
64
+ # ==========================================
65
+ # 3. Setup RAG Pipeline (Optional)
66
+ # ==========================================
67
+ rag_pipeline = None
68
+ try:
69
+ index_manager = IndexManager(
70
+ embedding_model=config.embedding.external_model,
71
+ language=config.retrieval.structural_language,
72
+ semantic_weight=1.0 - config.retrieval.structural_weight_alpha,
73
+ ast_weight=config.retrieval.structural_weight_alpha,
74
+ save_dir="data/indices"
75
+ )
76
+
77
+ if index_manager._indices_exist():
78
+ index_manager.load_indices()
79
+ rag_pipeline = RAGPipeline(
80
+ retriever=index_manager,
81
+ generator=finetuned_pipeline,
82
+ config=config.generation
83
+ )
84
+ logger.info("✅ RAG Pipeline initialized successfully.")
85
+ else:
86
+ logger.warning("⚠️ RAG indices not found in 'data/indices'. RAG feature will be disabled.")
87
+ except Exception as e:
88
+ logger.error(f"⚠️ Could not initialize RAG pipeline: {e}")
89
+
90
+
91
+ # ==========================================
92
+ # 4. Gradio Generation Logic
93
+ # ==========================================
94
+ def generate_mongo_query(question: str, model_choice: str, use_rag: bool, top_k: int):
95
+ if not question.strip():
96
+ return "Please enter a valid question.", "Latency: N/A"
97
+
98
+ start_time = time.time()
99
+
100
+ # RAG Generation
101
+ if use_rag and rag_pipeline is not None:
102
+ generated_query, context_metadata = rag_pipeline.generate_with_rag(question, top_k=int(top_k))
103
+ latency = (time.time() - start_time) * 1000
104
+
105
+ # Format context for display
106
+ context_str = "Retrieved Context:\n" + "-" * 30 + "\n"
107
+ for i, ctx in enumerate(context_metadata[:int(top_k)]):
108
+ q = ctx.get('question', 'N/A')
109
+ mql = ctx.get('generated_mongodb_query', ctx.get('mongodb_query', 'N/A'))
110
+ context_str += f"[{i + 1}] Q: {q}\n MQL: {mql}\n\n"
111
+
112
+ return generated_query, f"⏱️ Latency: {latency:.2f} ms\n\n{context_str}"
113
+
114
+ # Standard Generation (Base or Fine-Tuned)
115
+ else:
116
+ if model_choice == "Fine-Tuned (LoRA)":
117
+ result = finetuned_generator.generate_single(question)
118
+ else:
119
+ result = base_generator.generate_single(question)
120
+
121
+ latency = result['latency_ms']
122
+ info_text = f"⏱️ Latency: {latency:.2f} ms\nModel: {model_choice}"
123
+ return result['generated_query'], info_text
124
+
125
+
126
+ # ==========================================
127
+ # 5. Build Gradio UI
128
+ # ==========================================
129
+ with gr.Blocks(title="Text-to-MongoDB Generator", theme=gr.themes.Soft()) as demo:
130
+ gr.Markdown(
131
+ """
132
+ # 🚀 Text-to-MongoDB Query Generator
133
+ Convert natural language questions into executable MongoDB queries using **Base**, **Fine-Tuned**, or **RAG-enhanced** models.
134
+ """
135
+ )
136
+
137
+ with gr.Row():
138
+ # Left Column: Inputs
139
+ with gr.Column(scale=3):
140
+ question_input = gr.Textbox(
141
+ label="Natural Language Question",
142
+ placeholder="e.g., How many singers do we have?",
143
+ lines=2,
144
+ info="Type your question about the database here."
145
+ )
146
+
147
+ with gr.Row():
148
+ model_choice = gr.Radio(
149
+ choices=["Base Model", "Fine-Tuned (LoRA)"],
150
+ value="Fine-Tuned (LoRA)",
151
+ label="Model Selection"
152
+ )
153
+ use_rag = gr.Checkbox(
154
+ label="🧠 Use RAG (Retrieval-Augmented Generation)",
155
+ value=False,
156
+ info="Requires pre-built indices"
157
+ )
158
+
159
+ with gr.Accordion("⚙️ RAG Settings", open=False):
160
+ top_k_slider = gr.Slider(
161
+ minimum=1, maximum=10, value=3, step=1,
162
+ label="Top-K Retrieved Contexts",
163
+ info="Number of similar examples to retrieve from the vector database."
164
+ )
165
+
166
+ generate_btn = gr.Button("Generate MongoDB Query", variant="primary", size="lg")
167
+
168
+ # Right Column: Outputs
169
+ with gr.Column(scale=2):
170
+ query_output = gr.Code(
171
+ label="Generated MongoDB Query",
172
+ language="javascript",
173
+ lines=6,
174
+ interactive=False
175
+ )
176
+ info_output = gr.Textbox(
177
+ label="Generation Info & Context",
178
+ lines=8,
179
+ interactive=False,
180
+ max_lines=15
181
+ )
182
+
183
+ gr.Markdown("---")
184
+ gr.Markdown("### 💡 Example Questions")
185
+ gr.Examples(
186
+ examples=[
187
+ ["How many singers do we have?"],
188
+ ["What is the average age of all singers from France?"],
189
+ ["Show the name and release year of the song by the youngest singer."],
190
+ ["Find the number of pets whose weight is heavier than 10."],
191
+ ["What are the different countries with singers above age 20?"],
192
+ ["List the name and date of each battle."],
193
+ ],
194
+ inputs=[question_input],
195
+ cache_examples=False
196
+ )
197
+
198
+ # Link button to function
199
+ generate_btn.click(
200
+ fn=generate_mongo_query,
201
+ inputs=[question_input, model_choice, use_rag, top_k_slider],
202
+ outputs=[query_output, info_output]
203
+ )
204
+
205
+ # ==========================================
206
+ # 6. Launch the App
207
+ # ==========================================
208
+ if __name__ == "__main__":
209
+ # Launch locally on port 7860
210
+ demo.launch(
211
+ server_name="0.0.0.0", # Makes it accessible on your local network
212
+ server_port=7860,
213
+ share=False, # Set to True if you want a public temporary URL
214
+ show_error=True
215
+ )