yagnik12 commited on
Commit
44db095
·
verified ·
1 Parent(s): 2766639

Update ai_text_detector_valid_final.py

Browse files
Files changed (1) hide show
  1. ai_text_detector_valid_final.py +118 -77
ai_text_detector_valid_final.py CHANGED
@@ -1,90 +1,131 @@
 
1
  import torch
2
- from transformers import AutoTokenizer, AutoModelForSequenceClassification, pipeline
 
3
  import numpy as np
 
4
 
5
- # Multiple AI text detection models
6
- MODELS = {
7
- "DeBERTa Detector": "distilbert-base-uncased-finetuned-sst-2-english",
8
- "MonkeyDAnh":"MonkeyDAnh/my-awesome-ai-detector-roberta-base-v4-human-vs-machine-finetune",
9
- "Andreas122001":"andreas122001/roberta-academic-detector"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  }
11
-
12
- def load_model(model_id):
13
- tokenizer = AutoTokenizer.from_pretrained(model_id)
14
- model = AutoModelForSequenceClassification.from_pretrained(model_id)
15
- return tokenizer, model
16
-
17
- def predict(text, tokenizer, model):
18
- inputs = tokenizer(text, return_tensors="pt", truncation=True, padding=True)
 
 
 
 
 
 
19
  with torch.no_grad():
20
- outputs = model(**inputs)
21
- probs = torch.nn.functional.softmax(outputs.logits, dim=-1)
22
- return probs[0].numpy() # [human_prob, ai_prob]
23
-
24
-
25
- def verdict(ai_prob):
26
- """Return a human-readable verdict based on AI probability"""
27
- if ai_prob < 20:
28
- return "Most likely human-written."
29
- elif 20 <= ai_prob < 40:
30
- return "Possibly human-written with minimal AI assistance."
31
- elif 40 <= ai_prob < 60:
32
- return "Unclear – could be either human or AI-assisted."
33
- elif 60 <= ai_prob < 80:
34
- return "Possibly AI-generated, or a human using AI assistance."
35
- else: # ai_prob >= 80
36
- return "Likely AI-generated or heavily AI-assisted."
37
 
38
- def detect_text(text):
39
- results = {}
40
- ai_scores = []
41
 
42
- for name, model_id in MODELS.items():
43
- try:
44
- tokenizer, model = load_model(model_id)
45
- probs = predict(text, tokenizer, model)
46
- human_score, ai_score = probs
47
- results[name] = {
48
- "Human Probability": round(float(human_score) * 100, 2),
49
- "AI Probability": round(float(ai_score) * 100, 2),
50
- }
51
- ai_scores.append(ai_score)
52
- except Exception as e:
53
- results[name] = {"error": str(e)}
54
-
55
- # ------------------ Final Score (Average) ------------------
 
 
 
 
 
 
 
 
 
 
 
56
  try:
57
- ai_scores, human_scores = [], []
58
-
59
- for r in results.values():
60
- if isinstance(r, dict) and "AI Probability" in r and "Human Probability" in r:
61
- ai_scores.append(r["AI Probability"])
62
- human_scores.append(r["Human Probability"])
63
-
64
- if ai_scores and human_scores:
65
- avg_ai = sum(ai_scores) / len(ai_scores)
66
- avg_human = sum(human_scores) / len(human_scores)
67
-
68
- results["Final Score"] = {
69
- # "Human Probability (average)": float(round(avg_human, 2)),
70
- # "AI Probability (average)": float(round(avg_ai, 2))
71
- # "Verdict": verdict(avg_ai)
72
- verdict(avg_ai)
73
- }
74
  except Exception as e:
75
- results["Final Score"] = {"error": str(e)}
76
 
77
- return results
 
 
 
 
 
 
 
 
 
 
78
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
 
80
  if __name__ == "__main__":
81
- text = input("Enter text to analyze:\n")
82
- output = detect_text(text)
83
- print("\n--- Detection Results ---")
84
- for model, scores in output.items():
85
- print(f"\n[{model}]")
86
- for k, v in scores.items():
87
- if isinstance(v, (int, float)): # only add % for numeric values
88
- print(f"{k}: {v}%")
89
- else:
90
- print(f"{k}: {v}")
 
1
+ import os
2
  import torch
3
+ from transformers import AutoTokenizer, AutoModelForSequenceClassification
4
+ import requests
5
  import numpy as np
6
+ import re
7
 
