Spaces:
Runtime error
Runtime error
| import json | |
| import logging | |
| from pathlib import Path | |
| import joblib | |
| import numpy as np | |
| import torch | |
| from transformers import ( | |
| AutoTokenizer, | |
| AutoModelForSequenceClassification | |
| ) | |
| # ===================================================== | |
| # LOGGING | |
| # ===================================================== | |
| logging.basicConfig( | |
| level=logging.INFO, | |
| format="%(asctime)s - %(levelname)s - %(message)s" | |
| ) | |
| logger = logging.getLogger(__name__) | |
| # ===================================================== | |
| # PATHS | |
| # ===================================================== | |
| ARTIFACT_DIR = Path("src") | |
| MODEL_DIR = ARTIFACT_DIR / "models" | |
| FEATURE_DIR = ARTIFACT_DIR / "features" | |
| # | |
| # MODEL_PATH = ( | |
| # HF_MODEL_ID | |
| # ) | |
| # | |
| # MODEL_CONFIG_PATH = ( | |
| # MODEL_DIR / | |
| # "model_config.json" | |
| # ) | |
| # | |
| # TOKENIZER_PATH = ( | |
| # FEATURE_DIR / | |
| # "tokenizer" | |
| # ) | |
| HF_MODEL_ID = ( | |
| "rishigupta04/yt-comments-sentiment-analyzer" | |
| ) | |
| tokenizer = AutoTokenizer.from_pretrained( | |
| HF_MODEL_ID | |
| ) | |
| model = AutoModelForSequenceClassification.from_pretrained( | |
| HF_MODEL_ID | |
| ) | |
| LABEL_ENCODER_PATH = ( | |
| FEATURE_DIR / | |
| "label_encoder.pkl" | |
| ) | |
| # ===================================================== | |
| # DEVICE | |
| # ===================================================== | |
| DEVICE = ( | |
| "cuda" | |
| if torch.cuda.is_available() | |
| else "cpu" | |
| ) | |
| # ===================================================== | |
| # PREPROCESSOR | |
| # ===================================================== | |
| class TextPreprocessor: | |
| def preprocess( | |
| self, | |
| text | |
| ): | |
| if text is None: | |
| return "" | |
| return str(text).strip() | |
| # ===================================================== | |
| # PREDICTOR | |
| # ===================================================== | |
| class SentimentPredictor: | |
| def __init__(self): | |
| logger.info( | |
| f"Using Device: {DEVICE}" | |
| ) | |
| self.device = DEVICE | |
| self.preprocessor = ( | |
| TextPreprocessor() | |
| ) | |
| logger.info( | |
| "Loading tokenizer..." | |
| ) | |
| self.tokenizer = ( | |
| AutoTokenizer | |
| .from_pretrained( | |
| HF_MODEL_ID | |
| ) | |
| ) | |
| logger.info( | |
| "Loading label encoder..." | |
| ) | |
| self.label_encoder = ( | |
| joblib.load( | |
| LABEL_ENCODER_PATH | |
| ) | |
| ) | |
| self.config = { | |
| "model_name": | |
| HF_MODEL_ID | |
| } | |
| logger.info( | |
| "Loading model..." | |
| ) | |
| self.model = ( | |
| AutoModelForSequenceClassification | |
| .from_pretrained( | |
| HF_MODEL_ID | |
| ) | |
| ) | |
| self.model = ( | |
| AutoModelForSequenceClassification | |
| .from_pretrained( | |
| HF_MODEL_ID | |
| ) | |
| ) | |
| self.model.to( | |
| self.device | |
| ) | |
| self.model.eval() | |
| logger.info( | |
| "Model Loaded Successfully" | |
| ) | |
| # ================================================= | |
| # SINGLE PREDICTION | |
| # ================================================= | |
| def predict( | |
| self, | |
| text | |
| ): | |
| text = ( | |
| self.preprocessor | |
| .preprocess(text) | |
| ) | |
| encoded = self.tokenizer( | |
| text, | |
| truncation=True, | |
| padding=True, | |
| max_length=192, | |
| return_tensors="pt" | |
| ) | |
| input_ids = ( | |
| encoded["input_ids"] | |
| .to(self.device) | |
| ) | |
| attention_mask = ( | |
| encoded["attention_mask"] | |
| .to(self.device) | |
| ) | |
| outputs = self.model( | |
| input_ids=input_ids, | |
| attention_mask= | |
| attention_mask | |
| ) | |
| probs = torch.softmax( | |
| outputs.logits, | |
| dim=1 | |
| ) | |
| pred_idx = ( | |
| torch.argmax( | |
| probs, | |
| dim=1 | |
| ) | |
| .item() | |
| ) | |
| confidence = ( | |
| probs.max() | |
| .item() | |
| ) | |
| sentiment = ( | |
| self.label_encoder | |
| .inverse_transform( | |
| [pred_idx] | |
| )[0] | |
| ) | |
| return { | |
| "sentiment": | |
| sentiment, | |
| "confidence": | |
| round( | |
| confidence, | |
| 4 | |
| ) | |
| } | |
| # ================================================= | |
| # BATCH PREDICTION | |
| # ================================================= | |
| def predict_batch( | |
| self, | |
| texts, | |
| batch_size=64 | |
| ): | |
| results = [] | |
| for i in range( | |
| 0, | |
| len(texts), | |
| batch_size | |
| ): | |
| batch = texts[ | |
| i:i+batch_size | |
| ] | |
| batch = [ | |
| self.preprocessor | |
| .preprocess(t) | |
| for t in batch | |
| ] | |
| encoded = self.tokenizer( | |
| batch, | |
| truncation=True, | |
| padding=True, | |
| max_length=192, | |
| return_tensors="pt" | |
| ) | |
| input_ids = ( | |
| encoded["input_ids"] | |
| .to(self.device) | |
| ) | |
| attention_mask = ( | |
| encoded["attention_mask"] | |
| .to(self.device) | |
| ) | |
| outputs = self.model( | |
| input_ids=input_ids, | |
| attention_mask= | |
| attention_mask | |
| ) | |
| probs = torch.softmax( | |
| outputs.logits, | |
| dim=1 | |
| ) | |
| preds = torch.argmax( | |
| probs, | |
| dim=1 | |
| ) | |
| probs = ( | |
| probs.cpu() | |
| .numpy() | |
| ) | |
| preds = ( | |
| preds.cpu() | |
| .numpy() | |
| ) | |
| sentiments = ( | |
| self.label_encoder | |
| .inverse_transform( | |
| preds | |
| ) | |
| ) | |
| for sentiment, prob in zip( | |
| sentiments, | |
| probs | |
| ): | |
| results.append({ | |
| "sentiment": | |
| sentiment, | |
| "confidence": | |
| float( | |
| np.max( | |
| prob | |
| ) | |
| ) | |
| }) | |
| return results |