acsaco commited on
Commit
523047d
·
verified ·
1 Parent(s): 8073070

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +22 -36
app.py CHANGED
@@ -9,40 +9,50 @@ from fastapi import FastAPI
9
  from fastapi.responses import StreamingResponse
10
  from pydantic import BaseModel
11
  from typing import List, Optional, Dict
12
- from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer
13
  from threading import Thread
14
  import gradio as gr
15
 
 
 
 
 
16
  MODEL_ID = "Qwen/Qwen2.5-Coder-32B-Instruct-AWQ"
17
 
18
  # Cargar Tokenizer
19
  tokenizer = AutoTokenizer.from_pretrained(MODEL_ID, trust_remote_code=True)
20
 
21
- # Cargar Modelo en AWQ (18-20 GB VRAM)
 
 
 
 
 
 
 
 
22
  model = AutoModelForCausalLM.from_pretrained(
23
  MODEL_ID,
24
  dtype=torch.float16,
 
25
  device_map="auto",
26
  trust_remote_code=True
27
  )
28
 
29
- # Inicializar FastAPI
30
- app = FastAPI(title="Qwen2.5-Coder-32B OpenAI Compatible API")
31
 
32
- # --- Esquemas Pydantic ---
33
  class ChatMessage(BaseModel):
34
  role: str
35
  content: str
36
 
37
  class ChatCompletionRequest(BaseModel):
38
- model: Optional[str] = "Qwen/Qwen2.5-Coder-32B-Instruct-AWQ"
39
  messages: List[ChatMessage]
40
  temperature: Optional[float] = 0.2
41
  top_p: Optional[float] = 0.9
42
  max_tokens: Optional[int] = 2048
43
  stream: Optional[bool] = False
44
 
45
- # Función central de generación protegida por ZeroGPU
46
  @spaces.GPU(duration=120)
47
  def generate_stream_tokens(messages_dict: List[Dict[str, str]], temperature: float, top_p: float, max_tokens: int):
