Skip to content

Conversation

@dtransposed
Copy link
Contributor

@dtransposed dtransposed commented Aug 29, 2025

Bug description 🐛

Right now, BaseIncrementalDetokenizer can stop generation in two separate cases:

  1. EOS token found
    If <eos> appears in new_token_ids and stop_terminated=True, we hit the check at line 124 → and eventually return None.

  2. Stop string found
    Otherwise, we use StopChecker to look for stop strings inside the decoded text from new_token_ids → and eventually return stop_string.

The missing case

We don’t handle the situation where both conditions happen at once:

  • new_token_ids contain an <eos> token and
  • the decoded text also matches a stop string.

In this case, the current code only respects the EOS path and skips the stop string check.

The fix

We should:

  1. Always run StopChecker first (to handle stop strings properly).
  2. Then apply EOS termination (stop_terminated).

By swapping the order, stop strings take priority over EOS, which produces the expected behavior.

… test

Signed-off-by: dtransposed <damian.bogunowicz@gmail.com>
@mergify mergify bot added the v1 label Aug 29, 2025
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request addresses a bug where stop strings were ignored if an EOS token was present in the same batch of tokens. The proposed fix correctly reorders the logic to prioritize stop string evaluation before handling EOS token termination. The change is simple, effective, and accompanied by a new, thorough unit test that validates the corrected behavior for both including and excluding the stop string in the output. The fix appears correct and complete.

@njhill
Copy link
Member

njhill commented Aug 29, 2025

@dtransposed presumably you're talking about the spec decoding case?

What about when the eos token occurs in new_token_ids prior to the stop string?

@dtransposed
Copy link
Contributor Author

dtransposed commented Aug 29, 2025

@dtransposed presumably you're talking about the spec decoding case?

What about when the eos token occurs in new_token_ids prior to the stop string?

Yes, this is precisely how i stumbled upon this edge case - when I tested a very efficient speculator.

Is it possible though for detokenizer to see new_token_ids such that there are any tokens past <eos> token?
I thought that EngineCoreOutput.new_token_ids will never go past <eos> token here: https://github.com/vllm-project/vllm/blob/main/vllm/v1/engine/output_processor.py#L352 (this is the method where the detokenization is being used).

@dtransposed
Copy link
Contributor Author

@njhill Could I ask you for further review please?

Copy link
Member

@njhill njhill left a comment

Choose a reason for hiding this comment

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

Thanks @dtransposed yes I see what you mean.

Please see inline comment and then we can merge this.

Signed-off-by: dtransposed <damian.bogunowicz@gmail.com>
@dtransposed dtransposed requested a review from njhill September 8, 2025 08:07
Copy link
Member

@njhill njhill left a comment

Choose a reason for hiding this comment

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

Thanks @dtransposed!

@njhill njhill added the ready ONLY add when PR is ready to merge/full CI is needed label Sep 8, 2025
@njhill njhill enabled auto-merge (squash) September 8, 2025 17:02
@dtransposed
Copy link
Contributor Author

@njhill. Could you take a look at the failing tests? They seems orthogonal to the PR logic. If it looks good to you can I ask you to update the branch and force merge?

@vllm-bot vllm-bot merged commit 922d3b4 into vllm-project:main Sep 9, 2025
36 of 38 checks passed
eicherseiji pushed a commit to eicherseiji/vllm that referenced this pull request Sep 9, 2025
…ontain both `stop` str and `eos` token (vllm-project#23938)

Signed-off-by: dtransposed <damian.bogunowicz@gmail.com>
skyloevil pushed a commit to skyloevil/vllm that referenced this pull request Sep 13, 2025
…ontain both `stop` str and `eos` token (vllm-project#23938)

Signed-off-by: dtransposed <damian.bogunowicz@gmail.com>
FeiDaLI pushed a commit to FeiDaLI/vllm that referenced this pull request Sep 25, 2025
…ontain both `stop` str and `eos` token (vllm-project#23938)

Signed-off-by: dtransposed <damian.bogunowicz@gmail.com>
xuebwang-amd pushed a commit to xuebwang-amd/vllm that referenced this pull request Oct 10, 2025
…ontain both `stop` str and `eos` token (vllm-project#23938)

Signed-off-by: dtransposed <damian.bogunowicz@gmail.com>
Signed-off-by: xuebwang-amd <xuebwang@amd.com>
xuebwang-amd pushed a commit to xuebwang-amd/vllm that referenced this pull request Oct 24, 2025
…ontain both `stop` str and `eos` token (vllm-project#23938)

Signed-off-by: dtransposed <damian.bogunowicz@gmail.com>
Signed-off-by: xuebwang-amd <xuebwang@amd.com>
ppetrovicTT pushed a commit to tenstorrent/vllm that referenced this pull request Oct 27, 2025
…ontain both `stop` str and `eos` token (vllm-project#23938)

Signed-off-by: dtransposed <damian.bogunowicz@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

force-merge ready ONLY add when PR is ready to merge/full CI is needed v1

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants