import torch import torch.nn as nn from transformers import AutoTokenizer, AutoModel import gradio as gr # Model multitask (Topik & Sentimen) dengan nama layer sesuai model.pt class MultiTaskModel(nn.Module): def __init__(self, base_model_name, num_topic_classes, num_sentiment_classes): super(MultiTaskModel, self).__init__() self.encoder = AutoModel.from_pretrained(base_model_name) hidden_size = self.encoder.config.hidden_size self.topik_classifier = nn.Linear(hidden_size, num_topic_classes) self.sentiment_classifier = nn.Linear(hidden_size, num_sentiment_classes) def forward(self, input_ids, attention_mask, token_type_ids=None): outputs = self.encoder( input_ids=input_ids, attention_mask=attention_mask, token_type_ids=token_type_ids ) pooled_output = outputs.last_hidden_state[:, 0] topik_logits = self.topik_classifier(pooled_output) sentimen_logits = self.sentiment_classifier(pooled_output) return topik_logits, sentimen_logits # Load tokenizer & model tokenizer = AutoTokenizer.from_pretrained("tokenizer") model = MultiTaskModel("indobenchmark/indobert-base-p1", num_topic_classes=5, num_sentiment_classes=3) model.load_state_dict(torch.load("model.pt", map_location=torch.device("cpu"))) model.eval() # Label mapping topik_labels = ["Produk", "Layanan", "Pengiriman", "Lainnya"] sentimen_labels = ["Negatif", "Netral", "Positif"] def klasifikasi(text): inputs = tokenizer(text, return_tensors="pt", truncation=True, padding=True) with torch.no_grad(): topik_logits, sentimen_logits = model(**inputs) topik_probs = torch.softmax(topik_logits, dim=-1).squeeze() sentimen_probs = torch.softmax(sentimen_logits, dim=-1).squeeze() topik_result = {label: float(prob) for label, prob in zip(topik_labels, topik_probs)} sentimen_result = {label: float(prob) for label, prob in zip(sentimen_labels, sentimen_probs)} return {"Topik": topik_result, "Sentimen": sentimen_result} demo = gr.Interface(fn=klasifikasi, inputs="text", outputs="json", title="Klasifikasi Topik dan Sentimen Pelanggan") demo.launch()