Skip to content

[Rust Frontend] Fix macro-based content format detection - #49042

Merged
BugenZhao merged 1 commit into
vllm-project:mainfrom
reidliu41:fix/qwen35-content-format-detection
Jul 20, 2026
Merged

[Rust Frontend] Fix macro-based content format detection#49042
BugenZhao merged 1 commit into
vllm-project:mainfrom
reidliu41:fix/qwen35-content-format-detection

Conversation

@reidliu41

@reidliu41 reidliu41 commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Purpose

The Rust chat template detector only recognized loops directly over
message.content. It missed templates that pass the content into a macro and
iterate with {% for item in content %}.

Qwen3.5 uses the macro form, causing auto mode to incorrectly select the
string content format. Multimodal messages consequently lost the
<|vision_start|> and <|vision_end|> wrappers around <|image_pad|>, which
could produce incorrect prompt tokens and multimodal positions.

Recognize loops over a content parameter while preserving the existing
direct message.content detection. Add regression coverage using both a
minimal macro template and the repository's Qwen3.5 template.

The corrected auto-detection matches the explicit OpenAI content format and
the corresponding Python detector behavior.

Test Plan

  cargo nextest run \
    -p vllm-chat \
    -E 'test(detects_openai_template_with_content_parameter_loop) | test(qwen35_template_auto_detects_openai_multimodal_content)'

Test Result


Essential Elements of an Effective PR Description Checklist
  • The purpose of the PR, such as "Fix some issue (link existing issues this PR will resolve)".
  • The test plan, such as providing test command.
  • The test results, such as pasting the results comparison before and after, or e2e results
  • (Optional) The necessary documentation update, such as updating supported_models.md and examples for a new model.

Signed-off-by: reidliu41 <reid201711@gmail.com>
@mergify mergify Bot added the rust label Jul 18, 2026
@reidliu41
reidliu41 marked this pull request as ready for review July 18, 2026 15:39

@claude claude 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.

Claude Code Review

This pull request is from a fork — automated review is disabled. A repository maintainer can comment @claude review to run a one-time review.

@BugenZhao

Copy link
Copy Markdown
Member

@codex review

@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: 9a21df1386

ℹ️ 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".

&& message_varnames
.iter()
.any(|varname| is_var_or_elems_access(&loop_ast.iter, varname, Some("content")))
&& (is_var_access(&loop_ast.iter, "content")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Restrict bare content loops to message-fed macro parameters

This condition treats every loop over a variable named content anywhere in the template as evidence that message content uses OpenAI parts, without checking that the variable is a macro parameter receiving message.content (or is related to messages at all). For example, an unused helper macro or {% set content = documents %}{% for item in content %} now switches auto detection to OpenAi; to_template_content then passes every message body as an array rather than the string the template expects, producing incorrect prompts or render failures. Track the macro call/argument relationship instead of matching the variable name globally.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I took another look at the Python implementation and confirmed that it does not perform additional detection or trace macro call/argument relationships.
While such tracking could make the detection more precise, it would require broader AST analysis
and additional coverage for argument mapping, scoping, and related edge cases to avoid introducing new false negatives.
Given the added complexity and the current Python behavior, I think keeping the Rust implementation aligned with Python may be the better trade-off for now.

@BugenZhao BugenZhao left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for the fix.

I think in a longer term, we probably want to switch a more robust and less heuristic approach for detecting the format. For example, instead of doing static analysis on the template content, we can probe the desired behavior by seeding different inputs, like https://github.com/ai-dynamo/dynamo/blob/fa4916d7e8a5b192f7d6db71b934bec0330812be/lib/llm/src/preprocessor/prompt/template/formatters.rs#L15-L38

@BugenZhao BugenZhao added the ready ONLY add when PR is ready to merge/full CI is needed label Jul 20, 2026
@BugenZhao
BugenZhao enabled auto-merge (squash) July 20, 2026 09:07
@BugenZhao
BugenZhao merged commit 818cf61 into vllm-project:main Jul 20, 2026
31 checks passed
ArjunPakhan pushed a commit to ArjunPakhan/vllm that referenced this pull request Jul 21, 2026
aarushjain29 pushed a commit to ROCm/vllm that referenced this pull request Jul 21, 2026
…t#49042)

Signed-off-by: reidliu41 <reid201711@gmail.com>
Signed-off-by: aarushjain29 <Aarushi.Jain2@amd.com>
Tejas-Raj01 pushed a commit to Tejas-Raj01/vllm that referenced this pull request Jul 22, 2026
…t#49042)

Signed-off-by: reidliu41 <reid201711@gmail.com>
Signed-off-by: Tejas-Raj01 <rajtejas.xyz@gmail.com>
edwinlim0919 pushed a commit to chaeminlim-mb/vllm that referenced this pull request Jul 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready ONLY add when PR is ready to merge/full CI is needed rust

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants