premmm commited on
Commit
a2e3d8f
·
verified ·
1 Parent(s): 1c69f59

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. main.py +61 -31
main.py CHANGED
@@ -1,6 +1,8 @@
1
- from fastapi import FastAPI, Request, Form
2
  from fastapi.templating import Jinja2Templates
3
  from fastapi.responses import HTMLResponse
 
 
4
  import torch
5
  from transformers import AutoTokenizer
6
  from optimum.onnxruntime import ORTModelForSequenceClassification
@@ -14,36 +16,44 @@ import time
14
  logging.basicConfig(level=logging.INFO)
15
  logger = logging.getLogger(__name__)
16
 
17
- app = FastAPI()
 
 
 
 
 
 
 
 
 
 
18
  templates = Jinja2Templates(directory="templates")
19
 
20
- # Model Paths (Local Project Directory)
21
  QUANT_MINILM_PATH = "models/minilm_int8"
22
  QUANT_XLM_PATH = "models/xlm_roberta_int8"
23
  ML_MODEL_PATH = "models/baseline/spam_detection_model.pkl"
24
 
 
 
 
 
 
25
  # Load Models and Tokenizers
26
  logger.info("Loading Quantized Production Models...")
27
-
28
- # 1. MiniLM INT8
29
  minilm_tokenizer = AutoTokenizer.from_pretrained(QUANT_MINILM_PATH)
30
  minilm_model = ORTModelForSequenceClassification.from_pretrained(QUANT_MINILM_PATH, file_name="model_quantized.onnx")
31
 
32
- # 2. XLM-Roberta INT8
33
  xlm_tokenizer = AutoTokenizer.from_pretrained(QUANT_XLM_PATH)
34
  xlm_model = ORTModelForSequenceClassification.from_pretrained(QUANT_XLM_PATH, file_name="model_quantized.onnx")
35
 
36
- # 3. ML Model (Scikit-learn)
37
  ml_model = joblib.load(ML_MODEL_PATH)
38
 
39
  def preprocess_ml(text):
40
- if not isinstance(text, str):
41
- text = str(text)
42
- text = text.lower()
43
  text = re.sub(r'[^\w\s]', '', text)
44
  text = re.sub(r'\d+', '', text)
45
- text = text.strip()
46
- return text
47
 
48
  def predict_ort(text, model, tokenizer):
49
  start_time = time.time()
@@ -52,12 +62,43 @@ def predict_ort(text, model, tokenizer):
52
  outputs = model(**inputs)
53
  probs = torch.nn.functional.softmax(outputs.logits, dim=-1)
54
  prediction = torch.argmax(probs, dim=-1).item()
55
-
56
- latency = (time.time() - start_time) * 1000 # ms
57
-
58
  label = model.config.id2label[prediction] if hasattr(model.config, "id2label") else ("Spam" if prediction == 1 else "Ham")
59
- label = label.title()
60
- return label, probs[0][prediction].item(), latency
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
 
62
  @app.get("/", response_class=HTMLResponse)
63
  async def read_item(request: Request):
@@ -65,28 +106,17 @@ async def read_item(request: Request):
65
 
66
  @app.post("/compare")
67
  async def compare_models(text: str = Form(...)):
 
68
  results = []
69
-
70
- # MiniLM INT8
71
  l1, s1, t1 = predict_ort(text, minilm_model, minilm_tokenizer)
72
  results.append({"model": "MiniLM v2 (INT8)", "label": l1, "confidence": f"{s1:.4f}", "latency": f"{t1:.2f}ms"})
73
-
74
- # XLM-Roberta INT8
75
  l2, s2, t2 = predict_ort(text, xlm_model, xlm_tokenizer)
76
  results.append({"model": "XLM-R v2 (INT8)", "label": l2, "confidence": f"{s2:.4f}", "latency": f"{t2:.2f}ms"})
77
-
78
- # ML Model
79
  start3 = time.time()
80
- clean_text = preprocess_ml(text)
81
- pred3 = ml_model.predict([clean_text])[0]
82
  t3 = (time.time() - start3) * 1000
83
  l3 = "Spam" if pred3 == 1 else "Ham"
84
- try:
85
- p3 = ml_model.predict_proba([clean_text])[0][pred3]
86
- except:
87
- p3 = 1.0
88
- results.append({"model": "ML Model (English)", "label": l3, "confidence": f"{p3:.4f}", "latency": f"{t3:.2f}ms"})
89
-
90
  return results
91
 
92
  if __name__ == "__main__":
 
1
+ from fastapi import FastAPI, Request, Form, HTTPException
2
  from fastapi.templating import Jinja2Templates
3
  from fastapi.responses import HTMLResponse
4
+ from fastapi.middleware.cors import CORSMiddleware
5
+ from pydantic import BaseModel
6
  import torch
7
  from transformers import AutoTokenizer
8
  from optimum.onnxruntime import ORTModelForSequenceClassification
 
16
  logging.basicConfig(level=logging.INFO)
17
  logger = logging.getLogger(__name__)
18
 
