adyashanayak165-code commited on
Commit
f294f90
·
1 Parent(s): 50cac0b

final interface design

Browse files
app.py CHANGED
@@ -1,36 +1,42 @@
1
- import streamlit as st
2
- import streamlit as st
 
3
  import torch
4
 
5
- from transformers import (
6
- DistilBertForSequenceClassification,
7
- DistilBertTokenizerFast
8
- )
9
  MODEL_PATH = "AI-MODEL-FINGERPRINTING/notebooks/saved_distilbert_model"
10
 
11
- tokenizer = DistilBertTokenizerFast.from_pretrained(MODEL_PATH)
12
 
13
- model = DistilBertForSequenceClassification.from_pretrained(
14
- MODEL_PATH
15
- )
16
 
17
  model.eval()
18
 
19
- st.title("AI Model Fingerprinter")
20
-
21
- text = st.text_area(
22
- "Paste text here",
23
- height=250
24
- )
25
- model_names = [
26
- "Claude",
27
- "Gemini",
28
- "Grok",
29
- "Mistral",
30
- "OpenAI"
31
  ]
32
 
33
- if st.button("Analyze"):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
 
35
  inputs = tokenizer(
36
  text,
@@ -42,22 +48,22 @@ if st.button("Analyze"):
42
 
43
  with torch.no_grad():
44
  outputs = model(**inputs)
45
-
46
 
47
- probs = torch.softmax(outputs.logits, dim=1)
48
- st.write("Confidence Scores")
49
 
50
- for i, name in enumerate(model_names):
51
- st.write(
52
- f"{name}: {probs[0][i].item():.4f}"
53
- )
54
 
55
- pred_class = torch.argmax(probs, dim=1).item()
 
 
 
56
 
57
-
 
 
 
58
 
59
- predicted_model = model_names[pred_class]
60
 
61
- st.success(
62
- f"Predicted Model: {predicted_model}"
63
- )
 
1
+
2
+ from flask import Flask, render_template, request, jsonify
3
+ from transformers import AutoTokenizer, AutoModelForSequenceClassification
4
  import torch
5
 
6
+ app = Flask(__name__)
7
+
 
 
8
  MODEL_PATH = "AI-MODEL-FINGERPRINTING/notebooks/saved_distilbert_model"
9
 
10
+ print("Loading model...")
11
 
12
+ tokenizer = AutoTokenizer.from_pretrained(MODEL_PATH)
13
+ model = AutoModelForSequenceClassification.from_pretrained(MODEL_PATH)
 
14
 
15
  model.eval()
16
 
17
+ MODEL_NAMES = [
18
+ "claude",
19
+ "gemini",
20
+ "groq",
21
+ "mistral",
22
+ "openai"
 
 
 
 
 
 
23
  ]
24
 
25
+
26
+ @app.route("/")
27
+ def home():
28
+ return render_template("index.html")
29
+
30
+
31
+ @app.route("/predict", methods=["POST"])
32
+ def predict():
33
+
34
+ data = request.get_json()
35
+
36
+ text = data.get("text", "").strip()
37
+
38
+ if not text:
39
+ return jsonify({"error": "No text provided"})
40
 
41
  inputs = tokenizer(
42
  text,
 
48
 
49
  with torch.no_grad():
50
  outputs = model(**inputs)
51
+ probs = torch.softmax(outputs.logits, dim=1)[0]
52
 
53
+ pred_idx = torch.argmax(probs).item()
 
54
 
55
+ prediction = MODEL_NAMES[pred_idx]
 
 
 
56
 
57
+ scores = {
58
+ MODEL_NAMES[i]: round(float(probs[i]), 4)
59
+ for i in range(len(MODEL_NAMES))
60
+ }
61
 
62
+ return jsonify({
63
+ "prediction": prediction,
64
+ "scores": scores
65
+ })
66
 
 
67
 
68
+ if __name__ == "__main__":
69
+ app.run(debug=True)
 
data/prompts/yu.py DELETED
@@ -1,186 +0,0 @@
1
- from dotenv import load_dotenv
2
- import os
3
- import pandas as pd
4
- import time
5
-
6
- import google.generativeai as genai
7
-
8
- # ==========================================
9
- # LOAD ENV VARIABLES
10
- # ==========================================
11
-
12
- load_dotenv()
13
-
14
- # ==========================================
15
- # CONFIGURE GEMINI
16
- # ==========================================
17
-
18
- genai.configure(
19
- api_key=os.getenv("GEMINI_API_KEY").strip()
20
- )
21
-
22
- # ==========================================
23
- # LOAD PROMPT BANK
24
- # ==========================================
25
-
26
- df = pd.read_csv(
27
- "AI-MODEL-FINGERPRINTING/src/data_collection/prompt_bank.csv"
28
- )
29
-
30
- # ==========================================
31
- # FIX COLUMN NAMES
32
- # ==========================================
33
-
34
- df.columns = df.columns.str.strip()
35
-
36
- print(df.columns)
37
-
38
- # ==========================================
39
- # SELECT PROMPT RANGE
40
- # ==========================================
41
-
42
- # Example:
43
- # 0:20 -> prompts 1 to 20
44
- # 20:40 -> prompts 21 to 40
45
- # 40:60 -> prompts 41 to 60
46
-
47
- df = df.iloc[0:20]
48
-
49
- # ==========================================
50
- # OUTPUT FILE
51
- # ==========================================
52
-
53
-
54
- output_file = "AI-MODEL-FINGERPRINTING/src/data_collection/gemini_response.csv"
55
-
56
- # ==========================================
57
- # LOAD OLD RESPONSES IF FILE EXISTS
58
- # ==========================================
59
-
60
- if os.path.exists(output_file):
61
-
62
- old_df = pd.read_csv(output_file)
63
-
64
- completed_ids = set(old_df["prompt_id"])
65
-
66
- print(f"\nAlready completed: {len(completed_ids)} prompts")
67
-
68
- else:
69
-
70
- old_df = pd.DataFrame()
71
-
72
- completed_ids = set()
73
-
74
- # ==========================================
75
- # GEMINI RESPONSE FUNCTION
76
- # ==========================================
77
-
78
- def generate_gemini_response(prompt):
79
-
80
- try:
81
-
82
- model = genai.GenerativeModel(
83
- "models/gemini-2.5-flash"
84
- )
85
-
86
- response = model.generate_content(
87
- prompt
88
- )
89
-
90
- return response.text
91
-
92
- except Exception as e:
93
-
94
- print(f"\nGemini Error: {e}")
95
-
96
- return None
97
-
98
- # ==========================================
99
- # RESPONSE GENERATION LOOP
100
- # ==========================================
101
-
102
- results = []
103
-
104
- for index, row in df.iterrows():
105
-
106
- prompt_id = row["PROMPT_ID"]
107
-
108
- # ======================================
109
- # SKIP COMPLETED PROMPTS
110
- # ======================================
111
-
112
- if prompt_id in completed_ids:
113
-
114
- print(f"\nSkipping {prompt_id} (already done)")
115
-
116
- continue
117
-
118
- category = row["category"]
119
-
120
- prompt = row["PROMPT"]
121
-
122
- print(f"\nGenerating response for {prompt_id}...")
123
-
124
- generated_text = generate_gemini_response(
125
- prompt
126
- )
127
-
128
- # ======================================
129
- # HANDLE FAILED GENERATION
130
- # ======================================
131
-
132
- if generated_text is None:
133
-
134
- print(f"\nFailed for {prompt_id}")
135
-
136
- continue
137
-
138
- # ======================================
139
- # STORE RESULT
140
- # ======================================
141
-
142
- result = {
143
-
144
- "prompt_id": prompt_id,
145
-
146
- "category": category,
147
-
148
- "model": "gemini",
149
-
150
- "prompt": prompt,
151
-
152
- "response": generated_text
153
-
154
- }
155
-
156
- results.append(result)
157
-
158
- # ======================================
159
- # SAVE AFTER EVERY RESPONSE
160
- # ======================================
161
-
162
- temp_df = pd.DataFrame(results)
163
-
164
- final_df = pd.concat(
165
- [old_df, temp_df],
166
- ignore_index=True
167
- )
168
-
169
- final_df.to_csv(
170
- output_file,
171
- index=False
172
- )
173
-
174
- print(f"\nSaved {prompt_id}")
175
-
176
- # ======================================
177
- # DELAY TO AVOID RATE LIMITS
178
- # ======================================
179
-
180
- time.sleep(3)
181
-
182
- # ==========================================
183
- # FINAL MESSAGE
184
- # ==========================================
185
-
186
- print("\nGemini response generation completed.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
notebooks/analysis.ipynb CHANGED
The diff for this file is too large to render. See raw diff
 
notebooks/attack_samples.csv CHANGED
The diff for this file is too large to render. See raw diff
 
requirement.txt CHANGED
@@ -11,4 +11,6 @@ datasets
11
  accelerate
12
  evaluate
13
  sentencepiece
14
- shap
 
 
 
11
  accelerate
12
  evaluate
13
  sentencepiece
14
+ shap
15
+ flask
16
+ safetensors
static/script.js ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ document.addEventListener("DOMContentLoaded", () => {
2
+
3
+ const form = document.querySelector("form");
4
+
5
+ form.addEventListener("submit", async (e) => {
6
+
7
+ e.preventDefault();
8
+
9
+ const text = document.querySelector("textarea").value;
10
+
11
+ let resultDiv = document.getElementById("result");
12
+
13
+ if (!resultDiv) {
14
+ resultDiv = document.createElement("div");
15
+ resultDiv.id = "result";
16
+ document.querySelector(".container").appendChild(resultDiv);
17
+ }
18
+
19
+ resultDiv.innerHTML = `
20
+ <div class="result-box">
21
+ <p> Analyzing...</p>
22
+ </div>
23
+ `;
24
+
25
+ try {
26
+
27
+ const response = await fetch("/predict", {
28
+ method: "POST",
29
+ headers: {
30
+ "Content-Type": "application/json"
31
+ },
32
+ body: JSON.stringify({
33
+ text: text
34
+ })
35
+ });
36
+
37
+ const data = await response.json();
38
+
39
+ let html = `
40
+ <div class="result-box">
41
+
42
+ <h2>Prediction</h2>
43
+
44
+ <p class="prediction">
45
+ ${data.prediction.toUpperCase()}
46
+ </p>
47
+
48
+ <h3>Confidence Scores</h3>
49
+ `;
50
+
51
+ for (const [model, score] of Object.entries(data.scores)) {
52
+
53
+ html += `
54
+ <p>
55
+ <strong>${model.toUpperCase()}</strong> :
56
+ ${score}
57
+ </p>
58
+ `;
59
+ }
60
+
61
+ html += `
62
+ </div>
63
+ `;
64
+
65
+ resultDiv.innerHTML = html;
66
+
67
+ } catch (error) {
68
+
69
+ resultDiv.innerHTML = `
70
+ <div class="result-box">
71
+ <p>Error while analyzing text.</p>
72
+ </div>
73
+ `;
74
+
75
+ console.error(error);
76
+ }
77
+
78
+ });
79
+
80
+ });
static/style.css ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ body {
2
+ background-color: #0f172a;
3
+ color: #f8fafc;
4
+ font-family: Arial, sans-serif;
5
+ margin: 0;
6
+ padding: 0;
7
+ }
8
+
9
+ .container {
10
+ width: 80%;
11
+ max-width: 900px;
12
+ margin: 50px auto;
13
+ text-align: center;
14
+ }
15
+
16
+ h1 {
17
+ font-size: 3rem;
18
+ margin-bottom: 10px;
19
+ color:#60a5fa;
20
+ }
21
+
22
+ .subtitle {
23
+ color: #94a3b8;
24
+ margin-bottom: 30px;
25
+ }
26
+
27
+ textarea {
28
+ width: 100%;
29
+ height: 220px;
30
+ padding: 15px;
31
+ border-radius: 12px;
32
+ border: none;
33
+ background: #1e293b;
34
+ color: white;
35
+ font-size: 16px;
36
+ resize: none;
37
+ }
38
+
39
+ button {
40
+ margin-top: 20px;
41
+ padding: 12px 30px;
42
+ border: none;
43
+ border-radius: 10px;
44
+ background: #3b82f6;
45
+ color: white;
46
+ font-size: 18px;
47
+ cursor: pointer;
48
+ }
49
+
50
+ button:hover {
51
+ background: #2563eb;
52
+ }
53
+
54
+ .result-box {
55
+ margin-top: 30px;
56
+ padding: 20px;
57
+ background: #1e293b;
58
+ border-radius: 12px;
59
+ }
60
+
61
+ .prediction {
62
+ font-size: 32px;
63
+ color: #22c55e;
64
+ font-weight: bold;
65
+ letter-spacing: 2px;
66
+ }
templates/index.html ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>AI origin detector</title>
5
+ <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
6
+ </head>
7
+
8
+ <body>
9
+
10
+ <div class="container">
11
+
12
+ <h1> AI Origin Detector</h1>
13
+ <p class="subtitle">
14
+ Identify which AI model generated a piece of text.
15
+ </p>
16
+
17
+ <form method="POST">
18
+ <textarea
19
+ name="text"
20
+ placeholder="Paste AI generated text here..."
21
+ ></textarea>
22
+
23
+ <br>
24
+
25
+ <button type="submit">
26
+ Analyze
27
+ </button>
28
+ </form>
29
+
30
+ {% if prediction %}
31
+ <div class="result-box">
32
+ <h2>Prediction</h2>
33
+ <p class="prediction">{{ prediction }}</p>
34
+ </div>
35
+ {% endif %}
36
+
37
+ </div>
38
+ <script src="{{ url_for('static', filename='script.js') }}"></script>
39
+
40
+ </body>
41
+ </html>