kirikir13 commited on
Commit
6371af8
·
verified ·
1 Parent(s): 4a9e55c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +23 -91
app.py CHANGED
@@ -1,25 +1,13 @@
1
- # =============================================================================
2
- # codeMax — Qwen 3.6 27B CoderBot on ZeroGPU (Gradio 6)
3
- # Model: DavidAU/Qwen3.6-27B-Heretic-Uncensored-FINETUNE-NEO-CODE-Di-IMatrix-MAX-GGUF
4
- # =============================================================================
5
-
6
- import spaces
7
  import gradio as gr
8
  import os
9
  import json
10
  from pathlib import Path
11
- from typing import List, Optional, Generator
12
 
13
- # --- Config ----------------------------------------------------------------
14
- MODEL_REPO = os.environ.get(
15
- "MODEL_REPO",
16
- "DavidAU/Qwen3.6-27B-Heretic-Uncensored-FINETUNE-NEO-CODE-Di-IMatrix-MAX-GGUF",
17
- )
18
- MODEL_FILE = os.environ.get(
19
- "MODEL_FILE",
20
- "Qwen3.6-27B-NEO-CODE-HERE-2T-OT-Q4_K_M.gguf",
21
- )
22
- N_CTX = int(os.environ.get("N_CTX", "8192"))
23
  N_GPU = int(os.environ.get("N_GPU_LAYERS", "-1"))
24
 
25
  SYSTEM_PROMPT = """You are codeMax, an uncensored 27B coding assistant. You excel at:
@@ -27,14 +15,11 @@ SYSTEM_PROMPT = """You are codeMax, an uncensored 27B coding assistant. You exce
27
  - Debugging, refactoring, reviewing complex codebases
28
  - Explaining algorithms, architecture, system design
29
  - Reading shared files and answering about them
30
-
31
  Rules: put code in ```language blocks. Be precise and thorough."""
32
 
33
- # --- Model singleton -------------------------------------------------------
34
  _llm = None
35
  _model_path: Optional[str] = None
36
 
37
-
38
  def _download():
39
  global _model_path
40
  if _model_path is not None:
@@ -45,14 +30,13 @@ def _download():
45
  print(f"[MODEL] Cached -> {_model_path}")
46
  return _model_path
47
 
48
-
49
  def _load():
50
  global _llm
51
  if _llm is not None:
52
  return _llm
53
  from llama_cpp import Llama
54
  path = _download()
55
- print(f"[MODEL] Loading (n_gpu_layers={N_GPU})...")
56
  _llm = Llama(
57
  model_path=path,
58
  n_ctx=N_CTX,
@@ -64,10 +48,10 @@ def _load():
64
  print("[MODEL] Ready.")
65
  return _llm
66
 
 
 
67
 
68
- # --- File readers ----------------------------------------------------------
69
  def _read_text(path, enc="utf-8"):
70
- """Safe text reader with encoding fallback."""
71
  for e in [enc, "utf-8-sig", "latin-1", "cp1252", "utf-16"]:
72
  try:
73
  with open(path, "r", encoding=e) as f:
@@ -77,13 +61,10 @@ def _read_text(path, enc="utf-8"):
77
  with open(path, "r", encoding="utf-8", errors="replace") as f:
78
  return f.read()
79
 
80
-
81
  def parse_file(file_path, file_name):
82
- """Parse a single uploaded file into context-ready markdown."""
83
  suffix = Path(file_name).suffix.lower()
84
  name = Path(file_name).name
85
 
86
- # ---- Code / text files ----
87
  if suffix in (
88
  ".txt", ".md", ".py", ".ts", ".tsx", ".js", ".jsx", ".mjs",
89
  ".css", ".scss", ".less", ".html", ".htm", ".xml", ".svg",
@@ -99,17 +80,12 @@ def parse_file(file_path, file_name):
99
  ):
100
  content = _read_text(file_path)
101
  lang = suffix.lstrip(".")
102
- if suffix == ".md":
103
- lang = "markdown"
104
- elif suffix in (".yml",):
105
- lang = "yaml"
106
- elif suffix in (".tf", ".tfvars"):
107
- lang = "hcl"
108
- elif suffix in (".htm",):
109
- lang = "html"
110
  return f"### `{name}`\n```{lang}\n{content}\n```\n\n---\n"
111
 
112
- # ---- JSON ----
113
  if suffix == ".json":
114
  content = _read_text(file_path)
115
  try:
@@ -119,10 +95,8 @@ def parse_file(file_path, file_name):
119
  pass
120
  return f"### `{name}`\n```json\n{content}\n```\n\n---\n"
121
 
122
- # ---- CSV ----
123
  if suffix == ".csv":
124
- import csv
125
- import io
126
  content = _read_text(file_path)
127
  rows = list(csv.reader(io.StringIO(content)))
128
  if len(rows) > 51:
@@ -137,7 +111,6 @@ def parse_file(file_path, file_name):
137
  table.insert(1, sep)
138
  return f"### `{name}`\n" + "\n".join(table) + "\n\n---\n"
139
 
140
- # ---- Word documents ----
141
  if suffix == ".docx":
142
  try:
143
  import docx
@@ -147,28 +120,22 @@ def parse_file(file_path, file_name):
147
  except Exception as e:
148
  return f"### `{name}` (DOCX error: {e})\n\n---\n"
149
 
150
- # ---- PDF ----
151
  if suffix == ".pdf":
152
  try:
153
  import pdfplumber
154
  with pdfplumber.open(file_path) as pdf:
155
- text = "\n\n".join(
156
- page.extract_text() or "" for page in pdf.pages
157
- )
158
  return f"### `{name}`\n{text}\n\n---\n"
159
  except Exception as e:
160
  return f"### `{name}` (PDF error: {e})\n\n---\n"
161
 
162
- # ---- Fallback ----
163
  try:
164
  content = _read_text(file_path)
165
  return f"### `{name}`\n```\n{content[:10000]}\n```\n\n---\n"
166
  except Exception as e:
167
  return f"### `{name}` (could not read: {e})\n\n---\n"
168
 
169
-
170
  def parse_all_files(files):
171
- """Parse all uploaded files into a single context string."""
172
  if not files:
173
  return ""
174
  parts = []
@@ -188,36 +155,22 @@ def parse_all_files(files):
188
  parts.append(f"### `{name}`\nParse error: {e}\n\n---\n")
189
  return "\n".join(parts)
190
 
191
-
192
- # --- Generation (wrapped with @spaces.GPU for ZeroGPU) ---------------------
193
- @spaces.GPU
194
  def respond(message, history, uploaded_files):
195
- """Generate a streaming response from the model."""
196
  file_context = parse_all_files(uploaded_files)
197
  messages = [{"role": "system", "content": SYSTEM_PROMPT}]
198
 
199
- # Inject uploaded files as context
200
  if file_context:
201
- messages.append({
202
- "role": "user",
203
- "content": "[Uploaded files — read carefully]\n\n" + file_context,
204
- })
205
- messages.append({
206
- "role": "assistant",
207
- "content": "Got it! I've read through all the uploaded files.",
208
- })
209
 
210
- # Append conversation history (Gradio 6 "messages" format)
211
  for entry in history:
212
  role = entry.get("role", "user")
213
  content = entry.get("content", "")
214
  if content:
215
  messages.append({"role": role, "content": content})
216
 
217
- # Append the current user message
218
  messages.append({"role": "user", "content": message})
219
 
220
- # Stream from the model
221
  llm = _load()
222
  stream = llm.create_chat_completion(
223
  messages=messages,
@@ -245,38 +198,26 @@ def respond(message, history, uploaded_files):
245
  {"role": "assistant", "content": partial},
246
  ]
247
 
248
-
249
- # --- Gradio UI ------------------------------------------------------------
250
  def create_demo():
251
  with gr.Blocks(title="codeMax — Qwen 3.6 27B Coder") as demo:
252
  gr.Markdown(
253
  "# codeMax\n"
254
- "**Qwen 3.6 27B · Uncensored · Code-optimized · ZeroGPU**\n"
255
  "Drop code, docs, JSON, CSVs — chat with a 27B coding LLM."
256
  )
257
 
258
  with gr.Row(equal_height=True):
259
- # ---- Left column: chat ----
260
  with gr.Column(scale=3):
261
  chatbot = gr.Chatbot(
262
  label="Chat",
263
  height=580,
264
- avatar_images=(
265
- None,
266
- "https://huggingface.co/front/assets/huggingface_logo-noborder.svg",
267
- ),
268
  )
269
  with gr.Row():
270
- msg = gr.Textbox(
271
- placeholder="Ask about code, share files, or chat...",
272
- scale=8,
273
- show_label=False,
274
- container=False,
275
- )
276
  send = gr.Button(">", scale=1, variant="primary", min_width=48)
277
  clear_btn = gr.Button("Clear", size="sm")
278
 
279
- # ---- Right column: file upload ----
280
  with gr.Column(scale=1):
281
  gr.Markdown("### Drop Files")
282
  files = gr.File(
@@ -292,7 +233,6 @@ def create_demo():
292
  )
293
  uploaded_info = gr.Markdown("_No files uploaded._")
294
 
295
- # ---- Event handlers ----
296
  def update_info(uploaded):
297
  if not uploaded:
298
  return "_No files uploaded._"
@@ -308,23 +248,15 @@ def create_demo():
308
  for h in respond(message, history, current_files):
309
  yield h
310
 
311
- msg.submit(stream_response, [msg, chatbot, files], [chatbot]).then(
312
- lambda: "", None, [msg]
313
- )
314
- send.click(stream_response, [msg, chatbot, files], [chatbot]).then(
315
- lambda: "", None, [msg]
316
- )
317
  clear_btn.click(lambda: [], None, chatbot, queue=False)
318
  files.change(update_info, files, uploaded_info)
319
 
320
  return demo
321
 
322
-
323
  if __name__ == "__main__":
324
  demo = create_demo()
325
  demo.queue(default_concurrency_limit=1, max_size=4)
326
- demo.launch(
327
- css="""
328
- footer { display: none !important; }
329
- """
330
- )
 
1
+ ```python
 
 
 
 
 
2
  import gradio as gr
3
  import os
4
  import json
5
  from pathlib import Path
6
+ from typing import Optional
7
 
8
+ MODEL_REPO = os.environ.get("MODEL_REPO", "DavidAU/Qwen3.6-27B-Heretic-Uncensored-FINETUNE-NEO-CODE-Di-IMatrix-MAX-GGUF")
9
+ MODEL_FILE = os.environ.get("MODEL_FILE", "Qwen3.6-27B-NEO-CODE-HERE-2T-OT-Q4_K_M.gguf")
10
+ N_CTX = int(os.environ.get("N_CTX", "4096"))
 
 
 
 
 
 
 
11
  N_GPU = int(os.environ.get("N_GPU_LAYERS", "-1"))
12
 
13
  SYSTEM_PROMPT = """You are codeMax, an uncensored 27B coding assistant. You excel at:
 
15
  - Debugging, refactoring, reviewing complex codebases
16
  - Explaining algorithms, architecture, system design
17
  - Reading shared files and answering about them
 
18
  Rules: put code in ```language blocks. Be precise and thorough."""
19
 
 
20
  _llm = None
21
  _model_path: Optional[str] = None
22
 
 
23
  def _download():
24
  global _model_path
25
  if _model_path is not None:
 
30
  print(f"[MODEL] Cached -> {_model_path}")
31
  return _model_path
32
 
 
33
  def _load():
34
  global _llm
35
  if _llm is not None:
36
  return _llm
37
  from llama_cpp import Llama
38
  path = _download()
