Views
No views yet

--reasoning-parser gemma4.--default-chat-template-kwargs '{"enable_thinking": true}', or by setting {%- set enable_thinking = true %} in chat_template.jinja.| Layer Type | Bits | Notes |
|---|---|---|
lm_head | 16-bit | Kept in original precision to preserve final token prediction quality and avoid extra degradation at output projection |
vision_tower.* | 16-bit | Kept in original precision to better preserve visual feature extraction quality and reduce multimodal degradation |
embed_vision.* | 16-bit | Kept in original precision to maintain vision embedding fidelity and reduce quantization error before visual feature processing |
| gemma-4-31B-it-NVFP4A16-GPTQ | gemma-4-31B-it | Qwen3.8-27B-NVFP4A16-GPTQ | |
|---|---|---|---|
|
Model Size
|
67%↓↓
20.5 GB
|
62.6 GB
|
27.7 GB
|
|
Multidisciplinary reasoning
HLE
| 18.1 | 19.5 | 17.0 |
example.py, copy the example code below into it, and then run python example.py in terminal.1import argparse
2import atexit
3import json
4import os
5import shutil
6import subprocess
7import sys
8import time
9import urllib.error
10import urllib.request
11
12
13# Configuration
14DEFAULTS = {
15 "model": "YCWTG/gemma-4-31B-it-NVFP4A16-GPTQ",
16 "served_model_name": "YCWTG/gemma-4-31B-it-NVFP4A16-GPTQ",
17 "host": "localhost",
18 "port": 8000,
19 "max_model_len": 63590,
20 "enable_auto_tool_choice": True,
21 "tool_call_parser": "gemma4",
22 "max_num_seqs": 1,
23 "reasoning_parser": "gemma4",
24 "default_chat_template_kwargs": '{"enable_thinking": true}',
25 "allowed_local_media_path": "/home/ycwtg/image",
26}
27
28RUNTIME = {
29 "gpu_memory_utilization": 0.98,
30 "startup_timeout_sec": 1800,
31 "healthcheck_timeout_sec": 3,
32 "healthcheck_interval_sec": 1,
33 "chat_timeout_sec": 600,
34}
35
36# The API is always local; global HTTP_PROXY settings must not intercept it.
37LOCAL_HTTP = urllib.request.build_opener(urllib.request.ProxyHandler({}))
38
39SERVE_VALUE_ARGS = (
40 "served_model_name", "host", "port", "max_model_len",
41 "tool_call_parser", "max_num_seqs", "reasoning_parser",
42 "default_chat_template_kwargs",
43)
44CLIENT_VALUE_ARGS = ("model", *SERVE_VALUE_ARGS)
45BOOL_ARGS = ("enable_auto_tool_choice",)
46
47
48def cli_flag(name):
49 return "--" + ("max_num_seqs" if name == "max_num_seqs" else name.replace("_", "-"))
50
51
52def value_options(args, names):
53 return [part for name in names for part in (cli_flag(name), str(getattr(args, name)))]
54
55
56def boolean_options(args, explicit_false=False):
57 return [
58 cli_flag(name) if getattr(args, name) else "--no-" + cli_flag(name)[2:]
59 for name in BOOL_ARGS
60 if explicit_false or getattr(args, name)
61 ]
62
63
64def multiline_input():
65 print('User (type "END" on a single line to send, "exit" to quit):')
66 lines = []
67 while True:
68 line = input()
69 text = line.strip()
70 if text.lower() in {"exit", "quit"}:
71 return None
72 if text == "END":
73 break
74 lines.append(line)
75 return "\n".join(lines)
76
77
78def resolve_client_host(host):
79 return "127.0.0.1" if host in {"0.0.0.0", "::"} else host
80
81
82def launch_vllm(args):
83 vllm = shutil.which("vllm", path=os.path.dirname(sys.executable)) or shutil.which("vllm")
84 if not vllm:
85 raise RuntimeError("vllm command not found. Activate an environment that has vllm installed.")
86
87 cmd = [vllm, "serve", args.model, *value_options(args, SERVE_VALUE_ARGS)]
88 media_path = args.allowed_local_media_path
89 if media_path is not None and (not isinstance(media_path, str) or media_path.strip()):
90 cmd += ["--allowed-local-media-path", str(media_path)]
91 cmd += ["--gpu-memory-utilization", str(RUNTIME["gpu_memory_utilization"]), *boolean_options(args)]
92
93 print("Launching vLLM:")
94 print(" ".join(cmd))
95 env = os.environ.copy()
96 env["PATH"] = os.path.dirname(vllm) + os.pathsep + env.get("PATH", "")
97 try:
98 return subprocess.Popen(cmd, env=env)
99 except FileNotFoundError as e:
100 raise RuntimeError("vllm command not found. Activate an environment that has vllm installed.") from e
101
102
103def stop_vllm(proc):
104 if proc and proc.poll() is None:
105 proc.terminate()
106 try:
107 proc.wait(timeout=10)
108 except subprocess.TimeoutExpired:
109 proc.kill()
110
111
112def wait_vllm_ready(base_url, timeout_sec=RUNTIME["startup_timeout_sec"], proc=None):
113 deadline = time.time() + timeout_sec
114 req = urllib.request.Request(url=f"{base_url}/v1/models")
115 while time.time() < deadline:
116 if proc and proc.poll() is not None:
117 return False
118 try:
119 with LOCAL_HTTP.open(req, timeout=RUNTIME["healthcheck_timeout_sec"]) as resp:
120 if resp.status == 200:
121 return True
122 except urllib.error.URLError:
123 pass
124 time.sleep(RUNTIME["healthcheck_interval_sec"])
125 return False
126
127
128def chat_once(base_url, model_name, messages):
129 payload = {"model": model_name, "messages": messages, "skip_special_tokens": False}
130 req = urllib.request.Request(
131 url=f"{base_url}/v1/chat/completions",
132 data=json.dumps(payload, ensure_ascii=False).encode("utf-8"),
133 headers={"Content-Type": "application/json"},
134 method="POST",
135 )
136 with LOCAL_HTTP.open(req, timeout=RUNTIME["chat_timeout_sec"]) as resp:
137 data = json.loads(resp.read().decode("utf-8"))
138 return data["choices"][0]["message"]
139
140
141def chat_loop(base_url, model_name):
142 print("\n===== Chat Started =====\n")
143 messages = []
144
145 while True:
146 user_text = multiline_input()
147 if user_text is None:
148 break
149
150 messages.append({"role": "user", "content": user_text})
151 try:
152 assistant_msg = chat_once(base_url, model_name, messages)
153 except Exception as e:
154 print(f"\nRequest failed: {e}\n")
155 messages.pop()
156 continue
157
158 content = assistant_msg.get("content")
159 tool_calls = assistant_msg.get("tool_calls")
160
161 if content:
162 print(f"\nAssistant:\n{content}\n")
163 elif tool_calls:
164 print("\nAssistant(tool_calls):")
165 print(json.dumps(tool_calls, ensure_ascii=False, indent=2))
166 print()
167 else:
168 print("\nAssistant:\n(empty response)\n")
169
170 normalized_msg = {"role": "assistant", "content": content or ""}
171 if tool_calls:
172 normalized_msg["tool_calls"] = tool_calls
173 messages.append(normalized_msg)
174
175
176def build_client_command(args):
177 return [
178 sys.executable,
179 os.path.abspath(__file__),
180 "--_client",
181 *value_options(args, CLIENT_VALUE_ARGS),
182 *boolean_options(args, explicit_false=True),
183 ]
184
185
186def spawn_chat_terminal(args):
187 client_cmd = build_client_command(args)
188
189 if os.name == "nt":
190 terminal_cmd = ["cmd", "/c", "start", "", "cmd", "/k", subprocess.list2cmdline(client_cmd)]
191 elif shutil.which("ptyxis"):
192 terminal_cmd = ["ptyxis", "--standalone", "--new-window", "--title=vLLM Chat", "--", *client_cmd]
193 elif shutil.which("gnome-terminal"):
194 terminal_cmd = ["gnome-terminal", "--", *client_cmd]
195 elif shutil.which("x-terminal-emulator"):
196 terminal_cmd = ["x-terminal-emulator", "-e", *client_cmd]
197 else:
198 return False
199
200 try:
201 terminal_proc = subprocess.Popen(terminal_cmd)
202 if terminal_cmd[0] == "ptyxis":
203 time.sleep(0.5)
204 if terminal_proc.poll() is not None:
205 print(f"Failed to open Ptyxis (exit code {terminal_proc.returncode}).")
206 return False
207 return True
208 except Exception as e:
209 print(f"Failed to open a new terminal automatically: {e}")
210 return False
211
212
213def parse_args():
214 parser = argparse.ArgumentParser(description="Minimal local vLLM chat script")
215 parser.add_argument("--_client", action="store_true", help=argparse.SUPPRESS)
216
217 def add(name, *flags, **kwargs):
218 parser.add_argument(
219 *(flags or (f"--{name.replace('_', '-')}",)), dest=name, default=DEFAULTS[name], **kwargs
220 )
221
222 add("model")
223 add("served_model_name")
224 add("host")
225 add("port", type=int)
226 add("max_model_len", type=int)
227 add("max_num_seqs", "--max-num-seqs", "--max_num_seqs", type=int)
228 add("enable_auto_tool_choice", action=argparse.BooleanOptionalAction)
229 add("allowed_local_media_path", help="Optional local media path. Leave empty to disable.")
230 add("tool_call_parser")
231 add("reasoning_parser")
232 add("default_chat_template_kwargs")
233 return parser.parse_args()
234
235
236def main():
237 args = parse_args()
238 base_url = f"http://{resolve_client_host(args.host)}:{args.port}"
239 if args._client:
240 print(f"Waiting for model service: {base_url}")
241 if wait_vllm_ready(base_url):
242 chat_loop(base_url, args.served_model_name)
243 else:
244 print("Model service did not become ready.")
245 return
246
247 proc = launch_vllm(args)
248 atexit.register(stop_vllm, proc)
249 terminal_opened = spawn_chat_terminal(args)
250
251 print(f"Waiting for service to become ready: {base_url}")
252 if not wait_vllm_ready(base_url, proc=proc):
253 print(f"vLLM failed to become ready (exit code: {proc.poll()}). Check server logs above.")
254 stop_vllm(proc)
255 sys.exit(1)
256
257 if terminal_opened:
258 print("Model is ready. Opened a new terminal for chat; this terminal keeps server logs.")
259 print("Press Ctrl+C here to stop vLLM.")
260 try:
261 proc.wait()
262 except KeyboardInterrupt:
263 print("\nInterrupted. Stopping vLLM...")
264 else:
265 print("No supported terminal found. Falling back to chat in this terminal.")
266 chat_loop(base_url, args.served_model_name)
267
268
269if __name__ == "__main__":
270 main()
271vllm serve YCWTG/gemma-4-31B-it-NVFP4A16-GPTQ --served-model-name YCWTG/gemma-4-31B-it-NVFP4A16-GPTQ --host localhost --port 8000 --async-scheduling --max-model-len 63590 --enable-auto-tool-choice --tool-call-parser gemma4 --gpu-memory-utilization 0.98 --max_num_seqs 1 --allowed-local-media-path /home/ycwtg/imagevllm serve YCWTG/gemma-4-31B-it-NVFP4A16-GPTQ --served-model-name YCWTG/gemma-4-31B-it-NVFP4A16-GPTQ --host localhost --port 8000 --async-scheduling --max-model-len 63590 --enable-auto-tool-choice --tool-call-parser gemma4 --gpu-memory-utilization 0.98 --max_num_seqs 1 --allowed-local-media-path /home/ycwtg/image --reasoning-parser gemma4 --default-chat-template-kwargs '{"enable_thinking": true}'vllm serve YCWTG/gemma-4-31B-it-NVFP4A16-GPTQ --served-model-name YCWTG/gemma-4-31B-it-NVFP4A16-GPTQ --host localhost --port 8000 --async-scheduling --max-model-len 66634 --enable-auto-tool-choice --tool-call-parser gemma4 --gpu-memory-utilization 0.98 --max_num_seqs 1 --reasoning-parser gemma4 --default-chat-template-kwargs '{"enable_thinking": true}' --language-model-onlyhttp://localhost:8000/v1.