Electro0023 commited on
Commit
e9e49b8
Β·
verified Β·
1 Parent(s): 300bbfa

Replace Gradio SmolVLM app with DeepSeek-7B-base GGUF OpenAI-compatible API (Docker)

Browse files
Files changed (1) hide show
  1. main.py +61 -5
main.py CHANGED
@@ -166,6 +166,44 @@ def _require_model() -> Llama:
166
  return _llm
167
 
168
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
  # ── Endpoints ─────────────────────────────────────────────────────────────────
170
  @app.get("/health")
171
  def health() -> Dict[str, Any]:
@@ -201,6 +239,15 @@ def chat_completions(req: ChatCompletionRequest) -> Dict[str, Any]:
201
  if not req.messages:
202
  raise HTTPException(status_code=400, detail="`messages` must not be empty.")
203
 
 
 
 
 
 
 
 
 
 
204
  kwargs: Dict[str, Any] = dict(
205
  messages=[m.model_dump() for m in req.messages],
206
  temperature=req.temperature,
@@ -232,11 +279,20 @@ def generate(req: GenerateRequest) -> Dict[str, Any]:
232
  t0 = time.time()
233
  try:
234
  with _llm_lock:
235
- result = llm.create_chat_completion(
236
- messages=[{"role": "user", "content": req.prompt}],
237
- temperature=req.temperature,
238
- max_tokens=req.max_tokens,
239
- )
 
 
 
 
 
 
 
 
 
240
  except Exception as exc:
241
  raise HTTPException(status_code=500, detail=f"generation failed: {exc}") from exc
242
 
 
166
  return _llm
167
 
168
 
169
+ def _messages_to_raw_prompt(messages: List["ChatMessage"]) -> str:
170
+ """Flatten chat messages into a plain-text prompt for BASE (non-chat) models.
171
+
172
+ A base model was never trained on a chat template β€” wrapping its input in
173
+ one (e.g. llama-2 [INST] tags) makes it emit only <s>/</s> tokens. Instead
174
+ we join the message contents into plain text and let the model continue it.
175
+ """
176
+ parts = [m.content.strip() for m in messages if m.content and m.content.strip()]
177
+ return "\n\n".join(parts)
178
+
179
+
180
+ def _raw_chat_completion(llm: Llama, req: "ChatCompletionRequest") -> Dict[str, Any]:
181
+ """Text-completion path used when CHAT_FORMAT is empty (base model)."""
182
+ prompt = _messages_to_raw_prompt(req.messages)
183
+ result = llm.create_completion(
184
+ prompt=prompt,
185
+ temperature=req.temperature,
186
+ top_p=req.top_p,
187
+ max_tokens=req.max_tokens if req.max_tokens is not None else DEFAULT_MAX_TOKENS,
188
+ stop=req.stop,
189
+ )
190
+ text = result["choices"][0]["text"]
191
+ # Re-shape the completion result into an OpenAI chat-completion response so
192
+ # clients (which always call /v1/chat/completions) need no changes.
193
+ return {
194
+ "id": f"chatcmpl-{uuid.uuid4().hex}",
195
+ "object": "chat.completion",
196
+ "created": int(time.time()),
197
+ "model": MODEL_ID,
198
+ "choices": [{
199
+ "index": 0,
200
+ "message": {"role": "assistant", "content": text},
201
+ "finish_reason": result["choices"][0].get("finish_reason", "stop"),
202
+ }],
203
+ "usage": result.get("usage", {}),
204
+ }
205
+
206
+
207
  # ── Endpoints ─────────────────────────────────────────────────────────────────
208
  @app.get("/health")
209
  def health() -> Dict[str, Any]:
 
239
  if not req.messages:
240
  raise HTTPException(status_code=400, detail="`messages` must not be empty.")
241
 
242
+ # Base model (no chat template): use raw text completion instead of a chat
243
+ # template the model was never trained on.
244
+ if not CHAT_FORMAT:
245
+ try:
246
+ with _llm_lock:
247
+ return _raw_chat_completion(llm, req)
248
+ except Exception as exc:
249
+ raise HTTPException(status_code=500, detail=f"generation failed: {exc}") from exc
250
+
251
  kwargs: Dict[str, Any] = dict(
252
  messages=[m.model_dump() for m in req.messages],
253
  temperature=req.temperature,
 
279
  t0 = time.time()
280
  try:
281
  with _llm_lock:
282
+ if not CHAT_FORMAT: # base model -> raw continuation of the prompt
283
+ raw = llm.create_completion(prompt=req.prompt,
284
+ temperature=req.temperature,
285
+ max_tokens=req.max_tokens)
286
+ result = {
287
+ "choices": [{"message": {"content": raw["choices"][0]["text"]}}],
288
+ "usage": raw.get("usage", {}),
289
+ }
290
+ else:
291
+ result = llm.create_chat_completion(
292
+ messages=[{"role": "user", "content": req.prompt}],
293
+ temperature=req.temperature,
294
+ max_tokens=req.max_tokens,
295
+ )
296
  except Exception as exc:
297
  raise HTTPException(status_code=500, detail=f"generation failed: {exc}") from exc
298