Spaces:
Sleeping
Sleeping
File size: 5,291 Bytes
66028cc 1180a53 66028cc 4e05a46 a66d87f 66028cc 1180a53 66028cc 4e05a46 1a42889 66028cc 4e05a46 66028cc 4e05a46 1a42889 66028cc 1180a53 66028cc 1180a53 66028cc 1180a53 66028cc 1180a53 66028cc 1180a53 d0873ef 1180a53 66028cc 1180a53 66028cc 1180a53 66028cc 1180a53 66028cc 1180a53 66028cc 1180a53 66028cc 1180a53 66028cc 1180a53 66028cc a66d87f 1180a53 a66d87f 1180a53 a66d87f 1180a53 a66d87f 1180a53 a66d87f 1180a53 66028cc 1180a53 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | import os
from fastapi import FastAPI, Request, Form
from pydantic import BaseModel
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates
from transformers import AutoTokenizer, AutoModelForSequenceClassification
from datasets import load_from_disk
import torch
import random
import subprocess
import json
# Caricamento del modello e dei dati se già scaricati
MODEL = "cardiffnlp/twitter-roberta-base-sentiment-latest"
TWEET_PROCESSED_PATH = "data/processed/tweet_eval_tokenized"
YT_PROCESSED_PATH = "data/processed/youtube_tokenized"
tokenizer = AutoTokenizer.from_pretrained(MODEL)
model = AutoModelForSequenceClassification.from_pretrained(MODEL)
labels = ["negative", "neutral", "positive"]
# TWEET EVAL
if not os.path.exists(TWEET_PROCESSED_PATH):
print(f"Dataset Tweet Eval non trovato in {TWEET_PROCESSED_PATH}. Lo genero...")
if not os.environ.get("SKIP_DATA_PREP"):
if not os.path.exists(TWEET_PROCESSED_PATH):
subprocess.run(["python", "src/data_preparation.py", "tweet_eval"], check=True)
tweet_eval = load_from_disk(TWEET_PROCESSED_PATH)
# YOUTUBE COMMENTS
if not os.path.exists(YT_PROCESSED_PATH):
print(f" Dataset YouTube non trovato in {YT_PROCESSED_PATH}. Lo genero...")
if not os.environ.get("SKIP_DATA_PREP"):
if not os.path.exists(YT_PROCESSED_PATH):
subprocess.run(["python", "src/data_preparation.py", "youtube"], check=True)
youtube_ds = load_from_disk(YT_PROCESSED_PATH)
app = FastAPI(title="Sentiment Analysis API")
templates = Jinja2Templates(directory="app_templates/")
class TextInput(BaseModel):
text: str
def predict_sentiment(text: str):
inputs = tokenizer(text, return_tensors="pt", truncation=True, padding=True)
with torch.no_grad():
outputs = model(**inputs)
probs = torch.nn.functional.softmax(outputs.logits, dim=-1)
pred = torch.argmax(probs, dim=1).item()
confidence = probs[0][pred].item()
return {"label": labels[pred], "confidence": round(confidence, 3)}
@app.get("/", response_class=HTMLResponse)
async def home(request: Request):
return templates.TemplateResponse("index.html", {"request": request})
@app.get("/random_tweet", response_class=HTMLResponse)
def random_tweet(request: Request):
# sample = random.choice(tweet_eval["test"])
sample = tweet_eval["test"][random.randrange(len(tweet_eval["test"]))]
text = (
sample["text"]
if "text" in sample
else tokenizer.decode(sample["input_ids"], skip_special_tokens=True)
)
result = predict_sentiment(text)
true_label = labels[sample["label"]]
return templates.TemplateResponse(
"random_tweet.html",
{"request": request, "text": text, "true_label": true_label, "result": result},
)
@app.get("/predict", response_class=HTMLResponse)
def predict_page(request: Request):
return templates.TemplateResponse("predict.html", {"request": request, "result": None})
@app.post("/predict", response_class=HTMLResponse)
def predict_text(request: Request, text: str = Form(...)):
result = predict_sentiment(text)
return templates.TemplateResponse(
"predict.html", {"request": request, "text": text, "result": result}
)
@app.get("/random_youtube_comment", response_class=HTMLResponse)
def random_youtube_comment(request: Request):
sample = random.choice(youtube_ds["train"])
text = sample["text"] if "text" in sample else sample["text"]
true_label = sample["label"] if "label" in sample else "N/A"
if isinstance(true_label, int):
label_map = {0: "negative", 1: "neutral", 2: "positive"}
true_label = label_map.get(true_label, "N/A")
result = predict_sentiment(text)
return templates.TemplateResponse(
"random_youtube.html",
{"request": request, "text": text, "true_label": true_label, "result": result},
)
@app.get("/admin", response_class=HTMLResponse)
async def admin_dashboard(request: Request):
"""Pagina principale dell'area admin."""
metrics = None
metrics_path = "reports/metrics.json"
if os.path.exists(metrics_path):
with open(metrics_path, "r") as f:
metrics = json.load(f)
return templates.TemplateResponse("admin.html", {"request": request, "metrics": metrics})
@app.post("/admin/train")
async def retrain_model():
"""Lancia lo script di training."""
subprocess.run(["python", "src/train.py"], check=True)
return {"status": "Training completato"}
@app.post("/admin/monitor")
async def run_monitoring():
"""Esegue il monitoring e aggiorna metrics.json."""
subprocess.run(["python", "src/monitoring.py"], check=True)
return {"status": "Monitoring completato"}
@app.get("/admin/metrics", response_class=HTMLResponse)
def view_metrics(request: Request):
"""Visualizza i risultati del monitoring in forma tabellare e grafica."""
metrics_path = "reports/metrics.json"
metrics = None
if os.path.exists(metrics_path):
with open(metrics_path, "r") as f:
metrics = json.load(f)
return templates.TemplateResponse("metrics.html", {"request": request, "metrics": metrics})
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
|