Spaces:
Sleeping
Sleeping
Fix: use demo.launch() for ZeroGPU, add ninja, @spaces.GPU on gradio fn
Browse files- app.py +62 -7
- requirements.txt +1 -0
app.py
CHANGED
|
@@ -467,18 +467,72 @@ def read_root():
|
|
| 467 |
"version": "3.1.0-zerogpu"
|
| 468 |
}
|
| 469 |
|
| 470 |
-
# ── Gradio UI ──
|
| 471 |
-
|
|
|
|
|
|
|
| 472 |
req = ChatCompletionRequest(
|
| 473 |
model=MODEL_ID,
|
| 474 |
messages=[ChatMessage(role="user", content=user_message)],
|
| 475 |
max_tokens=int(max_tokens), bandwidth=int(bandwidth)
|
| 476 |
)
|
| 477 |
-
|
| 478 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 479 |
|
| 480 |
demo = gr.Interface(
|
| 481 |
-
fn=
|
| 482 |
inputs=[
|
| 483 |
gr.Textbox(label="Message", value="Explain quantum computing in simple terms."),
|
| 484 |
gr.Slider(minimum=10, maximum=512, value=100, step=1, label="Max Tokens"),
|
|
@@ -495,6 +549,7 @@ app = gr.mount_gradio_app(app, demo, path="/ui")
|
|
| 495 |
def root_redirect():
|
| 496 |
return RedirectResponse(url="/docs")
|
| 497 |
|
|
|
|
| 498 |
if __name__ == "__main__":
|
| 499 |
-
|
| 500 |
-
|
|
|
|
| 467 |
"version": "3.1.0-zerogpu"
|
| 468 |
}
|
| 469 |
|
| 470 |
+
# ── Gradio UI (must use @spaces.GPU decorated function) ──
|
| 471 |
+
@spaces.GPU(duration=60)
|
| 472 |
+
def gradio_inference(user_message, max_tokens, bandwidth):
|
| 473 |
+
"""Gradio wrapper that triggers ZeroGPU."""
|
| 474 |
req = ChatCompletionRequest(
|
| 475 |
model=MODEL_ID,
|
| 476 |
messages=[ChatMessage(role="user", content=user_message)],
|
| 477 |
max_tokens=int(max_tokens), bandwidth=int(bandwidth)
|
| 478 |
)
|
| 479 |
+
# Inline the inference here so @spaces.GPU wraps it
|
| 480 |
+
t0 = time.perf_counter()
|
| 481 |
+
prompt = tokenizer.apply_chat_template(
|
| 482 |
+
[{"role": "user", "content": user_message}],
|
| 483 |
+
tokenize=False, add_generation_prompt=True
|
| 484 |
+
)
|
| 485 |
+
inputs = tokenizer(prompt, return_tensors="pt", add_special_tokens=False)
|
| 486 |
+
if inputs["input_ids"].shape[1] > 1000:
|
| 487 |
+
inputs["input_ids"] = inputs["input_ids"][:, -1000:]
|
| 488 |
+
if "attention_mask" in inputs:
|
| 489 |
+
inputs["attention_mask"] = inputs["attention_mask"][:, -1000:]
|
| 490 |
+
|
| 491 |
+
kalpana_cache = KalpanaHuggingFaceCache(config=model.config, bandwidth=int(bandwidth), device="cuda")
|
| 492 |
+
|
| 493 |
+
model.to("cuda")
|
| 494 |
+
input_ids = inputs["input_ids"].to("cuda")
|
| 495 |
+
attention_mask = inputs["attention_mask"].to("cuda")
|
| 496 |
+
|
| 497 |
+
eos_tokens = [tokenizer.eos_token_id]
|
| 498 |
+
|
| 499 |
+
with torch.no_grad():
|
| 500 |
+
output = model.generate(
|
| 501 |
+
input_ids=input_ids, attention_mask=attention_mask,
|
| 502 |
+
max_new_tokens=int(max_tokens), temperature=0.7, do_sample=True,
|
| 503 |
+
top_p=0.9, repetition_penalty=1.1,
|
| 504 |
+
past_key_values=kalpana_cache, use_cache=True,
|
| 505 |
+
pad_token_id=tokenizer.eos_token_id, eos_token_id=eos_tokens
|
| 506 |
+
)
|
| 507 |
+
|
| 508 |
+
generated_text = tokenizer.decode(output[0][input_ids.shape[1]:], skip_special_tokens=True)
|
| 509 |
+
t1 = time.perf_counter()
|
| 510 |
+
|
| 511 |
+
model.to("cpu")
|
| 512 |
+
torch.cuda.empty_cache()
|
| 513 |
+
|
| 514 |
+
prompt_tokens = int(input_ids.shape[1])
|
| 515 |
+
completion_tokens = len(tokenizer(generated_text).input_ids)
|
| 516 |
+
total_tokens = prompt_tokens + completion_tokens
|
| 517 |
+
|
| 518 |
+
openai_cost = (prompt_tokens / 1e6) * OPENAI_INPUT_PER_1M + (completion_tokens / 1e6) * OPENAI_OUTPUT_PER_1M
|
| 519 |
+
kalpana_cost = (total_tokens / 1e6) * KALPANA_SALE_PER_1M
|
| 520 |
+
savings_pct = round(((openai_cost - kalpana_cost) / openai_cost) * 100, 1) if openai_cost > 0 else 0.0
|
| 521 |
+
|
| 522 |
+
return {
|
| 523 |
+
"model": MODEL_ID,
|
| 524 |
+
"response": generated_text,
|
| 525 |
+
"generation_time_sec": round(t1 - t0, 3),
|
| 526 |
+
"usage": {"prompt_tokens": prompt_tokens, "completion_tokens": completion_tokens, "total_tokens": total_tokens},
|
| 527 |
+
"cost_comparison": {
|
| 528 |
+
"openai_gpt4o_cost": f"${openai_cost:.6f}",
|
| 529 |
+
"kalpana_cost": f"${kalpana_cost:.6f}",
|
| 530 |
+
"savings": f"{savings_pct}%"
|
| 531 |
+
}
|
| 532 |
+
}
|
| 533 |
|
| 534 |
demo = gr.Interface(
|
| 535 |
+
fn=gradio_inference,
|
| 536 |
inputs=[
|
| 537 |
gr.Textbox(label="Message", value="Explain quantum computing in simple terms."),
|
| 538 |
gr.Slider(minimum=10, maximum=512, value=100, step=1, label="Max Tokens"),
|
|
|
|
| 549 |
def root_redirect():
|
| 550 |
return RedirectResponse(url="/docs")
|
| 551 |
|
| 552 |
+
# ZeroGPU REQUIRES demo.launch() — not uvicorn.run()
|
| 553 |
if __name__ == "__main__":
|
| 554 |
+
demo.launch(server_name="0.0.0.0", server_port=7860)
|
| 555 |
+
|
requirements.txt
CHANGED
|
@@ -10,4 +10,5 @@ protobuf
|
|
| 10 |
pypdf
|
| 11 |
python-multipart
|
| 12 |
torch
|
|
|
|
| 13 |
huggingface_hub<0.25
|
|
|
|
| 10 |
pypdf
|
| 11 |
python-multipart
|
| 12 |
torch
|
| 13 |
+
ninja
|
| 14 |
huggingface_hub<0.25
|