Luigi commited on
Commit
3b87f8e
·
1 Parent(s): 3350989

add missing part

Browse files
Files changed (1) hide show
  1. app.py +102 -11
app.py CHANGED
@@ -26,19 +26,30 @@ MODEL_LIST = [
26
  ]
27
 
28
  def merge_common_prefixes(suggestions, min_len=2):
 
 
 
 
 
29
  prefixes = []
30
  to_remove = set()
 
31
  for i in range(len(suggestions)):
32
  for j in range(i+1, len(suggestions)):
33
  s1, s2 = suggestions[i], suggestions[j]
 
34
  common = ''.join(c1 for c1, c2 in zip(s1, s2) if c1 == c2)
35
  if len(common) >= min_len:
36
  prefixes.append(common)
37
  to_remove.update([s1, s2])
 
 
38
  unique_prefixes = []
39
  for p in prefixes:
40
  if p not in unique_prefixes:
41
  unique_prefixes.append(p)
 
 
42
  remainder = [s for s in suggestions if s not in to_remove]
43
  return unique_prefixes + remainder
44
 
@@ -53,6 +64,12 @@ def get_pipeline(model_name):
53
 
54
  @spaces.GPU
55
  def suggest_next(text, model_name, k, m, num_beam_groups, diversity_penalty):
 
 
 
 
 
 
56
  gen_pipe = get_pipeline(model_name)
57
  # 構造 generate 參數字典,僅在 penalty>0 時加入 diversity 相關
58
  gen_kwargs = {
@@ -86,18 +103,88 @@ def suggest_next(text, model_name, k, m, num_beam_groups, diversity_penalty):
86
 
87
  return update(choices=final_suggestions, value=None)
88
 
89
- def append_suggestion(text, choice):
90
- return text + choice
91
 
92
- with gr.Blocks(css="""
93
- #suggestions-bar { width: 100%; margin-bottom: 8px; }
 
 
 
 
 
 
 
 
 
 
94
  #suggestions-bar .candidate-list {
95
- display: flex; gap: 8px; background: #fff;
96
- border: 1px solid #999; border-radius: 4px;
97
- padding: 6px; overflow-x: auto; white-space: nowrap;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
98
  }
99
- #suggestions-bar .candidate-list label { cursor: pointer; }
100
- """) as demo:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
  with gr.Column():
102
  suggestions = gr.Radio(
103
  [], label="", interactive=True, type="value",
@@ -108,11 +195,14 @@ with gr.Blocks(css="""
108
  lines=1, max_lines=20, elem_id="input-box"
109
  )
110
 
 
111
  with gr.Row():
112
  auto_predict = gr.Checkbox(
113
  value=True, label="自動預測(內容變更時觸發)", elem_id="auto-predict"
114
  )
115
- predict_button = gr.Button("預測", elem_id="predict-button")
 
 
116
 
117
  with gr.Accordion("進階設定", open=False):
118
  model_selector = gr.Dropdown(
@@ -133,6 +223,7 @@ with gr.Blocks(css="""
133
  label="多樣性懲罰 (diversity_penalty)"
134
  )
135
 
 
136
  predict_button.click(
137
  fn=suggest_next,
138
  inputs=[
@@ -167,4 +258,4 @@ with gr.Blocks(css="""
167
  outputs=input_text,
168
  )
169
 
170
- demo.launch()
 
26
  ]
27
 
28
  def merge_common_prefixes(suggestions, min_len=2):
29
+ """
30
+ 合併具有共同前綴的建議:
31
+ - 找出所有長度 ≥ min_len 的共同前綴
32
+ - 將這些前綴作為新建議,移除原有被合併的項目
33
+ """
34
  prefixes = []
35
  to_remove = set()
36
+
37
  for i in range(len(suggestions)):
38
  for j in range(i+1, len(suggestions)):
39
  s1, s2 = suggestions[i], suggestions[j]
40
+ # 計算字元級共同前綴
41
  common = ''.join(c1 for c1, c2 in zip(s1, s2) if c1 == c2)
42
  if len(common) >= min_len:
43
  prefixes.append(common)
44
  to_remove.update([s1, s2])
45
+
46
+ # 去重前綴
47
  unique_prefixes = []
48
  for p in prefixes:
49
  if p not in unique_prefixes:
50
  unique_prefixes.append(p)
51
+
52
+ # 剩下沒有被合併的建議
53
  remainder = [s for s in suggestions if s not in to_remove]
54
  return unique_prefixes + remainder
55
 
 
64
 
65
  @spaces.GPU
66
  def suggest_next(text, model_name, k, m, num_beam_groups, diversity_penalty):
67
+ """
68
+ 使用 Diverse Beam Search 產生 m 條候選:
69
+ - num_beams = m
70
+ - num_beam_groups, diversity_penalty 可調整多樣性
71
+ 之後轉繁體、去重、合併共同前綴後回傳。
72
+ """
73
  gen_pipe = get_pipeline(model_name)
74
  # 構造 generate 參數字典,僅在 penalty>0 時加入 diversity 相關
75
  gen_kwargs = {
 
103
 
104
  return update(choices=final_suggestions, value=None)
105
 
 
 
106
 
107
+ def append_suggestion(current, choice):
108
+ if choice is None:
109
+ return current
110
+ # 直接插入選中的候選文字
111
+ return current + choice
112
+
113
+ # 自訂 CSS:模擬經典中文輸入法候選欄樣式,並優化手機響應與自動高度
114
+ custom_css = """
115
+ #suggestions-bar {
116
+ width: 100%;
117
+ margin-bottom: 8px;
118
+ }
119
  #suggestions-bar .candidate-list {
120
+ display: flex;
121
+ gap: 8px;
122
+ background: #fff;
123
+ border: 1px solid #999;
124
+ border-radius: 4px;
125
+ padding: 6px;
126
+ overflow-x: auto;
127
+ white-space: nowrap;
128
+ }
129
+ #suggestions-bar .candidate-list label {
130
+ cursor: pointer;
131
+ padding: 6px 10px;
132
+ font-size: 16px;
133
+ }
134
+ #suggestions-bar .candidate-list label:hover {
135
+ background: #f5f5f5;
136
+ }
137
+ #suggestions-bar .candidate-list input[type=radio]:checked + label {
138
+ background: #e6f7ff;
139
+ border: 1px solid #1890ff;
140
+ }
141
+ #input-box textarea {
142
+ width: 100%;
143
+ font-size: 16px;
144
+ padding: 6px;
145
+ box-sizing: border-box;
146
+ overflow: hidden;
147
+ resize: none;
148
  }
