Views
No views yet
vinai/phobert-base on visolex/VLSP2018-ABSA-Restaurant for joint aspect detection + sentiment classification (shared heads).vinai/phobert-basevisolex/VLSP2018-ABSA-RestaurantAMBIENCE#GENERALDRINKS#PRICESDRINKS#QUALITYDRINKS#STYLE&OPTIONSFOOD#PRICESFOOD#QUALITYFOOD#STYLE&OPTIONSLOCATION#GENERALRESTAURANT#GENERALRESTAURANT#MISCELLANEOUSRESTAURANT#PRICESSERVICE#GENERALPOSITIVENEGATIVENEUTRAL1import torch
2from transformers import AutoTokenizer, AutoModel
3
4# Danh sách aspect và sentiment labels
5aspect_labels = [
6 "AMBIENCE#GENERAL", "DRINKS#PRICES", "DRINKS#QUALITY", "DRINKS#STYLE&OPTIONS",
7 "FOOD#PRICES", "FOOD#QUALITY", "FOOD#STYLE&OPTIONS", "LOCATION#GENERAL",
8 "RESTAURANT#GENERAL", "RESTAURANT#MISCELLANEOUS", "RESTAURANT#PRICES",
9 "SERVICE#GENERAL"
10]
11sentiment_labels = ["POSITIVE", "NEGATIVE", "NEUTRAL"]
12
13# Load tokenizer và model (phải về đúng class TransformerForABSA)
14repo = "visolex/phobert-absa-restaurant"
15tokenizer = AutoTokenizer.from_pretrained(repo, trust_remote_code=True)
16model = AutoModel.from_pretrained(repo, trust_remote_code=True)
17model.eval()
18
19def predict_absa_multi(
20 text: str,
21 aspect_labels: list[str],
22 sentiment_labels: list[str],
23 threshold: float = 0.5
24) -> list[tuple[str,str]]:
25 inputs = tokenizer(
26 text,
27 return_tensors="pt",
28 padding=True,
29 truncation=True,
30 max_length=256
31 )
32 inputs.pop("token_type_ids", None)
33
34 with torch.no_grad():
35 out = model(**inputs)
36
37 # out.logits có shape [1, A, S+1]
38 logits = out.logits.squeeze(0)
39 probs = torch.softmax(logits, dim=-1)
40
41 num_s = len(sentiment_labels)
42 none_id = probs.size(-1) - 1
43 results = []
44
45 for i, asp in enumerate(aspect_labels):
46 prob_i = probs[i]
47 pred_id = int(prob_i.argmax().item())
48
49 if pred_id != none_id and pred_id < num_s:
50 score = prob_i[pred_id].item()
51 if score >= threshold:
52 results.append((asp, sentiment_labels[pred_id].lower()))
53
54 return results
55
56# Example usage
57text = "Món ăn ở đây rất ngon nhưng giá hơi mắc một chút và phục vụ cũng khá chậm."
58preds = predict_absa_multi(text, aspect_labels, sentiment_labels, threshold=0.2)
59print(preds)
60# Expected output similar to: [('FOOD#QUALITY', 'positive'), ('FOOD#PRICES', 'negative'), ('SERVICE#GENERAL', 'negative')]