Marcus719 commited on
Commit
49dc795
·
verified ·
1 Parent(s): 45023b4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +114 -22
app.py CHANGED
@@ -136,34 +136,126 @@ def generate_response(prompt: str, max_tokens: int, state):
136
  return f"Error: {exc}\n\n{tb}", f"❌ Error: {exc}", state
137
 
138
  # ---------------- Gradio UI ----------------
139
- with gr.Blocks(title="Phi-3 Mini 4K - GGUF (4-bit)") as demo:
140
- gr.Markdown("## 🐠 Phi-3 Mini 4K - GGUF (4-bit)\nThis Space loads the quantized GGUF from the model repo and runs it with `llama-cpp-python`.")
141
- with gr.Row():
142
- prompt_in = gr.Textbox(lines=4, label="Prompt", placeholder="Write a haiku about physics...")
143
- with gr.Row():
144
- max_tokens = gr.Slider(minimum=16, maximum=1024, step=16, value=DEFAULT_MAX_TOKENS, label="Max tokens")
145
- with gr.Row():
146
- init_btn = gr.Button("Init Model")
147
- gen_btn = gr.Button("Generate")
148
- clear_btn = gr.Button("Clear")
 
 
 
 
 
 
 
 
 
 
 
 
149
  with gr.Row():
150
- output_txt = gr.Textbox(label="Output", lines=10)
 
 
 
 
 
 
 
 
 
 
 
 
151
  with gr.Row():
152
- status_label = gr.Label(value="⚪ Not initialized", label="Status")
153
- # Hidden state object holding the Llama instance and other runtime info
154
- state = gr.State({"llm": None, "gguf_path": None, "status": "Not initialized"})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
 
156
- # Wire init button
157
- init_btn.click(fn=init_model, inputs=state, outputs=[status_label, state])
 
 
 
 
158
 
159
- # Wire generate button (returns output text and status)
160
- gen_btn.click(fn=generate_response, inputs=[prompt_in, max_tokens, state], outputs=[output_txt, status_label, state])
161
 
162
- # Clear button functionality
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
163
  def clear_all():
164
- return "", "⚪ Not initialized", {"llm": None, "gguf_path": None, "status": "Not initialized"}
165
- clear_btn.click(fn=clear_all, outputs=[prompt_in, status_label, state])
 
 
 
 
 
 
 
 
 
 
 
166
 
167
- # Launch with no share by default (Spaces already public) and disable analytics to reduce noise.
168
  if __name__ == "__main__":
169
  demo.launch(server_name="0.0.0.0", server_port=7860, share=False)
 
136
  return f"Error: {exc}\n\n{tb}", f"❌ Error: {exc}", state
137
 
138
  # ---------------- Gradio UI ----------------
139
+
140
+ # 使用 Soft 主题,配色更具现代感
141
+ theme = gr.themes.Soft(
142
+ primary_hue="indigo",
143
+ secondary_hue="slate",
144
+ neutral_hue="slate",
145
+ font=[gr.themes.GoogleFont("Inter"), "ui-sans-serif", "system-ui"]
146
+ )
147
+
148
+ # 自定义 CSS 稍微调整一下边距和圆角
149
+ custom_css = """
150
+ #response-box {
151
+ font-family: 'Inter', sans-serif;
152
+ background-color: #f9fafb;
153
+ border-radius: 8px;
154
+ padding: 10px;
155
+ }
156
+ """
157
+
158
+ with gr.Blocks(title="Llama 3.2 Lab2 Project", theme=theme, css=custom_css) as demo:
159
+
160
+ # --- 标题和介绍区域 ---
161
  with gr.Row():
