arpitasethiii commited on
Commit
d8bb4c0
·
verified ·
1 Parent(s): 1713d80

Upload 4 files

Browse files
Files changed (4) hide show
  1. Dockerfile +10 -0
  2. README.md +27 -6
  3. app.py +146 -0
  4. requirements.txt +5 -0
Dockerfile ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.10-slim
2
+
3
+ WORKDIR /app
4
+
5
+ COPY requirements.txt .
6
+ RUN pip install --no-cache-dir -r requirements.txt
7
+
8
+ COPY . .
9
+
10
+ CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
README.md CHANGED
@@ -1,11 +1,32 @@
1
  ---
2
- title: Clickbait Detector Api
3
- emoji: 📊
4
- colorFrom: indigo
5
- colorTo: red
6
  sdk: docker
7
  pinned: false
8
- license: apache-2.0
9
  ---
10
 
11
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: Clickbait Detector API
3
+ emoji: 🎯
4
+ colorFrom: purple
5
+ colorTo: pink
6
  sdk: docker
7
  pinned: false
 
8
  ---
9
 
10
+ # Clickbait Detector API
11
+
12
+ AI-powered API to detect and neutralize clickbait headlines using DistilBERT and T5.
13
+
14
+ ## Endpoints
15
+
16
+ - `GET /` - API info
17
+ - `POST /detect` - Detect if headline is clickbait
18
+ - `POST /rewrite` - Rewrite clickbait to neutral
19
+ - `POST /analyze` - Detect + rewrite in one call
20
+
21
+ ## Usage
22
+ ```python
23
+ import requests
24
+
25
+ response = requests.post(
26
+ "https://YOUR-SPACE.hf.space/detect",
27
+ json={"headline": "You Won't Believe What Happened!"}
28
+ )
29
+ print(response.json())
30
+ ```
31
+
32
+ Powered by DistilBERT and T5.
app.py ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI
2
+ from fastapi.middleware.cors import CORSMiddleware
3
+ from pydantic import BaseModel
4
+ import torch
5
+ from transformers import AutoTokenizer, AutoModelForSequenceClassification
6
+ from transformers import T5Tokenizer, T5ForConditionalGeneration
7
+ import os
8
+
9
+ app = FastAPI(title="Clickbait Detector API")
10
+
11
+ # Enable CORS for Chrome Extension
12
+ app.add_middleware(
13
+ CORSMiddleware,
14
+ allow_origins=["*"],
15
+ allow_credentials=True,
16
+ allow_methods=["*"],
17
+ allow_headers=["*"],
18
+ )
19
+
20
+ # Global variables for models
21
+ tokenizer = None
22
+ model = None
23
+ t5_tokenizer = None
24
+ t5_model = None
25
+ device = None
26
+
27
+ @app.on_event("startup")
28
+ async def load_models():
29
+ """Load models on startup"""
30
+ global tokenizer, model, t5_tokenizer, t5_model, device
31
+
32
+ device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
33
+ print(f"Using device: {device}")
34
+
35
+ # Load DistilBERT
36
+ print("Loading DistilBERT model...")
37
+ tokenizer = AutoTokenizer.from_pretrained("distilbert-base-uncased")
38
+ model = AutoModelForSequenceClassification.from_pretrained(
39
+ "./clickbait_detector_model"
40
+ )
41
+ model.to(device)
42
+ model.eval()
43
+ print("✓ DistilBERT loaded")
44
+
45
+ # Load T5
46
+ print("Loading T5 model...")
47
+ t5_tokenizer = T5Tokenizer.from_pretrained("t5-base")
48
+ t5_model = T5ForConditionalGeneration.from_pretrained(
49
+ "./t5_clickbait_rewriter_finetuned"
50
+ )
51
+ t5_model.to(device)
52
+ t5_model.eval()
53
+ print("✓ T5 loaded")
54
+
55
+ class HeadlineRequest(BaseModel):
56
+ headline: str
57
+
58
+ @app.get("/")
59
+ def root():
60
+ return {
61
+ "name": "Clickbait Detector API",
62
+ "version": "1.0.0",
63
+ "status": "online",
64
+ "endpoints": {
65
+ "/detect": "POST - Detect if headline is clickbait",
66
+ "/rewrite": "POST - Rewrite clickbait to neutral",
67
+ "/analyze": "POST - Detect + Rewrite in one call"
68
+ }
69
+ }
70
+
71
+ @app.post("/detect")
72
+ def detect_clickbait(request: HeadlineRequest):
73
+ """Detect if headline is clickbait"""
74
+ try:
75
+ inputs = tokenizer(
76
+ request.headline,
77
+ return_tensors='pt',
78
+ padding=True,
79
+ truncation=True,
80
+ max_length=128
81
+ ).to(device)
82
+
83
+ with torch.no_grad():
84
+ outputs = model(**inputs)
85
+ probs = torch.softmax(outputs.logits, dim=1)
86
+ prediction = torch.argmax(probs, dim=1).item()
87
+ confidence = probs[0][prediction].item()
88
+
89
+ return {
90
+ "headline": request.headline,
91
+ "is_clickbait": bool(prediction),
92
+ "confidence": float(confidence),
93
+ "label": "clickbait" if prediction else "neutral"
94
+ }
95
+ except Exception as e:
96
+ return {"error": str(e)}
97
+
98
+ @app.post("/rewrite")
99
+ def rewrite_headline(request: HeadlineRequest):
100
+ """Rewrite clickbait headline to neutral"""
101
+ try:
102
+ prompt = f"rewrite clickbait to neutral: {request.headline}"
103
+ inputs = t5_tokenizer(
104
+ prompt,
105
+ return_tensors='pt',
106
+ max_length=128,
107
+ truncation=True
108
+ ).to(device)
109
+
110
+ with torch.no_grad():
111
+ outputs = t5_model.generate(
112
+ inputs['input_ids'],
113
+ max_length=64,
114
+ num_beams=5,
115
+ early_stopping=True
116
+ )
117
+
118
+ neutral = t5_tokenizer.decode(outputs[0], skip_special_tokens=True)
119
+
120
+ return {
121
+ "original": request.headline,
122
+ "rewritten": neutral
123
+ }
124
+ except Exception as e:
125
+ return {"error": str(e)}
126
+
127
+ @app.post("/analyze")
128
+ def analyze_headline(request: HeadlineRequest):
129
+ """Detect and rewrite in one call"""
130
+ try:
131
+ detection = detect_clickbait(request)
132
+
133
+ if detection.get("is_clickbait"):
134
+ rewrite = rewrite_headline(request)
135
+ return {
136
+ **detection,
137
+ "rewritten": rewrite.get("rewritten")
138
+ }
139
+ else:
140
+ return {
141
+ **detection,
142
+ "rewritten": request.headline,
143
+ "message": "Headline is already neutral"
144
+ }
145
+ except Exception as e:
146
+ return {"error": str(e)}
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ fastapi==0.104.1
2
+ uvicorn==0.24.0
3
+ transformers==4.35.2
4
+ torch==2.1.0
5
+ pydantic==2.5.0