
llama.cpp auto-parser 如何验证一个新聊天模板的解析并添加支持【免费下载链接】llama.cppLLM inference in C/C项目地址: https://gitcode.com/GitHub_Trending/ll/llama.cpp你手上有一个新的聊天模板Jinja 模板文件或存放在 GGUF 模型的tokenizer.chat_template键中的模板想确认 llama.cpp 的 auto-parser 能否正确提取它的 reasoning、content、tool-call 标记并在提取不正确时按项目既有机制添加支持。auto-parser 采用差分比较differential comparison分析模板入口在 common/chat.cpp 的common_chat_templates_apply_jinja中。验证与添加支持的完整流程见 docs/autoparser.md本文围绕该文档给出的调试工具和三种处理路径展开。准备条件模板与测试工具验证工作需要一个 llama.cpp 源码构建树其中包含测试工具。两个 debug 工具都在 tests/CMakeLists.txt 中注册test-chat-auto-parser已注册为测试带模板路径参数时切换为 debug 工具文档给出的可执行路径是bin/test-chat-auto-parsertest-chat-analysis仅构建、不注册为测试CMakeLists 注释标明 run it manually。输入模板有两种形式tests/test-chat-auto-parser.cpp 的debug_single_template()会按后缀自动区分.jinja或任意文本文件直接读取文件内容.gguf从 GGUF 文件中读取tokenizer.chat_template键找不到该键或值为空会报错。第一步用 test-chat-auto-parser 验证单个模板运行path/to/template.jinja替换为你的模板文件也可以是.gguf模型文件./bin/test-chat-auto-parser path/to/template.jinja不传任何参数时它运行自动测试套件第一个参数若是已存在的文件才进入 debug 模式若参数不是文件则作为测试过滤的正则使用。不带额外选项时的默认行为见 tests/test-chat-auto-parser.cpp 的debug_options启用工具定义with_toolstrue即会分析 tool-call 格式启用 generation promptadd_generation_prompttrue启用 reasoning 解析reasoning_format设为COMMON_REASONING_FORMAT_DEEPSEEK输出模式为both模板渲染 分析结果。常用选项来自该工具的--help用法说明./bin/test-chat-auto-parser template.jinja --input-messageall --generation-prompt1 ./bin/test-chat-auto-parser template.jinja --outputtemplate --input-messagetool_call_only选项作用--no-tools关闭工具定义只看 content/reasoning 分析--force-tool-call将 tool_choice 设为 required--parallel-tool-calls0\|1设置 parallel_tool_calls默认 1--generation-prompt0\|1设置 add_generation_prompt默认 1--enable-reasoning0\|1启用/关闭 reasoning 解析默认 1--outputanalysis\|template\|both输出模式默认 both--input-messageTYPE渲染的消息场景content_only、reasoning_content、tool_call_only、content_tool_call、reasoning_tool_call、content_fake_tool_call、all--debug-jinja启用 Jinja 细粒度调试也可用环境变量LLAMA_DEBUG_JINJAdebug 模式的输出包含这几部分见 tests/test-chat-auto-parser.cppTEMPLATE ANALYSIS自动解析检测到的格式与标记Generated Parser生成的 PEG 解析器结构Generated GrammarGBNF 语法以及Grammar Triggers触发 tokenPreserved Tokens所有提取出的非空标记的并集。对照解析结果时用 docs/autoparser.md 中的枚举定义核对reasoning_modeNONE/TAG_BASED如think.../think/TOOLS_ONLYcontent_modePLAIN无内容标记/ALWAYS_WRAPPED/WRAPPED_WITH_REASONINGtool_formatNONE/JSON_NATIVE纯 JSON/TAG_WITH_JSON如functionX{...}/TAG_WITH_TAGGED如paramkeyvalue/paramcall_id_positionNONE/PRE_FUNC_NAME/BETWEEN_FUNC_AND_ARGS/POST_ARGS。判断标准是文档给出的这一条运行test-chat-auto-parser template_path验证标记是否被正确提取——即输出中的标记是否与你模板中实际使用的标记一致、格式分类是否符合预期。注意一个分支如果模板命中了专用处理文档列出的专用模板包括 Ministral/Magistral Large 3、GPT-OSS 的|channel|、Functionary v3.2 的alldebug 工具会打印This template uses a specialized parser, analysis results will not be available.此时不输出分析结果——这类模板本就不走 auto-parser。深入排查差分分析与调试日志标记提取不对时用第二个工具查看模板在各变体下渲染出的 diff./bin/test-chat-analysis --template-file path/to/template.jinjatests/test-chat-analysis.cpp 的选项--template-file path分析自定义模板文件--template name按名称从测试套件模板中筛选如deepseek--all分析测试套件中全部模板无参数时的默认行为。它展示带/不带工具、reasoning 等条件下的渲染结果与差分对应 docs/autoparser.md Algorithm Details 一节描述的compare_variants()机制R1/R2/R3、C1、T1–T7 各阶段比较的正是这些变体。开启详细日志可以看到分析步骤、模式提取结果与生成的解析器结构LLAMA_ARG_LOG_VERBOSITY2 ./bin/test-chat-auto-parser path/to/template.jinja验证通过后模板已受支持如果你的模板遵循标准模式auto-parser 应自动检测docs/autoparser.md Adding Support for New Templates 第 1 条test-chat-auto-parser显示标记提取正确、解析器与语法符合预期就不需要改任何代码——模板已通过入口链路common_chat_templates_apply_jinja被支持。此时建议补一个测试用例防回归tests/test-chat.cpp提供peg_tester流式 API 编写解析测试文档中的示例Template.jinja与输入文本需替换为你自己的模板与场景auto tst peg_tester(models/templates/Template.jinja); tst.test(input text) .reasoning_format(COMMON_REASONING_FORMAT_AUTO) .tools({tool_json}) .parallel_tool_calls(true) .enable_thinking(true) .expect(expected_message) .run();docs/autoparser.md 的 Tested Templates 一列出了当前已有活跃测试的模板及其格式分类如 Qwen3-Coder 为 TAG_WITH_TAGGED、Llama 3.1/3.2/3.3 为 JSON_NATIVE可作为你新模板所属格式的对照参考。标记提取错误时添加 workaround差分分析提取了不正确标记但模板结构本质上仍属于 auto-parser 可处理的格式时在 common/chat-diff-analyzer.cpp 的workarounds向量里添加一个 workaround lambda。写法约定文档要求且现有实现一致检查模板源码中一个唯一的标识性子串tmpl.src.find(...)命中后直接覆写analysis结构体中的分析结果用LOG_DBG打印补丁名称以便调试时识别。以现有的 Granite 3.3 workaroundcommon/chat-diff-analyzer.cpp为例// Granite 3.3, with separate reasoning and content markers [](const common_chat_template tmpl, autoparser analysis) - void { if (tmpl.src.find(Write your thoughts between think/think and write your response between response/response) ! std::string::npos) { analysis.reasoning.mode reasoning_mode::TAG_BASED; analysis.reasoning.start think; analysis.reasoning.end /think; analysis.preserved_tokens.push_back(think); analysis.preserved_tokens.push_back(/think); analysis.content.mode content_mode::WRAPPED_WITH_REASONING; analysis.content.start response; analysis.content.end /response; analysis.preserved_tokens.push_back(response); analysis.preserved_tokens.push_back(/response); LOG_DBG(ANSI_ORANGE [Patch: Granite 3.3]\n ANSI_RESET); } },其他现有 workaroundOld Qwen/DeepSeek thinking 模板、Cohere Command R、Functionary 3.1、DeepSeek-R1-Distill-Qwen、Nemotron Nano v2、Fireworks遵循同样的模式。可覆写的字段见 common/chat-auto-parser.h 中autoparser聚合的reasoning、content、tools子结构。改完后重新构建再用./bin/test-chat-auto-parser path/to/template.jinja复跑确认输出中标记已变为正确值workaround 命中时LLAMA_ARG_LOG_VERBOSITY2下能看到对应的[Patch: ...]日志。需要完全不同处理时专用 handler模板的处理逻辑与 auto-parser 的差分/组合方式根本不同无法用标记覆写解决时在 common/chat.cpp 的 auto-parser 调用块之前添加一个专用 handler 函数。文档点名了三个这样处理的先例GPT-OSSchannel-based、Functionary v3.2收件人分隔符、Ministral[THINK]...[/THINK]标签。专用模板命中后test-chat-auto-parser会打印 uses a specialized parser 并跳过分析输出这本身可以用作你新增 handler 生效的验证信号。已知边界与限制auto-parser 唯一的启发式是 JSON 检测区分JSON_NATIVE与 tag 格式其余标记全部来自模板比较工具格式分析只在jinja_caps.supports_tool_calls为真时执行check_per_call_markers()T2只在supports_parallel_tool_calls时运行若analyze_tools判定支持工具调用但无法确定格式build_parser()会记录错误并返回eps()优雅降级而不是中断——debug 输出中若工具部分解析器为空可回到test-chat-analysis的 diff 输出定位generation prompt 由add_generation_promptfalse与true两种渲染结果做差得到模板若忽略该参数diff 为空解析器构建时会用渲染出的data.prompt作为回退限非TOOLS_ONLY模式。【免费下载链接】llama.cppLLM inference in C/C项目地址: https://gitcode.com/GitHub_Trending/ll/llama.cpp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考