162
+ with gr.Column(scale=1):
163
+ gr.Markdown("# 🦙 Llama 3.2 (3B) Fine-Tuned Chatbot")
164
+ gr.Markdown(
165
+ """
166
+ **ID2223 Lab 2 Project** | Fine-tuned on the **FineTome-100k** dataset.
167
+ Running locally on CPU via **GGUF** quantization (4-bit).
168
+ """
169
+ )
170
+ with gr.Column(scale=0, min_width=150):
171
+ # 状态显示放在右上角,醒目
172
+ status_label = gr.Label(value="⚪ Not initialized", label="System Status", show_label=False)
173
+
174
+ # --- 主体布局:左侧控制,右侧输出 ---
175
  with gr.Row():
176
+
177
+ # 左侧:控制面板
178
+ with gr.Column(scale=4):
179
+ with gr.Group():
180
+ prompt_in = gr.Textbox(
181
+ lines=5,
182
+ label="User Instruction",
183
+ placeholder="E.g., Explain quantum entanglement to a 5-year-old...",
184
+ elem_id="prompt-input"
185
+ )
186
+
187
+ # 将参数折叠起来,保持界面清爽
188
+ with gr.Accordion("⚙️ Advanced Parameters", open=False):
189
+ max_tokens = gr.Slider(
190
+ minimum=16,
191
+ maximum=1024,
192
+ step=16,
193
+ value=DEFAULT_MAX_TOKENS,
194
+ label="Max Generation Tokens",
195
+ info="Longer generations require more CPU time."
196
+ )
197
+
198
+ # 按钮区域
199
+ with gr.Row():
200
+ init_btn = gr.Button("🚀 1. Load Model", variant="secondary", scale=1)
201
+ gen_btn = gr.Button("✨ 2. Generate", variant="primary", scale=2)
202
+
203
+ with gr.Row():
204
+ clear_btn = gr.Button("🗑️ Clear History", variant="stop")
205
+
206
+ # 右侧:回复展示
207
+ with gr.Column(scale=6):
208
+ output_txt = gr.Textbox(
209
+ label="Llama Response",
210
+ lines=15,
211
+ placeholder="The model response will appear here...",
212
+ show_copy_button=True, # 允许复制内容
213
+ elem_id="response-box"
214
+ )
215
 
216
+ # --- 底部版权/说明 ---
217
+ with gr.Row():
218
+ gr.Markdown(
219
+ "⚠️ *Note: Inference is running on CPU. Generation speed depends on the Space hardware.*",
220
+ elem_classes=["footer-text"]
221
+ )
222
 
223
+ # --- 状态管理 (Hidden) ---
224
+ state = gr.State({"llm": None, "gguf_path": None, "status": "Not initialized"})
225
 
226
+ # --- 事件绑定 ---
227
+ # 点击 Load Model
228
+ init_btn.click(
229
+ fn=init_model,
230
+ inputs=state,
231
+ outputs=[status_label, state],
232
+ show_progress=True
233
+ )
234
+
235
+ # 点击 Generate
236
+ gen_btn.click(
237
+ fn=generate_response,
238
+ inputs=[prompt_in, max_tokens, state],
239
+ outputs=[output_txt, status_label, state],
240
+ show_progress=True
241
+ )
242
+
243
+ # 点击 Clear
244
  def clear_all():
245
+ return "", "⚪ Ready", {"llm": None, "gguf_path": None, "status": "Not initialized"}
246
+
247
+ # 注意:Clear 按钮逻辑稍微修改,避免清空掉已加载的模型对象
248
+ # 这里的 clear_all 只是重置了 UI,实际你可以保留 state 中的 llm 以免重复加载
249
+ # 改进版 Clear 逻辑:
250
+ def soft_clear(current_state):
251
+ # 保持模型加载状态,只清空文本
252
+ status = "✅ Ready" if current_state.get("llm") else "⚪ Not initialized"
253
+ return "", status, current_state
254
+
255
+ clear_btn.click(fn=soft_clear, inputs=[state], outputs=[prompt_in, status_label, state])
256
+ # 同时也清空输出框
257
+ clear_btn.click(lambda: "", outputs=[output_txt])
258
 
259
+ # Launch configuration
260
  if __name__ == "__main__":
261
  demo.launch(server_name="0.0.0.0", server_port=7860, share=False)