问题描述
在使用 LM Studio 0.3.11 加载 Qwen qwq-32b(量化级别 Q2_K)模型时,自定义 Jinja2 模板在渲染提示(prompt)时反复报错。常见的错误提示包括:
Error rendering prompt with jinja template: Error: Parser Error: Expected closing statement token. OpenSquareBracket !== CloseStatement
Error rendering prompt with jinja template: Error: Unknown StringValue filter: lstrip
Error rendering prompt with jinja template: Error: Unknown StringValue filter: default
Error rendering prompt with jinja template: Error: Cannot apply filter "length" to type: NullValue
这些错误导致模板无法正常工作,影响模型的对话功能。
问题原因
经过分析,问题的根本原因主要与 LM Studio 的 Jinja2 实现和输入数据有关:
- Jinja 解析器限制:
- LM Studio 的 Jinja2 环境是一个精简版,不支持部分标准过滤器,如
lstrip
和default
。 - 对数组索引(如
split('\n')[-1]
)的解析存在 bug,会触发OpenSquareBracket
错误。
- 输入数据问题:
- 当
messages
或tools
变量为None
时,模板中使用|length
过滤器会导致NullValue
错误。 - LM Studio 在某些情况下未正确传递
messages
或tools
,导致运行时异常。
- 模板复杂性:
- 原始模板包含嵌套条件、循环和字符串操作(如
split('\n')[-1]
),超出了 LM Studio Jinja 解析器的处理能力。
解决方法
通过多次调整,最终得到了一个稳定的模板方案。以下是解决步骤和最终模板:
解决步骤
- 避免不受支持的过滤器:替换
lstrip
为trim
,移除default
,以适应 LM Studio 的限制。 - 处理索引问题:用
|last
替代split('\n')[-1]
,避免直接数组索引。 - 添加防御性检查:对
messages
和tools
添加is none
检查,防止对None
使用|length
。 - 简化逻辑:减少嵌套条件,确保模板结构清晰。
最终模板
以下是经过验证的稳定模板:
{%- if messages is not defined or messages is none or messages|length == 0 %}
{{ '<|im_start|>system\n消息列表为空或未定义。<|im_end|>\n' }}
{%- else %}
{%- if tools is defined and tools is not none and tools|length > 0 %}
{{ '<|im_start|>system\n\n# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within <tools></tools> XML tags:\n<tools>' }}
{%- for tool in tools %}
{{ '\n' }}{{ tool | tojson }}
{%- endfor %}
{{ '\n</tools>\n\nFor each function call, return a json object with function name and arguments within <tool_call></tool_call> XML tags:\n<tool_call>\n{\"name\": <function-name>, \"arguments\": <args-json-object>}\n</tool_call><|im_end|>\n' }}
{%- endif %}
{%- for message in messages %}
{%- if message.role == "user" or (message.role == "system" and not loop.first) %}
{{ '<|im_start|>' }}{{ message.role }}{{ '\n' }}{{ message.content }}{{ '<|im_end|>\n' }}
{%- elif message.role == "system" and loop.first %}
{{ '<|im_start|>system\n' }}{{ message.content }}{{ '<|im_end|>\n' }}
{%- elif message.role == "assistant" and (message.tool_calls is not defined or not message.tool_calls) %}
{%- set lines = message.content.split('\n') %}
{%- set content = lines|last|trim %}
{{ '<|im_start|>assistant\n' }}{{ content }}{{ '<|im_end|>\n' }}
{%- endif %}
{%- endfor %}
{%- endif %}
{%- if add_generation_prompt %}
{{ '<|im_start|>assistant\n' }}
{%- endif %}
功能说明
- 消息处理:支持 system、user 和 assistant 角色,第一条 system 消息单独处理。
- 助手输出:只显示最后一行(通过 |last|trim),可根据需求改为完整内容。
- 工具支持:可选添加工具信息,确保 tools 数据有效。
- 防御性:处理 None 值和空列表情况。
使用方法
- 在 LM Studio 中替换模板为上述内容。
- 输入消息,例如:
[{"role": "system", "content": "你是一个助手"}, {"role": "user", "content": "你好"}]
- 运行并验证输出。
总结
通过调整模板,我们成功绕过了 LM Studio Jinja 解析器的限制,解决了 Qwen qwq-32b 模型的提示渲染问题。如果您遇到类似问题,建议检查过滤器支持情况、避免复杂索引,并确保输入数据有效。未来可向 LM Studio 团队反馈这些限制,以改进工具支持。
本文由 Ggrok 参与测试与编写。
Mac OS X 10_15_7Chrome 133.0.0.0来自 河南 的大神
大佬你好,我遇到了这个问题,然后很幸运地看到了您的解决方法。
我的问题在于,我看不懂这个。。。
不知道该对 Lm 做什么改动。。。
我试着求助 qwen2.5_17b,它给的回复我也一样看不懂。。。
如何“在 LM Studio 中替换模板为上述内容。”呢?
PS:本人使用的是 MacBook Pro 128G M3 max。
非常期待大佬的回复!祝大佬一切顺利!
在 我的模型 中找到下载的 qwq-32b,点击齿轮进入配置,找到 Prompt - 提示模版,替换成文中模板就可以了
Mac OS X 10_15_7Chrome 133.0.0.0来自 河南 的大神
感谢大佬的耐心回复!问题果然成功解决了!
Mac OS X 10_15_7Chrome 133.0.0.0来自 浙江省 的大神
复制失败
Mac OS X 10_15_7Chrome 133.0.0.0来自 北美地区 的大神
怎么复制不了啊
Windows 10Chrome 122.0.6261.95来自 上海 的大神
现在都加上禁止复制功能啦