Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
| 1 |
import subprocess
|
| 2 |
import sys
|
| 3 |
import multiprocessing
|
|
|
|
| 4 |
|
| 5 |
# Install prebuilt CPU wheel at runtime
|
| 6 |
subprocess.run([
|
|
@@ -17,54 +18,57 @@ from huggingface_hub import hf_hub_download
|
|
| 17 |
# Calculate physical cores to prevent hyperthreading contention
|
| 18 |
physical_cores = max(1, multiprocessing.cpu_count() // 2)
|
| 19 |
|
| 20 |
-
# Safely fetch the NUMA distribution flag, fallback to boolean True
|
| 21 |
NUMA_STRATEGY = getattr(llama_cpp, "GGML_NUMA_STRATEGY_DISTRIBUTE", True)
|
| 22 |
|
| 23 |
-
# Download the highly compressed Q3_K_M GGUF model file
|
| 24 |
model_path = hf_hub_download(
|
| 25 |
"Jackrong/Qwopus3.5-9B-Coder-GGUF",
|
| 26 |
"Qwopus3.5-9B-coder-Exp-Q3_K_M.gguf",
|
| 27 |
)
|
| 28 |
|
| 29 |
-
# Load GGUF model with Q4 KV Cache and maximum CPU optimizations
|
| 30 |
llm = Llama(
|
| 31 |
model_path=model_path,
|
| 32 |
n_gpu_layers=0,
|
| 33 |
n_ctx=4096,
|
| 34 |
-
|
| 35 |
-
# Required for Qwen/Qwopus to prevent context cache corruption
|
| 36 |
chat_format="chatml",
|
| 37 |
-
|
| 38 |
-
# ⚡ 1. Hyperthreading Avoidance
|
| 39 |
n_threads=physical_cores,
|
| 40 |
n_threads_batch=physical_cores,
|
| 41 |
-
|
| 42 |
-
# ⚡ 2. NUMA Awareness
|
| 43 |
numa=NUMA_STRATEGY,
|
| 44 |
-
|
| 45 |
-
# ⚡ 3. Q4_0 KV Cache Quantization + Flash Attention
|
| 46 |
-
# Cuts memory usage significantly compared to default or Q8
|
| 47 |
flash_attn=True,
|
| 48 |
type_k=llama_cpp.GGML_TYPE_Q4_0,
|
| 49 |
type_v=llama_cpp.GGML_TYPE_Q4_0,
|
| 50 |
-
|
| 51 |
-
# ⚡ 4. CPU Cache Alignment
|
| 52 |
n_batch=512,
|
| 53 |
n_ubatch=512,
|
| 54 |
)
|
| 55 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 56 |
def respond(message, history, system_message, max_tokens, temperature, top_p):
|
| 57 |
messages = [{"role": "system", "content": system_message}]
|
| 58 |
|
| 59 |
-
# Dynamically handle history format
|
| 60 |
for item in history:
|
| 61 |
if isinstance(item, dict):
|
| 62 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 63 |
elif isinstance(item, (list, tuple)):
|
| 64 |
if item[0]:
|
| 65 |
messages.append({"role": "user", "content": item[0]})
|
| 66 |
if item[1]:
|
| 67 |
-
|
|
|
|
|
|
|
| 68 |
|
| 69 |
messages.append({"role": "user", "content": message})
|
| 70 |
|
|
@@ -81,7 +85,6 @@ def respond(message, history, system_message, max_tokens, temperature, top_p):
|
|
| 81 |
response += delta["content"]
|
| 82 |
yield response
|
| 83 |
|
| 84 |
-
# Gradio interface definition
|
| 85 |
chatbot = gr.ChatInterface(
|
| 86 |
fn=respond,
|
| 87 |
additional_inputs=[
|
|
@@ -90,7 +93,7 @@ chatbot = gr.ChatInterface(
|
|
| 90 |
gr.Slider(minimum=0.1, maximum=2.0, value=0.7, step=0.1, label="Temperature"),
|
| 91 |
gr.Slider(minimum=0.1, maximum=1.0, value=0.95, step=0.05, label="Top-p"),
|
| 92 |
],
|
| 93 |
-
title="Qwopus 3.5 Coder
|
| 94 |
)
|
| 95 |
|
| 96 |
if __name__ == "__main__":
|
|
|
|
| 1 |
import subprocess
|
| 2 |
import sys
|
| 3 |
import multiprocessing
|
| 4 |
+
import re # ⚡ ADDED: Regular expressions to clean chat history
|
| 5 |
|
| 6 |
# Install prebuilt CPU wheel at runtime
|
| 7 |
subprocess.run([
|
|
|
|
| 18 |
# Calculate physical cores to prevent hyperthreading contention
|
| 19 |
physical_cores = max(1, multiprocessing.cpu_count() // 2)
|
| 20 |
|
|
|
|
| 21 |
NUMA_STRATEGY = getattr(llama_cpp, "GGML_NUMA_STRATEGY_DISTRIBUTE", True)
|
| 22 |
|
|
|
|
| 23 |
model_path = hf_hub_download(
|
| 24 |
"Jackrong/Qwopus3.5-9B-Coder-GGUF",
|
| 25 |
"Qwopus3.5-9B-coder-Exp-Q3_K_M.gguf",
|
| 26 |
)
|
| 27 |
|
|
|
|
| 28 |
llm = Llama(
|
| 29 |
model_path=model_path,
|
| 30 |
n_gpu_layers=0,
|
| 31 |
n_ctx=4096,
|
|
|
|
|
|
|
| 32 |
chat_format="chatml",
|
|
|
|
|
|
|
| 33 |
n_threads=physical_cores,
|
| 34 |
n_threads_batch=physical_cores,
|
|
|
|
|
|
|
| 35 |
numa=NUMA_STRATEGY,
|
|
|
|
|
|
|
|
|
|
| 36 |
flash_attn=True,
|
| 37 |
type_k=llama_cpp.GGML_TYPE_Q4_0,
|
| 38 |
type_v=llama_cpp.GGML_TYPE_Q4_0,
|
|
|
|
|
|
|
| 39 |
n_batch=512,
|
| 40 |
n_ubatch=512,
|
| 41 |
)
|
| 42 |
|
| 43 |
+
# ⚡ ADDED: Function to strip reasoning blocks from past turns
|
| 44 |
+
def clean_thoughts(text):
|
| 45 |
+
if not text:
|
| 46 |
+
return text
|
| 47 |
+
# Removes everything between <think> and </think>, including the tags
|
| 48 |
+
cleaned = re.sub(r'<think>.*?</think>\n*', '', text, flags=re.DOTALL)
|
| 49 |
+
# Also clean up any stray orphan closing tags just in case
|
| 50 |
+
cleaned = cleaned.replace('</think>', '').strip()
|
| 51 |
+
return cleaned
|
| 52 |
+
|
| 53 |
def respond(message, history, system_message, max_tokens, temperature, top_p):
|
| 54 |
messages = [{"role": "system", "content": system_message}]
|
| 55 |
|
| 56 |
+
# Dynamically handle history format
|
| 57 |
for item in history:
|
| 58 |
if isinstance(item, dict):
|
| 59 |
+
content = item.get("content", "")
|
| 60 |
+
# ⚡ Strip thoughts if the message is from the assistant
|
| 61 |
+
if item.get("role") == "assistant":
|
| 62 |
+
content = clean_thoughts(content)
|
| 63 |
+
messages.append({"role": item.get("role"), "content": content})
|
| 64 |
+
|
| 65 |
elif isinstance(item, (list, tuple)):
|
| 66 |
if item[0]:
|
| 67 |
messages.append({"role": "user", "content": item[0]})
|
| 68 |
if item[1]:
|
| 69 |
+
# ⚡ Strip thoughts from the assistant's previous reply
|
| 70 |
+
cleaned_reply = clean_thoughts(item[1])
|
| 71 |
+
messages.append({"role": "assistant", "content": cleaned_reply})
|
| 72 |
|
| 73 |
messages.append({"role": "user", "content": message})
|
| 74 |
|
|
|
|
| 85 |
response += delta["content"]
|
| 86 |
yield response
|
| 87 |
|
|
|
|
| 88 |
chatbot = gr.ChatInterface(
|
| 89 |
fn=respond,
|
| 90 |
additional_inputs=[
|
|
|
|
| 93 |
gr.Slider(minimum=0.1, maximum=2.0, value=0.7, step=0.1, label="Temperature"),
|
| 94 |
gr.Slider(minimum=0.1, maximum=1.0, value=0.95, step=0.05, label="Top-p"),
|
| 95 |
],
|
| 96 |
+
title="Qwopus 3.5 Coder (Q3_K_M + Q4 KV Cache)",
|
| 97 |
)
|
| 98 |
|
| 99 |
if __name__ == "__main__":
|