39
+ print(f"[MODEL] Loading (n_gpu_layers={N_GPU}, n_ctx={N_CTX})...")
40
  _llm = Llama(
41
  model_path=path,
42
  n_ctx=N_CTX,
 
48
  print("[MODEL] Ready.")
49
  return _llm
50
 
51
+ print("[BOOT] Loading model at startup...")
52
+ _load()
53
 
 
54
  def _read_text(path, enc="utf-8"):
 
55
  for e in [enc, "utf-8-sig", "latin-1", "cp1252", "utf-16"]:
56
  try:
57
  with open(path, "r", encoding=e) as f:
 
61
  with open(path, "r", encoding="utf-8", errors="replace") as f:
62
  return f.read()
63
 
 
64
  def parse_file(file_path, file_name):
 
65
  suffix = Path(file_name).suffix.lower()
66
  name = Path(file_name).name
67
 
 
68
  if suffix in (
69
  ".txt", ".md", ".py", ".ts", ".tsx", ".js", ".jsx", ".mjs",
70
  ".css", ".scss", ".less", ".html", ".htm", ".xml", ".svg",
 
80
  ):
81
  content = _read_text(file_path)
82
  lang = suffix.lstrip(".")
83
+ if suffix == ".md": lang = "markdown"
84
+ elif suffix in (".yml",): lang = "yaml"
85
+ elif suffix in (".tf", ".tfvars"): lang = "hcl"
86
+ elif suffix in (".htm",): lang = "html"
 
 
 
 
87
  return f"### `{name}`\n```{lang}\n{content}\n```\n\n---\n"
88
 
 
89
  if suffix == ".json":
90
  content = _read_text(file_path)
91
  try:
 
95
  pass
96
  return f"### `{name}`\n```json\n{content}\n```\n\n---\n"
97
 
 
98
  if suffix == ".csv":
99
+ import csv, io
 
100
  content = _read_text(file_path)
101
  rows = list(csv.reader(io.StringIO(content)))
102
  if len(rows) > 51:
 
111
  table.insert(1, sep)
112
  return f"### `{name}`\n" + "\n".join(table) + "\n\n---\n"
113
 
 
114
  if suffix == ".docx":
115
  try:
116
  import docx
 
120
  except Exception as e:
121
  return f"### `{name}` (DOCX error: {e})\n\n---\n"
122
 
 
123
  if suffix == ".pdf":
124
  try:
125
  import pdfplumber
126
  with pdfplumber.open(file_path) as pdf:
127
+ text = "\n\n".join(page.extract_text() or "" for page in pdf.pages)
 
 
128
  return f"### `{name}`\n{text}\n\n---\n"
129
  except Exception as e:
130
  return f"### `{name}` (PDF error: {e})\n\n---\n"
131
 
 
132
  try:
133
  content = _read_text(file_path)
134
  return f"### `{name}`\n```\n{content[:10000]}\n```\n\n---\n"
135
  except Exception as e:
136
  return f"### `{name}` (could not read: {e})\n\n---\n"
137
 
 
138
  def parse_all_files(files):
 
139
  if not files:
140
  return ""
141
  parts = []
 
155
  parts.append(f"### `{name}`\nParse error: {e}\n\n---\n")
156
  return "\n".join(parts)
157
 
 
 
 
158
  def respond(message, history, uploaded_files):
 
159
  file_context = parse_all_files(uploaded_files)
160
  messages = [{"role": "system", "content": SYSTEM_PROMPT}]
161
 
 
162
  if file_context:
163
+ messages.append({"role": "user", "content": "[Uploaded files]\n\n" + file_context})
164
+ messages.append({"role": "assistant", "content": "Got it! I've read through all the uploaded files."})
 
 
 
 
 
 
165
 
 
166
  for entry in history:
167
  role = entry.get("role", "user")
168
  content = entry.get("content", "")
169
  if content:
170
  messages.append({"role": role, "content": content})
171
 
 
172
  messages.append({"role": "user", "content": message})
173
 
 
174
  llm = _load()
175
  stream = llm.create_chat_completion(
176
  messages=messages,
 
198
  {"role": "assistant", "content": partial},
199
  ]
200
 
 
 
201
  def create_demo():
202
  with gr.Blocks(title="codeMax — Qwen 3.6 27B Coder") as demo:
203
  gr.Markdown(
204
  "# codeMax\n"
205
+ "**Qwen 3.6 27B · Uncensored · Code-optimized · Dedicated GPU**\n"
206
  "Drop code, docs, JSON, CSVs — chat with a 27B coding LLM."
207
  )
208
 
209
  with gr.Row(equal_height=True):
 
210
  with gr.Column(scale=3):
211
  chatbot = gr.Chatbot(
212
  label="Chat",
213
  height=580,
214
+ avatar_images=(None, "https://huggingface.co/front/assets/huggingface_logo-noborder.svg"),
 
 
 
215
  )
216
  with gr.Row():
217
+ msg = gr.Textbox(placeholder="Ask about code, share files, or chat...", scale=8, show_label=False, container=False)
 
 
 
 
 
218
  send = gr.Button(">", scale=1, variant="primary", min_width=48)
219
  clear_btn = gr.Button("Clear", size="sm")
220
 
 
221
  with gr.Column(scale=1):
222
  gr.Markdown("### Drop Files")
223
  files = gr.File(
 
233
  )
234
  uploaded_info = gr.Markdown("_No files uploaded._")
235
 
 
236
  def update_info(uploaded):
237
  if not uploaded:
238
  return "_No files uploaded._"
 
248
  for h in respond(message, history, current_files):
249
  yield h
250
 
251
+ msg.submit(stream_response, [msg, chatbot, files], [chatbot]).then(lambda: "", None, [msg])
252
+ send.click(stream_response, [msg, chatbot, files], [chatbot]).then(lambda: "", None, [msg])
 
 
 
 
253
  clear_btn.click(lambda: [], None, chatbot, queue=False)
254
  files.change(update_info, files, uploaded_info)
255
 
256
  return demo
257
 
 
258
  if __name__ == "__main__":
259
  demo = create_demo()
260
  demo.queue(default_concurrency_limit=1, max_size=4)
261
+ demo.launch(css="""footer { display: none !important; }""")
262
+ ```