import os import torch import torch.nn as nn import torch.nn.functional as F from transformers import AutoTokenizer, AutoModelForSequenceClassification, AutoModel from tavily import TavilyClient from dotenv import load_dotenv import gradio as gr load_dotenv() TAVILY_API_KEY = os.getenv("TAVILY_API_KEY") try: tavily_client = TavilyClient(api_key=TAVILY_API_KEY) except Exception: tavily_client = None class StanceModel(nn.Module): def __init__(self, model_name, num_labels=2, dropout=0.1): super().__init__() self.encoder = AutoModel.from_pretrained(model_name) hidden = self.encoder.config.hidden_size self.dropout = nn.Dropout(dropout) self.classifier = nn.Sequential( nn.Linear(hidden, hidden // 2), nn.GELU(), nn.Dropout(dropout), nn.Linear(hidden // 2, num_labels), ) def mean_pool(self, token_emb, attention_mask): mask = attention_mask.unsqueeze(-1).float() summed = (token_emb * mask).sum(dim=1) count = mask.sum(dim=1).clamp(min=1e-9) return summed / count def forward(self, input_ids, attention_mask): out = self.encoder(input_ids=input_ids, attention_mask=attention_mask) pooled = self.mean_pool(out.last_hidden_state, attention_mask) pooled = self.dropout(pooled) return self.classifier(pooled) device = torch.device("cuda" if torch.cuda.is_available() else "cpu") print("Loading VeriDex Models...") BASE_DIR = os.path.dirname(os.path.abspath(__file__)) fn_dir = os.path.join(BASE_DIR, "models", "fakeNewsModel") st_dir = os.path.join(BASE_DIR, "models", "stanceModel") image_dir = os.path.join(BASE_DIR, "models", "imageDetectionModel") # Ensure directories exist os.makedirs(fn_dir, exist_ok=True) os.makedirs(st_dir, exist_ok=True) os.makedirs(image_dir, exist_ok=True) # Fetch heavy weights from HF Model repository if not present locally from huggingface_hub import hf_hub_download repo_id = "rex177/VeriDex-Weights" if not os.path.exists(os.path.join(fn_dir, "pytorch_model.bin")): try: print("Downloading Fake News Model Weights from Hub...") hf_hub_download(repo_id=repo_id, filename="pytorch_model.bin", local_dir=fn_dir) except Exception as e: print(f"Failed to download fake news weights: {e}") if not os.path.exists(os.path.join(st_dir, "model.safetensors")): try: print("Downloading Stance Model Weights from Hub...") hf_hub_download(repo_id=repo_id, filename="model.safetensors", local_dir=st_dir) except Exception as e: print(f"Failed to download stance weights: {e}") if not os.path.exists(os.path.join(image_dir, "best_model.pth")): try: print("Downloading Image Forensics Weights from Hub...") hf_hub_download(repo_id=repo_id, filename="best_model.pth", local_dir=image_dir) except Exception as e: print(f"Failed to download image weights: {e}") if not os.path.exists(os.path.join(st_dir, "classifier_head.pt")): try: hf_hub_download(repo_id=repo_id, filename="classifier_head.pt", local_dir=st_dir) except Exception: pass if not os.path.exists(os.path.join(st_dir, "spm.model")): try: hf_hub_download(repo_id=repo_id, filename="spm.model", local_dir=st_dir) except Exception: pass # Load Fake News Model if os.path.exists(os.path.join(fn_dir, "pytorch_model.bin")) or os.path.exists(os.path.join(fn_dir, "model.safetensors")): fn_tokenizer = AutoTokenizer.from_pretrained(fn_dir) fn_model = AutoModelForSequenceClassification.from_pretrained(fn_dir).to(device) else: fn_tokenizer = AutoTokenizer.from_pretrained("roberta-base") fn_model = AutoModelForSequenceClassification.from_pretrained("roberta-base", num_labels=2).to(device) fn_model.eval() # Load Stance Model st_base = "microsoft/deberta-v3-base" if os.path.exists(os.path.join(st_dir, "model.safetensors")) or os.path.exists(os.path.join(st_dir, "pytorch_model.bin")): st_tokenizer = AutoTokenizer.from_pretrained(st_dir) st_model = StanceModel(st_dir).to(device) else: st_tokenizer = AutoTokenizer.from_pretrained(st_base) st_model = StanceModel(st_base).to(device) head_path = os.path.join(st_dir, "classifier_head.pt") if os.path.exists(head_path): st_model.classifier.load_state_dict(torch.load(head_path, map_location=device)) st_model.eval() print("VeriDex Engine Ready!") def verify_claim(text, image=None): if not text or len(text.strip()) == 0: return "
Fake Probability: {round(prob_fake * 100, 2)}%
Real Probability: {round(prob_real * 100, 2)}%
{image_status}