OrbitMC commited on
Commit
7e2bbde
Β·
verified Β·
1 Parent(s): e8f7730

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +36 -158
app.py CHANGED
@@ -1,14 +1,7 @@
1
- import os
2
- import subprocess
3
- import time
4
- import requests
5
- import json
6
- import zipfile
7
- import tarfile
8
- import stat
9
  import gradio as gr
10
  import spaces
11
  from huggingface_hub import hf_hub_download
 
12
 
13
  # 1. DUMMY GPU FUNCTION: satisfies the Hugging Face startup checker
14
  @spaces.GPU(duration=5)
@@ -19,168 +12,53 @@ def dummy_gpu():
19
  # Automatically execute it once right away
20
  dummy_gpu()
21
 
22
- # 2. DOWNLOAD MODEL
23
- def setup_model():
24
- print("Downloading model...")
25
- repo = "Abiray/MiniCPM5-1B-GGUF"
26
- filename = "minicpm5-1b-Q6_K.gguf"
27
- model_path = hf_hub_download(repo_id=repo, filename=filename)
28
- print(f"Model downloaded to: {model_path}")
29
- return model_path
30
 
31
- # 3. DOWNLOAD PRE-BUILT LLAMA.CPP BINARY
32
- def get_prebuilt_llama():
33
- server_bin = "./llama-server"
34
- if os.path.exists(server_bin):
35
- print("Pre-built llama-server already exists.")
36
- return server_bin
37
-
38
- print("Fetching latest pre-built llama.cpp release...")
39
- api_url = "https://api.github.com/repos/ggml-org/llama.cpp/releases/latest"
40
-
41
- try:
42
- resp = requests.get(api_url).json()
43
- target_asset = None
44
- # Support both .zip and .tar.gz (Linux recently migrated to tar.gz)
45
- for asset in resp.get("assets", []):
46
- name = asset["name"].lower()
47
- if "ubuntu-x64" in name and (name.endswith(".zip") or name.endswith(".tar.gz")) and not any(x in name for x in ["vulkan", "rocm", "sycl", "openvino", "cuda"]):
48
- target_asset = asset
49
- break
50
-
51
- if not target_asset:
52
- raise ValueError("No matching CPU asset found in latest release.")
53
-
54
- download_url = target_asset["browser_download_url"]
55
- archive_name = target_asset["name"]
56
-
57
- except Exception as e:
58
- print(f"GitHub API check failed ({e}), using fallback direct URL...")
59
- # Updated to a highly recent July 2026 build that supports MiniCPM architecture natively
60
- download_url = "https://github.com/ggml-org/llama.cpp/releases/download/b9940/llama-b9940-bin-ubuntu-x64.tar.gz"
61
- archive_name = "llama-fallback.tar.gz"
62
-
63
- print(f"Downloading {archive_name} from {download_url}...")
64
- with requests.get(download_url, stream=True) as r:
65
- r.raise_for_status()
66
- with open(archive_name, "wb") as f:
67
- for chunk in r.iter_content(chunk_size=8192):
68
- f.write(chunk)
69
-
70
- print("Extracting archive...")
71
- if archive_name.endswith(".zip"):
72
- with zipfile.ZipFile(archive_name, 'r') as zip_ref:
73
- zip_ref.extractall("./llama_extracted")
74
- elif archive_name.endswith(".tar.gz"):
75
- with tarfile.open(archive_name, "r:gz") as tar_ref:
76
- tar_ref.extractall("./llama_extracted")
77
-
78
- # Locate the binary inside the extracted folder
79
- found_bin = None
80
- for root, dirs, files in os.walk("./llama_extracted"):
81
- if "llama-server" in files:
82
- found_bin = os.path.join(root, "llama-server")
83
- break
84
-
85
- if not found_bin:
86
- raise RuntimeError("llama-server binary not found in the extracted files!")
87
-
88
- # Move it to root and clean up
89
- os.rename(found_bin, server_bin)
90
-
91
- # Make it executable (chmod +x)
92
- st = os.stat(server_bin)
93
- os.chmod(server_bin, st.st_mode | stat.S_IEXEC)
94
-
95
- print("Pre-built llama-server is ready!")
96
- return server_bin
97
-
98
- # 4. START BACKGROUND SERVER
99
- def start_server(model_path, server_bin_path):
100
- cmd = [
101
- server_bin_path,
102
- "-m", model_path,
103
- "--host", "127.0.0.1",
104
- "--port", "8080",
105
- "-t", "2",
106
- "--cache-type-k", "q8_0",
107
- "--cache-type-v", "q8_0",
108
- "-c", "8192",
109
- "-n", "4096"
110
- ]
111
-
112
- print("Booting local llama-server with command:")
113
- print(" ".join(cmd))
114
-
115
- server_process = subprocess.Popen(cmd)
116
-
117
- print("Waiting for llama-server to initialize...")
118
- for _ in range(120):
119
- # Fail-fast check
120
- if server_process.poll() is not None:
121
- raise RuntimeError(f"llama-server crashed instantly with return code {server_process.returncode}! Check the C++ logs above for the reason.")
122
-
123
- try:
124
- response = requests.get("http://127.0.0.1:8080/health")
125
- if response.status_code == 200:
126
- print("llama-server is up and running!")
127
- return server_process
128
- except requests.exceptions.ConnectionError:
129
- time.sleep(2)
130
-
131
- raise RuntimeError("Server failed to start within the timeout period.")
132
 
