pystoff commited on
Commit
4e397a7
·
verified ·
1 Parent(s): 5e61dc8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +30 -69
app.py CHANGED
@@ -1,36 +1,18 @@
1
- # IMPORTANT: import spaces BEFORE torch
2
  import spaces
3
  import torch
4
-
5
- from fastapi import FastAPI
6
- from fastapi.middleware.cors import CORSMiddleware
7
  from transformers import AutoModelForCausalLM, AutoTokenizer
 
 
 
 
8
  import gradio as gr
9
 
10
  MODEL_NAME = "teknium/OpenHermes-2.5-Mistral-7B"
11
 
12
- # -----------------------------
13
- # Load tokenizer
14
- # -----------------------------
15
- tokenizer = AutoTokenizer.from_pretrained(
16
- MODEL_NAME,
17
- use_fast=True,
18
- )
19
-
20
- # -----------------------------
21
- # Load model on CPU at startup.
22
- # It will be moved to GPU inside the @spaces.GPU function.
23
- # -----------------------------
24
- model = AutoModelForCausalLM.from_pretrained(
25
- MODEL_NAME,
26
- dtype=torch.float16,
27
- device_map="cpu",
28
- )
29
  model.eval()
30
 
31
- # -----------------------------
32
- # Generation function (runs on ZeroGPU)
33
- # -----------------------------
34
  @spaces.GPU(duration=120)
35
  def generate_reply(prompt: str, max_tokens: int = 512, temperature: float = 0.7) -> str:
36
  model.to("cuda")
@@ -44,37 +26,17 @@ def generate_reply(prompt: str, max_tokens: int = 512, temperature: float = 0.7)
44
  temperature=temperature,
45
  pad_token_id=tokenizer.eos_token_id,
46
  )
47
- result = tokenizer.decode(output[0], skip_special_tokens=True)
48
  finally:
49
  model.to("cpu")
50
  torch.cuda.empty_cache()
51
- return result
52
 
53
- # -----------------------------
54
- # Minimal Gradio app (required for ZeroGPU)
55
- # -----------------------------
56
  with gr.Blocks() as demo:
57
- gr.Markdown(
58
- "## OpenHermes-2.5-Mistral-7B API\n"
59
- "This Space exposes an OpenAI-compatible endpoint at "
60
- "`POST /v1/chat/completions`."
61
- )
62
-
63
- # Reuse Gradio's underlying FastAPI app
64
- app = demo.app
65
-
66
- app.add_middleware(
67
- CORSMiddleware,
68
- allow_origins=["*"],
69
- allow_methods=["*"],
70
- allow_headers=["*"],
71
- )
72
 
73
- # -----------------------------
74
- # OpenAI-style endpoint
75
- # -----------------------------
76
- @app.post("/v1/chat/completions")
77
- async def chat_completions(payload: dict):
78
  messages = payload.get("messages", [])
79
  temperature = float(payload.get("temperature", 0.7))
80
  max_tokens = int(payload.get("max_tokens", 512))
@@ -88,26 +50,25 @@ async def chat_completions(payload: dict):
88
 
89
  reply = generate_reply(prompt, max_tokens=max_tokens, temperature=temperature)
90
 
91
- return {
92
  "id": "openhermes-2.5-mistral-7b-response",
93
  "object": "chat.completion",
94
- "choices": [
95
- {
96
- "index": 0,
97
- "message": {
98
- "role": "assistant",
99
- "content": reply,
100
- },
101
- "finish_reason": "stop",
102
- }
103
- ],
104
- }
 
 
 
 
 
 
105
 
106
- # -----------------------------
107
- # Launch at module top level (NOT inside __main__)
108
- # -----------------------------
109
- if __name__ == "__main__":
110
- demo.launch(server_name="0.0.0.0", server_port=7860, ssr_mode=False)
111
- else:
112
- # Hugging Face Spaces imports the module, so launch must also run here.
113
- demo.launch(server_name="0.0.0.0", server_port=7860, ssr_mode=False)
 
 
1
  import spaces
2
  import torch
 
 
 
3
  from transformers import AutoModelForCausalLM, AutoTokenizer
4
+ from fastapi import FastAPI, Request
5
+ from fastapi.middleware.cors import CORSMiddleware
6
+ from fastapi.responses import JSONResponse
7
+ from starlette.routing import Route
8
  import gradio as gr
9
 
10
  MODEL_NAME = "teknium/OpenHermes-2.5-Mistral-7B"
11
 
12
+ tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, use_fast=True)
13
+ model = AutoModelForCausalLM.from_pretrained(MODEL_NAME, dtype=torch.float16, device_map="cpu")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  model.eval()
15
 
 
 
 
16
  @spaces.GPU(duration=120)
17
  def generate_reply(prompt: str, max_tokens: int = 512, temperature: float = 0.7) -> str:
18
  model.to("cuda")
 
26
  temperature=temperature,
27
  pad_token_id=tokenizer.eos_token_id,
28
  )
29
+ return tokenizer.decode(output[0], skip_special_tokens=True)
30
  finally:
31
  model.to("cpu")
32
  torch.cuda.empty_cache()
 
33
 
 
 
 
34
  with gr.Blocks() as demo:
35
+ gr.Markdown("API is running. POST to `/v1/chat/completions`.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
 
37
+ # --- Register the custom route FIRST ---
38
+ async def chat_completions(request: Request):
39
+ payload = await request.json()
 
 
40
  messages = payload.get("messages", [])
41
  temperature = float(payload.get("temperature", 0.7))
42
  max_tokens = int(payload.get("max_tokens", 512))
 
50
 
51
  reply = generate_reply(prompt, max_tokens=max_tokens, temperature=temperature)
52
 
53
+ return JSONResponse({
54
  "id": "openhermes-2.5-mistral-7b-response",
55
  "object": "chat.completion",
56
+ "choices": [{
57
+ "index": 0,
58
+ "message": {"role": "assistant", "content": reply},
59
+ "finish_reason": "stop",
60
+ }],
61
+ })
62
+
63
+ # Insert at position 0 so it runs before Gradio's catch-all
64
+ demo.app.router.routes.insert(0, Route("/v1/chat/completions", chat_completions, methods=["POST"]))
65
+
66
+ # --- CORS middleware ---
67
+ demo.app.add_middleware(
68
+ CORSMiddleware,
69
+ allow_origins=["*"],
70
+ allow_methods=["*"],
71
+ allow_headers=["*"],
72
+ )
73
 
74
+ demo.launch(server_name="0.0.0.0", server_port=7860, ssr_mode=False)