test_v3 / app.py
shimaa22's picture
Update app.py
27aca0a verified
Raw
History Blame Contribute Delete
2.85 kB
import os
import gc
import torch
import torch.nn as nn
import joblib
import numpy as np
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from transformers import AutoTokenizer, AutoModel
from torch.utils.data import Dataset, DataLoader
from typing import Optional
import uvicorn
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
# =========================
# CONFIG
# =========================
#MODEL_NAME = "BAAI/bge-small-en-v1.5"
MODEL_NAME = os.path.join(
BASE_DIR,
"BAAI_bge-small-en-v1.5_best_progressive"
)
MAX_LENGTH = 256
MAX_CHUNKS = 10
BATCH_SIZE = 8
DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
LR_PIPELINE_PATH = os.path.join(BASE_DIR, "lr_assets", "tfidf_lr_pipeline.joblib")
CHECKPOINT_PATH = os.path.join(BASE_DIR, "models", "BAAI_bge-small-en-v1.5_progressive_checkpoint.pt")
# =========================
# MODEL (minimal safe load)
# =========================
class SimpleModel(nn.Module):
def __init__(self):
super().__init__()
self.encoder = AutoModel.from_pretrained(
MODEL_NAME,
local_files_only=True
)
H = self.encoder.config.hidden_size
self.classifier = nn.Linear(H, 1)
print("πŸš€ Loading tokenizer...")
tokenizer = AutoTokenizer.from_pretrained(
MODEL_NAME,
local_files_only=True
)
print("πŸš€ Loading model...")
model = SimpleModel().to(DEVICE)
print("πŸš€ Loading checkpoint...")
ckpt = torch.load(CHECKPOINT_PATH, map_location=DEVICE, weights_only=False)
state = ckpt.get("model_state_dict") or ckpt.get("best_overall_state")
model.load_state_dict(state, strict=False)
model.eval()
print("πŸš€ Loading LR...")
lr_model = joblib.load(LR_PIPELINE_PATH)
# =========================
# API
# =========================
app = FastAPI(title="Readmission API")
class Request(BaseModel):
text: str
@app.get("/")
def home():
return {"status": "running"}
@app.post("/predict")
def predict(req: Request):
if not req.text:
raise HTTPException(400, "empty text")
inputs = tokenizer(
req.text,
truncation=True,
padding=True,
return_tensors="pt",
max_length=MAX_LENGTH
).to(DEVICE)
with torch.no_grad():
logits = model(inputs["input_ids"], inputs["attention_mask"])
bert_prob = torch.sigmoid(logits).item()
lr_prob = lr_model.predict_proba([req.text])[0][1]
final = 0.7 * bert_prob + 0.3 * lr_prob
pred = int(final > 0.5)
return {
"probability": final,
"prediction": pred,
"bert_prob": bert_prob,
"lr_prob": lr_prob
}
# =========================
# RUN (IMPORTANT for HF Spaces)
# =========================
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=7860)