149
+ #predict-button {
150
+ margin-top: 8px;
151
+ width: 100%;
152
+ }
153
+ /* 手機響應式 */
154
+ @media only screen and (max-width: 600px) {
155
+ #suggestions-bar .candidate-list label {
156
+ padding: 8px;
157
+ font-size: 18px;
158
+ }
159
+ #predict-button {
160
+ font-size: 18px;
161
+ }
162
+ }
163
+ """
164
+
165
+ # 自動增高腳本
166
+ auto_height_js = """
167
+ <script>
168
+ window.addEventListener('load', () => {
169
+ const textarea = document.querySelector('#input-box textarea');
170
+ if (!textarea) return;
171
+ textarea.style.height = 'auto';
172
+ textarea.addEventListener('input', function() {
173
+ this.style.height = 'auto';
174
+ this.style.height = this.scrollHeight + 'px';
175
+ });
176
+ });
177
+ </script>
178
+ """
179
+
180
+ with gr.Blocks(css=custom_css) as demo:
181
+ gr.HTML(auto_height_js)
182
+ gr.Markdown(
183
+ "## 🇹🇼 繁體中文 IME 加速器 \
184
+ "
185
+ "結合小型語言模型與 ZeroGPU,提供即時輸入法風格候選欄。"
186
+ )
187
+
188
  with gr.Column():
189
  suggestions = gr.Radio(
190
  [], label="", interactive=True, type="value",
 
195
  lines=1, max_lines=20, elem_id="input-box"
196
  )
197
 
198
+ # 永遠顯示預測按鈕
199
  with gr.Row():
200
  auto_predict = gr.Checkbox(
201
  value=True, label="自動預測(內容變更時觸發)", elem_id="auto-predict"
202
  )
203
+ predict_button = gr.Button(
204
+ "預測", elem_id="predict-button"
205
+ )
206
 
207
  with gr.Accordion("進階設定", open=False):
208
  model_selector = gr.Dropdown(
 
223
  label="多樣性懲罰 (diversity_penalty)"
224
  )
225
 
226
+ # 綁定事件
227
  predict_button.click(
228
  fn=suggest_next,
229
  inputs=[
 
258
  outputs=input_text,
259
  )
260
 
261
+ demo.launch()