Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,10 +1,10 @@
|
|
| 1 |
import os
|
| 2 |
import sys
|
| 3 |
|
| 4 |
-
# 1. 強制下載 Spacy 模型
|
| 5 |
os.system(f"{sys.executable} -m spacy download en_core_web_sm")
|
| 6 |
|
| 7 |
-
# 2. 解決相容性
|
| 8 |
try:
|
| 9 |
import huggingface_hub
|
| 10 |
if not hasattr(huggingface_hub, 'HfFolder'):
|
|
@@ -21,72 +21,70 @@ import gradio as gr
|
|
| 21 |
from fastcoref import FCoref
|
| 22 |
from deep_translator import GoogleTranslator
|
| 23 |
|
| 24 |
-
#
|
| 25 |
-
print("🚀 [System] 正在
|
| 26 |
try:
|
| 27 |
-
# 使用相容性最高的參數名稱
|
| 28 |
model = FCoref(model_name_or_path='biu-nlp/f-coref', device='cpu')
|
| 29 |
-
print("✅ [System] 模型載
|
| 30 |
-
except
|
| 31 |
-
# 萬一連上面的都不行,就用最原始的 positional argument
|
| 32 |
model = FCoref('biu-nlp/f-coref', device='cpu')
|
| 33 |
-
print("✅ [System]
|
| 34 |
|
| 35 |
-
|
|
|
|
| 36 |
if not user_input.strip():
|
| 37 |
-
return "
|
| 38 |
|
| 39 |
try:
|
| 40 |
-
#
|
| 41 |
has_chinese = any('\u4e00' <= char <= '\u9fff' for char in user_input)
|
| 42 |
if has_chinese:
|
| 43 |
working_text = GoogleTranslator(source='zh-CN', target='en').translate(user_input)
|
| 44 |
-
mode_notice = "
|
| 45 |
else:
|
| 46 |
working_text = user_input
|
| 47 |
-
mode_notice = "
|
| 48 |
|
| 49 |
-
#
|
| 50 |
preds = model.predict(texts=[working_text])
|
| 51 |
clusters = preds[0].get_clusters()
|
| 52 |
|
| 53 |
-
#
|
| 54 |
-
|
| 55 |
-
result += f"📝 英文邏輯空間: {working_text}\n"
|
| 56 |
-
try:
|
| 57 |
-
translation_back = GoogleTranslator(source='en', target='zh-TW').translate(working_text)
|
| 58 |
-
result += f"📖 英翻中結果: {translation_back}\n"
|
| 59 |
-
except:
|
| 60 |
-
pass
|
| 61 |
-
|
| 62 |
-
result += "---------------------------------\n"
|
| 63 |
|
| 64 |
-
#
|
|
|
|
| 65 |
if clusters:
|
| 66 |
-
result += "📚【AI 智慧單字卡 / Vocabulary Cards】\n"
|
| 67 |
extracted_words = set()
|
| 68 |
-
# 抓取實體鏈裡的所有單字
|
| 69 |
for cluster in clusters:
|
| 70 |
for item in cluster:
|
| 71 |
-
# 清理冠詞
|
| 72 |
clean_word = item.lower().replace("the ", "").replace("a ", "").replace("her ", "").replace("his ", "").strip()
|
| 73 |
-
if len(clean_word) > 2 and clean_word not in ['she', 'he', 'him', 'her', 'it', 'they']:
|
| 74 |
extracted_words.add(clean_word)
|
| 75 |
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 84 |
|
| 85 |
-
#
|
|
|
|
|
|
|
|
|
|
| 86 |
if not clusters:
|
| 87 |
-
|
| 88 |
else:
|
| 89 |
-
|
| 90 |
for i, cluster in enumerate(clusters):
|
| 91 |
cluster_str_en = ' ↔ '.join(cluster)
|
| 92 |
try:
|
|
@@ -94,20 +92,48 @@ def coref_chat(user_input):
|
|
| 94 |
cluster_str_zh = ' ↔ '.join(translated_items)
|
| 95 |
except:
|
| 96 |
cluster_str_zh = cluster_str_en
|
| 97 |
-
|
|
|
|
| 98 |
|
| 99 |
-
return
|
| 100 |
|
| 101 |
except Exception as e:
|
| 102 |
-
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 103 |
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
)
|
| 111 |
|
| 112 |
if __name__ == "__main__":
|
| 113 |
demo.launch()
|
|
|
|
| 1 |
import os
|
| 2 |
import sys
|
| 3 |
|
| 4 |
+
# 1. 強制下載 Spacy 英文模型
|
| 5 |
os.system(f"{sys.executable} -m spacy download en_core_web_sm")
|
| 6 |
|
| 7 |
+
# 2. 解決新舊版本 Hub 相容性的 Mock 補丁
|
| 8 |
try:
|
| 9 |
import huggingface_hub
|
| 10 |
if not hasattr(huggingface_hub, 'HfFolder'):
|
|
|
|
| 21 |
from fastcoref import FCoref
|
| 22 |
from deep_translator import GoogleTranslator
|
| 23 |
|
| 24 |
+
# 3. 初始化輕量級消解模型
|
| 25 |
+
print("🚀 [System] 正在初始化 F-Coref 核心大腦...")
|
| 26 |
try:
|
|
|
|
| 27 |
model = FCoref(model_name_or_path='biu-nlp/f-coref', device='cpu')
|
| 28 |
+
print("✅ [System] 模型加載成功!")
|
| 29 |
+
except:
|
|
|
|
| 30 |
model = FCoref('biu-nlp/f-coref', device='cpu')
|
| 31 |
+
print("✅ [System] 備用路徑加載成功!")
|
| 32 |
|
| 33 |
+
# 4. 核心運算邏輯
|
| 34 |
+
def coref_learning_pipeline(user_input):
|
| 35 |
if not user_input.strip():
|
| 36 |
+
return "等待輸入...", "等待輸入...", "等待輸入..."
|
| 37 |
|
| 38 |
try:
|
| 39 |
+
# A. 判斷語言並進行中翻英橋接
|
| 40 |
has_chinese = any('\u4e00' <= char <= '\u9fff' for char in user_input)
|
| 41 |
if has_chinese:
|
| 42 |
working_text = GoogleTranslator(source='zh-CN', target='en').translate(user_input)
|
| 43 |
+
mode_notice = "中文輸入模式(已啟動 AI 跨語言橋接)"
|
| 44 |
else:
|
| 45 |
working_text = user_input
|
| 46 |
+
mode_notice = "英文原語模式"
|
| 47 |
|
| 48 |
+
# B. 執行 AI 指代消解運算
|
| 49 |
preds = model.predict(texts=[working_text])
|
| 50 |
clusters = preds[0].get_clusters()
|
| 51 |
|
| 52 |
+
# C. 欄位一:生成「英翻中結果」
|
| 53 |
+
translation_text = GoogleTranslator(source='en', target='zh-TW').translate(working_text)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 54 |
|
| 55 |
+
# D. 欄位二:生成妳要的【AI 智慧單字本】
|
| 56 |
+
vocab_output = ""
|
| 57 |
if clusters:
|
|
|
|
| 58 |
extracted_words = set()
|
|
|
|
| 59 |
for cluster in clusters:
|
| 60 |
for item in cluster:
|
| 61 |
+
# 清理冠詞與代名詞,只留下核心實體名詞
|
| 62 |
clean_word = item.lower().replace("the ", "").replace("a ", "").replace("her ", "").replace("his ", "").strip()
|
| 63 |
+
if len(clean_word) > 2 and clean_word not in ['she', 'he', 'him', 'her', 'it', 'they', 'i', 'you']:
|
| 64 |
extracted_words.add(clean_word)
|
| 65 |
|
| 66 |
+
if extracted_words:
|
| 67 |
+
for word in sorted(extracted_words):
|
| 68 |
+
try:
|
| 69 |
+
# 翻成繁體中文
|
| 70 |
+
word_zh = GoogleTranslator(source='en', target='zh-TW').translate(word)
|
| 71 |
+
# 格式化成妳要的:【Farmer (農夫)】樣式
|
| 72 |
+
vocab_output += f"🔸 {word.capitalize()} ➔ {word_zh}\n"
|
| 73 |
+
except:
|
| 74 |
+
pass
|
| 75 |
+
else:
|
| 76 |
+
vocab_output = "ℹ️ 本句的核心實體多為代名詞,未偵測到適合學習的高階名詞。"
|
| 77 |
+
else:
|
| 78 |
+
vocab_output = "🔍 未偵測到明確的指代關係,嘗試輸入更長的段落以提取單字!"
|
| 79 |
|
| 80 |
+
# E. 欄位三:生成「AI 語意共指報告」
|
| 81 |
+
report_text = f"✨ 系統狀態:{mode_notice}\n"
|
| 82 |
+
report_text += f"📝 英文運算空間: {working_text}\n"
|
| 83 |
+
report_text += "-----------------------------------------\n"
|
| 84 |
if not clusters:
|
| 85 |
+
report_text += "🔍 分析結果:指代關係明確,無需額外消解。"
|
| 86 |
else:
|
| 87 |
+
report_text += "🎯【實體連連看鏈結 (Entity Chains)】:\n"
|
| 88 |
for i, cluster in enumerate(clusters):
|
| 89 |
cluster_str_en = ' ↔ '.join(cluster)
|
| 90 |
try:
|
|
|
|
| 92 |
cluster_str_zh = ' ↔ '.join(translated_items)
|
| 93 |
except:
|
| 94 |
cluster_str_zh = cluster_str_en
|
| 95 |
+
report_text += f" 🔗 鏈結 {i+1} (中): {cluster_str_zh}\n"
|
| 96 |
+
report_text += f" └─ (英): {cluster_str_en}\n"
|
| 97 |
|
| 98 |
+
return translation_text, vocab_output, report_text
|
| 99 |
|
| 100 |
except Exception as e:
|
| 101 |
+
return f"錯誤: {str(e)}", "無法整合單字", f"運行異常: {str(e)}"
|
| 102 |
+
|
| 103 |
+
# 5. 精美 UI 介面設計(利用 Blocks 切分獨立區塊)
|
| 104 |
+
with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="indigo")) as demo:
|
| 105 |
+
gr.Markdown("# 🤖 Janice's AI 跨語言智慧語意學習終端")
|
| 106 |
+
gr.Markdown("### 🚀 專題亮點:結合核心指代消解 (Coreference Resolution) 與動態單字卡生成技術")
|
| 107 |
+
|
| 108 |
+
with gr.Row():
|
| 109 |
+
with gr.Column(scale=1):
|
| 110 |
+
txt_input = gr.Textbox(
|
| 111 |
+
label="📥 請輸入中文或英文段落 (Input Text)",
|
| 112 |
+
placeholder="例如:Mary is a Farmer. Mary had a little lamb.",
|
| 113 |
+
lines=5
|
| 114 |
+
)
|
| 115 |
+
btn_submit = gr.Button("🔥 執行多維度 AI 語意解析", variant="primary")
|
| 116 |
+
|
| 117 |
+
with gr.Column(scale=1):
|
| 118 |
+
# 這三個是各自獨立的漂亮框框!
|
| 119 |
+
out_translation = gr.Textbox(label="📖 完整文本翻譯 (Translation)", lines=3)
|
| 120 |
+
# 這裡就是妳要的專屬單字本!
|
| 121 |
+
out_vocab = gr.Textbox(label="📚 AI 智慧單字本 (Vocabulary Booklet)", lines=4)
|
| 122 |
+
out_report = gr.Textbox(label="🎯 AI 語意消解報告 (Coreference Report)", lines=6)
|
| 123 |
+
|
| 124 |
+
btn_submit.click(
|
| 125 |
+
fn=coref_learning_pipeline,
|
| 126 |
+
inputs=txt_input,
|
| 127 |
+
outputs=[out_translation, out_vocab, out_report]
|
| 128 |
+
)
|
| 129 |
|
| 130 |
+
gr.Examples(
|
| 131 |
+
examples=[
|
| 132 |
+
["Mary is a Farmer. Mary had a little lamb. John is a dancer. John like ballet."],
|
| 133 |
+
["張醫生正在動手術。她很冷靜。她的助手在旁邊遞器材,他看起來很緊張。"]
|
| 134 |
+
],
|
| 135 |
+
inputs=txt_input
|
| 136 |
+
)
|
| 137 |
|
| 138 |
if __name__ == "__main__":
|
| 139 |
demo.launch()
|