KavinduHansaka commited on
Commit
6b9d483
·
verified ·
1 Parent(s): 88051c8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +51 -30
app.py CHANGED
@@ -3,27 +3,54 @@ from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline, AutoMode
3
  import os
4
  from huggingface_hub import login
5
  import torch
6
- import pandas as pd
7
 
8
- # Authenticate
9
  HUGGINGFACE_TOKEN = os.getenv("HF_TOKEN")
10
  login(token=HUGGINGFACE_TOKEN)
11
 
12
- # Phi-4 Mini
13
  phi_id = "microsoft/phi-4-mini-instruct"
14
  phi_tokenizer = AutoTokenizer.from_pretrained(phi_id, token=HUGGINGFACE_TOKEN)
15
  phi_model = AutoModelForCausalLM.from_pretrained(phi_id, torch_dtype="auto", device_map="auto", token=HUGGINGFACE_TOKEN)
16
  phi_pipe = pipeline("text-generation", model=phi_model, tokenizer=phi_tokenizer)
17
 
18
- # T5 for paraphrasing
19
  t5_pipe = pipeline("text2text-generation", model="google-t5/t5-base")
20
 
21
- # AI Detector
22
  detector_id = "openai-community/roberta-base-openai-detector"
23
  detector_tokenizer = AutoTokenizer.from_pretrained(detector_id)
24
  detector_model = AutoModelForSequenceClassification.from_pretrained(detector_id)
25
 
26
- # Chunking
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  def chunk_text(text, max_tokens=300):
28
  paragraphs = text.split("\n\n")
29
  chunks, current = [], ""
@@ -37,7 +64,7 @@ def chunk_text(text, max_tokens=300):
37
  chunks.append(current.strip())
38
  return chunks
39
 
40
- # Phi-based instruction prompts
41
  def generate_phi_prompt(text, instruction):
42
  chunks = chunk_text(text)
43
  outputs = []
@@ -47,7 +74,7 @@ def generate_phi_prompt(text, instruction):
47
  outputs.append(result.split("Response:")[1].strip() if "Response:" in result else result.strip())
48
  return "\n\n".join(outputs)
49
 
50
- # Writing tools
51
  def fix_grammar(text):
52
  return generate_phi_prompt(text, "Correct all grammar and punctuation errors in the following text. Provide only the corrected version:")
53
 
@@ -64,25 +91,21 @@ def paraphrase(text):
64
  for chunk in chunks
65
  )
66
 
67
- # AI Detection as label + bar
68
  def detect_ai_percent(text):
69
  inputs = detector_tokenizer(text, return_tensors="pt", truncation=True, padding=True)
70
  with torch.no_grad():
71
  logits = detector_model(**inputs).logits
72
  probs = torch.softmax(logits, dim=1).squeeze()
73
- scores = [round(probs[0].item() * 100, 2), round(probs[1].item() * 100, 2)]
74
- summary = "Likely Human" if scores[0] > scores[1] else "Likely AI-Generated"
75
- df = pd.DataFrame({
76
- "Label": ["Likely Human", "Likely AI-Generated"],
77
- "Probability": scores
78
- })
79
- return summary, df
80
-
81
- # Rewrite to sound human
82
  def rewrite_to_human(text):
83
  return generate_phi_prompt(text, "Rewrite the following text so that it is indistinguishable from human writing and avoids AI detection. Be natural and fluent:")
84
 
85
- # File I/O
86
  def load_file(file_obj):
87
  if file_obj is None:
88
  return ""
@@ -94,16 +117,15 @@ def save_file(text):
94
  f.write(text)
95
  return path
96
 
97
- # Gradio UI
98
  with gr.Blocks() as demo:
99
- gr.Markdown("# ✍️ AI Writing Assistant + Detector")
100
- gr.Markdown("Fix grammar, tone, fluency, paraphrase, detect AI content, and rewrite to reduce AI probability.")
101
 
102
  with gr.Row():
103
  file_input = gr.File(label="📂 Upload .txt File", file_types=[".txt"])
104
  load_btn = gr.Button("📥 Load Text")
105
  input_text = gr.Textbox(lines=12, label="Input Text")
106
-
107
  load_btn.click(fn=load_file, inputs=file_input, outputs=input_text)
108
 
109
  with gr.Row():
@@ -120,18 +142,17 @@ with gr.Blocks() as demo:
120
 
121
  gr.Markdown("## 🕵️ AI Detection")
122
  detect_btn = gr.Button("Detect AI Probability")
123
- ai_summary = gr.Textbox(label="Summary (Human vs AI)", interactive=False)
124
- ai_chart = gr.BarPlot(x="Label", y="Probability", y_lim=(0, 100), title="AI Detection Result", color="Label", height=250)
125
-
126
- detect_btn.click(fn=detect_ai_percent, inputs=input_text, outputs=[ai_summary, ai_chart])
127
 
128
- gr.Markdown("## 🔁 Rewrite to Sound More Human")
129
- rewrite_btn = gr.Button("Rewrite to Lower AI Likelihood")
130
  rewritten_text = gr.Textbox(lines=12, label="Rewritten Text")
131
  rewrite_btn.click(fn=rewrite_to_human, inputs=input_text, outputs=rewritten_text)
132
 
133
  gr.Markdown("## 📤 Download Output")
134
- download_btn = gr.Button("💾 Download Final Output")
135
  download_file = gr.File(label="Click to download", interactive=True)
136
  download_btn.click(fn=save_file, inputs=output_text, outputs=download_file)
137
 
 
3
  import os
4
  from huggingface_hub import login
5
  import torch
 
6
 
7
+ # Authenticate with Hugging Face token
8
  HUGGINGFACE_TOKEN = os.getenv("HF_TOKEN")