133
- # Execute initialization
134
- model_filepath = setup_model()
135
- llama_executable = get_prebuilt_llama()
136
- start_server(model_filepath, llama_executable)
137
-
138
- # 5. GRADIO UI TO INTERACT WITH LOCAL SERVER
139
  def chat_with_llama(message, history):
 
140
  messages = [{"role": "system", "content": "You are a helpful AI assistant."}]
 
141
  for user_msg, assistant_msg in history:
142
  messages.append({"role": "user", "content": user_msg})
143
  messages.append({"role": "assistant", "content": assistant_msg})
144
-
145
  messages.append({"role": "user", "content": message})
146
 
147
- payload = {
148
- "messages": messages,
149
- "stream": True,
150
- "temperature": 0.7
151
- }
 
 
152
 
153
- try:
154
- response = requests.post(
155
- "http://127.0.0.1:8080/v1/chat/completions",
156
- json=payload,
157
- stream=True
158
- )
159
-
160
- partial_response = ""
161
- for line in response.iter_lines():
162
- if line:
163
- decoded_line = line.decode('utf-8')
164
- if decoded_line.startswith("data: "):
165
- data_str = decoded_line[6:]
166
- if data_str == "[DONE]":
167
- break
168
- try:
169
- data = json.loads(data_str)
170
- if "choices" in data and len(data["choices"]) > 0:
171
- delta = data["choices"][0].get("delta", {})
172
- if "content" in delta:
173
- partial_response += delta["content"]
174
- yield partial_response
175
- except json.JSONDecodeError:
176
- continue
177
- except Exception as e:
178
- yield f"Error communicating with local server: {str(e)}"
179
 
180
- # 6. LAUNCH GRADIO APP
181
  with gr.Blocks() as demo:
182
- gr.Markdown("# Native CPU Pre-Built `llama.cpp` on ZeroGPU Space")
183
- gr.Markdown(f"Running **MiniCPM5-1B-GGUF** natively using the pre-compiled Ubuntu `llama-server`! Bypassing compilation and GPU logic entirely.")
184
 
185
  gr.ChatInterface(
186
  fn=chat_with_llama,
 
 
 
 
 
 
 
 
 
1
  import gradio as gr
2
  import spaces
3
  from huggingface_hub import hf_hub_download
4
+ from llama_cpp import Llama
5
 
6
  # 1. DUMMY GPU FUNCTION: satisfies the Hugging Face startup checker
7
  @spaces.GPU(duration=5)
 
12
  # Automatically execute it once right away
13
  dummy_gpu()
14
 
15
+ # 2. LOAD MODEL DIRECTLY IN PYTHON
16
+ print("Downloading model...")
17
+ model_path = hf_hub_download(
18
+ repo_id="Abiray/MiniCPM5-1B-GGUF",
19
+ filename="minicpm5-1b-Q6_K.gguf"
20
+ )
 
 
21
 
22
+ print("Loading model into memory via llama-cpp-python...")
23
+ llm = Llama(
24
+ model_path=model_path,
25
+ n_ctx=8192, # Safe 8k context limit to avoid RAM crashes
26
+ n_threads=2, # Perfectly matches Hugging Face standard CPU cores
27
+ verbose=False # Keeps the terminal clean
28
+ )
29
+ print("Model loaded successfully!")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
 
31
+ # 3. CHAT FUNCTION
 
 
 
 
 
32
  def chat_with_llama(message, history):
33
+ # Format the conversation history
34
  messages = [{"role": "system", "content": "You are a helpful AI assistant."}]
35
+
36
  for user_msg, assistant_msg in history:
37
  messages.append({"role": "user", "content": user_msg})
38
  messages.append({"role": "assistant", "content": assistant_msg})
39
+
40
  messages.append({"role": "user", "content": message})
41
 
42
+ # Generate the response in a stream
43
+ stream = llm.create_chat_completion(
44
+ messages=messages,
45
+ stream=True,
46
+ temperature=0.7,
47
+ max_tokens=1024
48
+ )
49
 
50
+ partial_response = ""
51
+ for chunk in stream:
52
+ if "choices" in chunk and len(chunk["choices"]) > 0:
53
+ delta = chunk["choices"][0].get("delta", {})
54
+ if "content" in delta:
55
+ partial_response += delta["content"]
56
+ yield partial_response
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
 
58
+ # 4. LAUNCH GRADIO APP
59
  with gr.Blocks() as demo:
60
+ gr.Markdown("# Native CPU `llama-cpp-python` on ZeroGPU Space")
61
+ gr.Markdown("Running **MiniCPM5-1B-GGUF** natively using Python bindings! No background servers, no zip downloads, and no compiling.")
62
 
63
  gr.ChatInterface(
64
  fn=chat_with_llama,