common : enable reasoning budget sampler for gemma4 (#21697)
* fix: enable reasoning budget sampler for gemma4 Add thinking_start_tag and thinking_end_tag to common_chat_params_init_gemma4(). Without these, the reasoning budget sampler never activates for gemma4. Make the newline after "thought" optional in the PEG parser to handle budget=0 (sampler forces end tag before the newline). Add test case for empty thinking block. Fixes #21487 * use p.space() instead of p.optional(p.literal("\n")) in gemma4 thought parser
This commit is contained in:
+5
-3
@@ -1083,7 +1083,9 @@ static common_chat_params common_chat_params_init_gemma4(const common_chat_templ
|
|||||||
|
|
||||||
data.prompt = common_chat_template_direct_apply_impl(tmpl, inputs);
|
data.prompt = common_chat_template_direct_apply_impl(tmpl, inputs);
|
||||||
data.format = COMMON_CHAT_FORMAT_PEG_GEMMA4;
|
data.format = COMMON_CHAT_FORMAT_PEG_GEMMA4;
|
||||||
data.supports_thinking = true;
|
data.supports_thinking = true;
|
||||||
|
data.thinking_start_tag = "<|channel>thought";
|
||||||
|
data.thinking_end_tag = "<channel|>";
|
||||||
|
|
||||||
data.preserved_tokens = {
|
data.preserved_tokens = {
|
||||||
"<|channel>",
|
"<|channel>",
|
||||||
@@ -1102,9 +1104,9 @@ static common_chat_params common_chat_params_init_gemma4(const common_chat_templ
|
|||||||
auto start = p.rule("start", p.prefix(inputs.generation_prompt, "<|channel>"));
|
auto start = p.rule("start", p.prefix(inputs.generation_prompt, "<|channel>"));
|
||||||
|
|
||||||
if (extract_reasoning) {
|
if (extract_reasoning) {
|
||||||
p.rule("thought", p.literal("<|channel>thought\n") + p.reasoning(p.until("<channel|>")) + p.literal("<channel|>"));
|
p.rule("thought", p.literal("<|channel>thought") + p.space() + p.reasoning(p.until("<channel|>")) + p.literal("<channel|>"));
|
||||||
} else {
|
} else {
|
||||||
p.rule("thought", p.content(p.literal("<|channel>thought\n") + p.until("<channel|>") + p.literal("<channel|>")));
|
p.rule("thought", p.content(p.literal("<|channel>thought") + p.space() + p.until("<channel|>") + p.literal("<channel|>")));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto thought = (p.peek(p.literal("<|channel>")) + p.ref("thought")) | p.negate(p.literal("<|channel>"));
|
auto thought = (p.peek(p.literal("<|channel>")) + p.ref("thought")) | p.negate(p.literal("<|channel>"));
|
||||||
|
|||||||
@@ -1988,6 +1988,13 @@ static void test_template_output_peg_parsers(bool detailed_debug) {
|
|||||||
.expect(message_assist_thoughts)
|
.expect(message_assist_thoughts)
|
||||||
.run();
|
.run();
|
||||||
|
|
||||||
|
// Empty reasoning (budget=0: sampler forces end tag before newline)
|
||||||
|
tst.test(
|
||||||
|
"<|channel>thought<channel|>Hello, world!\nWhat's up?")
|
||||||
|
.reasoning_format(COMMON_REASONING_FORMAT_AUTO)
|
||||||
|
.expect(simple_assist_msg("Hello, world!\nWhat's up?", ""))
|
||||||
|
.run();
|
||||||
|
|
||||||
// Reasoning and content with reasoning_format = none
|
// Reasoning and content with reasoning_format = none
|
||||||
tst.test(
|
tst.test(
|
||||||
"<|channel>thought\nI'm\nthinking<channel|>Hello, world!\nWhat's up?")
|
"<|channel>thought\nI'm\nthinking<channel|>Hello, world!\nWhat's up?")
|
||||||
|
|||||||
Reference in New Issue
Block a user