hsuwill000 commited on
Commit
defa84e
·
verified ·
1 Parent(s): 0584daf

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +156 -60
app.py CHANGED
@@ -1,70 +1,166 @@
 
 
 
1
  import gradio as gr
2
- from huggingface_hub import InferenceClient
3
-
4
-
5
- def respond(
6
- message,
7
- history: list[dict[str, str]],
8
- system_message,
9
- max_tokens,
10
- temperature,
11
- top_p,
12
- hf_token: gr.OAuthToken,
13
- ):
14
- """
15
- For more information on `huggingface_hub` Inference API support, please check the docs: https://huggingface.co/docs/huggingface_hub/v0.22.2/en/guides/inference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  """
17
- client = InferenceClient(token=hf_token.token, model="openai/gpt-oss-20b")
18
 
 
 
 
 
 
 
19
  messages = [{"role": "system", "content": system_message}]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
 
21
- messages.extend(history)
 
 
22
 
23
- messages.append({"role": "user", "content": message})
24
 
25
- response = ""
26
-
27
- for message in client.chat_completion(
28
- messages,
29
- max_tokens=max_tokens,
30
- stream=True,
31
- temperature=temperature,
32
- top_p=top_p,
33
- ):
34
- choices = message.choices
35
- token = ""
36
- if len(choices) and choices[0].delta.content:
37
- token = choices[0].delta.content
38
-
39
- response += token
40
- yield response
41
-
42
-
43
- """
44
- For information on how to customize the ChatInterface, peruse the gradio docs: https://www.gradio.app/docs/chatinterface
45
- """
46
- chatbot = gr.ChatInterface(
47
- respond,
48
- type="messages",
49
- additional_inputs=[
50
- gr.Textbox(value="You are a friendly Chatbot.", label="System message"),
51
- gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max new tokens"),
52
- gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Temperature"),
53
- gr.Slider(
54
- minimum=0.1,
55
- maximum=1.0,
56
- value=0.95,
57
- step=0.05,
58
- label="Top-p (nucleus sampling)",
59
- ),
60
- ],
61
- )
62
-
63
- with gr.Blocks() as demo:
64
- with gr.Sidebar():
65
- gr.LoginButton()
66
- chatbot.render()
67
 
68
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
  if __name__ == "__main__":
70
- demo.launch()
 
 
 
1
+ # app.py
2
+
3
+ import os
4
  import gradio as gr
5
+ from typing import List, Dict
6
+ from huggingface_hub import hf_hub_download
7
+ from llama_cpp import Llama
8
+
9
+ # --- 1. 模型設定與下載 ---
10
+
11
+ # 您指定的模型資訊
12
+ MODEL_NAME = "Qwen3-0.6B-Q8_0.gguf"
13
+ MODEL_REPO = "Qwen/Qwen3-0.6B-GGUF"
14
+
15
+ # 固定的系統提示
16
+ DEFAULT_SYSTEM_MESSAGE = "You are a friendly and helpful assistant. Please answer the user's questions concisely and accurately."
17
+
18
+ # 步驟 1: 下載 GGUF 模型
19
+ # 模型會被下載到 ~/.cache/huggingface/hub/ 或指定的快取目錄
20
+ try:
21
+ print(f"嘗試從 {MODEL_REPO} 下載 {MODEL_NAME}...")
22
+ model_path = hf_hub_download(repo_id=MODEL_REPO, filename=MODEL_NAME)
23
+ print(f"模型下載完成,路徑: {model_path}")
24
+ except Exception as e:
25
+ print(f"**錯誤**:無法下載模型。請檢查網路連線或模型名稱/權限。錯誤訊息: {e}")
26
+ # 在 Gradio Space 中,如果模型無法下載,應用程式會無法啟動。
27
+ # 這裡可以選擇性地退出或使用本地路徑作為備用(如果存在)。
28
+ exit(1)
29
+
30
+
31
+ # --- 2. Llama.cpp 初始化 ---
32
+
33
+ # 步驟 2: 初始化 Llama.cpp 實例
34
+ # n_gpu_layers=0 表示不使用 GPU (CPU 推論),如果環境支援 CUDA/cuBLAS,可以設定為 >0
35
+ try:
36
+ print("正在初始化 Llama.cpp 實例...")
37
+ llm = Llama(
38
+ model_path=model_path,
39
+ n_ctx=4096, # 上下文長度
40
+ n_batch=512, # 批次大小
41
+ n_threads=os.cpu_count() // 2 or 1, # 使用一半的 CPU 核心
42
+ n_gpu_layers=0, # CPU 推論
43
+ verbose=False # 關閉內部日誌輸出
44
+ )
45
+ print("Llama.cpp 模型加載成功。")
46
+ except Exception as e:
47
+ print(f"**錯誤**:Llama.cpp 實例初始化失敗。錯誤訊息: {e}")
48
+ exit(1)
49
+
50
+
51
+ # --- 3. 推論核心函式 ---
52
+
53
+ def llama_inference(
54
+ message: str,
55
+ chat_history: List[List[str]],
56
+ system_message: str = DEFAULT_SYSTEM_MESSAGE,
57
+ max_tokens: int = 4096,
58
+ temperature: float = 0.7,
59
+ top_p: float = 0.95
60
+ ) -> str:
61
  """
62
+ 使用 Llama.cpp 實例執行推論並返回回應。
63
 
64
+ :param message: 當前的使用者輸入。
65
+ :param chat_history: Gradio 傳遞的聊天歷史記錄 (list of [user, bot] pairs)。
66
+ :return: LLM 的回應文字。
67
+ """
68
+
69
+ # 將 Gradio 的聊天歷史轉換為 Llama.cpp/OpenAI 格式的 messages 列表
70
  messages = [{"role": "system", "content": system_message}]
