From cdf9142aa5be27cdd447d8fdfc89b29ad23b7778 Mon Sep 17 00:00:00 2001 From: firecoperana <18252262+firecoperana@users.noreply.github.com> Date: Tue, 24 Mar 2026 01:48:20 -0500 Subject: [PATCH] fix grammar stack empty error for qwen3.5 (#1490) * fix grammar stack empty error for qwen3.5 * Add to --help --------- Co-authored-by: firecoperana --- common/chat.cpp | 7 +++---- common/chat.h | 1 + common/common.cpp | 8 ++++++++ common/common.h | 1 + examples/server/server-common.cpp | 1 + examples/server/server-common.h | 1 + examples/server/server-context.cpp | 1 + 7 files changed, 16 insertions(+), 4 deletions(-) diff --git a/common/chat.cpp b/common/chat.cpp index 269b2fd7..1764f62a 100644 --- a/common/chat.cpp +++ b/common/chat.cpp @@ -3171,10 +3171,9 @@ static common_chat_params common_chat_templates_apply_jinja( workaround::func_args_not_string(params.messages); // Models with support (Step-3.5-Flash, Nemotron 3 Nano) use the // Nemotron v3 PEG parser for streaming and schema-aware parameter parsing. - // Qwen3-Coder has no in its template. - //if (src.find("") != std::string::npos) { - // return common_chat_params_init_qwen3_coder(tmpl, params); - //} + if (inputs.use_peg) { + return common_chat_params_init_qwen3_coder(tmpl, params); + } return common_chat_params_init_qwen3_coder_xml(tmpl, params); } diff --git a/common/chat.h b/common/chat.h index 1c7fba02..0c40dd18 100644 --- a/common/chat.h +++ b/common/chat.h @@ -157,6 +157,7 @@ struct common_chat_templates_inputs { std::map chat_template_kwargs; bool add_bos = false; bool add_eos = false; + bool use_peg = false; }; struct common_chat_params { diff --git a/common/common.cpp b/common/common.cpp index ddde7502..f1770e2d 100644 --- a/common/common.cpp +++ b/common/common.cpp @@ -1959,6 +1959,10 @@ bool gpt_params_find_arg(int argc, char ** argv, const std::string & arg, gpt_pa params.use_jinja = true; return true; } + if (arg == "--peg") { + params.use_peg = true; + return true; + } if (arg == "--chat-template-kwargs") { CHECK_ARG std::string value = argv[i]; @@ -2246,6 +2250,7 @@ void gpt_params_print_usage(int /*argc*/, char ** argv, const gpt_params & param options.push_back({ "*", "-h, --help, --usage", "print usage and exit" }); options.push_back({ "*", " --version", "show version and build info" }); options.push_back({ "*", "-v, --verbose", "print verbose information" }); + options.push_back({ "*", " --minilog", "print important information" }); options.push_back({ "*", " --verbosity N", "set specific verbosity level (default: %d)", params.verbosity }); options.push_back({ "*", " --verbose-prompt", "print a verbose prompt before generation (default: %s)", params.verbose_prompt ? "true" : "false" }); options.push_back({ "*", "-dr, --dry-run", "skip loading tensors in the files"}); @@ -2374,6 +2379,9 @@ void gpt_params_print_usage(int /*argc*/, char ** argv, const gpt_params & param "if suffix/prefix are specified, template will be disabled\n" "only commonly used templates are accepted:\n" "https://github.com/ggerganov/llama.cpp/wiki/Templates-supported-by-llama_chat_apply_template" }); + options.push_back({ "main", " --peg", + "use peg parser for qwen3.5 models.\n" + "https://github.com/ikawrakow/ik_llama.cpp/pull/1490" }); options.push_back({ "main", " --chat-template JINJA_TEMPLATE", "use jinja template for chat (default: disabled)\n" }); options.push_back({ "main", " --chat-template-file file_with_JINJA_TEMPLATE", diff --git a/common/common.h b/common/common.h index aa189a69..7d0ea30a 100644 --- a/common/common.h +++ b/common/common.h @@ -392,6 +392,7 @@ struct gpt_params { std::string public_path = ""; std::string chat_template = ""; bool use_jinja = false; // NOLINT + bool use_peg = false; std::string system_prompt = ""; bool enable_chat_template = true; common_reasoning_format reasoning_format = COMMON_REASONING_FORMAT_DEEPSEEK; diff --git a/examples/server/server-common.cpp b/examples/server/server-common.cpp index 6932921f..b1549449 100644 --- a/examples/server/server-common.cpp +++ b/examples/server/server-common.cpp @@ -784,6 +784,7 @@ json oaicompat_chat_params_parse( inputs.parallel_tool_calls = json_value(body, "parallel_tool_calls", false); inputs.add_generation_prompt = json_value(body, "add_generation_prompt", true); inputs.reasoning_format = opt.reasoning_format; + inputs.use_peg = opt.use_peg; if (body.contains("reasoning_format")) { inputs.reasoning_format = common_reasoning_format_from_name(body.at("reasoning_format").get()); } diff --git a/examples/server/server-common.h b/examples/server/server-common.h index 1eab9294..4d451d8c 100644 --- a/examples/server/server-common.h +++ b/examples/server/server-common.h @@ -245,6 +245,7 @@ json oaicompat_chat_params_parse(const json& body); struct server_chat_params { bool use_jinja; + bool use_peg; bool prefill_assistant; common_reasoning_format reasoning_format; std::map chat_template_kwargs; diff --git a/examples/server/server-context.cpp b/examples/server/server-context.cpp index 8e26f71c..1a4945d8 100644 --- a/examples/server/server-context.cpp +++ b/examples/server/server-context.cpp @@ -314,6 +314,7 @@ void server_context::init() { chat_params = { /* use_jinja */ params_base.use_jinja, + /* use_peg */ params_base.use_peg, /* prefill_assistant */ params_base.prefill_assistant, /* reasoning_format */ params_base.reasoning_format, /* chat_template_kwargs */ params_base.default_template_kwargs,