geekydraco commited on
Commit
86d6d13
·
verified ·
1 Parent(s): b82461f

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +234 -0
app.py ADDED
@@ -0,0 +1,234 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import spaces # must be imported before torch/other CUDA-touching modules (ZeroGPU requirement)
2
+ import time
3
+ from pathlib import Path
4
+ import sys
5
+ import os
6
+ import logging
7
+
8
+ # ==========================================
9
+ # 0. Fix sys.path BEFORE importing anything from src/
10
+ # ==========================================
11
+ project_root = Path(__file__).parent.resolve()
12
+ sys.path.insert(0, str(project_root))
13
+ sys.path.insert(0, str(project_root / "src"))
14
+
15
+ import gradio as gr
16
+ import torch
17
+ from config import load_config
18
+ from src.models.load_model import ModelLoader
19
+ from src.generators.program_generator import GenerationPipeline
20
+ from src.generators.text_to_mongo_generator import TextToMongoGenerator
21
+ from src.generators.doc_generator import DocGenerator
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
+ # Text-to-MongoDB Generators
62
+ base_generator = TextToMongoGenerator(base_pipeline, config)
63
+ finetuned_generator = TextToMongoGenerator(finetuned_pipeline, config)
64
+
65
+ # Documentation Generators
66
+ base_doc_generator = DocGenerator(base_pipeline)
67
+ finetuned_doc_generator = DocGenerator(finetuned_pipeline)
68
+
69
+ # ==========================================
70
+ # 3. Setup RAG Pipeline (Optional)
71
+ # ==========================================
72
+ rag_pipeline = None
73
+ try:
74
+ index_manager = IndexManager(
75
+ embedding_model=config.embedding.external_model,
76
+ language=config.retrieval.structural_language,
77
+ semantic_weight=1.0 - config.retrieval.structural_weight_alpha,
78
+ ast_weight=config.retrieval.structural_weight_alpha,
79
+ save_dir="data/indices"
80
+ )
81
+ if index_manager._indices_exist():
82
+ index_manager.load_indices()
83
+ rag_pipeline = RAGPipeline(
84
+ retriever=index_manager,
85
+ generator=finetuned_pipeline,
86
+ config=config.generation
87
+ )
88
+ logger.info("✅ RAG Pipeline initialized successfully.")
89
+ else:
90
+ logger.warning("⚠️ RAG indices not found in 'data/indices'. RAG feature will be disabled.")
91
+ except Exception as e:
92
+ logger.error(f"⚠️ Could not initialize RAG pipeline: {e}")
93
+
94
+ # ==========================================
95
+ # 4. Gradio Generation Logic
96
+ # ==========================================
97
+ @spaces.GPU(duration=60)
98
+ def generate_output(task, input_text, model_choice, use_rag, top_k):
99
+ if not input_text.strip():
100
+ return "Please enter a valid input.", "Latency: N/A"
101
+
102
+ start_time = time.time()
103
+
104
+ if task == "Text-to-MongoDB":
105
+ if use_rag and rag_pipeline is not None:
106
+ generated_query, context_metadata = rag_pipeline.generate_with_rag(input_text, top_k=int(top_k))
107
+ latency = (time.time() - start_time) * 1000
108
+ context_str = "Retrieved Context:\n" + "-" * 30 + "\n"
109
+ for i, ctx in enumerate(context_metadata[:int(top_k)]):
110
+ q = ctx.get('question', 'N/A')
111
+ mql = ctx.get('generated_mongodb_query', ctx.get('mongodb_query', 'N/A'))
112
+ context_str += f"[{i + 1}] Q: {q}\n MQL: {mql}\n\n"
113
+ return generated_query, f"⏱️ Latency: {latency:.2f} ms\n\n{context_str}"
114
+ else:
115
+ if model_choice == "Fine-Tuned (LoRA)":
116
+ result = finetuned_generator.generate_single(input_text)
117
+ else:
118
+ result = base_generator.generate_single(input_text)
119
+ latency = result['latency_ms']
120
+ info_text = f"⏱️ Latency: {latency:.2f} ms\nModel: {model_choice}\nTask: Text-to-MongoDB"
121
+ return result['generated_query'], info_text
122
+
123
+ elif task == "Documentation Generation":
124
+ if model_choice == "Fine-Tuned (LoRA)":
125
+ generated_doc = finetuned_doc_generator.generate_docstring(input_text)
126
+ else:
127
+ generated_doc = base_doc_generator.generate_docstring(input_text)
128
+ latency = (time.time() - start_time) * 1000
129
+ info_text = f"⏱️ Latency: {latency:.2f} ms\nModel: {model_choice}\nTask: Documentation Generation"
130
+ return generated_doc, info_text
131
+
132
+ def update_ui(task):
133
+ """Dynamically updates input placeholders and output syntax highlighting based on the selected task."""
134
+ if task == "Text-to-MongoDB":
135
+ return (
136
+ gr.update(placeholder="e.g., How many singers do we have?", label="Natural Language Question"),
137
+ gr.update(language="javascript")
138
+ )
139
+ else:
140
+ return (
141
+ gr.update(placeholder="e.g., def add(a, b):\n return a + b", label="Code Snippet"),
142
+ gr.update(language="python")
143
+ )
144
+
145
+ # ==========================================
146
+ # 5. Build Gradio UI
147
+ # ==========================================
148
+ with gr.Blocks(title="CodeGen", theme=gr.themes.Soft()) as demo:
149
+ gr.Markdown(
150
+ """
151
+ # 🚀 CodeGen
152
+ Generate **MongoDB queries** or **Code Documentation** using Base, Fine-Tuned, or RAG-enhanced models.
153
+ """
154
+ )
155
+
156
+ with gr.Row():
157
+ # Left Column: Controls
158
+ with gr.Column(scale=1):
159
+ task_selector = gr.Radio(
160
+ choices=["Text-to-MongoDB", "Documentation Generation"],
161
+ value="Text-to-MongoDB",
162
+ label="Select Task"
163
+ )
164
+ model_choice = gr.Radio(
165
+ choices=["Base Model", "Fine-Tuned (LoRA)"],
166
+ value="Fine-Tuned (LoRA)",
167
+ label="Model Selection"
168
+ )
169
+
170
+ with gr.Accordion("⚙️ Advanced Settings", open=False):
171
+ use_rag = gr.Checkbox(
172
+ label="🧠 Use RAG (Text-to-MongoDB only)",
173
+ value=False,
174
+ info="Requires pre-built indices"
175
+ )
176
+ top_k_slider = gr.Slider(
177
+ minimum=1, maximum=10, value=3, step=1,
178
+ label="Top-K Retrieved Contexts"
179
+ )
180
+
181
+ generate_btn = gr.Button("Generate", variant="primary", size="lg")
182
+
183
+ # Right Column: Inputs & Outputs
184
+ with gr.Column(scale=2):
185
+ input_box = gr.Textbox(
186
+ label="Natural Language Question",
187
+ placeholder="e.g., How many singers do we have?",
188
+ lines=6,
189
+ info="Type your question or paste your code snippet here."
190
+ )
191
+ output_box = gr.Code(
192
+ label="Generated Output",
193
+ language="javascript",
194
+ lines=10,
195
+ interactive=False
196
+ )
197
+ info_output = gr.Textbox(
198
+ label="Generation Info",
199
+ lines=4,
200
+ interactive=False
201
+ )
202
+
203
+ gr.Markdown("---")
204
+ gr.Markdown("### 💡 Example Prompts")
205
+ gr.Examples(
206
+ examples=[
207
+ ["How many singers do we have?", "Text-to-MongoDB"],
208
+ ["What is the average age of all singers from France?", "Text-to-MongoDB"],
209
+ ["def calculate_area(radius):\n return 3.14159 * radius ** 2", "Documentation Generation"],
210
+ ["import os\ndef list_files(directory):\n return os.listdir(directory)", "Documentation Generation"],
211
+ ],
212
+ inputs=[input_box, task_selector],
213
+ cache_examples=False
214
+ )
215
+
216
+ # Link events
217
+ task_selector.change(fn=update_ui, inputs=task_selector, outputs=[input_box, output_box])
218
+
219
+ generate_btn.click(
220
+ fn=generate_output,
221
+ inputs=[task_selector, input_box, model_choice, use_rag, top_k_slider],
222
+ outputs=[output_box, info_output]
223
+ )
224
+
225
+ # ==========================================
226
+ # 6. Launch the App
227
+ # ==========================================
228
+ if __name__ == "__main__":
229
+ demo.launch(
230
+ server_name="0.0.0.0",
231
+ server_port=7860,
232
+ share=False,
233
+ show_error=True
234
+ )