Spaces:
Running on Zero
Running on Zero
File size: 2,630 Bytes
5e288ca 79b56f3 5d245cc 5e288ca e39cfc2 79b56f3 02730dd 79b56f3 a4327db 79b56f3 5e288ca 79b56f3 5e288ca a82ce96 5e288ca 4cde538 5e288ca bed9a72 5e288ca 4cde538 5e288ca 4cde538 02730dd 5e288ca 02730dd 5e288ca 4cde538 5e288ca 02730dd 79b56f3 4cde538 79b56f3 4cde538 02730dd 5e288ca 3d0c68f 5d245cc 3d0c68f 5d245cc 00d07aa 5d245cc 02730dd e39cfc2 5e288ca 79b56f3 5e288ca | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | import os
from threading import Thread
import spaces
import torch
from transformers import AutoProcessor, AutoModelForMultimodalLM, TextIteratorStreamer
from gradio import Server
from gradio.data_classes import FileData
from fastapi.responses import HTMLResponse
MODEL_ID = "meta-models/Muse-Glimmer-30B"
processor = AutoProcessor.from_pretrained(MODEL_ID)
model = AutoModelForMultimodalLM.from_pretrained(
MODEL_ID,
dtype=torch.bfloat16,
).to("cuda")
app = Server()
@app.api(name="chat")
@spaces.GPU(size="xlarge", duration=240)
def chat(message: str,
media: FileData | None,
history: list,
reasoning: str) -> str:
"""Streaming multimodal chat with Muse-Glimmer-30B.
history: list of {"role": "user"|"assistant", "content": str}
media: optional image or video FileData uploaded via the Gradio client
"""
messages = []
for m in history:
messages.append({"role": m["role"], "content": m["content"]})
content = []
if media:
path = media["path"]
if path.lower().rsplit(".", 1)[-1] in ("mp4", "mov", "webm", "mkv", "avi"):
content.append({"type": "video", "path": path})
else:
content.append({"type": "image", "path": path})
if message:
content.append({"type": "text", "text": message})
messages.append({"role": "user", "content": content})
template_kwargs = dict(
add_generation_prompt=True,
tokenize=True,
return_dict=True,
return_tensors="pt",
reasoning_strength=reasoning,
)
if any(c["type"] == "video" for c in content):
template_kwargs["processor_kwargs"] = {"num_frames": 32}
inputs = processor.apply_chat_template(messages, **template_kwargs).to(model.device)
streamer = TextIteratorStreamer(processor, skip_prompt=True, skip_special_tokens=True)
# Use the model's generation_config defaults (recommended sampling
# params ship with the model); only cap length for ZeroGPU runtime.
thread = Thread(
target=model.generate,
kwargs=dict(
**inputs,
streamer=streamer,
max_new_tokens=1024,
),
)
thread.start()
reply = ""
for token in streamer:
reply += token
yield reply # raw stream; frontend splits reasoning from final reply
thread.join()
@app.get("/", response_class=HTMLResponse)
async def homepage():
html_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "index.html")
with open(html_path, "r", encoding="utf-8") as f:
return f.read()
app.launch(show_error=True)
|