CCCL segmented_sort.cu AST chain → traced back to base engine zip → discovered base patch_ops.sh deploys 10+ files we were missing. Missing patches that caused real failures: 1. paged_attn.py — Triton context_attention_fwd HANGS BI-V100 GPUs permanently. Base engine replaces it with _forward_prefix_pytorch pure-PyTorch fallback. WITHOUT THIS: GPU hang on any prefix-cached request → timeout → 0 score. 2. patch_xformers_sdpa_seq.py — head_dim=256 > cudnnFlashAttn 128 limit. Qwen3.5 uses head_dim=256. Without this bypass, attention crashes. 3. sequence.py — completion_tokens inflation under chunked prefill. Bug: get_output_token_ids_to_return(delta=True) with num_new_tokens=0 returns the ENTIRE prompt. 10K prompt × 3 chunks = 30K false tokens. 4. scheduler.py — num_cached_tokens tracking for prefix caching. 5. mamba_cache.py — GatedDeltaNet state management. 6. patch_model_runner.py — prefix_cache_hit stays True in chunked-prefill chunk 2+, causing undersized block_tables and crash. Also: conditional qwen3_5.py deployment (CCCL JIT pattern) — if Docker image already has a working qwen3_5.py (with corex integration), don't overwrite it. Only deploy ours if the image version is missing.
80 lines
2.5 KiB
Python
80 lines
2.5 KiB
Python
"""
|
|
Patches vLLM 0.6.3 to register Qwen3CoderToolParser under the name "qwen3_coder".
|
|
|
|
Deploy steps on the remote machine (already called by patch_ops.sh):
|
|
1. cp qwen3coder_tool_parser.py \
|
|
/usr/local/corex/lib/python3/dist-packages/vllm/entrypoints/openai/tool_parsers/
|
|
2. python3 patch_vllm_tool_parser.py
|
|
|
|
Usage after patching:
|
|
--tool-call-parser qwen3_coder --enable-auto-tool-choice
|
|
"""
|
|
|
|
import os
|
|
|
|
VLLM_ROOT = "/usr/local/corex/lib/python3/dist-packages/vllm"
|
|
TOOL_PARSERS_DIR = f"{VLLM_ROOT}/entrypoints/openai/tool_parsers"
|
|
INIT_FILE = f"{TOOL_PARSERS_DIR}/__init__.py"
|
|
|
|
|
|
def patch_file(path, replacements):
|
|
with open(path, "r") as f:
|
|
content = f.read()
|
|
|
|
patched = False
|
|
for old, new in replacements:
|
|
if new in content:
|
|
print(f" [skip] already patched: {repr(new[:70])}")
|
|
continue
|
|
if old not in content:
|
|
print(f" [warn] anchor not found: {repr(old[:70])}")
|
|
continue
|
|
content = content.replace(old, new, 1)
|
|
patched = True
|
|
print(f" [ok] patched: {repr(old[:50])} -> {repr(new[:50])}")
|
|
|
|
if patched:
|
|
with open(path, "w") as f:
|
|
f.write(content)
|
|
|
|
|
|
def main():
|
|
if not os.path.isdir(TOOL_PARSERS_DIR):
|
|
raise FileNotFoundError(
|
|
f"Tool parsers directory not found: {TOOL_PARSERS_DIR}\n"
|
|
"Verify the vLLM installation path.")
|
|
|
|
print(f"=== Patching {INIT_FILE} ===")
|
|
patch_file(INIT_FILE, [
|
|
(
|
|
"from .mistral_tool_parser import MistralToolParser",
|
|
"from .mistral_tool_parser import MistralToolParser\n"
|
|
"from .qwen3coder_tool_parser import Qwen3CoderToolParser",
|
|
),
|
|
(
|
|
'"MistralToolParser", "Internlm2ToolParser", "Llama3JsonToolParser"\n]',
|
|
'"MistralToolParser", "Internlm2ToolParser", "Llama3JsonToolParser",\n'
|
|
' "Qwen3CoderToolParser"\n]',
|
|
),
|
|
])
|
|
|
|
print("\n=== Verification ===")
|
|
try:
|
|
import importlib.util
|
|
spec = importlib.util.spec_from_file_location(
|
|
"qwen3coder_tool_parser",
|
|
f"{TOOL_PARSERS_DIR}/qwen3coder_tool_parser.py",
|
|
)
|
|
mod = importlib.util.module_from_spec(spec)
|
|
print(f" Module spec loaded: {spec.name}")
|
|
print(" (full import requires torch/vllm runtime — skipping exec)")
|
|
except Exception as e:
|
|
print(f" [warn] spec check failed: {e}")
|
|
|
|
print("\nDone. Start vLLM server with:")
|
|
print(" --tool-call-parser qwen3_coder --enable-auto-tool-choice")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|