# import os # import json # import re # import numpy as np # import torch # import torch.nn as nn # import torch.nn.functional as F # import gradio as gr # # Standalone Model Architecture # class SimpleMCQModel(nn.Module): # def __init__(self, vocab_size, embed_dim=128, hidden_dim=64): # super().__init__() # self.embedding = nn.Embedding(vocab_size, embed_dim, padding_idx=0) # self.fc1 = nn.Linear(embed_dim, hidden_dim) # self.relu = nn.ReLU() # self.fc2 = nn.Linear(hidden_dim, 1) # def forward(self, x): # batch_size, num_opts, max_len = x.shape # x = x.view(batch_size * num_opts, max_len) # embedded = self.embedding(x) # pooled = embedded.mean(dim=1) # out = self.relu(self.fc1(pooled)) # scores = self.fc2(out) # scores = scores.view(batch_size, num_opts) # return scores # # Standalone Tokenizer # class MCQTokenizer: # def __init__(self, vocab=None, max_len=128): # self.vocab = vocab or {"": 0, "": 1} # self.max_len = max_len # @staticmethod # def clean_text(text): # text = str(text).lower() # text = re.sub(r'[^a-z0-9 ]', '', text) # return text # def tokenize(self, text): # words = self.clean_text(text).split() # tokens = [self.vocab.get(w, self.vocab.get("", 1)) for w in words] # if len(tokens) < self.max_len: # tokens = tokens + [self.vocab.get("", 0)] * (self.max_len - len(tokens)) # else: # tokens = tokens[:self.max_len] # return tokens # @classmethod # def load_vocab(cls, vocab_path, max_len=128): # with open(vocab_path, 'r', encoding='utf-8') as f: # vocab = json.load(f) # return cls(vocab=vocab, max_len=max_len) # # Load artifacts locally # BASE_DIR = os.path.dirname(os.path.abspath(__file__)) # CONFIG_PATH = os.path.join(BASE_DIR, "config.json") # MODEL_PATH = os.path.join(BASE_DIR, "model.pt") # VOCAB_PATH = os.path.join(BASE_DIR, "vocab.json") # LABEL_PATH = os.path.join(BASE_DIR, "label_mapping.json") # # Fallback to model1_hf if running from project root # if not os.path.exists(CONFIG_PATH): # BASE_DIR = os.path.join(os.path.dirname(BASE_DIR), "model1_hf") # CONFIG_PATH = os.path.join(BASE_DIR, "config.json") # MODEL_PATH = os.path.join(BASE_DIR, "model.pt") # VOCAB_PATH = os.path.join(BASE_DIR, "vocab.json") # LABEL_PATH = os.path.join(BASE_DIR, "label_mapping.json") # with open(CONFIG_PATH, "r", encoding="utf-8") as f: # config = json.load(f) # with open(LABEL_PATH, "r", encoding="utf-8") as f: # raw_labels = json.load(f) # label_map = {int(k): v for k, v in raw_labels.items()} # tokenizer = MCQTokenizer.load_vocab(VOCAB_PATH, max_len=config.get("max_length", 128)) # model = SimpleMCQModel(vocab_size=config["vocab_size"], embed_dim=config["embedding_dim"], hidden_dim=config["hidden_dim"]) # try: # model.load_state_dict(torch.load(MODEL_PATH, map_location="cpu")) # model.eval() # print("Model loaded successfully") # except Exception as e: # print("ERROR:", e) # raise # def predict_mcq(prompt, opt_a, opt_b, opt_c, opt_d, opt_e): # if not prompt.strip(): # return ( # "Please enter a question.", # "", # {} # ) # options = [opt_a, opt_b, opt_c, opt_d, opt_e] # option_tensors = [] # for opt_text in options: # combined_text = str(prompt) + " " + str(opt_text) # tokens = tokenizer.tokenize(combined_text) # option_tensors.append(tokens) # x = torch.tensor([option_tensors], dtype=torch.long) # with torch.no_grad(): # logits = model(x) # probs = F.softmax(logits, dim=1).squeeze(0).cpu().numpy() # sorted_indices = np.argsort(probs)[::-1] # top1_idx = sorted_indices[0] # top1_label = label_map[top1_idx] # top1_text = options[top1_idx] # top3_labels = [label_map[i] for i in sorted_indices[:3]] # # Confidence distribution dict # confidence_dict = {f"Option {label_map[i]}: {options[i]}": float(probs[i]) for i in range(5)} # top_pred_badge = f"🏆 Option {top1_label}: {top1_text} ({probs[top1_idx]*100:.1f}% Confidence)" # top3_str = " ".join(top3_labels) # return top_pred_badge, top3_str, confidence_dict # # Custom CSS for rich aesthetics # custom_css = """ # .container { max-width: 900px; margin: auto; } # .header-box { text-align: center; margin-bottom: 20px; } # .prediction-box { font-size: 1.3em; font-weight: bold; padding: 15px; background: #eef2ff; border-radius: 8px; border-left: 5px solid #4f46e5; margin-bottom: 15px; } # """ # print("Creating Gradio interface...") # with gr.Blocks() as demo: # print("Blocks created") # gr.Markdown( # """ # # 🧠 Smart MCQ Solver — Model 1 Demo # ### Custom PyTorch Deep Learning Architecture (`SimpleMCQModel`) # Select an example or type a custom Multiple Choice Question (MCQ) to view the model's top predictions and option probability distribution. # """ # ) # with gr.Row(): # with gr.Column(scale=3): # prompt_input = gr.Textbox( # label="Question / Prompt", # placeholder="Enter the main question or prompt...", # lines=3, # value="Which of the following elements has the highest electrical conductivity at room temperature?" # ) # opt_a_input = gr.Textbox(label="Option A", value="Gold") # opt_b_input = gr.Textbox(label="Option B", value="Silver") # opt_c_input = gr.Textbox(label="Option C", value="Copper") # opt_d_input = gr.Textbox(label="Option D", value="Aluminum") # opt_e_input = gr.Textbox(label="Option E", value="Iron") # submit_btn = gr.Button("⚡ Predict Best Option", variant="primary", size="lg") # with gr.Column(scale=2): # top_pred_output = gr.Markdown(value="*Submit a question to see prediction results.*") # top3_output = gr.Textbox(label="Top-3 Ranked Choices (MAP@3 Format)", interactive=False) # confidence_output = gr.JSON(label="Probability Distribution") # # gr.Examples( # # examples=[ # # [ # # "Which process converts light energy into chemical energy in plants?", # # "Respiration", # # "Photosynthesis", # # "Transpiration", # # "Osmosis", # # "Fermentation" # # ], # # [ # # "What is the derivative of x^2 with respect to x?", # # "x", # # "2x", # # "x^3 / 3", # # "2", # # "1/x" # # ], # # [ # # "Which planet is known as the Red Planet?", # # "Venus", # # "Jupiter", # # "Mars", # # "Saturn", # # "Mercury" # # ] # # ], # # inputs=[prompt_input, opt_a_input, opt_b_input, opt_c_input, opt_d_input, opt_e_input], # # outputs=[top_pred_output, top3_output, confidence_output], # # fn=predict_mcq, # # cache_examples=False # # ) # submit_btn.click( # fn=predict_mcq, # inputs=[prompt_input, opt_a_input, opt_b_input, opt_c_input, opt_d_input, opt_e_input], # outputs=[top_pred_output, top3_output, confidence_output] # ) # # demo.queue() # if __name__ == "__main__": # print("Launching app...") # demo.launch(show_error=True) import gradio as gr with gr.Blocks() as demo: gr.Markdown("# Hello World") if __name__ == "__main__": demo.launch(show_error=True)