Spaces:
Running
on
Zero
Running
on
Zero
File size: 4,536 Bytes
dc13b6d f358820 dc13b6d 2f31c84 dc13b6d da40aec dc13b6d e894885 812c80c 2a9fd77 cc1322f dc13b6d 42dc39c dc13b6d 2f31c84 dc13b6d da40aec 041841e da40aec 8722708 72f7051 2f31c84 041841e 72f7051 dc13b6d 91852e0 f4fd3fb 041841e 6277588 6bcfde9 44ac7e8 041841e 6bcfde9 041841e 44ac7e8 041841e 44ac7e8 041841e 44ac7e8 041841e 44ac7e8 041841e 44ac7e8 041841e 44ac7e8 041841e 44ac7e8 da40aec 041841e da40aec dc13b6d 6bcfde9 dc13b6d 6bcfde9 041841e 44ac7e8 da40aec 44ac7e8 da40aec 44ac7e8 da40aec c58eafa da40aec 041841e dc13b6d 0fd90d3 041841e dc13b6d 6277588 041841e 6277588 dc13b6d 041841e |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
import spaces
import gradio as gr
from gradio import update
from functools import lru_cache
from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
from opencc import OpenCC # 用於簡體轉繁體
# 初始化簡體到繁體轉換器
cc = OpenCC('s2t')
# 可選模型列表
MODEL_LIST = [
"liswei/Taiwan-ELM-270M",
"Mxode/SmolLM-Chinese-180M",
"flyingfishinwater/chinese-baby-llama2",
"unsloth/gemma-3-1b-pt",
"ckiplab/gpt2-tiny-chinese",
"ckiplab/gpt2-base-chinese",
"liswei/Taiwan-ELM-1_1B",
"benchang1110/Qwen2.5-Taiwan-1.5B-Instruct",
"benchang1110/Taiwan-tinyllama-v1.0-base",
"lianghsun/Llama-3.2-Taiwan-3B",
"twinkle-ai/Llama-3.2-3B-F1-Instruct",
"Epiculous/Violet_Twilight-v0.2",
]
@lru_cache(maxsize=None)
def get_pipeline(model_name):
tok = AutoTokenizer.from_pretrained(model_name)
mdl = AutoModelForCausalLM.from_pretrained(
model_name, weights_only=False, trust_remote_code=True
)
mdl.to("cuda")
return pipeline("text-generation", model=mdl, tokenizer=tok, device=0)
@spaces.GPU
def suggest_next(text, model_name, k, m):
"""
使用 Beam Search 產生 m 條候選,並一次更新候選列表,轉繁體並編號。
"""
gen_pipe = get_pipeline(model_name)
outs = gen_pipe(
text,
max_new_tokens=k,
num_beams=m,
num_return_sequences=m,
do_sample=False,
early_stopping=True
)
suggestions = [out["generated_text"][len(text):].strip() for out in outs]
suggestions = [s for s in suggestions if s]
suggestions = [cc.convert(s) for s in suggestions]
numbered = [f"{i+1}. {s}" for i, s in enumerate(suggestions)]
return update(choices=numbered, value=None)
def append_suggestion(current, choice):
if choice is None:
return current
text = choice.split(". ", 1)[1] if ". " in choice else choice
return current + text
# 自訂 CSS:模擬經典中文輸入法候選欄樣式
custom_css = """
#suggestions-bar {
margin-bottom: 8px;
}
#suggestions-bar .candidate-list {
display: flex;
gap: 8px;
background: #fff;
border: 1px solid #999;
border-radius: 4px;
padding: 4px 6px;
overflow-x: auto;
white-space: nowrap;
}
#suggestions-bar .candidate-list input[type=radio] {
display: none;
}
#suggestions-bar .candidate-list label {
position: relative;
cursor: pointer;
padding: 4px 8px;
font-size: 14px;
}
#suggestions-bar .candidate-list label:hover {
background: #f5f5f5;
}
#suggestions-bar .candidate-list input[type=radio]:checked + label {
background: #e6f7ff;
border: 1px solid #1890ff;
}
"""
with gr.Blocks(css=custom_css) as demo:
gr.Markdown(
"## 🇹🇼 繁體中文 IME 加速器 \
"
"結合小型語言模型與 ZeroGPU,提供即時輸入法風格候選欄。"
)
# 候選條(置於上方)
suggestions = gr.Radio(
[], label="", interactive=True, type="value",
elem_id="suggestions-bar", elem_classes="candidate-list"
)
# 輸入框(置於候選條下方)
input_text = gr.Textbox(
label="", placeholder="請輸入拼音或文字…",
lines=1, max_lines=1, elem_id="input-box"
)
# 預測按鈕(置於文字框下方)
predict_button = gr.Button("預測", elem_id="predict-button")
# 進階參數設定(可摺疊)
with gr.Accordion("進階設定", open=False):
model_selector = gr.Dropdown(
MODEL_LIST, value=MODEL_LIST[0], label="模型"
)
k_slider = gr.Slider(
minimum=1, maximum=50, step=1, value=1, label="K(最大新詞元數)"
)
m_slider = gr.Slider(
minimum=1, maximum=30, step=1, value=6, label="M(建議數/Beam 數)"
)
auto_predict = gr.Checkbox(
value=True, label="自動預測(內容變更時觸發)", elem_id="auto-predict"
)
# 事件綁定
predict_button.click(
fn=suggest_next,
inputs=[input_text, model_selector, k_slider, m_slider],
outputs=suggestions,
)
input_text.change(
fn=lambda txt, mdl, k, m, auto: suggest_next(txt, mdl, k, m) if auto else update(choices=[], value=None),
inputs=[input_text, model_selector, k_slider, m_slider, auto_predict],
outputs=suggestions,
)
suggestions.change(
fn=append_suggestion,
inputs=[input_text, suggestions],
outputs=input_text,
)
demo.launch()
|