AnViMt / main.py
Phitran21's picture
Upload 5 files
43fabf7 verified
Raw
History Blame Contribute Delete
4.48 kB
import os
import numpy as np
import onnxruntime as ort
import sentencepiece as spm
# =========================
# PATH
# =========================
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
ENCODER_PATH = os.path.join(BASE_DIR, "encoder_model.onnx")
DECODER_PATH = os.path.join(BASE_DIR, "decoder_model.onnx")
SPM_PATH = os.path.join(BASE_DIR, "spm.model")
# =========================
# SETTINGS
# =========================
MAX_INPUT_LEN = 256
MAX_OUTPUT_LEN = 256
PAD_ID = 0
UNK_ID = 1
BOS_ID = 2
EOS_ID = 3
# =========================
# CHECK FILES
# =========================
for path in [ENCODER_PATH, DECODER_PATH, SPM_PATH]:
if not os.path.exists(path):
raise FileNotFoundError(f"Không tìm thấy file: {path}")
# =========================
# LOAD TOKENIZER
# =========================
print("Đang load tokenizer...")
sp = spm.SentencePieceProcessor()
sp.load(SPM_PATH)
print(
f"Tokenizer: vocab={sp.get_piece_size()} | "
f"PAD={sp.pad_id()} BOS={sp.bos_id()} EOS={sp.eos_id()}"
)
# =========================
# ONNX RUNTIME
# =========================
print("Đang load ONNX model...")
providers = ["CPUExecutionProvider"]
encoder_session = ort.InferenceSession(
ENCODER_PATH,
providers=providers
)
decoder_session = ort.InferenceSession(
DECODER_PATH,
providers=providers
)
# =========================
# SHOW MODEL INFO
# =========================
print("\nEncoder inputs:")
for x in encoder_session.get_inputs():
print(" ", x.name, x.shape, x.type)
print("\nDecoder inputs:")
for x in decoder_session.get_inputs():
print(" ", x.name, x.shape, x.type)
# =========================
# TRANSLATE
# =========================
def translate(text):
text = text.strip()
if not text:
return ""
# ---------------------------------
# 1. ENCODE INPUT
# ---------------------------------
src_ids = sp.encode(text, out_type=int)
# Giới hạn context
src_ids = src_ids[:MAX_INPUT_LEN - 2]
# BART format
src_ids = [BOS_ID] + src_ids + [EOS_ID]
input_ids = np.array(
[src_ids],
dtype=np.int64
)
attention_mask = np.ones_like(
input_ids,
dtype=np.int64
)
# ---------------------------------
# 2. ENCODER
# ---------------------------------
encoder_outputs = encoder_session.run(
None,
{
"input_ids": input_ids,
"attention_mask": attention_mask
}
)
encoder_hidden_states = encoder_outputs[0]
# ---------------------------------
# 3. DECODER GREEDY
# ---------------------------------
generated = [BOS_ID]
for _ in range(MAX_OUTPUT_LEN):
decoder_input_ids = np.array(
[generated],
dtype=np.int64
)
decoder_inputs = {}
# Tự map input để tránh lệch tên
for inp in decoder_session.get_inputs():
name = inp.name
if name == "input_ids":
decoder_inputs[name] = decoder_input_ids
elif "encoder_hidden_states" in name:
decoder_inputs[name] = encoder_hidden_states
elif "encoder_attention_mask" in name:
decoder_inputs[name] = attention_mask
decoder_outputs = decoder_session.run(
None,
decoder_inputs
)
# Output đầu tiên là logits
logits = decoder_outputs[0]
# Lấy token cuối
next_token_logits = logits[0, -1, :]
next_token = int(
np.argmax(next_token_logits)
)
generated.append(next_token)
if next_token == EOS_ID:
break
# ---------------------------------
# 4. DECODE
# ---------------------------------
output_ids = generated[1:]
if EOS_ID in output_ids:
output_ids = output_ids[
:output_ids.index(EOS_ID)
]
result = sp.decode(output_ids)
return result
# =========================
# INTERACTIVE CLI
# =========================
print("\nEN → VI translator v2 ready")
print("Type 'exit' để thoát\n")
while True:
try:
text = input("EN > ").strip()
except (KeyboardInterrupt, EOFError):
print("\nBye")
break
if text.lower() in ["exit", "quit", "q"]:
print("Bye")
break
if not text:
continue
result = translate(text)
print("VI >", result)
print()