SearingShot's picture
Copy local model into disfluency container
b75008d
Raw
History Blame Contribute Delete
1.82 kB
import os
from pathlib import Path
import torch
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from transformers import AutoModelForSeq2SeqLM, AutoTokenizer
MODEL_PATH = Path(os.getenv("MODEL_PATH", "/app/speechCleaner_t5_model")).resolve()
MAX_LENGTH = int(os.getenv("MAX_LENGTH", "256"))
NUM_BEAMS = int(os.getenv("NUM_BEAMS", "4"))
app = FastAPI(title="SignApp Disfluency Remover")
tokenizer = None
model = None
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
class TextInput(BaseModel):
text: str
def load_model():
global tokenizer, model
if tokenizer is None or model is None:
if not MODEL_PATH.exists():
raise RuntimeError(f"Model directory not found: {MODEL_PATH}")
tokenizer = AutoTokenizer.from_pretrained(str(MODEL_PATH), local_files_only=True)
model = AutoModelForSeq2SeqLM.from_pretrained(str(MODEL_PATH), local_files_only=True)
model.to(device)
model.eval()
@app.on_event("startup")
def startup():
load_model()
@app.get("/health")
def health():
return {"status": "ok", "device": str(device), "model_path": str(MODEL_PATH)}
@app.post("/clean/")
def clean(body: TextInput):
text = body.text.strip()
if not text:
raise HTTPException(status_code=400, detail="Text is empty")
load_model()
inputs = tokenizer(
"clean speech: " + text,
return_tensors="pt",
truncation=True,
padding=True,
).to(device)
with torch.no_grad():
outputs = model.generate(
**inputs,
max_length=MAX_LENGTH,
num_beams=NUM_BEAMS,
early_stopping=True,
)
cleaned_text = tokenizer.decode(outputs[0], skip_special_tokens=True).strip()
return {"cleaned_text": cleaned_text}