Sushantkas commited on
Commit
1ec3957
·
verified ·
1 Parent(s): b6455bb

Upload app.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +101 -0
app.py ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import spaces # noqa: E402 (must be imported before torch/transformers)
2
+ # v2: added kernels dependency for FP8 inference
3
+
4
+ import json
5
+ import re
6
+ import time
7
+
8
+ import gradio as gr
9
+ import torch
10
+ from transformers import AutoModelForCausalLM, AutoTokenizer
11
+
12
+ MODEL_ID = "Qwen/Qwen3-Coder-30B-A3B-Instruct-FP8"
13
+
14
+ tokenizer = AutoTokenizer.from_pretrained(MODEL_ID)
15
+ model = AutoModelForCausalLM.from_pretrained(
16
+ MODEL_ID,
17
+ dtype="auto",
18
+ ).to("cuda")
19
+ model.eval()
20
+
21
+ TOOL_CALL_RE = re.compile(r"<tool_call>\s*<function=(?P<name>[^>]+)>(?P<body>.*?)</function>\s*</tool_call>", re.DOTALL)
22
+ PARAM_RE = re.compile(r"<parameter=(?P<name>[^>]+)>(?P<value>.*?)</parameter>", re.DOTALL)
23
+
24
+
25
+ def _parse_tool_calls(text: str):
26
+ """Extract <tool_call> blocks from generated text into OpenAI-style tool_calls."""
27
+ tool_calls = []
28
+ for match in TOOL_CALL_RE.finditer(text):
29
+ name = match.group("name").strip()
30
+ body = match.group("body")
31
+ arguments = {}
32
+ for pmatch in PARAM_RE.finditer(body):
33
+ pname = pmatch.group("name").strip()
34
+ pvalue = pmatch.group("value").strip("\n")
35
+ arguments[pname] = pvalue
36
+ tool_calls.append(
37
+ {
38
+ "id": f"call_{len(tool_calls)}_{int(time.time() * 1000)}",
39
+ "type": "function",
40
+ "function": {"name": name, "arguments": json.dumps(arguments)},
41
+ }
42
+ )
43
+ leftover = TOOL_CALL_RE.sub("", text).strip()
44
+ return leftover, tool_calls
45
+
46
+
47
+ @spaces.GPU(duration=45)
48
+ def chat_completions(messages_json: str, tools_json: str = "", max_new_tokens: int = 2048) -> str:
49
+ """Run one chat-completion turn against Qwen3-Coder-30B-A3B-Instruct-FP8.
50
+
51
+ messages_json: JSON-encoded list of {"role", "content"} (and optionally
52
+ "tool_calls" / "tool_call_id" for prior turns), OpenAI chat format.
53
+ tools_json: JSON-encoded list of OpenAI-style tool/function definitions,
54
+ or an empty string for no tools.
55
+ max_new_tokens: generation budget for this turn.
56
+
57
+ Returns a JSON-encoded object: {"content": str, "tool_calls": [...]}.
58
+ """
59
+ messages = json.loads(messages_json)
60
+ tools = json.loads(tools_json) if tools_json else None
61
+
62
+ prompt = tokenizer.apply_chat_template(
63
+ messages,
64
+ tools=tools,
65
+ add_generation_prompt=True,
66
+ tokenize=False,
67
+ )
68
+ inputs = tokenizer(prompt, return_tensors="pt").to("cuda")
69
+
70
+ with torch.no_grad():
71
+ output_ids = model.generate(
72
+ **inputs,
73
+ max_new_tokens=max_new_tokens,
74
+ do_sample=False,
75
+ )
76
+
77
+ generated = output_ids[0][inputs["input_ids"].shape[1]:]
78
+ text = tokenizer.decode(generated, skip_special_tokens=True)
79
+
80
+ content, tool_calls = _parse_tool_calls(text)
81
+ return json.dumps({"content": content, "tool_calls": tool_calls})
82
+
83
+
84
+ demo = gr.Interface(
85
+ fn=chat_completions,
86
+ inputs=[
87
+ gr.Text(label="messages_json"),
88
+ gr.Text(label="tools_json", value=""),
89
+ gr.Number(label="max_new_tokens", value=2048, precision=0),
90
+ ],
91
+ outputs=gr.Text(label="completion_json"),
92
+ title="Qwen3-Coder-30B-A3B-Instruct-FP8 — chat completions",
93
+ description=(
94
+ "Internal inference endpoint for the Coding Model project. "
95
+ "Called via the local OpenAI-compatible shim, not directly by end users."
96
+ ),
97
+ api_name="chat_completions",
98
+ )
99
+
100
+ if __name__ == "__main__":
101
+ demo.launch(mcp_server=True)