Spaces:
Running
on
Zero
Running
on
Zero
File size: 3,987 Bytes
dc13b6d f358820 dc13b6d 2f31c84 dc13b6d da40aec dc13b6d e894885 812c80c 2a9fd77 cc1322f dc13b6d 42dc39c dc13b6d 2f31c84 dc13b6d da40aec 2f31c84 da40aec 8722708 2f31c84 72f7051 2f31c84 72f7051 91852e0 dc13b6d 91852e0 f4fd3fb 44ac7e8 dc13b6d 2f31c84 44ac7e8 da40aec 2f31c84 44ac7e8 da40aec dc13b6d 44ac7e8 0fd90d3 44ac7e8 0fd90d3 44ac7e8 7e8e5b2 44ac7e8 dc13b6d 44ac7e8 da40aec 44ac7e8 da40aec 44ac7e8 da40aec c58eafa da40aec dc13b6d 0fd90d3 dc13b6d |
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 |
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]
return update(choices=suggestions, value=None)
def append_suggestion(current, choice):
if choice is None:
return current
# 模擬輸入法候選選中
return current + choice
# 自訂 CSS:模擬經典中文輸入法候選欄樣式
custom_css = """
#suggestions-bar .candidate-list {
display: flex;
gap: 12px;
background: #ffffff;
border: 1px solid #ccc;
border-radius: 4px;
padding: 6px;
}
#suggestions-bar .candidate-list input[type=radio] {
display: none;
}
#suggestions-bar .candidate-list label {
cursor: pointer;
padding: 2px 6px;
border-radius: 4px;
}
#suggestions-bar .candidate-list label:hover {
background: #f0f0f0;
}
#suggestions-bar .candidate-list input[type=radio]:checked + label {
background: #e0e0e0;
border: 1px solid #888;
}
"""
with gr.Blocks(css=custom_css) as demo:
# 標題和說明
gr.Markdown(
"## 🇹🇼 繁體中文輸入法加速器 \n"
"結合小型語言模型與 ZeroGPU,即時 IME 風格候選條。"
)
# 經典候選欄:水平排列
suggestions = gr.Radio(
[], label="", interactive=True, type="value",
elem_id="suggestions-bar", elem_classes="candidate-list"
)
# 輸入區與按鈕:單行輸入框 + 小按鈕
with gr.Row():
input_text = gr.Textbox(
label="", placeholder="請輸入拼音或文字…", lines=1, max_lines=1
)
gpu_button = gr.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 數)"
)
# 事件綁定
gpu_button.click(
fn=suggest_next,
inputs=[input_text, model_selector, k_slider, m_slider],
outputs=suggestions,
)
suggestions.change(
fn=append_suggestion,
inputs=[input_text, suggestions],
outputs=input_text,
)
demo.launch()
|