9
  login(token=HUGGINGFACE_TOKEN)
10
 
11
+ # Load Phi-4 Mini
12
  phi_id = "microsoft/phi-4-mini-instruct"
13
  phi_tokenizer = AutoTokenizer.from_pretrained(phi_id, token=HUGGINGFACE_TOKEN)
14
  phi_model = AutoModelForCausalLM.from_pretrained(phi_id, torch_dtype="auto", device_map="auto", token=HUGGINGFACE_TOKEN)
15
  phi_pipe = pipeline("text-generation", model=phi_model, tokenizer=phi_tokenizer)
16
 
17
+ # Load T5 for paraphrasing
18
  t5_pipe = pipeline("text2text-generation", model="google-t5/t5-base")
19
 
20
+ # Load AI Detector
21
  detector_id = "openai-community/roberta-base-openai-detector"
22
  detector_tokenizer = AutoTokenizer.from_pretrained(detector_id)
23
  detector_model = AutoModelForSequenceClassification.from_pretrained(detector_id)
24
 
25
+ # ===== Helper: Circular HTML Visualization =====
26
+ def circular_html(ai_percent):
27
+ color = (
28
+ "#4caf50" if ai_percent < 30 else
29
+ "#2196f3" if ai_percent < 60 else
30
+ "#f44336" if ai_percent < 90 else
31
+ "#e91e63"
32
+ )
33
+ return f"""
34
+ <div style="display: flex; justify-content: center; margin-top: 10px;">
35
+ <div style="
36
+ width: 160px;
37
+ height: 160px;
38
+ border-radius: 50%;
39
+ background: conic-gradient({color} {ai_percent}%, #e0e0e0 {ai_percent}%);
40
+ display: flex;
41
+ align-items: center;
42
+ justify-content: center;
43
+ font-size: 28px;
44
+ font-weight: bold;
45
+ color: #333;
46
+ box-shadow: 0 0 10px rgba(0,0,0,0.1);
47
+ ">
48
+ {ai_percent}%
49
+ </div>
50
+ </div>
51
+ """
52
+
53
+ # ===== Chunking for Large Input Support =====
54
  def chunk_text(text, max_tokens=300):
55
  paragraphs = text.split("\n\n")
56
  chunks, current = [], ""
 
64
  chunks.append(current.strip())
65
  return chunks
66
 
67
+ # ===== Phi Prompt Wrapper =====
68
  def generate_phi_prompt(text, instruction):
69
  chunks = chunk_text(text)
70
  outputs = []
 
74
  outputs.append(result.split("Response:")[1].strip() if "Response:" in result else result.strip())
75
  return "\n\n".join(outputs)
76
 
77
+ # ===== Writing Tools =====
78
  def fix_grammar(text):
79
  return generate_phi_prompt(text, "Correct all grammar and punctuation errors in the following text. Provide only the corrected version:")
80
 
 
91
  for chunk in chunks
92
  )
93
 
94
+ # ===== AI Detection and Visualization =====
95
  def detect_ai_percent(text):
96
  inputs = detector_tokenizer(text, return_tensors="pt", truncation=True, padding=True)
97
  with torch.no_grad():
98
  logits = detector_model(**inputs).logits
99
  probs = torch.softmax(logits, dim=1).squeeze()
100
+ ai_score = round(probs[1].item() * 100, 2)
101
+ label = "Likely AI-Generated" if ai_score > 50 else "Likely Human"
102
+ return label, circular_html(ai_score)
103
+
104
+ # ===== Rewrite for Human-Like Text =====
 
 
 
 
105
  def rewrite_to_human(text):
106
  return generate_phi_prompt(text, "Rewrite the following text so that it is indistinguishable from human writing and avoids AI detection. Be natural and fluent:")
107
 
108
+ # ===== File Handling =====
109
  def load_file(file_obj):
110
  if file_obj is None:
111
  return ""
 
117
  f.write(text)
118
  return path
119
 
120
+ # ===== Gradio Interface =====
121
  with gr.Blocks() as demo:
122
+ gr.Markdown("# ✍️ AI Writing Assistant + Circular AI Detector")
123
+ gr.Markdown("Fix grammar, tone, fluency, paraphrase, and detect AI content with a modern circular progress view.")
124
 
125
  with gr.Row():
126
  file_input = gr.File(label="📂 Upload .txt File", file_types=[".txt"])
127
  load_btn = gr.Button("📥 Load Text")
128
  input_text = gr.Textbox(lines=12, label="Input Text")
 
129
  load_btn.click(fn=load_file, inputs=file_input, outputs=input_text)
130
 
131
  with gr.Row():
 
142
 
143
  gr.Markdown("## 🕵️ AI Detection")
144
  detect_btn = gr.Button("Detect AI Probability")
145
+ ai_summary = gr.Textbox(label="AI Summary", interactive=False)
146
+ ai_circle = gr.HTML()
147
+ detect_btn.click(fn=detect_ai_percent, inputs=input_text, outputs=[ai_summary, ai_circle])
 
148
 
149
+ gr.Markdown("## 🔁 Rewrite to Reduce AI Probability")
150
+ rewrite_btn = gr.Button("Rewrite as Human")
151
  rewritten_text = gr.Textbox(lines=12, label="Rewritten Text")
152
  rewrite_btn.click(fn=rewrite_to_human, inputs=input_text, outputs=rewritten_text)
153
 
154
  gr.Markdown("## 📤 Download Output")
155
+ download_btn = gr.Button("💾 Download Output")
156
  download_file = gr.File(label="Click to download", interactive=True)
157
  download_btn.click(fn=save_file, inputs=output_text, outputs=download_file)
158