TheOCEAN's picture
updated app.py
d7a3ca2 verified
Raw
History Blame Contribute Delete
2.83 kB
import pickle
import json
import torch
from fastapi import FastAPI
from pydantic import BaseModel
from transformers import BertTokenizer
import io
# 1. Initialize App and Load Assets
# ==================================
app = FastAPI(
title="TEXI'OR Sentiment Analysis API",
description="An API to classify text into different sentiments using a fine-tuned BERT model.",
version="1.0"
)
class TextInput(BaseModel):
text: str
device = torch.device('cpu')
print(f"βœ… Using device: {device}")
# Custom Unpickler to load a GPU-trained model onto a CPU
class CPU_Unpickler(pickle.Unpickler):
def find_class(self, module, name):
if module == 'torch.storage' and name == '_load_from_bytes':
return lambda b: torch.load(io.BytesIO(b), map_location='cpu')
else:
return super().find_class(module, name)
# Load the fine-tuned model and tokenizer
try:
with open('bert_sentiment_model.pkl', 'rb') as f:
model = CPU_Unpickler(f).load()
model.to(device)
model.eval()
print("βœ… Model 'bert_sentiment_model.pkl' loaded successfully onto CPU.")
except FileNotFoundError:
print("❌ Model file not found. Make sure 'bert_sentiment_model.pkl' is uploaded.")
model = None
try:
with open('Label_Dict.json', 'r') as f:
label_dict = json.load(f)
idx2label = {int(v): k for k, v in label_dict.items()}
print("βœ… Label dictionary 'Label_Dict.json' loaded successfully.")
except FileNotFoundError:
print("❌ Label dictionary 'Label_Dict.json' not found.")
idx2label = None
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
print("βœ… Tokenizer loaded successfully.")
# 2. Define API Endpoints
# ========================
@app.get("/")
def read_root():
return {"message": "Welcome to the TEXI'OR API. Use the /predict endpoint to get a sentiment."}
@app.post("/predict")
def predict_sentiment(text_input: TextInput):
if not all([model, idx2label, tokenizer]):
return {"error": "API is not ready. A model, label, or tokenizer component failed to load."}
text = text_input.text
inputs = tokenizer(
text, padding=True, truncation=True, max_length=150, return_tensors='pt'
)
input_ids = inputs['input_ids'].to(device)
attention_mask = inputs['attention_mask'].to(device)
with torch.no_grad():
outputs = model(input_ids=input_ids, attention_mask=attention_mask)
logits = outputs.logits
probabilities = torch.nn.functional.softmax(logits, dim=-1)
confidence, predicted_class_idx = torch.max(probabilities, dim=1)
predicted_label = idx2label.get(predicted_class_idx.item(), "Unknown Label")
confidence_score = confidence.item()
return {
"sentiment": predicted_label,
"confidence": round(confidence_score, 4)
}