nlp-evaluation / app.py
somriksur's picture
Upload app.py with huggingface_hub
1444863 verified
Raw
History Blame Contribute Delete
4.2 kB
"""
NLP Evaluation API - Production Deployment
==========================================
Multi-task NLP model for interview evaluation
"""
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import torch
import torch.nn as nn
from transformers import RobertaTokenizer, RobertaModel
import uvicorn
app = FastAPI(title="NLP Evaluation API", version="1.0.0")
# Model configuration
TASKS = {
"sentiment": {"labels": ["negative", "neutral", "positive"], "num_labels": 3},
"emotion": {"labels": ["nervous", "confident", "stressed", "calm", "motivated"], "num_labels": 5},
"communication": {"labels": ["poor", "fair", "good", "excellent"], "num_labels": 4},
"confidence_level": {"labels": ["low", "medium", "high"], "num_labels": 3},
"stress_level": {"labels": ["low", "medium", "high"], "num_labels": 3}
}
class MultiTaskRoBERTa(nn.Module):
def __init__(self):
super().__init__()
self.roberta = RobertaModel.from_pretrained("roberta-base")
hidden_size = 768
self.classifiers = nn.ModuleDict({
task: nn.Sequential(
nn.Dropout(0.1),
nn.Linear(hidden_size, hidden_size//2),
nn.ReLU(),
nn.Dropout(0.1),
nn.Linear(hidden_size//2, info["num_labels"])
)
for task, info in TASKS.items()
})
def forward(self, input_ids, attention_mask):
outputs = self.roberta(input_ids=input_ids, attention_mask=attention_mask)
pooled = outputs.last_hidden_state[:, 0, :]
return {task: classifier(pooled) for task, classifier in self.classifiers.items()}
# Load model
print("🧠 Loading model...")
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = MultiTaskRoBERTa().to(device)
checkpoint = torch.load("best_model_ultimate.pt", map_location=device)
model.load_state_dict(checkpoint["model_state_dict"])
model.eval()
print(f"✅ Model loaded on {device}")
# Load tokenizer
print("🔤 Loading tokenizer...")
tokenizer = RobertaTokenizer.from_pretrained("roberta-base")
print("✅ Tokenizer loaded")
class AnalyzeRequest(BaseModel):
text: str
class AnalyzeResponse(BaseModel):
sentiment: str
emotion: str
communication: str
confidence_level: str
stress_level: str
scores: dict
@app.get("/")
def root():
return {
"message": "NLP Evaluation API",
"version": "1.0.0",
"status": "running",
"model": "RoBERTa-base Multi-Task (126M params)",
"tasks": list(TASKS.keys())
}
@app.get("/health")
def health():
return {"status": "healthy", "model_loaded": True}
@app.post("/analyze", response_model=AnalyzeResponse)
def analyze(request: AnalyzeRequest):
try:
# Tokenize
encoding = tokenizer(
request.text,
max_length=256,
padding="max_length",
truncation=True,
return_tensors="pt"
)
input_ids = encoding["input_ids"].to(device)
attention_mask = encoding["attention_mask"].to(device)
# Predict
with torch.no_grad():
logits = model(input_ids, attention_mask)
# Get predictions and scores
predictions = {}
scores = {}
for task, task_logits in logits.items():
probs = torch.softmax(task_logits, dim=1)
pred_idx = torch.argmax(probs, dim=1).item()
pred_label = TASKS[task]["labels"][pred_idx]
pred_score = probs[0][pred_idx].item()
predictions[task] = pred_label
scores[task] = round(pred_score, 4)
return AnalyzeResponse(
sentiment=predictions["sentiment"],
emotion=predictions["emotion"],
communication=predictions["communication"],
confidence_level=predictions["confidence_level"],
stress_level=predictions["stress_level"],
scores=scores
)
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=7860)