Views
No views yet
1import torch
2import torch.nn.functional as F
3from transformers import AutoModelForSeq2SeqLM, MBartTokenizer
4
5device = "cuda:0" if torch.cuda.is_available() else "cpu"
6
7MODEL_REPO = "dmidge/mbart-large-50-eng2span"
8
9model = AutoModelForSeq2SeqLM.from_pretrained(MODEL_REPO).to(device)
10model.eval()
11tokenizer = MBartTokenizer.from_pretrained(
12 "facebook/mbart-large-50", src_lang="en_XX", tgt_lang="es_XX"
13)
14
15
16def translate_with_confidence(src_sentence: str):
17 """
18 Translate English text to Spanish and return a list of (word, confidence_score) tuples.
19 """
20 # Tokenize input
21 inputs = tokenizer(src_sentence, return_tensors="pt").to(device)
22 forced_bos_token_id = tokenizer.lang_code_to_id["es_XX"]
23
24 # Generate translation with scores
25 with torch.no_grad():
26 output = model.generate(
27 **inputs,
28 forced_bos_token_id=forced_bos_token_id,
29 return_dict_in_generate=True,
30 output_scores=True,
31 )
32
33 translated_tokens = output.sequences[0]
34
35 special_ids = set(tokenizer.all_special_ids)
36 cleaned_ids = [id for id in translated_tokens.tolist() if id not in special_ids]
37 decoded_tokens = tokenizer.convert_ids_to_tokens(cleaned_ids)
38
39 # Compute confidence scores
40 token_confidences = []
41 score_idx = 0
42
43 for _, id in enumerate(translated_tokens[1:]):
44 if id.item() in special_ids:
45 continue
46
47 logits = output.scores[score_idx][0]
48 probs = F.softmax(logits, dim=-1)
49 token_confidences.append(1.0 - probs[id].item())
50 score_idx += 1
51
52 # Merge subword tokens into full words with average confidence
53 def merge_subword_scores(tokens, scores):
54 words = []
55 confidences = []
56 current_word = ""
57 current_scores = []
58
59 for token, score in zip(tokens, scores):
60 if token.startswith("▁"):
61 if current_word:
62 words.append(current_word)
63 confidences.append(sum(current_scores) / len(current_scores))
64
65 current_word = token.lstrip("▁")
66 current_scores = [score]
67 else:
68 current_word += token
69 current_scores.append(score)
70
71 if current_word:
72 words.append(current_word)
73 confidences.append(sum(current_scores) / len(current_scores))
74
75 return words, confidences
76
77 return merge_subword_scores(decoded_tokens, token_confidences)
78
79
80if __name__ == "__main__":
81 while True:
82 english = input("Enter English to translate: ")
83 if english.lower() == "stop":
84 break
85
86 words, scores = translate_with_confidence(english)
87 for word, score in zip(words, scores):
88 print(f"{word} - {score*100.0:.4f}%")