8
+ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
9
+
10
+ # ---------------------------
11
+ # ModernBERT Models (SzegedAI Workflow)
12
+ # ---------------------------
13
+ model1_path = "modernbert.bin"
14
+ model2_path = "https://huggingface.co/mihalykiss/modernbert_2/resolve/main/Model_groups_3class_seed12"
15
+ model3_path = "https://huggingface.co/mihalykiss/modernbert_2/resolve/main/Model_groups_3class_seed22"
16
+
17
+ tokenizer_modernbert = AutoTokenizer.from_pretrained("answerdotai/ModernBERT-base")
18
+
19
+ model_1 = AutoModelForSequenceClassification.from_pretrained("answerdotai/ModernBERT-base", num_labels=41)
20
+ model_1.load_state_dict(torch.load(model1_path, map_location=device))
21
+ model_1.to(device).eval()
22
+
23
+ model_2 = AutoModelForSequenceClassification.from_pretrained("answerdotai/ModernBERT-base", num_labels=41)
24
+ model_2.load_state_dict(torch.hub.load_state_dict_from_url(model2_path, map_location=device))
25
+ model_2.to(device).eval()
26
+
27
+ model_3 = AutoModelForSequenceClassification.from_pretrained("answerdotai/ModernBERT-base", num_labels=41)
28
+ model_3.load_state_dict(torch.hub.load_state_dict_from_url(model3_path, map_location=device))
29
+ model_3.to(device).eval()
30
+
31
+ label_mapping = {
32
+ 0: '13B', 1: '30B', 2: '65B', 3: '7B', 4: 'GLM130B', 5: 'bloom_7b',
33
+ 6: 'bloomz', 7: 'cohere', 8: 'davinci', 9: 'dolly', 10: 'dolly-v2-12b',
34
+ 11: 'flan_t5_base', 12: 'flan_t5_large', 13: 'flan_t5_small',
35
+ 14: 'flan_t5_xl', 15: 'flan_t5_xxl', 16: 'gemma-7b-it', 17: 'gemma2-9b-it',
36
+ 18: 'gpt-3.5-turbo', 19: 'gpt-35', 20: 'gpt4', 21: 'gpt4o',
37
+ 22: 'gpt_j', 23: 'gpt_neox', 24: 'human', 25: 'llama3-70b', 26: 'llama3-8b',
38
+ 27: 'mixtral-8x7b', 28: 'opt_1.3b', 29: 'opt_125m', 30: 'opt_13b',
39
+ 31: 'opt_2.7b', 32: 'opt_30b', 33: 'opt_350m', 34: 'opt_6.7b',
40
+ 35: 'opt_iml_30b', 36: 'opt_iml_max_1.3b', 37: 't0_11b', 38: 't0_3b',
41
+ 39: 'text-davinci-002', 40: 'text-davinci-003'
42
  }
43
+
44
+ def clean_text(text: str) -> str:
45
+ text = re.sub(r"\s{2,}", " ", text)
46
+ text = re.sub(r"\s+([,.;:?!])", r"\1", text)
47
+ return text
48
+
49
+ def classify_szegedai(text: str):
50
+ """ModernBERT ensemble detector (replaces SzegedAI Space call)."""
51
+ cleaned_text = clean_text(text)
52
+ if not cleaned_text.strip():
53
+ return {"error": "Empty text"}
54
+
55
+ inputs = tokenizer_modernbert(cleaned_text, return_tensors="pt", truncation=True, padding=True).to(device)
56
+
57
  with torch.no_grad():
58
+ logits_1 = model_1(**inputs).logits
59
+ logits_2 = model_2(**inputs).logits
60
+ logits_3 = model_3(**inputs).logits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
 
62
+ probs = (torch.softmax(logits_1, dim=1) +
63
+ torch.softmax(logits_2, dim=1) +
64
+ torch.softmax(logits_3, dim=1)) / 3
65
 
66
+ probs = probs[0]
67
+ ai_probs = probs.clone()
68
+ ai_probs[24] = 0 # "human" label index
69
+ ai_total_prob = ai_probs.sum().item() * 100
70
+ human_prob = 100 - ai_total_prob
71
+
72
+ ai_index = torch.argmax(ai_probs).item()
73
+ ai_model = label_mapping[ai_index]
74
+
75
+ return {
76
+ "Human Probability": round(human_prob, 2),
77
+ "AI Probability": round(ai_total_prob, 2),
78
+ "Identified LLM": ai_model
79
+ }
80
+
81
+ # ---------------------------
82
+ # Your Other Detectors
83
+ # ---------------------------
84
+ MODELS = {
85
+ "DeBERTa Detector": "distilbert-base-uncased-finetuned-sst-2-english",
86
+ "MonkeyDAnh": "MonkeyDAnh/my-awesome-ai-detector-roberta-base-v4-human-vs-machine-finetune",
87
+ "Andreas122001": "andreas122001/roberta-academic-detector",
88
+ }
89
+
90
+ def run_hf_model(model_id, text):
91
  try:
92
+ tokenizer = AutoTokenizer.from_pretrained(model_id)
93
+ model = AutoModelForSequenceClassification.from_pretrained(model_id)
94
+ inputs = tokenizer(text, return_tensors="pt", truncation=True, padding=True)
95
+ with torch.no_grad():
96
+ logits = model(**inputs).logits
97
+ probs = torch.softmax(logits, dim=-1).cpu().numpy()[0]
98
+ return {"Human Probability": float(probs[0]*100), "AI Probability": float(probs[1]*100)}
 
 
 
 
 
 
 
 
 
 
99
  except Exception as e:
100
+ return {"error": str(e)}
101
 
102
+ # ---------------------------
103
+ # Main Detector
104
+ # ---------------------------
105
+ def detect_text(text):
106
+ results = {}
107
+ # HuggingFace transformer models
108
+ for name, model_id in MODELS.items():
109
+ results[name] = run_hf_model(model_id, text)
110
+
111
+ # SzegedAI ModernBERT ensemble
112
+ results["SzegedAI Detector"] = classify_szegedai(text)
113
 
114
+ # Final verdict
115
+ ai_probs = []
116
+ for v in results.values():
117
+ if "AI Probability" in v:
118
+ ai_probs.append(v["AI Probability"])
119
+ avg_ai = np.mean(ai_probs) if ai_probs else 0
120
+ if avg_ai > 80:
121
+ verdict = "Likely AI-generated"
122
+ elif avg_ai > 40:
123
+ verdict = "Possibly human-written with AI assistance"
124
+ else:
125
+ verdict = "Likely human-written"
126
+ results["Final Score"] = {"Verdict": verdict}
127
+ return results
128
 
129
  if __name__ == "__main__":
130
+ sample = "This is a test sentence written by AI or human."
131
+ print(detect_text(sample))