Skip to content

Fix the order of _free_encoder_inputs - #38907

Merged
ywang96 merged 11 commits into
vllm-project:mainfrom
gty111:fix_encoder_free
Apr 11, 2026
Merged

ywang96 merged 11 commits into
vllm-project:mainfrom
gty111:fix_encoder_free

Conversation

@gty111

@gty111 gty111 commented Apr 3, 2026 •

Copy link
Copy Markdown
Collaborator

Purpose

#38551

Clipboard_Screenshot_1775212606

freeable can be triggered before fetch due to an inconsistency in how num_computed_tokens is updated.

After a request is scheduled, the scheduler immediately updates the token counter:

request.num_computed_tokens += num_scheduled_tokens

However, at this point the GPU has not actually finished computing those tokens yet. Some of these tokens are still in the scheduling pipeline and have not been executed.

Later, in _free_encoder_inputs, the logic uses the updated num_computed_tokens to determine whether the encoder inputs are freeable. Since the counter already includes tokens that are only scheduled (but not yet computed), the condition may incorrectly evaluate to true.

As a result, encoder inputs may be marked as freeable too early, even though the corresponding GPU computation has not completed.

Test Plan

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.
  • (Optional) Release notes update. If your change is user facing, please update the release notes draft in the Google Doc.

Signed-off-by: Tianyu Guo <guoty9@mail2.sysu.edu.cn>
Signed-off-by: Tianyu Guo <guoty9@mail2.sysu.edu.cn>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR addresses a scheduler/model-runner ordering issue where encoder inputs could be marked freeable (and subsequently evicted) based on scheduled tokens rather than actually processed tokens, leading to encoder cache misses under high concurrency in multimodal + speculative decoding workloads.

Changes:

  • Reorders Scheduler._update_after_schedule so _free_encoder_inputs runs before request.num_computed_tokens is advanced for newly scheduled tokens.
  • Adds several debug print(...) statements across scheduler, encoder cache manager, and GPU model runner paths (currently not gated).

Reviewed changes

Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.

File Description
vllm/v1/core/sched/scheduler.py Calls _free_encoder_inputs before advancing num_computed_tokens to prevent premature encoder-input freeing.
vllm/v1/worker/gpu_model_runner.py Adds stdout debug prints around freeing/fetching encoder cache entries.
vllm/v1/core/encoder_cache_manager.py Adds stdout debug prints when items become freeable/are evicted.
Comments suppressed due to low confidence (1)

vllm/v1/core/sched/scheduler.py:1659

  • Remove the debug print here (or gate it behind the project's logger at an appropriate level). This runs in the scheduling hot path and will spam stdout / degrade performance under concurrency.
            start_pos = mm_feature.mm_position.offset
            num_tokens = mm_feature.mm_position.length
            if self.is_encoder_decoder and request.num_computed_tokens > 0:
                # With Whisper, as soon as we've generated a single token,

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 989 to +1004
for req_id, num_scheduled_token in num_scheduled_tokens.items():
request = self.requests[req_id]
request.num_computed_tokens += num_scheduled_token
request.is_prefill_chunk = request.num_computed_tokens < (
request.num_tokens + request.num_output_placeholders
)
scheduler_output.has_structured_output_requests |= (
request.use_structured_output and not request.is_prefill_chunk
)

# NOTE: _free_encoder_inputs relies on num_computed_tokens, which
# may be updated again in _update_from_output for speculative
# decoding. However, it is safe to call the method here because
# encoder inputs are always part of the prompt, not the output,
# and thus are unaffected by speculative decoding.
if request.has_encoder_inputs:
self._free_encoder_inputs(request)
request.num_computed_tokens += num_scheduled_token
request.is_prefill_chunk = request.num_computed_tokens < (
request.num_tokens + request.num_output_placeholders
)
scheduler_output.has_structured_output_requests |= (
request.use_structured_output and not request.is_prefill_chunk
)

Copilot AI Apr 3, 2026

Copy link

Choose a reason for hiding this comment

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

This change fixes a subtle ordering bug between _free_encoder_inputs and num_computed_tokens advancement. Please add a focused unit/regression test (likely in tests/v1/core/test_scheduler.py) that reproduces the premature-free scenario (scheduled-but-not-computed tokens causing an encoder cache entry to become freeable/evictable) and verifies it no longer happens.

Copilot uses AI. Check for mistakes.

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

Copy link
Copy Markdown
Contributor

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 reorders the scheduler logic to call '_free_encoder_inputs' before updating the computed token count for a request. It also introduces several debug print statements across the cache manager, scheduler, and model runner. The review feedback identifies these print statements as items that should be removed before merging to avoid log clutter and potential performance impacts.

I am having trouble creating individual review comments. Click here to see my feedback.

vllm/v1/core/encoder_cache_manager.py (176)

high

Debug print statements should be removed before merging to production code to avoid cluttering logs and potential performance impact.

vllm/v1/core/encoder_cache_manager.py (242)

high

Debug print statements should be removed before merging to production code to avoid cluttering logs and potential performance impact.

vllm/v1/core/sched/scheduler.py (1658)

high

Debug print statements should be removed before merging to production code to avoid cluttering logs and potential performance impact.

vllm/v1/worker/gpu_model_runner.py (1082)

high

Debug print statements should be removed before merging to production code to avoid cluttering logs and potential performance impact.

vllm/v1/worker/gpu_model_runner.py (2952)

high

Debug print statements should be removed before merging to production code to avoid cluttering logs and potential performance impact.

@ywang96

ywang96 commented Apr 4, 2026

Copy link
Copy Markdown
Member

@claude review

@ywang96 ywang96 added the ready ONLY add when PR is ready to merge/full CI is needed label Apr 5, 2026

@ywang96 ywang96 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!

@ywang96
ywang96 enabled auto-merge (squash) April 5, 2026 09:20
auto-merge was automatically disabled April 7, 2026 03:37

Head branch was pushed to by a user without write access

@ywang96
ywang96 merged commit 8d0aabd into vllm-project:main Apr 11, 2026
50 of 52 checks passed
wojciech-wais pushed a commit to wojciech-wais/vllm that referenced this pull request Apr 13, 2026
Signed-off-by: Tianyu Guo <guoty9@mail2.sysu.edu.cn>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
whkuo269 pushed a commit to whkuo269/vllm that referenced this pull request Apr 23, 2026
Signed-off-by: Tianyu Guo <guoty9@mail2.sysu.edu.cn>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
avinashsingh77 pushed a commit to avinashsingh77/vllm that referenced this pull request Apr 27, 2026
Signed-off-by: Tianyu Guo <guoty9@mail2.sysu.edu.cn>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Signed-off-by: Avinash Singh <avinashsingh.rcoem@gmail.com>
mystous pushed a commit to mystous/vllm_hybrid that referenced this pull request May 10, 2026
Signed-off-by: Tianyu Guo <guoty9@mail2.sysu.edu.cn>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
my-other-github-account pushed a commit to my-other-github-account/vllm that referenced this pull request May 15, 2026
Signed-off-by: Tianyu Guo <guoty9@mail2.sysu.edu.cn>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
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 v1

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants