Spaces:
Running
on
Zero
Running
on
Zero
File size: 3,659 Bytes
dc13b6d f358820 dc13b6d da40aec dc13b6d cc1322f dc13b6d c97ac97 dc13b6d 42dc39c dc13b6d 5799add dc13b6d da40aec 44ac7e8 da40aec 8722708 72f7051 44ac7e8 91852e0 dc13b6d 91852e0 f4fd3fb 44ac7e8 dc13b6d 44ac7e8 da40aec 1593e08 44ac7e8 da40aec dc13b6d 44ac7e8 0fd90d3 44ac7e8 0fd90d3 44ac7e8 7e8e5b2 44ac7e8 dc13b6d 44ac7e8 da40aec 44ac7e8 da40aec 44ac7e8 da40aec 44ac7e8 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 |
import spaces
import gradio as gr
from gradio import update
from functools import lru_cache
from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
# 可選模型列表
MODEL_LIST = [
"unsloth/gemma-3-1b-pt",
"ckiplab/gpt2-tiny-chinese",
"ckiplab/gpt2-base-chinese",
"liswei/Taiwan-ELM-270M",
"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]
# 更新候選條
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=10, 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()
|