19
+ app = FastAPI(title="Spam Detection System API")
20
+
21
+ # 1. Enable CORS for cross-platform system calls
22
+ app.add_middleware(
23
+ CORSMiddleware,
24
+ allow_origins=["*"], # In production, replace with your actual platform URL
25
+ allow_credentials=True,
26
+ allow_methods=["*"],
27
+ allow_headers=["*"],
28
+ )
29
+
30
  templates = Jinja2Templates(directory="templates")
31
 
32
+ # Model Paths
33
  QUANT_MINILM_PATH = "models/minilm_int8"
34
  QUANT_XLM_PATH = "models/xlm_roberta_int8"
35
  ML_MODEL_PATH = "models/baseline/spam_detection_model.pkl"
36
 
37
+ # Request Schema for System Calls
38
+ class PredictionRequest(BaseModel):
39
+ text: str
40
+ model: str = "minilm" # Default to the fastest production model
41
+
42
  # Load Models and Tokenizers
43
  logger.info("Loading Quantized Production Models...")
 
 
44
  minilm_tokenizer = AutoTokenizer.from_pretrained(QUANT_MINILM_PATH)
45
  minilm_model = ORTModelForSequenceClassification.from_pretrained(QUANT_MINILM_PATH, file_name="model_quantized.onnx")
46
 
 
47
  xlm_tokenizer = AutoTokenizer.from_pretrained(QUANT_XLM_PATH)
48
  xlm_model = ORTModelForSequenceClassification.from_pretrained(QUANT_XLM_PATH, file_name="model_quantized.onnx")
49
 
 
50
  ml_model = joblib.load(ML_MODEL_PATH)
51
 
52
  def preprocess_ml(text):
53
+ text = str(text).lower()
 
 
54
  text = re.sub(r'[^\w\s]', '', text)
55
  text = re.sub(r'\d+', '', text)
56
+ return text.strip()
 
57
 
58
  def predict_ort(text, model, tokenizer):
59
  start_time = time.time()
 
62
  outputs = model(**inputs)
63
  probs = torch.nn.functional.softmax(outputs.logits, dim=-1)
64
  prediction = torch.argmax(probs, dim=-1).item()
65
+ latency = (time.time() - start_time) * 1000
 
 
66
  label = model.config.id2label[prediction] if hasattr(model.config, "id2label") else ("Spam" if prediction == 1 else "Ham")
67
+ return label.title(), probs[0][prediction].item(), latency
68
+
69
+ # --- SYSTEM ENDPOINTS ---
70
+
71
+ @app.get("/health")
72
+ async def health_check():
73
+ """System health check to verify models are loaded."""
74
+ return {"status": "ready", "models_loaded": ["minilm_int8", "xlm_roberta_int8", "baseline_ml"]}
75
+
76
+ @app.post("/api/v1/predict")
77
+ async def system_predict(request: PredictionRequest):
78
+ """Formal JSON API endpoint for system-to-system integration."""
79
+ if not request.text:
80
+ raise HTTPException(status_code=400, detail="Text is required")
81
+
82
+ if request.model == "minilm":
83
+ label, conf, lat = predict_ort(request.text, minilm_model, minilm_tokenizer)
84
+ elif request.model == "xlm":
85
+ label, conf, lat = predict_ort(request.text, xlm_model, xlm_tokenizer)
86
+ else:
87
+ # Fallback to ML Model
88
+ start = time.time()
89
+ pred = ml_model.predict([preprocess_ml(request.text)])[0]
90
+ lat = (time.time() - start) * 1000
91
+ label = "Spam" if pred == 1 else "Ham"
92
+ conf = 1.0
93
+
94
+ return {
95
+ "label": label,
96
+ "confidence": float(conf),
97
+ "latency_ms": float(lat),
98
+ "model_used": request.model
99
+ }
100
+
101
+ # --- WEB UI ENDPOINTS ---
102
 
103
  @app.get("/", response_class=HTMLResponse)
104
  async def read_item(request: Request):
 
106
 
107
  @app.post("/compare")
108
  async def compare_models(text: str = Form(...)):
109
+ # Legacy endpoint for the HTML frontend
110
  results = []
 
 
111
  l1, s1, t1 = predict_ort(text, minilm_model, minilm_tokenizer)
112
  results.append({"model": "MiniLM v2 (INT8)", "label": l1, "confidence": f"{s1:.4f}", "latency": f"{t1:.2f}ms"})
 
 
113
  l2, s2, t2 = predict_ort(text, xlm_model, xlm_tokenizer)
114
  results.append({"model": "XLM-R v2 (INT8)", "label": l2, "confidence": f"{s2:.4f}", "latency": f"{t2:.2f}ms"})
 
 
115
  start3 = time.time()
116
+ pred3 = ml_model.predict([preprocess_ml(text)])[0]
 
117
  t3 = (time.time() - start3) * 1000
118
  l3 = "Spam" if pred3 == 1 else "Ham"
119
+ results.append({"model": "ML Model (English)", "label": l3, "confidence": "1.0000", "latency": f"{t3:.2f}ms"})
 
 
 
 
 
120
  return results
121
 
122
  if __name__ == "__main__":