| from fastapi import FastAPI |
| from pydantic import BaseModel |
| from typing import List |
| from transformers import AutoTokenizer, AutoModelForSequenceClassification |
| from huggingface_hub import hf_hub_download |
| import torch |
| import json |
|
|
| MODEL_DIR = "Fatima1412/ingredients-distilbert-classifier" |
|
|
| tokenizer = None |
| model = None |
| id2label = None |
|
|
| app = FastAPI(title="Ingredients Classifier API") |
|
|
| @app.on_event("startup") |
| def load_model(): |
| global tokenizer, model, id2label |
|
|
| try: |
| |
| tokenizer = AutoTokenizer.from_pretrained(MODEL_DIR) |
| model = AutoModelForSequenceClassification.from_pretrained(MODEL_DIR) |
| model.eval() |
|
|
| |
| mapping_path = hf_hub_download( |
| repo_id=MODEL_DIR, |
| filename="labels_mapping.json" |
| ) |
|
|
| with open(mapping_path, "r") as f: |
| id2label = {int(k): v for k, v in json.load(f).items()} |
|
|
| print("Model and label mapping loaded successfully.") |
|
|
| except Exception as e: |
| print("⚠ WARNING: Model not loaded. Check Hugging Face repo.") |
| print(e) |
|
|
|
|
| class IngredientsRequest(BaseModel): |
| ingredients: str |
|
|
|
|
| class PredictionResponse(BaseModel): |
| label_id: int |
| label_name: str |
| probabilities: List[float] |
|
|
|
|
| def predict_ingredients(text): |
| inputs = tokenizer(text, return_tensors="pt") |
|
|
| |
| if "token_type_ids" in inputs: |
| del inputs["token_type_ids"] |
|
|
| with torch.no_grad(): |
| outputs = model(**inputs) |
|
|
| logits = outputs.logits |
| probs = torch.softmax(logits, dim=-1).tolist()[0] |
| label_id = logits.argmax(dim=-1).item() |
| label_name = id2label[label_id] |
|
|
| return label_id, label_name, probs |
|
|
|
|
| @app.post("/predict", response_model=PredictionResponse) |
| def predict(req: IngredientsRequest): |
| label_id, label_name, probs = predict_ingredients(req.ingredients) |
| return PredictionResponse( |
| label_id=label_id, |
| label_name=label_name, |
| probabilities=probs |
| ) |
|
|