48
  text = tokenizer.apply_chat_template(
@@ -75,7 +85,6 @@ def generate_stream_tokens(messages_dict: List[Dict[str, str]], temperature: flo
75
  for new_token in streamer:
76
  yield new_token
77
 
78
- # --- Endpoints OpenAI (/v1) ---
79
  @app.get("/v1/models")
80
  async def list_models():
81
  return {
@@ -96,7 +105,6 @@ async def chat_completions(req: ChatCompletionRequest):
96
  created_time = int(time.time())
97
  messages_dict = [{"role": m.role, "content": m.content} for m in req.messages]
98
 
99
- # Manejo de streaming (SSE)
100
  if req.stream:
101
  async def event_generator():
102
  for token in generate_stream_tokens(
@@ -110,13 +118,7 @@ async def chat_completions(req: ChatCompletionRequest):
110
  "object": "chat.completion.chunk",
111
  "created": created_time,
112
  "model": req.model,
113
- "choices": [
114
- {
115
- "index": 0,
116
- "delta": {"content": token},
117
- "finish_reason": None
118
- }
119
- ]
120
  }
121
  yield f"data: {json.dumps(chunk)}\n\n"
122
 
@@ -125,20 +127,13 @@ async def chat_completions(req: ChatCompletionRequest):
125
  "object": "chat.completion.chunk",
126
  "created": created_time,
127
  "model": req.model,
128
- "choices": [
129
- {
130
- "index": 0,
131
- "delta": {},
132
- "finish_reason": "stop"
133
- }
134
- ]
135
  }
136
  yield f"data: {json.dumps(final_chunk)}\n\n"
137
  yield "data: [DONE]\n\n"
138
 
139
  return StreamingResponse(event_generator(), media_type="text/event-stream")
140
 
141
- # Respuesta estándar (sin streaming)
142
  full_content = ""
143
  for token in generate_stream_tokens(
144
  messages_dict,
@@ -156,21 +151,13 @@ async def chat_completions(req: ChatCompletionRequest):
156
  "choices": [
157
  {
158
  "index": 0,
159
- "message": {
160
- "role": "assistant",
161
- "content": full_content
162
- },
163
  "finish_reason": "stop"
164
  }
165
  ],
166
- "usage": {
167
- "prompt_tokens": -1,
168
- "completion_tokens": -1,
169
- "total_tokens": -1
170
- }
171
  }
172
 
173
- # --- Interfaz Gradio ---
174
  def gradio_generate(message, history, system_prompt, temperature, top_p, max_tokens):
175
  messages = []
176
  if system_prompt:
@@ -188,7 +175,7 @@ def gradio_generate(message, history, system_prompt, temperature, top_p, max_tok
188
 
189
  with gr.Blocks(title="Qwen2.5-Coder-32B API & UI", theme=gr.themes.Soft()) as gradio_app:
190
  gr.Markdown("# 🚀 Qwen2.5-Coder-32B-Instruct (AWQ en ZeroGPU)")
191
- gr.Markdown("Servicio con interfaz web y endpoints OpenAI (`/v1/chat/completions`).")
192
  gr.ChatInterface(
193
  fn=gradio_generate,
194
  additional_inputs=[
@@ -199,7 +186,6 @@ with gr.Blocks(title="Qwen2.5-Coder-32B API & UI", theme=gr.themes.Soft()) as gr
199
  ]
200
  )
201
 
202
- # Montar Gradio en la raíz
203
  app = gr.mount_gradio_app(app, gradio_app, path="/")
204
 
205
  if __name__ == "__main__":
 
9
  from fastapi.responses import StreamingResponse
10
  from pydantic import BaseModel
11
  from typing import List, Optional, Dict
12
+ from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer, AwqConfig
13
  from threading import Thread
14
  import gradio as gr
15
 
16
+ # Desactivar kernels Marlin incompatibles con el init en CPU de ZeroGPU
17
+ os.environ["GPTQMODEL_DISABLE_MARLIN"] = "1"
18
+ os.environ["AUTOAWQ_USE_MARLIN"] = "0"
19
+
20
  MODEL_ID = "Qwen/Qwen2.5-Coder-32B-Instruct-AWQ"
21
 
22
  # Cargar Tokenizer
23
  tokenizer = AutoTokenizer.from_pretrained(MODEL_ID, trust_remote_code=True)
24
 
25
+ # Forzar backend GEMM estándar de AWQ para evitar fallos de repacking en CPU
26
+ quant_config = AwqConfig(
27
+ bits=4,
28
+ version="gemm",
29
+ fuse_max_seq_len=4096,
30
+ do_fuse=False
31
+ )
32
+
33
+ # Cargar modelo en modo device_map="auto" compatible con ZeroGPU
34
  model = AutoModelForCausalLM.from_pretrained(
35
  MODEL_ID,
36
  dtype=torch.float16,
37
+ quantization_config=quant_config,
38
  device_map="auto",
39
  trust_remote_code=True
40
  )
41
 
42
+ app = FastAPI(title="Qwen2.5-Coder-32B OpenAI API")
 
43
 
 
44
  class ChatMessage(BaseModel):
45
  role: str
46
  content: str
47
 
48
  class ChatCompletionRequest(BaseModel):
49
+ model: Optional[str] = MODEL_ID
50
  messages: List[ChatMessage]
51
  temperature: Optional[float] = 0.2
52
  top_p: Optional[float] = 0.9
53
  max_tokens: Optional[int] = 2048
54
  stream: Optional[bool] = False
55
 
 
56
  @spaces.GPU(duration=120)
57
  def generate_stream_tokens(messages_dict: List[Dict[str, str]], temperature: float, top_p: float, max_tokens: int):
58
  text = tokenizer.apply_chat_template(
 
85
  for new_token in streamer:
86
  yield new_token
87
 
 
88
  @app.get("/v1/models")
89
  async def list_models():
90
  return {
 
105
  created_time = int(time.time())
106
  messages_dict = [{"role": m.role, "content": m.content} for m in req.messages]
107
 
 
108
  if req.stream:
109
  async def event_generator():
110
  for token in generate_stream_tokens(
 
118
  "object": "chat.completion.chunk",
119
  "created": created_time,
120
  "model": req.model,
121
+ "choices": [{"index": 0, "delta": {"content": token}, "finish_reason": None}]
 
 
 
 
 
 
122
  }
123
  yield f"data: {json.dumps(chunk)}\n\n"
124
 
 
127
  "object": "chat.completion.chunk",
128
  "created": created_time,
129
  "model": req.model,
130
+ "choices": [{"index": 0, "delta": {}, "finish_reason": "stop"}]
 
 
 
 
 
 
131
  }
132
  yield f"data: {json.dumps(final_chunk)}\n\n"
133
  yield "data: [DONE]\n\n"
134
 
135
  return StreamingResponse(event_generator(), media_type="text/event-stream")
136
 
 
137
  full_content = ""
138
  for token in generate_stream_tokens(
139
  messages_dict,
 
151
  "choices": [
152
  {
153
  "index": 0,
154
+ "message": {"role": "assistant", "content": full_content},
 
 
 
155
  "finish_reason": "stop"
156
  }
157
  ],
158
+ "usage": {"prompt_tokens": -1, "completion_tokens": -1, "total_tokens": -1}
 
 
 
 
159
  }
160
 
 
161
  def gradio_generate(message, history, system_prompt, temperature, top_p, max_tokens):
162
  messages = []
163
  if system_prompt:
 
175
 
176
  with gr.Blocks(title="Qwen2.5-Coder-32B API & UI", theme=gr.themes.Soft()) as gradio_app:
177
  gr.Markdown("# 🚀 Qwen2.5-Coder-32B-Instruct (AWQ en ZeroGPU)")
178
+ gr.Markdown("Endpoint OpenAI: `/v1/chat/completions` | Modelo: `Qwen/Qwen2.5-Coder-32B-Instruct-AWQ`")
179
  gr.ChatInterface(
180
  fn=gradio_generate,
181
  additional_inputs=[
 
186
  ]
187
  )
188
 
 
189
  app = gr.mount_gradio_app(app, gradio_app, path="/")
190
 
191
  if __name__ == "__main__":