Files
desktop-transfer/translator.py
xiaji 8a5450eeae 添加PyInstaller打包配置及清理脚本
添加translate.ico图标文件
更新.gitignore忽略.spec文件
修改main.py导入路径为main_window_final
优化translator.py的错误处理
添加pyinstaller-one技能目录及文档
更新main.spec配置排除不必要的依赖
添加verify_features.py功能验证脚本
2026-01-16 16:37:07 +08:00

187 lines
7.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import os
from utils.logger import logger
# 尝试导入llama_cpp如果失败则设置Llama为None
try:
from llama_cpp import Llama
llama_cpp_available = True
except ImportError:
logger.warning("llama-cpp-python库未找到将尝试使用transformers库")
Llama = None
llama_cpp_available = False
# 尝试导入transformers库
try:
from transformers import AutoModelForCausalLM, AutoTokenizer
transformers_available = True
except (ImportError, KeyboardInterrupt):
logger.warning("transformers库导入失败或被中断")
transformers_available = False
class Translator:
def __init__(self, model_path=None):
self.model = None
self.model_path = model_path
self.is_ready = False
self.model_name = ""
self.llama_cpp_available = llama_cpp_available
self.transformers_available = transformers_available
self.use_transformers = False
def load_model(self, model_path=None):
"""加载模型"""
if model_path:
self.model_path = model_path
if not self.model_path:
logger.error("未提供模型路径")
return False
try:
logger.info(f"开始加载模型: {self.model_path}")
if self.llama_cpp_available:
if os.path.exists(self.model_path):
try:
self.model = Llama(
model_path=self.model_path,
n_ctx=2048,
n_threads=4,
n_gpu_layers=100
)
self.use_transformers = False
self.is_ready = True
self.model_name = os.path.basename(self.model_path)
logger.info(f"模型加载成功: {self.model_name}")
return True
except Exception as e:
logger.warning(f"使用llama-cpp-python加载模型失败: {e}")
else:
logger.warning(f"模型文件不存在: {self.model_path}")
if self.transformers_available:
try:
from transformers import AutoConfig
if os.path.exists(self.model_path):
config = AutoConfig.from_pretrained(
self.model_path,
local_files_only=True,
trust_remote_code=True
)
self.model = AutoModelForCausalLM.from_pretrained(
self.model_path,
local_files_only=True,
trust_remote_code=True,
torch_dtype="auto"
)
self.tokenizer = AutoTokenizer.from_pretrained(
self.model_path,
local_files_only=True,
trust_remote_code=True
)
else:
config = AutoConfig.from_pretrained(
self.model_path,
trust_remote_code=True
)
self.model = AutoModelForCausalLM.from_pretrained(
self.model_path,
trust_remote_code=True,
torch_dtype="auto"
)
self.tokenizer = AutoTokenizer.from_pretrained(
self.model_path,
trust_remote_code=True
)
self.use_transformers = True
self.is_ready = True
self.model_name = self.model_path
logger.info(f"使用transformers加载模型成功: {self.model_name}")
return True
except Exception as e:
logger.error(f"使用transformers加载模型失败: {e}")
return False
logger.error("没有可用的模型加载方式")
return False
except Exception as e:
logger.error(f"模型加载失败: {e}")
self.is_ready = False
return False
def translate(self, text, context="", terms=None):
"""执行翻译"""
if not self.is_ready or not self.model:
logger.error("模型未就绪,无法执行翻译")
return ""
try:
# 构建翻译提示词
prompt = self._build_prompt(text, context, terms)
logger.info(f"开始翻译,输入长度: {len(text)} 字符")
if self.use_transformers:
import torch
inputs = self.tokenizer(prompt, return_tensors="pt")
with torch.no_grad():
outputs = self.model.generate(
**inputs,
max_new_tokens=2048,
temperature=0.7,
top_p=0.95,
do_sample=True
)
translated_text = self.tokenizer.decode(outputs[0][inputs.input_ids.shape[1]:], skip_special_tokens=True)
else:
output = self.model(
prompt,
max_tokens=2048,
temperature=0.7,
top_p=0.95,
stop=["\n原文:", "\n译文:", "\n###"]
)
translated_text = output["choices"][0]["text"].strip()
logger.info(f"翻译完成,输出长度: {len(translated_text)} 字符")
return translated_text
except Exception as e:
logger.error(f"翻译失败: {e}")
return ""
def _build_prompt(self, text, context="", terms=None):
"""构建翻译提示词"""
prompt = "你是一个专业的翻译助手,根据以下要求将中文翻译成英文:\n"
if context:
prompt += f"\n文本背景/场景介绍:{context}\n"
if terms:
prompt += "\n术语定义:\n"
for term in terms:
prompt += f"{term}\n"
prompt += f"\n原文:{text}\n译文:"
return prompt
def unload_model(self):
"""卸载模型"""
if self.model:
try:
del self.model
self.model = None
self.is_ready = False
logger.info("模型已卸载")
return True
except Exception as e:
logger.error(f"模型卸载失败: {e}")
return False
return True
def get_model_info(self):
"""获取模型信息"""
if self.is_ready:
return f"{self.model_name.split('.')[0]}"
return "未加载模型"