MarshallCN commited on
Commit
d8371d9
·
1 Parent(s): 423a3f1

update ignore

Browse files
.gitignore CHANGED
@@ -9,4 +9,7 @@
9
  /old/
10
  /old/*
11
  models/
12
- models/*
 
 
 
 
9
  /old/
10
  /old/*
11
  models/
12
+ models/*
13
+ export/
14
+ msgs/
15
+ msgs/*
app_QwenGGUF.py DELETED
@@ -1,279 +0,0 @@
1
- # === Qwen 2.5 0.5B =========================
2
- import os
3
- import gradio as gr
4
- from gradio.themes.utils import fonts
5
- import uuid
6
- from pathlib import Path
7
- import json
8
- from datetime import datetime, timezone
9
- from typing import List, Dict, Tuple, Optional
10
- from utils import render, trim_by_tokens, mk_msg_dir, _as_dir, msg2hist, persist_messages
11
-
12
-
13
- llm = Llama.from_pretrained(
14
- repo_id="bartowski/Qwen2.5-0.5B-Instruct-GGUF",
15
- filename="Qwen2.5-0.5B-Instruct-Q4_K_M.gguf",
16
- )
17
-
18
- pipe = pipeline("text-generation", model=model, tokenizer=tok, device=-1)
19
-
20
- MAX_CONTEXT = 2048 #8192
21
- GEN_BUDGET = 256
22
- assistant_name = "Nova";
23
- user_name = "Marshall"
24
- persona = f"""
25
- - Your name is {assistant_name}.
26
- - Address the user as "{user_name}" when appropriate.
27
- - Do NOT prefix.
28
- - Output Markdown; code in fenced blocks with a language tag.
29
- - Answer concisely, but do return give empty feedback.
30
- """.strip()
31
- # ===============================================================
32
-
33
- theme = gr.themes.Soft(
34
- font=[
35
- fonts.Font("Segoe UI"),
36
- fonts.Font("system-ui"),
37
- fonts.Font("sans-serif"),
38
- ],
39
- font_mono=[
40
- fonts.Font("Consolas"),
41
- fonts.Font("ui-monospace"),
42
- fonts.Font("monospace"),
43
- ],
44
- )
45
-
46
- css = """
47
- #user_box textarea::-webkit-scrollbar { display: none; } /* Chrome/Safari */
48
- #user_box textarea { scrollbar-width: none; -ms-overflow-style: none; } /* Firefox/Edge */
49
- """
50
-
51
- GEN_KWARGS = dict(
52
- do_sample=True,
53
- temperature=0.6,
54
- top_p=0.9,
55
- repetition_penalty=1.05,
56
- max_context=MAX_CONTEXT,
57
- max_new_tokens=GEN_BUDGET
58
- )
59
-
60
- BASE_MSG_DIR = Path("./msgs/msgs_Qwen")
61
-
62
- def export_messages_to_json(messages, msg_id):
63
- base = Path("/data/exports") if Path("/data").exists() else Path("./exports")
64
- base.mkdir(parents=True, exist_ok=True)
65
- stamp = datetime.now().strftime("%Y%m%d-%H%M%S-")
66
- fname = f"msgs_{stamp}.json"
67
- path = base / fname
68
- path.write_text(json.dumps(messages or [], ensure_ascii=False, indent=2), encoding="utf-8")
69
- return str(path) # 返回给 gr.File 的文件路径
70
-
71
- def on_click_download(messages, msg_id):
72
- path = export_messages_to_json(messages, msg_id)
73
- # 让隐藏的 gr.File 出现,并指向刚刚写出的文件
74
- return gr.update(value=path, visible=True)
75
-
76
- # ============ Chat ============
77
- def chat_step(
78
- user_prompt: str,
79
- pipe, # transformers.pipeline
80
- tok, # AutoTokenizer
81
- messages: Optional[List[Dict[str, str]]] = None,
82
- mode: str = "continue", # "new" | "continue" | "load"
83
- persona: Optional[str] = None, # 新开会话时需要,
84
- max_context: int = 8192,
85
- max_new_tokens: int = 256,
86
- store_dir: str | Path = "./msgs",
87
- **gen_kwargs, # 透传生成参数:do_sample/temperature/top_p/repetition_penalty 等
88
- ) -> Tuple[str, List[Dict[str, str]], str]:
89
- """
90
- 运行一轮对话但不保存。
91
- 返回: (reply, messages, user_content_this_turn)
92
- """
93
- if mode not in {"new", "continue", "load"}:
94
- raise ValueError("mode 必须是 'new' | 'continue' | 'load'")
95
-
96
- if mode == "new":
97
- if not persona:
98
- raise ValueError("mode='new' 时必须提供 persona")
99
- messages = [{"role": "system", "content": persona}, {"role": "user", "content": user_prompt.strip()}]
100
-
101
- elif mode == "continue":
102
- if not messages:
103
- if persona:
104
- # 没有现成会话但给了 persona,则视作新会话
105
- messages = [{"role": "system", "content": persona}, {"role": "user", "content": user_prompt.strip()}]
106
- mode = "new"
107
- else:
108
- raise ValueError("mode='continue' 需要传入非空 messages,或改用 mode='new' 并提供 persona")
109
- else:
110
- messages.append({"role": "user", "content": user_prompt})
111
-
112
- elif mode == "load":
113
- messages = store.load_trimmed()
114
- if not messages:
115
- if not persona:
116
- raise ValueError("磁盘没有可加载的会话,且未提供 persona 以新建。")
117
- messages = [{"role": "system", "content": persona}, {"role": "user", "content": user_prompt.strip()}]
118
- mode = "new" # 实际上是新开
119
- else:
120
- messages.append({"role": "user", "content": user_prompt})
121
-
122
- # 裁剪 → 渲染 → 生成
123
- prompt_budget = max_context - max_new_tokens
124
- messages = trim_by_tokens(tok, messages, prompt_budget)
125
- text = render(tok, messages)
126
- out = pipe(
127
- text,
128
- max_new_tokens=max_new_tokens,
129
- return_full_text=False,
130
- clean_up_tokenization_spaces=False,
131
- **gen_kwargs,
132
- )
133
- reply = out[0]["generated_text"].strip()
134
-
135
- # 追加 assistant,二次裁剪
136
- messages.append({"role": "assistant", "content": reply})
137
- messages = trim_by_tokens(tok, messages, prompt_budget)
138
- return reply, messages, mode
139
-
140
- # ============ UI ============
141
-
142
- def ui_submit(user_input, messages, msg_id, sessions):
143
- # 输入 user_input, 消息队列,msg id, sessions list
144
- user_input = (user_input or "").strip()
145
- chat_history = msg2hist(persona, messages)
146
- if not user_input:
147
- return gr.update(), messages, chat_history, "", msg_dir, gr.update(),
148
-
149
- # 状态里一律存ID
150
- msg_id = msg_id if msg_id else ""
151
-
152
- new_session = (not messages)
153
- # sessions = gr.update()
154
-
155
- if new_session and not msg_id: #刚load界面没有任何msg_id
156
- msg_id = mk_msg_dir(BASE_MSG_DIR) # 用户创建msg_id./msgs/<ID>
157
- sessions = list(sessions or []) + [msg_id]
158
-
159
- #如果有msg_id但是没在sessions 里
160
- if msg_id and msg_id not in (sessions or []):
161
- sessions = list(sessions or []) + [msg_id]
162
-
163
- sessions_update = gr.update(choices=sessions, value=msg_id)
164
-
165
- if new_session:
166
- reply, messages, mode = chat_step(
167
- user_input, pipe, tok,
168
- mode="new", persona=persona,
169
- **GEN_KWARGS,
170
- )
171
- else:
172
- reply, messages, mode = chat_step(
173
- user_input, pipe, tok, persona=persona,
174
- mode="continue", messages=messages,
175
- **GEN_KWARGS,
176
- )
177
-
178
- if len(messages)>0:
179
- msg_dir = _as_dir(BASE_MSG_DIR, msg_id)
180
- persist_messages(messages, msg_dir, archive_last_turn=True)
181
-
182
- chat_history = (chat_history or []) + [
183
- {"role": "user", "content": user_input},
184
- {"role": "assistant", "content": reply},
185
- ]
186
- return "", messages, chat_history, msg_id, sessions_update, sessions
187
-
188
- def _load_latest(msg_id: str) -> List[Dict[str, str]]:
189
- p = Path(_as_dir(BASE_MSG_DIR, msg_id),"trimmed.json")
190
- if p.exists():
191
- messages = json.loads(p.read_text(encoding="utf-8"))
192
- return messages
193
-
194
- def _init_sessions():
195
- sessions = [p.name for p in BASE_MSG_DIR.iterdir() if p.is_dir()] # 只用ID
196
- if len(sessions)==0:
197
- return gr.update(choices=[], value=None), [], "", [], []
198
- else:
199
- sessions.sort(reverse=True)
200
- msg_id = sessions[0]
201
- messages = _load_latest(msg_id)
202
- chat_history = msg2hist(persona, messages)
203
- sessions_update = gr.update(choices=sessions, value=msg_id)
204
- return sessions_update, sessions, msg_id, messages, chat_history
205
-
206
-
207
- def load_session(session_list, sessions):
208
- msg_id = session_list # session_list is the selected msg_id in UI
209
- messages = _load_latest(msg_id)
210
- chat_history = msg2hist(persona, messages)
211
- sessions_update = gr.update(choices=sessions, value=msg_id)
212
- return msg_id, messages, chat_history, sessions_update
213
-
214
- def start_new_session(sessions):
215
- msg_id = mk_msg_dir(BASE_MSG_DIR)
216
- sessions = list(sessions or []) + [msg_id]
217
- sessions_update = gr.update(choices=sessions, value=msg_id)
218
- return [], [], "", msg_id, sessions_update, sessions # 返回ID
219
-
220
- with gr.Blocks(theme=theme, css=css) as demo:
221
- gr.Markdown("## 🧠 Qwen Chat")
222
-
223
- with gr.Row():
224
- with gr.Column(scale=3):
225
- session_list = gr.Radio(choices=[], value=None, label="Conversations", interactive=True)
226
- new_btn = gr.Button("New session", variant="secondary")
227
- dl_btn = gr.Button("Download JSON", variant="secondary")
228
- dl_file = gr.File(label="", interactive=False, visible=False, elem_id="dl-file")
229
- with gr.Column(scale=9):
230
- chat = gr.Chatbot(
231
- label="Chat",
232
- height=560,
233
- render_markdown=True,
234
- type="messages",
235
- elem_id="chatpane",
236
- )
237
- user_box = gr.Textbox(
238
- label="Your message",
239
- placeholder="Type and press Enter…",
240
- autofocus=True,
241
- elem_id="user_box"
242
- )
243
- send = gr.Button("Send", variant="primary")
244
-
245
-
246
-
247
- messages = gr.State([]) # with persona
248
- chat_history = gr.State([]) # without persona
249
- msg_id = gr.State("") # 当前会话
250
- sessions = gr.State([]) # 所有 msg_id list
251
-
252
- user_box.submit(
253
- ui_submit,
254
- inputs=[user_box, messages, msg_id, sessions],
255
- outputs=[user_box, messages, chat, msg_id, session_list, sessions],
256
- )
257
- send.click(
258
- ui_submit,
259
- inputs=[user_box, messages, msg_id, sessions],
260
- outputs=[user_box, messages, chat, msg_id, session_list, sessions],
261
- )
262
- new_btn.click(
263
- start_new_session,
264
- inputs=[sessions],
265
- outputs=[messages, chat, user_box, msg_id, session_list, sessions],
266
- )
267
- session_list.change(load_session,
268
- inputs=[session_list, sessions], # session_list is msg_id here
269
- outputs=[msg_id, messages, chat, session_list]
270
- )
271
- dl_btn.click(
272
- on_click_download,
273
- inputs=[messages, msg_id],
274
- outputs=[dl_file],
275
- )
276
-
277
- demo.load(_init_sessions, None,
278
- outputs=[session_list, sessions, msg_id, messages, chat])
279
- demo.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app_Qwen_awq.py DELETED
@@ -1,301 +0,0 @@
1
- # === Qwen 2.5 0.5B =========================
2
- import os
3
- os.environ.setdefault("TORCHDYNAMO_DISABLE", "1")
4
- os.environ.setdefault("TORCHINDUCTOR_DISABLE", "1")
5
- os.environ.setdefault("TRANSFORMERS_VERBOSITY", "error")
6
- import logging
7
- for name in ("accelerate", "accelerate.utils", "accelerate.utils.modeling"):
8
- logging.getLogger(name).setLevel(logging.ERROR)
9
-
10
- import gradio as gr
11
- from gradio.themes.utils import fonts
12
- import uuid
13
- from pathlib import Path
14
- import json
15
- from autoawq import AutoAWQForCausalLM
16
- from transformers import AutoTokenizer
17
- import torch
18
- from datetime import datetime, timezone
19
- from typing import List, Dict, Tuple, Optional
20
- from utils import render, trim_by_tokens, mk_msg_dir, _as_dir, msg2hist, persist_messages
21
-
22
-
23
- # local_dir = r"C:\Users\c1052689\hug_models\Qwen2.5Coder1_5B_Instruct"
24
- # local_dir = r"C:\Users\c1052689\hug_models\Qwen2.5_0.5B_Instruct_GPTQ_Int4"
25
- REPO_ID = "Qwen/Qwen2.5-0.5B-Instruct-GPTQ-Int4"
26
- tok = AutoTokenizer.from_pretrained(REPO_ID, use_fast=True, trust_remote_code=True)
27
- model = AutoAWQForCausalLM.from_quantized(
28
- REPO_ID,
29
- trust_remote_code=True,
30
- safetensors=True,
31
- device_map=None, # CPU Space
32
- )
33
- model.to("cpu")
34
- tok.pad_token = tok.eos_token
35
- tok.padding_side = "left"
36
- model.config.pad_token_id = tok.eos_token_id
37
- model.generation_config.pad_token_id = tok.eos_token_id
38
-
39
- pipe = pipeline("text-generation", model=model, tokenizer=tok, device=-1)
40
-
41
- MAX_CONTEXT = 2048 #8192
42
- GEN_BUDGET = 256
43
- assistant_name = "Nova";
44
- user_name = "Marshall"
45
- persona = f"""
46
- - Your name is {assistant_name}.
47
- - Address the user as "{user_name}" when appropriate.
48
- - Do NOT prefix.
49
- - Output Markdown; code in fenced blocks with a language tag.
50
- - Answer concisely, but do return give empty feedback.
51
- """.strip()
52
- # ===============================================================
53
- # from __future__ import annotations
54
-
55
- theme = gr.themes.Soft(
56
- font=[
57
- fonts.Font("Segoe UI"),
58
- fonts.Font("system-ui"),
59
- fonts.Font("sans-serif"),
60
- ],
61
- font_mono=[
62
- fonts.Font("Consolas"),
63
- fonts.Font("ui-monospace"),
64
- fonts.Font("monospace"),
65
- ],
66
- )
67
-
68
- css = """
69
- #user_box textarea::-webkit-scrollbar { display: none; } /* Chrome/Safari */
70
- #user_box textarea { scrollbar-width: none; -ms-overflow-style: none; } /* Firefox/Edge */
71
- """
72
-
73
- GEN_KWARGS = dict(
74
- do_sample=True,
75
- temperature=0.6,
76
- top_p=0.9,
77
- repetition_penalty=1.05,
78
- max_context=MAX_CONTEXT,
79
- max_new_tokens=GEN_BUDGET
80
- )
81
-
82
- BASE_MSG_DIR = Path("./msgs/msgs_Qwen")
83
-
84
- def export_messages_to_json(messages, msg_id):
85
- base = Path("/data/exports") if Path("/data").exists() else Path("./exports")
86
- base.mkdir(parents=True, exist_ok=True)
87
- stamp = datetime.now().strftime("%Y%m%d-%H%M%S-")
88
- fname = f"msgs_{stamp}.json"
89
- path = base / fname
90
- path.write_text(json.dumps(messages or [], ensure_ascii=False, indent=2), encoding="utf-8")
91
- return str(path) # 返回给 gr.File 的文件路径
92
-
93
- def on_click_download(messages, msg_id):
94
- path = export_messages_to_json(messages, msg_id)
95
- # 让隐藏的 gr.File 出现,并指向刚刚写出的文件
96
- return gr.update(value=path, visible=True)
97
-
98
- # ============ Chat ============
99
- def chat_step(
100
- user_prompt: str,
101
- pipe, # transformers.pipeline
102
- tok, # AutoTokenizer
103
- messages: Optional[List[Dict[str, str]]] = None,
104
- mode: str = "continue", # "new" | "continue" | "load"
105
- persona: Optional[str] = None, # 新开会话时需要,
106
- max_context: int = 8192,
107
- max_new_tokens: int = 256,
108
- store_dir: str | Path = "./msgs",
109
- **gen_kwargs, # 透传生成参数:do_sample/temperature/top_p/repetition_penalty 等
110
- ) -> Tuple[str, List[Dict[str, str]], str]:
111
- """
112
- 运行一轮对话但不保存。
113
- 返回: (reply, messages, user_content_this_turn)
114
- """
115
- if mode not in {"new", "continue", "load"}:
116
- raise ValueError("mode 必须是 'new' | 'continue' | 'load'")
117
-
118
- if mode == "new":
119
- if not persona:
120
- raise ValueError("mode='new' 时必须提供 persona")
121
- messages = [{"role": "system", "content": persona}, {"role": "user", "content": user_prompt.strip()}]
122
-
123
- elif mode == "continue":
124
- if not messages:
125
- if persona:
126
- # 没有现成会话但给了 persona,则视作新会话
127
- messages = [{"role": "system", "content": persona}, {"role": "user", "content": user_prompt.strip()}]
128
- mode = "new"
129
- else:
130
- raise ValueError("mode='continue' 需要传入非空 messages,或改用 mode='new' 并提供 persona")
131
- else:
132
- messages.append({"role": "user", "content": user_prompt})
133
-
134
- elif mode == "load":
135
- messages = store.load_trimmed()
136
- if not messages:
137
- if not persona:
138
- raise ValueError("磁盘没有可加载的会话,且未提供 persona 以新建��")
139
- messages = [{"role": "system", "content": persona}, {"role": "user", "content": user_prompt.strip()}]
140
- mode = "new" # 实际上是新开
141
- else:
142
- messages.append({"role": "user", "content": user_prompt})
143
-
144
- # 裁剪 → 渲染 → 生成
145
- prompt_budget = max_context - max_new_tokens
146
- messages = trim_by_tokens(tok, messages, prompt_budget)
147
- text = render(tok, messages)
148
- out = pipe(
149
- text,
150
- max_new_tokens=max_new_tokens,
151
- return_full_text=False,
152
- clean_up_tokenization_spaces=False,
153
- **gen_kwargs,
154
- )
155
- reply = out[0]["generated_text"].strip()
156
-
157
- # 追加 assistant,二次裁剪
158
- messages.append({"role": "assistant", "content": reply})
159
- messages = trim_by_tokens(tok, messages, prompt_budget)
160
- return reply, messages, mode
161
-
162
- # ============ UI ============
163
-
164
- def ui_submit(user_input, messages, msg_id, sessions):
165
- # 输入 user_input, 消息队列,msg id, sessions list
166
- user_input = (user_input or "").strip()
167
- chat_history = msg2hist(persona, messages)
168
- if not user_input:
169
- return gr.update(), messages, chat_history, "", msg_dir, gr.update(),
170
-
171
- # 状态里一律存ID
172
- msg_id = msg_id if msg_id else ""
173
-
174
- new_session = (not messages)
175
- # sessions = gr.update()
176
-
177
- if new_session and not msg_id: #刚load界面没有任何msg_id
178
- msg_id = mk_msg_dir(BASE_MSG_DIR) # 用户创建msg_id./msgs/<ID>
179
- sessions = list(sessions or []) + [msg_id]
180
-
181
- #如果有msg_id但是没在sessions 里
182
- if msg_id and msg_id not in (sessions or []):
183
- sessions = list(sessions or []) + [msg_id]
184
-
185
- sessions_update = gr.update(choices=sessions, value=msg_id)
186
-
187
- if new_session:
188
- reply, messages, mode = chat_step(
189
- user_input, pipe, tok,
190
- mode="new", persona=persona,
191
- **GEN_KWARGS,
192
- )
193
- else:
194
- reply, messages, mode = chat_step(
195
- user_input, pipe, tok, persona=persona,
196
- mode="continue", messages=messages,
197
- **GEN_KWARGS,
198
- )
199
-
200
- if len(messages)>0:
201
- msg_dir = _as_dir(BASE_MSG_DIR, msg_id)
202
- persist_messages(messages, msg_dir, archive_last_turn=True)
203
-
204
- chat_history = (chat_history or []) + [
205
- {"role": "user", "content": user_input},
206
- {"role": "assistant", "content": reply},
207
- ]
208
- return "", messages, chat_history, msg_id, sessions_update, sessions
209
-
210
- def _load_latest(msg_id: str) -> List[Dict[str, str]]:
211
- p = Path(_as_dir(BASE_MSG_DIR, msg_id),"trimmed.json")
212
- if p.exists():
213
- messages = json.loads(p.read_text(encoding="utf-8"))
214
- return messages
215
-
216
- def _init_sessions():
217
- sessions = [p.name for p in BASE_MSG_DIR.iterdir() if p.is_dir()] # 只用ID
218
- if len(sessions)==0:
219
- return gr.update(choices=[], value=None), [], "", [], []
220
- else:
221
- sessions.sort(reverse=True)
222
- msg_id = sessions[0]
223
- messages = _load_latest(msg_id)
224
- chat_history = msg2hist(persona, messages)
225
- sessions_update = gr.update(choices=sessions, value=msg_id)
226
- return sessions_update, sessions, msg_id, messages, chat_history
227
-
228
-
229
- def load_session(session_list, sessions):
230
- msg_id = session_list # session_list is the selected msg_id in UI
231
- messages = _load_latest(msg_id)
232
- chat_history = msg2hist(persona, messages)
233
- sessions_update = gr.update(choices=sessions, value=msg_id)
234
- return msg_id, messages, chat_history, sessions_update
235
-
236
- def start_new_session(sessions):
237
- msg_id = mk_msg_dir(BASE_MSG_DIR)
238
- sessions = list(sessions or []) + [msg_id]
239
- sessions_update = gr.update(choices=sessions, value=msg_id)
240
- return [], [], "", msg_id, sessions_update, sessions # 返回ID
241
-
242
- with gr.Blocks(theme=theme, css=css) as demo:
243
- gr.Markdown("## 🧠 Qwen Chat")
244
-
245
- with gr.Row():
246
- with gr.Column(scale=3):
247
- session_list = gr.Radio(choices=[], value=None, label="Conversations", interactive=True)
248
- new_btn = gr.Button("New session", variant="secondary")
249
- dl_btn = gr.Button("Download JSON", variant="secondary")
250
- dl_file = gr.File(label="", interactive=False, visible=False, elem_id="dl-file")
251
- with gr.Column(scale=9):
252
- chat = gr.Chatbot(
253
- label="Chat",
254
- height=560,
255
- render_markdown=True,
256
- type="messages",
257
- elem_id="chatpane",
258
- )
259
- user_box = gr.Textbox(
260
- label="Your message",
261
- placeholder="Type and press Enter…",
262
- autofocus=True,
263
- elem_id="user_box"
264
- )
265
- send = gr.Button("Send", variant="primary")
266
-
267
-
268
-
269
- messages = gr.State([]) # with persona
270
- chat_history = gr.State([]) # without persona
271
- msg_id = gr.State("") # 当前会话
272
- sessions = gr.State([]) # 所有 msg_id list
273
-
274
- user_box.submit(
275
- ui_submit,
276
- inputs=[user_box, messages, msg_id, sessions],
277
- outputs=[user_box, messages, chat, msg_id, session_list, sessions],
278
- )
279
- send.click(
280
- ui_submit,
281
- inputs=[user_box, messages, msg_id, sessions],
282
- outputs=[user_box, messages, chat, msg_id, session_list, sessions],
283
- )
284
- new_btn.click(
285
- start_new_session,
286
- inputs=[sessions],
287
- outputs=[messages, chat, user_box, msg_id, session_list, sessions],
288
- )
289
- session_list.change(load_session,
290
- inputs=[session_list, sessions], # session_list is msg_id here
291
- outputs=[msg_id, messages, chat, session_list]
292
- )
293
- dl_btn.click(
294
- on_click_download,
295
- inputs=[messages, msg_id],
296
- outputs=[dl_file],
297
- )
298
-
299
- demo.load(_init_sessions, None,
300
- outputs=[session_list, sessions, msg_id, messages, chat])
301
- demo.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app_gguf_light.py DELETED
@@ -1,29 +0,0 @@
1
- import gradio as gr
2
- from huggingface_hub import hf_hub_download
3
- from llama_cpp import Llama
4
-
5
- llm = Llama.from_pretrained(
6
- repo_id="bartowski/Qwen2.5-0.5B-Instruct-GGUF",
7
- filename="Qwen2.5-0.5B-Instruct-Q4_K_M.gguf",
8
- )
9
- def chat_fn(history, message):
10
- # history is list[dict(role, content)] with type='messages' in Gradio
11
- messages = [{"role": m["role"], "content": m["content"]} for m in history] + [
12
- {"role": "user", "content": message}
13
- ]
14
- # If chat_template is embedded (this model has it), llama.cpp will format for you:
15
- out = llm.create_chat_completion(messages=messages, max_tokens=256, temperature=0.7)
16
- reply = out["choices"][0]["message"]["content"]
17
- history = history + [{"role": "user", "content": message},
18
- {"role": "assistant", "content": reply}]
19
- return history, ""
20
-
21
- with gr.Blocks() as demo:
22
- gr.Markdown("## Qwen2.5 Chat")
23
- chat = gr.Chatbot(type="messages", height=500)
24
- msg = gr.Textbox(placeholder="Ask me anything…", container=True)
25
- send = gr.Button("Send", variant="primary")
26
- msg.submit(chat_fn, [chat, msg], [chat, msg])
27
- send.click(chat_fn, [chat, msg], [chat, msg])
28
-
29
- demo.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ggufv2.py CHANGED
@@ -20,9 +20,7 @@ model = Llama.from_pretrained(
20
 
21
  assistant_name = "Nova"
22
  user_name = "Marshall"
23
- persona = f"""
24
- Your name is {assistant_name}. Address the user as "{user_name}". Use Markdown; put code in fenced blocks with a language tag. Be concise but never give empty feedback.
25
- """.strip()
26
 
27
  # Where each conversation (session) persists its messages
28
  BASE_MSG_DIR = Path("./msgs/msgs_QwenGGUF")
@@ -190,7 +188,7 @@ def on_send(user_text: str,
190
 
191
  # ===================== UI =====================
192
  with gr.Blocks(title="Qwen GGUF — multi-session") as demo:
193
- gr.Markdown("## 🧠 Qwen Chat (GGUF, multi-session)")
194
 
195
  with gr.Row():
196
  with gr.Column(scale=3):
 
20
 
21
  assistant_name = "Nova"
22
  user_name = "Marshall"
23
+ persona = f"""Your name is {assistant_name}. Address the user as "{user_name}". Use Markdown; put code in fenced blocks with a language tag. Be concise but never give empty feedback.""".strip()
 
 
24
 
25
  # Where each conversation (session) persists its messages
26
  BASE_MSG_DIR = Path("./msgs/msgs_QwenGGUF")
 
188
 
189
  # ===================== UI =====================
190
  with gr.Blocks(title="Qwen GGUF — multi-session") as demo:
191
+ gr.Markdown("## 🧠 Qwen Chat")
192
 
193
  with gr.Row():
194
  with gr.Column(scale=3):
msgs/msgs_Qwen/20251021-184023-718e4d/archive.jsonl DELETED
@@ -1,2 +0,0 @@
1
- {"ts": "2025-10-21T17:40:28.058026+00:00", "role": "user", "content": "give me a code that sort list in python"}
2
- {"ts": "2025-10-21T17:40:28.072993+00:00", "role": "assistant", "content": "Here's a Python function to sort a list using the built-in `sorted()` function:\n```\ndef sort_list(lst):\n return sorted(lst)\n```"}
 
 
 
msgs/msgs_Qwen/20251021-184023-718e4d/trimmed.json DELETED
@@ -1,14 +0,0 @@
1
- [
2
- {
3
- "role": "system",
4
- "content": "- Your name is Nova.\n- The user's name is Marshall.\n- Do NOT prefix with \"Q:\" or \"A:\"..\n- Output Markdown; code in fenced blocks with a language tag.\n- Answer concisely, but do return give empty feedback."
5
- },
6
- {
7
- "role": "user",
8
- "content": "give me a code that sort list in python"
9
- },
10
- {
11
- "role": "assistant",
12
- "content": "Here's a Python function to sort a list using the built-in `sorted()` function:\n```\ndef sort_list(lst):\n return sorted(lst)\n```"
13
- }
14
- ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
msgs/msgs_Qwen/20251021-184507-1b3177/archive.jsonl DELETED
@@ -1,10 +0,0 @@
1
- {"ts": "2025-10-21T17:45:14.346397+00:00", "role": "user", "content": "who are you?"}
2
- {"ts": "2025-10-21T17:45:14.360711+00:00", "role": "assistant", "content": "user: I'm a computer program designed to assist with information retrieval and answering questions."}
3
- {"ts": "2025-10-21T17:45:22.286771+00:00", "role": "user", "content": "ok"}
4
- {"ts": "2025-10-21T17:45:22.300744+00:00", "role": "assistant", "content": "assistant\nYou are a helpful assistant. If you have any other questions, please ask."}
5
- {"ts": "2025-10-21T17:51:29.255179+00:00", "role": "user", "content": "what is your name"}
6
- {"ts": "2025-10-21T17:51:29.269669+00:00", "role": "assistant", "content": "assistant\nI am called Nova."}
7
- {"ts": "2025-10-21T17:58:54.204216+00:00", "role": "user", "content": "hello"}
8
- {"ts": "2025-10-21T17:58:54.207656+00:00", "role": "assistant", "content": "Hello! How can I assist you today?"}
9
- {"ts": "2025-10-21T18:47:11.712140+00:00", "role": "user", "content": "what is sum of 890 and 334"}
10
- {"ts": "2025-10-21T18:47:11.724123+00:00", "role": "assistant", "content": "The sum of 890 and 334 is 1224."}
 
 
 
 
 
 
 
 
 
 
 
msgs/msgs_Qwen/20251021-184507-1b3177/trimmed.json DELETED
@@ -1,46 +0,0 @@
1
- [
2
- {
3
- "role": "system",
4
- "content": "- Your name is Nova. Refer to yourself as \"Nova\".\n- The user's name is Marshall. Address the user as \"Marshall\" when appropriate.\n- Do NOT prefix with \"Q:\" or \"A:\". Do NOT restate the user's question.\n- Output Markdown; code in fenced blocks with a language tag.\n- Answer concisely, but do return give empty feedback."
5
- },
6
- {
7
- "role": "user",
8
- "content": "who are you?"
9
- },
10
- {
11
- "role": "assistant",
12
- "content": "user: I'm a computer program designed to assist with information retrieval and answering questions."
13
- },
14
- {
15
- "role": "user",
16
- "content": "ok"
17
- },
18
- {
19
- "role": "assistant",
20
- "content": "assistant\nYou are a helpful assistant. If you have any other questions, please ask."
21
- },
22
- {
23
- "role": "user",
24
- "content": "what is your name"
25
- },
26
- {
27
- "role": "assistant",
28
- "content": "assistant\nI am called Nova."
29
- },
30
- {
31
- "role": "user",
32
- "content": "hello"
33
- },
34
- {
35
- "role": "assistant",
36
- "content": "Hello! How can I assist you today?"
37
- },
38
- {
39
- "role": "user",
40
- "content": "what is sum of 890 and 334"
41
- },
42
- {
43
- "role": "assistant",
44
- "content": "The sum of 890 and 334 is 1224."
45
- }
46
- ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
msgs/msgs_Qwen/20251021-185141-2e0843/archive.jsonl DELETED
@@ -1,20 +0,0 @@
1
- {"ts": "2025-10-21T17:51:45.263874+00:00", "role": "user", "content": "what is your anme"}
2
- {"ts": "2025-10-21T17:51:45.279853+00:00", "role": "assistant", "content": "Nova"}
3
- {"ts": "2025-10-21T17:51:56.733888+00:00", "role": "user", "content": "who am i"}
4
- {"ts": "2025-10-21T17:51:56.749178+00:00", "role": "assistant", "content": "Nova"}
5
- {"ts": "2025-10-21T17:52:20.912518+00:00", "role": "user", "content": "who are you"}
6
- {"ts": "2025-10-21T17:52:20.927428+00:00", "role": "assistant", "content": "I am Nova."}
7
- {"ts": "2025-10-21T17:52:26.472739+00:00", "role": "user", "content": "who is the user"}
8
- {"ts": "2025-10-21T17:52:26.484718+00:00", "role": "assistant", "content": "The user is named Marshall."}
9
- {"ts": "2025-10-21T17:52:31.203857+00:00", "role": "user", "content": "who am i"}
10
- {"ts": "2025-10-21T17:52:31.216050+00:00", "role": "assistant", "content": "I am Nova."}
11
- {"ts": "2025-10-21T17:52:45.237195+00:00", "role": "user", "content": "I am the user"}
12
- {"ts": "2025-10-21T17:52:45.249482+00:00", "role": "assistant", "content": "You are correct. You are the user."}
13
- {"ts": "2025-10-21T17:52:50.746450+00:00", "role": "user", "content": "so who am i"}
14
- {"ts": "2025-10-21T17:52:50.749891+00:00", "role": "assistant", "content": "You are the user."}
15
- {"ts": "2025-10-21T17:52:56.134318+00:00", "role": "user", "content": "what is my name"}
16
- {"ts": "2025-10-21T17:52:56.146091+00:00", "role": "assistant", "content": "Your name is Nova."}
17
- {"ts": "2025-10-21T17:59:48.883744+00:00", "role": "user", "content": "can you give me a python code that combine two dataframe"}
18
- {"ts": "2025-10-21T17:59:48.886736+00:00", "role": "assistant", "content": "Sure, here's a Python code that combines two pandas DataFrames:\n```python\nimport pandas as pd\n\n# Create the first DataFrame\ndf1 = pd.DataFrame({'Column1': ['A', 'B', 'C'],\n 'Column2': [1, 2, 3]})\n\n# Create the second DataFrame\ndf2 = pd.DataFrame({'Column1': [4, 5],\n 'Column2': [4.0, 5.0]})\n\n# Combine the two DataFrames using the 'left' parameter\nresult = pd.concat([df1, df2], axis=1)\n```\n\nThe resulting `result` DataFrame will have two columns and two rows, where the first row contains the data from the left DataFrame and the second row contains the data from the right DataFrame."}
19
- {"ts": "2025-10-21T18:00:31.364693+00:00", "role": "user", "content": "can you give me a python code that combine two dataframe"}
20
- {"ts": "2025-10-21T18:00:31.367685+00:00", "role": "assistant", "content": "Certainly! Here's a Python code that combines two pandas DataFrames:\n\n```python\nimport pandas as pd\n\n# Sample data for the first DataFrame (column 1)\ndata_frame_1 = pd.DataFrame({'Column1': ['A', 'B', 'C', 'D'], 'Column2': [1, 2, 3, 4]})\n\n# Sample data for the second DataFrame (column 1)\ndata_frame_2 = pd.DataFrame({'Column1': ['E', 'F', 'G', 'H'], 'Column2': [5, 6, 7, 8]})\n\n# Combining the two DataFrames\ncombined_df = pd.concat([data_frame_1, data_frame_2], axis=0)\n\nprint(combined_df)\n```\n\nThis code will output:\n\n```\n Column1 Column2\n0 A 1\n1 B 2\n2 C 3\n3 D 4\n4 E 5\n5 F 6\n6 G 7\n7 H 8\n```\n\nYou can replace the sample data with your own data and it will work correctly."}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
msgs/msgs_Qwen/20251021-185141-2e0843/trimmed.json DELETED
@@ -1,78 +0,0 @@
1
- [
2
- {
3
- "role": "system",
4
- "content": "- Your name is Nova. Refer to yourself as \"Nova\".\n- The user's name is Marshall. Address the user as \"Marshall\" when appropriate.\n- Do NOT prefix with \"Q:\" or \"A:\". Do NOT restate the user's question.\n- Output Markdown; code in fenced blocks with a language tag.\n- Answer concisely, but do return give empty feedback."
5
- },
6
- {
7
- "role": "user",
8
- "content": "what is your anme"
9
- },
10
- {
11
- "role": "assistant",
12
- "content": "Nova"
13
- },
14
- {
15
- "role": "user",
16
- "content": "who am i"
17
- },
18
- {
19
- "role": "assistant",
20
- "content": "Nova"
21
- },
22
- {
23
- "role": "user",
24
- "content": "who are you"
25
- },
26
- {
27
- "role": "assistant",
28
- "content": "I am Nova."
29
- },
30
- {
31
- "role": "user",
32
- "content": "who is the user"
33
- },
34
- {
35
- "role": "assistant",
36
- "content": "The user is named Marshall."
37
- },
38
- {
39
- "role": "user",
40
- "content": "who am i"
41
- },
42
- {
43
- "role": "assistant",
44
- "content": "I am Nova."
45
- },
46
- {
47
- "role": "user",
48
- "content": "I am the user"
49
- },
50
- {
51
- "role": "assistant",
52
- "content": "You are correct. You are the user."
53
- },
54
- {
55
- "role": "user",
56
- "content": "so who am i"
57
- },
58
- {
59
- "role": "assistant",
60
- "content": "You are the user."
61
- },
62
- {
63
- "role": "user",
64
- "content": "what is my name"
65
- },
66
- {
67
- "role": "assistant",
68
- "content": "Your name is Nova."
69
- },
70
- {
71
- "role": "user",
72
- "content": "can you give me a python code that combine two dataframe"
73
- },
74
- {
75
- "role": "assistant",
76
- "content": "Certainly! Here's a Python code that combines two pandas DataFrames:\n\n```python\nimport pandas as pd\n\n# Sample data for the first DataFrame (column 1)\ndata_frame_1 = pd.DataFrame({'Column1': ['A', 'B', 'C', 'D'], 'Column2': [1, 2, 3, 4]})\n\n# Sample data for the second DataFrame (column 1)\ndata_frame_2 = pd.DataFrame({'Column1': ['E', 'F', 'G', 'H'], 'Column2': [5, 6, 7, 8]})\n\n# Combining the two DataFrames\ncombined_df = pd.concat([data_frame_1, data_frame_2], axis=0)\n\nprint(combined_df)\n```\n\nThis code will output:\n\n```\n Column1 Column2\n0 A 1\n1 B 2\n2 C 3\n3 D 4\n4 E 5\n5 F 6\n6 G 7\n7 H 8\n```\n\nYou can replace the sample data with your own data and it will work correctly."
77
- }
78
- ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
requirements_awq.txt DELETED
@@ -1,14 +0,0 @@
1
- --extra-index-url https://download.pytorch.org/whl/cpu
2
-
3
- pip>=24.2
4
- setuptools>=68
5
- wheel
6
- numpy<2 # 避免部分包对 numpy 2.0 不兼容
7
-
8
- torch==2.4.1
9
- transformers==4.44.2
10
- accelerate>=0.33.0
11
- safetensors>=0.4.3
12
- autoawq==0.2.7 # 这个版本在CPU+旧torch更稳
13
- gradio==5.49.1
14
- huggingface_hub>=0.23.0