71
+
72
+ for human, assistant in chat_history:
73
+ # 歷史對話
74
+ messages.append({"role": "user", "content": human})
75
+ messages.append({"role": "assistant", "content": assistant})
76
+
77
+ # 當前訊息
78
+ messages.append({"role": "user", "content": message})
79
+
80
+
81
+ try:
82
+ # 呼叫 Llama.cpp 的 create_chat_completion 介面 (與 OpenAI 格式相容)
83
+ response = llm.create_chat_completion(
84
+ messages=messages,
85
+ max_tokens=max_tokens,
86
+ temperature=temperature,
87
+ top_p=top_p,
88
+ # stream=False 是預設值
89
+ )
90
+
91
+ # 解析回應
92
+ if response.get('choices') and response['choices'][0].get('message'):
93
+ content = response['choices'][0]['message'].get('content', "⚠️ LLM 服務回傳空內容。")
94
+ return content
95
+
96
+ return "⚠️ LLM 服務回傳空內容。"
97
 
98
+ except Exception as e:
99
+ print(f"[Error] Llama Inference failed: {e}")
100
+ return f"❌ 伺服器錯誤 (Llama.cpp 推論失敗): {e}"
101
 
 
102
 
103
+ # --- 4. Gradio 介面設定 ---
104
+
105
+ # 定義 Gradio 聊天函式 (用於更新介面)
106
+ def chat_interface(message: str, history: List[List[str]]):
107
+ """Gradio 介面調用函式。"""
108
+
109
+ # 這裡可以固定或從另一個輸入元件獲取參數,為了簡化,使用硬編碼值
110
+ response = llama_inference(
111
+ message=message,
112
+ chat_history=history,
113
+ system_message=DEFAULT_SYSTEM_MESSAGE,
114
+ max_tokens=4096,
115
+ temperature=0.7,
116
+ top_p=0.95
117
+ )
118
+
119
+ # Gradio 聊天介面要求回傳回應文字
120
+ return response
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
 
122
 
123
+ # 建立 Gradio 介面
124
+ with gr.Blocks(title="Qwen3-0.6B-GGUF 聊天機器人") as demo:
125
+ gr.Markdown(
126
+ f"""
127
+ # Qwen3-0.6B-GGUF 聊天機器人
128
+ 使用 **llama-cpp-python** 模組運行 **{MODEL_NAME}** 模型。
129
+ """
130
+ )
131
+
132
+ # 聊天元件
133
+ chatbot = gr.Chatbot(
134
+ label="聊天記錄",
135
+ height=500
136
+ )
137
+
138
+ # 聊天輸入元件
139
+ chat_input = gr.Textbox(
140
+ show_label=False,
141
+ placeholder="請輸入你的問題...",
142
+ container=False
143
+ )
144
+
145
+ # 綁定聊天邏輯
146
+ # submit 觸發事件:
147
+ # - fn: 要執行的 Python 函式 (chat_interface)
148
+ # - inputs: 函式接收的輸入 ([Textbox 的內容, Chatbot 的歷史])
149
+ # - outputs: 函式輸出的結果 (Chatbot 的新歷史)
150
+ chat_input.submit(
151
+ fn=chat_interface,
152
+ inputs=[chat_input, chatbot],
153
+ outputs=chatbot
154
+ ).then(
155
+ # 清空輸入框
156
+ fn=lambda: "",
157
+ inputs=None,
158
+ outputs=chat_input,
159
+ queue=False
160
+ )
161
+
162
+ # 啟動應用程式
163
  if __name__ == "__main__":
164
+ # 在 Gradio Space 中,會使用 gunicorn 或類似服務來運行,但如果要在本地測試,可以使用以下命令:
165
+ # python app.py
166
+ demo.launch(server_name="0.0.0.0", server_port=7860)