[Bug]: Rust frontend chat-template rendering fails with 500 “unknown function: raise_exception” for templates that legally use it (e.g. Qwen

当你在 vLLM 0.30.0 的 Rust 前端(Rust frontend)下使用带有 raise_exception(...) 调用的 chat template(例如 Qwen3 系列用于校验 reasoning_effort 的模板)发起请求时,minijinja 渲染器不认识该函数,导致

快速结论:当你在 vLLM 0.30.0 的 Rust 前端(Rust frontend)下使用带有 raise_exception(...) 调用的 chat template(例如 Qwen3 系列用于校验 reasoning_effort 的模板)发起请求时,minijinja 渲染器不认识该函数,导致 chat-template 渲染失败并返回 HTTP 500 unknown function: raise_exception。优先确认是否启用了 Rust 前端、是否使用了含 raise_exception 的模板,并考虑切换到 Python 前端或采用模板侧临时修复。

适用环境:Issue 中确认的环境为 vLLM 0.30.0,Ubuntu 22.04.5 LTS,Python 3.12.13,PyTorch 2.13.0+cu130,CUDA 13.0,NVIDIA GeForce RTX 4090(报告为多卡,collect_env 输出中列出 8 张,正文提及 2 张用于复现),NVIDIA 驱动 580.105.08。其他未在 Issue 中明确的项目不做推断。

最快修复方案:暂无确认的一步修复方案。Issue 中经生产环境验证的临时方案是:复制模型的 chat_template.jinja,用正则把每个 raise_exception(...) 块替换为空字符串输出,然后用 --chat-template 指向修改后的模板重启服务;Issue 中提到对 Qwen3.8-27B-FP8 有 9 处此类块,处理后原本循环 500 的 agent 客户端请求可正常完成并返回 200。官方修复方向为在 minijinja 环境注册 raise_exception,并将渲染失败归类为请求校验错误返回 400,与 Python 前端的 TemplateError → 400 映射对齐,但截至整理时该修复尚未在 Issue 中确认落地。

注意事项:模板侧替换会移除模板原本的参数校验逻辑(例如对 reasoning_effort 白名单 xhigh|medium|low 的检查),非法参数可能不再被模板拦截,行为与官方模板产生差异。Issue 中还观察到客户端发送了 reasoning_effort: "high",而 Qwen3 模板白名单不含该值;报告者认为这属于次要问题,核心仍是渲染器不支持 raise_exception。上述临时方案只针对 Qwen3 类模板实例验证,其他模板需自行确认正则匹配范围。

问题场景

用户在 vLLM 0.30.0 的 Rust 前端下加载使用 raise_exception(...) 的 chat template(如 Qwen3 系列用于 reasoning_effort 校验的模板),通过 agent 客户端持续发起 chat 请求时,chat-template 渲染在服务端失败,客户端反复收到 HTTP 500,而不是模板预期的校验提示。切换到 Python 前端或将模板中的 raise_exception 移除后,同样的请求可以正常完成。

报错原文

500 Internal Server Error
unknown function: raise_exception

原因分析

可能是 Rust 前端所用 minijinja 渲染环境没有注册 raise_exception 函数,而模型自带的 chat template 合法地调用了它(例如 Qwen3 模板用 raise_exception 对 reasoning_effort 等参数做白名单校验)。Python 前端会把这类模板错误映射为 400 TemplateError,而 Rust 前端在渲染阶段直接失败,于是以 500 返回。Issue 中维护者也确认修复计划是在 renderer/hf/template.rs 的 minijinja 环境注册 raise_exception,并把失败映射为请求校验错误(400)。

环境排查

  • 确认 vLLM 版本是否为 0.30.0(Issue 复现版本)。
  • 确认当前服务是否启用了 Rust 前端,而非 Python 前端。
  • 确认所加载模型的 chat_template.jinja 中是否存在 raise_exception( 调用,以及调用位置和数量。
  • 确认 Python 版本(Issue 为 3.12.13)、PyTorch 版本(Issue 为 2.13.0+cu130)、CUDA 版本(Issue 为 13.0)。
  • 确认 GPU 型号与驱动(Issue 为 RTX 4090,驱动 580.105.08)。
  • 若客户端发送了 reasoning_effort,确认其取值是否落在模板白名单内(Qwen3 模板白名单为 xhigh|medium|low)。

解决步骤

  1. 先确认报错确实来自 chat-template 渲染:查看服务端日志中是否出现 unknown function: raise_exception,并确认请求路径经过 Rust 前端。
  2. 如果不是必须使用 Rust 前端,可优先尝试切换到 Python 前端验证请求能否正常渲染返回(Issue 中未给出具体切换命令,按你所部署版本的配置方式操作)。
  3. 采用 Issue 中在生产环境验证过的模板侧临时方案:复制模型的 chat_template.jinja,用正则把每个 raise_exception(...) 块替换为空输出,例如:
    import re
    s = open('chat_template.jinja', encoding='utf-8').read()
    pat = re.compile(r"\{\{-?\s*raise_exception\(.*?\)\s*\}\}", re.S)
    open('chat_template_fixed.jinja', 'w').write(pat.sub("{{- '' }}", s))
  4. 检查替换结果:确认生成的 chat_template_fixed.jinja 中不再包含 raise_exception,且模板其他控制流未被破坏。
  5. 使用 --chat-template <path>/chat_template_fixed.jinja 重启 vLLM 服务。
  6. 如果客户端发送了 reasoning_effort: "high" 这类不在 Qwen3 模板白名单中的值,可在客户端侧改用白名单内的取值,或等待官方在 API 层做参数规范化(Issue 中仅作为补充观察,未确认已实现)。
  7. 关注官方修复:在 minijinja 环境注册 raise_exception,并把渲染失败映射为 400,与 Python 前端的 TemplateError 行为对齐。

验证方法

用之前会触发 500 的同一 agent 客户端请求流重新发起请求:若已应用模板侧修复,应不再出现 unknown function: raise_exception,请求正常返回 200 并完成;若后续版本已合入渲染器修复,则模板合法调用 raise_exception 时应按模板自身消息失败并返回 400,而不是 500。Issue 中提到报告者在 2×4090 复现环境上可协助验证官方 PR,可参照该方式复测。

参考来源

vllm-project/vllm #59009

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 26278

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注