MarshallCN commited on
Commit ·
d8371d9
1
Parent(s): 423a3f1
update ignore
Browse files- .gitignore +4 -1
- app_QwenGGUF.py +0 -279
- app_Qwen_awq.py +0 -301
- app_gguf_light.py +0 -29
- ggufv2.py +2 -4
- msgs/msgs_Qwen/20251021-184023-718e4d/archive.jsonl +0 -2
- msgs/msgs_Qwen/20251021-184023-718e4d/trimmed.json +0 -14
- msgs/msgs_Qwen/20251021-184507-1b3177/archive.jsonl +0 -10
- msgs/msgs_Qwen/20251021-184507-1b3177/trimmed.json +0 -46
- msgs/msgs_Qwen/20251021-185141-2e0843/archive.jsonl +0 -20
- msgs/msgs_Qwen/20251021-185141-2e0843/trimmed.json +0 -78
- requirements_awq.txt +0 -14
.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
|
| 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
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|