Mohd-Shujath commited on
Commit
2d7b7d3
·
1 Parent(s): 56e59a7

Fix: use +cpu tagged manylinux wheel from AIencoder (no CUDA deps)

Browse files
Files changed (1) hide show
  1. app.py +65 -48
app.py CHANGED
@@ -2,49 +2,73 @@ import os
2
  import sys
3
  import subprocess
4
 
5
- # -------------------------------------------------------------
6
- # 1. Auto-bootstrap prebuilt manylinux llama-cpp-python
7
- # (Installs in 3 seconds, zero build timeout, zero musl error)
8
- # -------------------------------------------------------------
9
- try:
10
- from llama_cpp import Llama
11
- except ImportError:
12
- print("Bootstrapping pre-built manylinux llama-cpp-python from Hugging Face...")
13
  from huggingface_hub import HfApi, hf_hub_download
14
 
15
  api = HfApi()
16
  files = api.list_repo_files("AIencoder/llama-cpp-wheels", repo_type="dataset")
17
 
18
  py_tag = f"cp{sys.version_info.major}{sys.version_info.minor}"
19
- candidate = None
20
- for p in files:
21
- if p.endswith(".whl") and "linux/x86_64/cpu/" in p and (py_tag in p or "py3-none" in p):
22
- candidate = p
23
- break
24
- if not candidate:
25
- for p in files:
26
- if p.endswith(".whl") and "linux/x86_64" in p and "cpu" in p and (py_tag in p or "py3-none" in p):
27
- candidate = p
28
- break
29
-
30
- print(f"Installing precompiled wheel: {candidate}")
31
- whl_path = hf_hub_download("AIencoder/llama-cpp-wheels", candidate, repo_type="dataset")
32
- subprocess.check_call([sys.executable, "-m", "pip", "install", whl_path])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  from llama_cpp import Llama
34
- print("llama-cpp-python ready!")
35
 
36
  from typing import List, Literal, Optional
37
  from pydantic import BaseModel, Field
38
  from fastapi import FastAPI, HTTPException, Header
39
  import gradio as gr
40
 
41
- # -------------------------------------------------------------
42
- # 2. Configuration & Load Qwen GGUF Model
43
- # -------------------------------------------------------------
44
  MODEL_PATH = "Qwen3.5-0.8B.Q4_K_M.gguf"
45
  API_KEY = os.getenv("API_KEY", "commitcon-secret-2026")
46
 
47
- print(f"Loading {MODEL_PATH} via llama-cpp ...")
48
  llm = Llama(
49
  model_path=MODEL_PATH,
50
  n_ctx=4096,
@@ -53,9 +77,9 @@ llm = Llama(
53
  )
54
  print("Model loaded successfully!")
55
 
56
- # -------------------------------------------------------------
57
- # 3. FastAPI Service Endpoint
58
- # -------------------------------------------------------------
59
  app = FastAPI(title="CommitCon Sherpa AI Copilot")
60
 
61
  class HistoryMessage(BaseModel):
@@ -69,9 +93,10 @@ class ChatRequest(BaseModel):
69
  history: List[HistoryMessage] = Field(default_factory=list)
70
 
71
  SYSTEM_PROMPT = (
72
- "You are Sherpa, an AI driving assistant for the CommitCon ride-hailing repositioning platform in Bengaluru. "
73
- "Your job is to provide concise, direct, helpful recommendations to drivers about where to reposition for high demand, "
74
- "earnings, and low traffic delays. Keep your advice practical, realistic, and focused on maximizing their earnings."
 
75
  )
76
 
77
  def run_inference(prompt: str, history: List[dict] = None) -> str:
@@ -80,11 +105,8 @@ def run_inference(prompt: str, history: List[dict] = None) -> str:
80
  for m in history:
81
  messages.append({"role": m["role"], "content": m["content"]})
82
  messages.append({"role": "user", "content": prompt})
83
-
84
  response = llm.create_chat_completion(
85
- messages=messages,
86
- temperature=0.7,
87
- max_tokens=512,
88
  )
89
  return response["choices"][0]["message"]["content"]
90
 
@@ -96,20 +118,16 @@ def root():
96
  def chat_endpoint(payload: ChatRequest, x_api_key: Optional[str] = Header(None)):
97
  if API_KEY and x_api_key != API_KEY:
98
  raise HTTPException(status_code=401, detail="Unauthorized: Invalid API Key")
99
-
100
  formatted_history = [{"role": m.role, "content": m.content} for m in payload.history]
101
  answer = run_inference(payload.driver_prompt, formatted_history)
102
-
103
  return {
104
- "status": "success",
105
- "answer": answer,
106
- "model": "project-driver-qwen-gguf",
107
- "zone_context": payload.current_zone_id
108
  }
109
 
110
- # -------------------------------------------------------------
111
- # 4. Mount Gradio Playground for testing
112
- # -------------------------------------------------------------
113
  def gradio_chat(user_message, history):
114
  hist_formatted = []
115
  if history:
@@ -122,7 +140,6 @@ def gradio_chat(user_message, history):
122
  demo = gr.ChatInterface(
123
  fn=gradio_chat,
124
  title="🧭 CommitCon Sherpa Driver Copilot",
125
- description="Fine-tuned Qwen 0.8B Q4_K_M AI Driver Copilot for ride repositioning."
126
  )
127
-
128
  app = gr.mount_gradio_app(app, demo, path="/")
 
2
  import sys
3
  import subprocess
4
 
5
+ # =============================================================
6
+ # 1. Bootstrap: Install a KNOWN-GOOD prebuilt CPU-only wheel
7
+ # Versions >= 0.3.20 use "+cpu" tag = zero CUDA dependency
8
+ # =============================================================
9
+ def bootstrap_llama_cpp():
10
+ print("Bootstrapping llama-cpp-python (CPU-only, manylinux)...")
 
 
11
  from huggingface_hub import HfApi, hf_hub_download
12
 
13
  api = HfApi()
14
  files = api.list_repo_files("AIencoder/llama-cpp-wheels", repo_type="dataset")
15
 
16
  py_tag = f"cp{sys.version_info.major}{sys.version_info.minor}"
17
+
18
+ # Filter: linux/x86_64/cpu, version 0.3.x, "+cpu" in name, py3-none or matching cpXXX
19
+ candidates = [
20
+ p for p in files
21
+ if p.endswith(".whl")
22
+ and "linux/x86_64/cpu/" in p
23
+ and "/0.3." in p
24
+ and "+cpu" in p
25
+ and ("py3-none" in p or py_tag in p)
26
+ ]
27
+
28
+ if not candidates:
29
+ # Fallback: any 0.3.x cpu wheel matching our python
30
+ candidates = [
31
+ p for p in files
32
+ if p.endswith(".whl")
33
+ and "linux/x86_64/cpu/" in p
34
+ and "/0.3." in p
35
+ and ("py3-none" in p or py_tag in p)
36
+ and "cuda" not in p.lower()
37
+ ]
38
+
39
+ # Sort descending to pick latest version
40
+ candidates.sort(reverse=True)
41
+ if not candidates:
42
+ raise RuntimeError("No compatible CPU wheel found!")
43
+
44
+ chosen = candidates[0]
45
+ print(f"Selected wheel: {chosen}")
46
+ whl_path = hf_hub_download("AIencoder/llama-cpp-wheels", chosen, repo_type="dataset")
47
+ subprocess.check_call([
48
+ sys.executable, "-m", "pip", "install", "--force-reinstall", whl_path
49
+ ])
50
+ print("llama-cpp-python installed successfully!")
51
+
52
+ try:
53
+ from llama_cpp import Llama
54
+ # Verify it actually loads (catches CUDA linkage errors)
55
+ print("llama-cpp-python already available.")
56
+ except (ImportError, RuntimeError, OSError):
57
+ bootstrap_llama_cpp()
58
  from llama_cpp import Llama
 
59
 
60
  from typing import List, Literal, Optional
61
  from pydantic import BaseModel, Field
62
  from fastapi import FastAPI, HTTPException, Header
63
  import gradio as gr
64
 
65
+ # =============================================================
66
+ # 2. Load GGUF Model
67
+ # =============================================================
68
  MODEL_PATH = "Qwen3.5-0.8B.Q4_K_M.gguf"
69
  API_KEY = os.getenv("API_KEY", "commitcon-secret-2026")
70
 
71
+ print(f"Loading {MODEL_PATH} via llama-cpp-python ...")
72
  llm = Llama(
73
  model_path=MODEL_PATH,
74
  n_ctx=4096,
 
77
  )
78
  print("Model loaded successfully!")
79
 
80
+ # =============================================================
81
+ # 3. FastAPI Endpoints
82
+ # =============================================================
83
  app = FastAPI(title="CommitCon Sherpa AI Copilot")
84
 
85
  class HistoryMessage(BaseModel):
 
93
  history: List[HistoryMessage] = Field(default_factory=list)
94
 
95
  SYSTEM_PROMPT = (
96
+ "You are Sherpa, an AI driving assistant for the CommitCon ride-hailing "
97
+ "repositioning platform in Bengaluru. Provide concise, direct, helpful "
98
+ "recommendations to drivers about where to reposition for high demand, "
99
+ "earnings, and low traffic delays."
100
  )
101
 
102
  def run_inference(prompt: str, history: List[dict] = None) -> str:
 
105
  for m in history:
106
  messages.append({"role": m["role"], "content": m["content"]})
107
  messages.append({"role": "user", "content": prompt})
 
108
  response = llm.create_chat_completion(
109
+ messages=messages, temperature=0.7, max_tokens=512
 
 
110
  )
111
  return response["choices"][0]["message"]["content"]
112
 
 
118
  def chat_endpoint(payload: ChatRequest, x_api_key: Optional[str] = Header(None)):
119
  if API_KEY and x_api_key != API_KEY:
120
  raise HTTPException(status_code=401, detail="Unauthorized: Invalid API Key")
 
121
  formatted_history = [{"role": m.role, "content": m.content} for m in payload.history]
122
  answer = run_inference(payload.driver_prompt, formatted_history)
 
123
  return {
124
+ "status": "success", "answer": answer,
125
+ "model": "project-driver-qwen-gguf", "zone_context": payload.current_zone_id
 
 
126
  }
127
 
128
+ # =============================================================
129
+ # 4. Gradio Chat UI
130
+ # =============================================================
131
  def gradio_chat(user_message, history):
132
  hist_formatted = []
133
  if history:
 
140
  demo = gr.ChatInterface(
141
  fn=gradio_chat,
142
  title="🧭 CommitCon Sherpa Driver Copilot",
143
+ description="Fine-tuned Qwen 0.8B Q4_K_M — llama-cpp-python CPU inference"
144
  )
 
145
  app = gr.mount_gradio_app(app, demo, path="/")