Spaces:
Sleeping
Sleeping
| # translator.py | |
| from gradio_client import Client | |
| import re | |
| import time | |
| import config | |
| import logging | |
| # 設定日誌 | |
| logger = logging.getLogger(__name__) | |
| try: | |
| # 💡 真正的 NLLB 運算大本營在這裡 | |
| client = Client("https://ai-labs.ilrdf.org.tw/kari-seejiq-tnpusu-ai-hmjil/") | |
| except Exception as e: | |
| logger.error(f"翻譯引擎初始化失敗: {e}") | |
| def get_clean_value(res): | |
| if isinstance(res, dict) and 'value' in res: | |
| return res['value'] | |
| if isinstance(res, list) and len(res) > 0: | |
| return res[0] | |
| return res | |
| def is_gibberish(text): | |
| """防亂碼濾網:檢查是否違反基本拼寫原則""" | |
| text_lower = text.lower() | |
| if re.search(r'[fvz]', text_lower): | |
| return True | |
| if re.search(r'[^aeiouwy\s]{6,}', text_lower): | |
| return True | |
| return False | |
| def calculate_confidence(text, is_chinese, tribe_name): | |
| """智慧信心值判定核心""" | |
| if not is_chinese and tribe_name == "太魯閣" and is_gibberish(text): | |
| return "low", "低 (疑為亂碼或不符拼寫規範)" | |
| if is_chinese and (len(set(text)) < 3 and len(text) > 6): | |
| return "low", "低 (語意不清或無效輸入)" | |
| complex_keywords = ["法律", "規定", "科技", "系統", "網路", "醫療", "政策", "分析", "資料", "會議", "機制", "科學", "專業", "名詞"] | |
| if is_chinese: | |
| if len(text) > 25 or any(kw in text for kw in complex_keywords): | |
| return "medium", "中 (含專業術語或複雜長句)" | |
| else: | |
| if len(text.split()) > 10: | |
| return "medium", "中 (複雜句結構)" | |
| return "high", "高 (一般生活簡單句)" | |
| def basic_format(text, direction): | |
| """💡 使用超快速的 Python 原生語法進行基本格式化""" | |
| text = str(text).strip() | |
| if direction == "zh_to_native" and text: | |
| # 確保輸出的族語第一個字母大寫 | |
| text = text[0].upper() + text[1:] | |
| return text | |
| def translate(text: str, tribe_name: str): | |
| # 💡 確保傳入資料庫的名稱是正確的,避免 RAG 抓空 | |
| db_tribe_name = "太魯閣語" if tribe_name == "太魯閣" else tribe_name | |
| if tribe_name not in config.TRIBE_MAP: | |
| return {"error": f"暫時不支援 {tribe_name}"} | |
| try: | |
| is_chinese = bool(re.search(r'[\u4e00-\u9fa5]', text)) | |
| # 計算信心值 | |
| conf_level, conf_desc = calculate_confidence(text, is_chinese, tribe_name) | |
| if conf_level == "low": | |
| return { | |
| "source": text, | |
| "target": "⚠️ 無法精準翻譯,請確認拼字或語意是否完整。", | |
| "direction": "unknown", | |
| "tribe": tribe_name, | |
| "db_tribe": db_tribe_name, | |
| "confidence_level": conf_level, | |
| "confidence_desc": conf_desc | |
| } | |
| # 💡 測速計時起點 | |
| api_start_time = time.time() | |
| # 正常翻譯流程 (純 NLLB,無 Gemini 負擔) | |
| if is_chinese: | |
| back_code = get_clean_value(client.predict(ethnicity=tribe_name, api_name="/lambda_1")) | |
| raw_result = get_clean_value(client.predict( | |
| text=text, src_lang="zho_Hant", tgt_lang=back_code, api_name="/translate_1" | |
| )) | |
| direction = "zh_to_native" | |
| final_result = basic_format(raw_result, direction) | |
| else: | |
| go_code = get_clean_value(client.predict(ethnicity=tribe_name, api_name="/lambda")) | |
| raw_result = get_clean_value(client.predict( | |
| text=text, src_lang=go_code, tgt_lang="zho_Hant", api_name="/translate" | |
| )) | |
| direction = "native_to_zh" | |
| final_result = basic_format(raw_result, direction) | |
| # 💡 測速計時終點 | |
| api_duration = time.time() - api_start_time | |
| logger.info(f"📡 [遠端 API 呼叫耗時] 字數: {len(text)} | 等待 AI Labs 伺服器回應耗時: {api_duration:.2f} 秒") | |
| return { | |
| "source": text, | |
| "target": final_result, | |
| "direction": direction, | |
| "tribe": tribe_name, | |
| "db_tribe": db_tribe_name, # 💡 提供給後續 deep_analyzer 進行 RAG 檢索使用 | |
| "confidence_level": conf_level, | |
| "confidence_desc": conf_desc | |
| } | |
| except Exception as e: | |
| logger.error(f"翻譯過程出錯: {e}") | |
| return {"error": f"翻譯過程出錯: {str(e)}"} |