Skip to content

fix: map GGUF architecture to built-in chat template when embedded is missing - #9440

Closed
mvanhorn wants to merge 1 commit into
aaif-goose:mainfrom
mvanhorn:fix/9110-goose-local-inference-gemma4-chat-template-fallback
Closed

fix: map GGUF architecture to built-in chat template when embedded is missing#9440
mvanhorn wants to merge 1 commit into
aaif-goose:mainfrom
mvanhorn:fix/9110-goose-local-inference-gemma4-chat-template-fallback

Conversation

@mvanhorn

Copy link
Copy Markdown
Contributor

Summary

Maps the GGUF model architecture metadata to a built-in chat template when the model does not ship an embedded template, instead of unconditionally using chatml. gemma/llama/qwen/phi families now get an architecture-appropriate fallback with a specific warning level per case.

Why this matters

Issue #9110 reported that local-inference models without an embedded chat template silently defaulted to chatml, which produces wrong outputs for gemma/llama families. The old llamacpp path issued warn!("Model has no embedded chat template, falling back to chatml") and continued. For a Gemma-family model that is the wrong template; the response degrades badly.

Changes

  • New select_chat_template() in local_inference.rs returns either Embedded(t) when the embedded template is present or BuiltIn(BuiltInChatTemplateFallback) when it is not
  • Architecture-aware fallback table: gemma/gemma2/gemma3 -> "gemma" (info), gemma4 -> "gemma" with Gemma4Unsupported warning, llama/llama2 -> "llama2", llama3 -> "llama3", qwen2 -> "chatml", phi3 -> "phi3"
  • Unknown architecture -> "chatml" with UnknownArchitecture warning
  • Missing or whitespace-only architecture -> "chatml" with MissingArchitecture warning
  • Architecture matching is case + whitespace insensitive; original-cased name preserved for the log
  • LlamaCppBackend::load reads the model arch via meta_val_str("general.architecture") and routes through select_chat_template
  • log_chat_template_fallback emits info vs warn based on the fallback variant

Testing

cargo test --features local-inference -p goose --lib local_inference_tests -- 6/6 pass:

  • embedded template used unchanged
  • 8 known architectures fall back to expected templates with KnownArchitecture warning
  • LLaMa3 fallback is case + whitespace insensitive (case preserved in result)
  • unknown arch -> chatml + warn
  • gemma4 -> gemma + Gemma4Unsupported warn
  • missing/empty/whitespace arch -> chatml + MissingArchitecture warn

Fixes #9110

@mvanhorn
mvanhorn force-pushed the fix/9110-goose-local-inference-gemma4-chat-template-fallback branch from 0d4757c to 9187455 Compare May 27, 2026 05:19

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0d4757cb16

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Some(("gemma", ChatTemplateFallbackWarning::KnownArchitecture))
}
"gemma4" => Some(("gemma", ChatTemplateFallbackWarning::Gemma4Unsupported)),
"llama" | "llama2" => Some(("llama2", ChatTemplateFallbackWarning::KnownArchitecture)),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid treating every llama GGUF as Llama 2

When a GGUF is missing tokenizer.chat_template, this maps the general.architecture value llama to the Llama 2 template, but that metadata value is shared by newer Llama-family GGUFs as well (the local provider’s default model is Llama 3.2). In that fallback path, Llama 3.x models without an embedded template will be prompted with [INST]...[/INST] instead of the Llama 3 header/eot format, leading to malformed prompts and poor or broken responses; the fallback needs more specific model metadata/name handling before choosing llama2.

Useful? React with 👍 / 👎.

@mvanhorn
mvanhorn force-pushed the fix/9110-goose-local-inference-gemma4-chat-template-fallback branch from 9187455 to 3a663d2 Compare May 27, 2026 13:50
@jh-block

Copy link
Copy Markdown
Collaborator

Thanks very much for the work here. For now we have gone a slightly different path (#9442), I wrote a bit about the reasoning in #9110 (comment) — very open to discussion on this as I know the stricter path may make some GGUF conversions (that lack embedded chat templates) a little harder to use, but at least there is an escape hatch for using them now.

@jh-block jh-block closed this May 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Gemma-4 Chat Template Support Issue

2 participants