Skip to content

[Bugfix][KV Offload] Release pending CPU lookup pins on cache reset - #59862

Merged
ivanium merged 2 commits into
vllm-project:mainfrom
zupengwang:fix-simplecpu-reset-lookup-pins
Oct 4, 2026
Merged

ivanium merged 2 commits into
vllm-project:mainfrom
zupengwang:fix-simplecpu-reset-lookup-pins

Conversation

@zupengwang

@zupengwang zupengwang commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Overview

Release SimpleCPUOffload lookup-only CPU block references during cache reset. A request waiting for GPU allocation can otherwise prevent reset_prefix_cache(reset_connector=True) from succeeding even after GPU blocks and in-flight transfers have drained.

Claims

  • Reset releases temporary CPU lookup pins and invalidates their saved lookup state.
  • Existing in-flight DMA references remain protected until completion.
  • A deterministic regression covers eager/lazy modes and one/two cache groups.

Validation

Validated against upstream 5f30fc7031cae49bf51073fc953d419b08f8887c, using its matching precompiled native extensions.

Check Unpatched + regression Patched
New reset regression 4 assertion failures (reset() returns False) 4 pass within the full scheduler suite
Scheduler, KV events, connector and metrics suites — 92 passed
CUDA worker suite, RTX 4090 — 21 passed
Real Scheduler allocation-pressure diagnostic Reset fails after GPU blocks are released Reset succeeds; retry has no stale CPU hit
Qwen2.5-0.5B-Instruct GPU diagnostic 16 lookup references prevent reset References released; reset and subsequent generation pass
.venv/bin/python -m pytest -q tests/v1/simple_kv_offload/test_scheduler.py -k test_reset_releases_pending_cpu_hits
.venv/bin/python -m pytest -q \
  tests/v1/simple_kv_offload/test_scheduler.py \
  tests/v1/simple_kv_offload/test_kv_events.py \
  tests/v1/kv_connector/unit/test_simple_cpu_offload_connector.py \
  tests/v1/kv_connector/unit/test_simple_cpu_offload_metrics.py
.venv/bin/python -m pytest -q tests/v1/simple_kv_offload/test_worker.py
pre-commit run --files vllm/v1/simple_kv_offload/manager.py tests/v1/simple_kv_offload/test_scheduler.py
pre-commit run mypy-3.12 --hook-stage manual --files vllm/v1/simple_kv_offload/manager.py tests/v1/simple_kv_offload/test_scheduler.py

All applicable changed-file hooks, mypy 3.10/3.12 and git diff --check passed. The existing Buildkite KV Offload suite collects the new test; test tethering passed. Upstream CI has not run for this candidate.

The GPU diagnostic used MRV2, FP16, TP=1, eager execution and 128 MiB each of GPU/CPU KV cache. After a real CPU store/load round trip with 256 cached tokens, it explicitly paused a queued request after the production CPU lookup. Baseline reset returned False; the patch released all 16 lookup pins, reset successfully and generated the same token [19] with zero cached tokens. Actual allocation pressure is covered separately by the real Scheduler diagnostic, whose worker token output is synthetic. This is a focused correctness check, not a performance or broad model-quality claim. Multi-node, disk/GDS and other GPU backends were not validated.

Details

get_num_new_matched_tokens() pins matching CPU blocks until update_state_after_alloc() consumes the lookup. Failed GPU allocation leaves that lookup in _pending_cpu_hits. Reset already abandons transfers safely but omitted these pre-allocation references.

Reuse _free_pending_cpu_hit() before clearing the pending lookup map. These references have no associated worker DMA; submitted transfers retain their separate pins and existing completion-based cleanup. A waiting request performs a fresh lookup when scheduling resumes. No API, storage format or normal scheduling policy changes are introduced.

Duplicate screening on 2026-10-03 covered open/closed/merged PRs, related issues, recent commits and the contributor's existing PRs. #42289 introduced temporary lookup pins; #39726 introduced reset support. Both are merged. The active #57816 addresses eager-store placement after MRV2 preemption, a different state transition. No active implementation of this lookup-pin reset fix was found. This draft does not claim to close an existing issue.

AI assistance: OpenAI Codex performed investigation, implementation, local/remote validation and drafting. The human contributor has confirmed review of the final change and authorized submission. The reported validation was performed with Codex; independent human reruns have not been confirmed.


Pull Request Checklist
  • I used vLLM's /pr-checklist skill. (Mandatory for agents, optional for humans).

  • AI assistance was used during the creation of this PR.

  • Design Fit: Minimizes impact on core components, reuses existing functionality, and justifies added complexity.

  • Testing and Validation: Validates the change and ensures any added tests are meaningful and reliable, with CI coverage or documented CI resource constraints and validation performed outside CI.

  • Code Quality and Style: Keeps code and comments clear and concise, and updates relevant documentation and examples.

  • Pull Request Contents: Includes a brief summary and relevant links, supports claims with evidence, explains root causes and implementation trade-offs, and follows the contributing guide.

Release lookup-only CPU block references before resetting the cache.
Cover reset before GPU allocation in eager/lazy and single/multi-group cases.

Co-authored-by: OpenAI Codex
Signed-off-by: Wang Zupeng <zupenwang@gmail.com>
@mergify mergify Bot added the bug Something isn't working label Oct 3, 2026
@zupengwang
zupengwang marked this pull request as ready for review October 3, 2026 09:31
@zupengwang
zupengwang requested a review from ivanium as a code owner October 3, 2026 09:31

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

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

LGTM. Thanks for the fix!

@ivanium ivanium added the ready ONLY add when PR is ready to merge/full CI is needed label Oct 4, 2026
@ivanium

ivanium commented Oct 4, 2026

Copy link
Copy Markdown
Contributor

/ci run

@ivanium
ivanium enabled auto-merge (squash) October 4, 2026 02:54
@github-actions

github-actions Bot commented Oct 4, 2026

Copy link
Copy Markdown

✅ @zupengwang, CI is now available for this PR.

  • /ci run starts upstream CI; /amd-ci run starts AMD CI only.
  • Your branch must contain every commit currently on its upstream target branch. Merge or rebase onto the latest target branch, then rerun the command. Append --allow-stale to a run command to test an outdated branch at your own risk.
  • /ci retry retries failed jobs in the CI build for the current PR head. If the current head has no CI build, it starts a new CI build for the current head containing only jobs that failed in the latest earlier CI build for this PR.
  • /amd-ci retry retries failed jobs in AMD CI for the current PR head. Use /amd-ci run when the current head has no AMD CI build.
  • /ci cancel cancels scheduled or running CI builds for this PR branch; /amd-ci cancel does the same for AMD CI only.

@github-actions

github-actions Bot commented Oct 4, 2026

Copy link
Copy Markdown

✅ Triggered Buildkite CI #92778 for commit 999cff2c9bf6.

@vllm-agent

Copy link
Copy Markdown
Collaborator

CI selector (shadow): 3 test steps (6 jobs) instead of 62 (79 jobs)

Shadow mode: this changes nothing about what CI runs. It shows what the evidence-based selector would pick for this PR, next to today's rules. How it works.

Feedback welcome: reply here if it would skip a step this change needs, or runs something unrelated.

steps (jobs) Today's rules Selector Would skip Would add
NVIDIA, CPU and others 62 (79) 3 (6) 59 (73) 0 (0)
AMD mirrors 53 (64) 2 (5) 51 (59) 0 (0)
Selector would run (3)
  • v1-kv-connectors ×4
  • v1-kv-offload
  • v1-others-cpu
Would skip (today's rules run them) (59)
  • ascend-npu-test
  • async-engine-inputs-utils-worker
  • basic-correctness ×2
  • basic-correctness-cpu-offload
  • basic-correctness-cumem
  • basic-correctness-prefetch-offload
  • basic-correctness-sleep-mode
  • basic-models-test-other-cpu
  • basic-models-tests-initialization
  • basic-models-tests-other
  • benchmarks-cli-test
  • cpu-language-generation-and-pooling-model-tests ×3
  • cpu-multimodal-config
  • cpu-params-env-tokenizers-parser
  • cpu-reasoning-renderers
  • cpu-tool-parsers
  • e2e-core-1-gpu
  • e2e-core-large-memory
  • e2e-scheduling-1-gpu
  • e2e-scheduling-accuracy-1-gpu
  • entrypoints-integration-api-server ×4
  • entrypoints-integration-api-server-generate
  • entrypoints-integration-api-server-openai-chat_completion
  • entrypoints-integration-api-server-openai-completion
  • entrypoints-integration-llm
  • entrypoints-integration-multimodal
  • entrypoints-integration-pooling
  • entrypoints-integration-responses-api
  • entrypoints-integration-speech_to_text
  • kernels-fla-ops-test-b200
  • kernels-mhc-test-b200
  • kernels-root-misc-test-b200
  • kimi-k3-prefix-cache-4xb200 ×2
  • kv-offload-large
  • kv-offload-medium
  • kv-offload-small
  • language-models-tests-granite-l4-compatibility
  • language-models-tests-hybrid ×2
  • language-models-tests-standard
  • metrics-tracing-2-gpus
  • multi-modal-models-standard-1-qwen2
  • multi-modal-models-standard-2-qwen3-gemma
  • multi-modal-models-standard-3-llava-qwen2-vl
  • multi-modal-models-standard-4-other-whisper
  • multi-modal-processor ×4
  • multi-modal-processor-cpu ×4
  • pytorch-compilation-dynamic-shapes
  • pytorch-compilation-passes-unit-tests
  • pytorch-compilation-unit-tests
  • pytorch-compilation-unit-tests-h100
  • pytorch-fullgraph-cudagraph-l4-compatibility
  • pytorch-fullgraph-test
  • regression
  • v1-core
  • v1-executor-worker
  • v1-logits-oracle
  • v1-metrics-lmeval
  • v1-sample
  • v1-spec-decode
Would add (today's rules do not run them) (0)

none

AMD mirrors: would skip (51)
  • async-engine-inputs-utils-worker
  • basic-correctness ×2
  • basic-correctness-cpu-offload
  • basic-correctness-cumem
  • basic-correctness-prefetch-offload
  • basic-correctness-sleep-mode
  • basic-models-tests-initialization
  • basic-models-tests-other
  • benchmarks-cli-test
  • e2e-core-1-gpu
  • e2e-core-large-memory
  • e2e-scheduling-1-gpu
  • e2e-scheduling-accuracy-1-gpu
  • entrypoints-integration-api-server ×4
  • entrypoints-integration-api-server-generate
  • entrypoints-integration-api-server-openai-chat_completion
  • entrypoints-integration-api-server-openai-completion
  • entrypoints-integration-llm
  • entrypoints-integration-multimodal
  • entrypoints-integration-pooling
  • entrypoints-integration-responses-api
  • entrypoints-integration-speech_to_text
  • kernels-fla-ops-test-b200
  • kernels-mhc-test-b200
  • kernels-root-misc-test-b200
  • kv-offload-large
  • kv-offload-medium
  • kv-offload-small
  • language-models-tests-granite-l4-compatibility
  • language-models-tests-hybrid ×2
  • language-models-tests-standard
  • metrics-tracing-2-gpus
  • multi-modal-models-standard-1-qwen2
  • multi-modal-models-standard-2-qwen3-gemma
  • multi-modal-models-standard-3-llava-qwen2-vl
  • multi-modal-models-standard-4-other-whisper
  • multi-modal-processor ×4
  • platform-tests
  • pytorch-compilation-dynamic-shapes
  • pytorch-compilation-passes-unit-tests
  • pytorch-compilation-unit-tests
  • pytorch-compilation-unit-tests-h100
  • pytorch-fullgraph-cudagraph-l4-compatibility
  • pytorch-fullgraph-test
  • regression
  • v1-core
  • v1-executor-worker
  • v1-logits-oracle
  • v1-metrics-lmeval
  • v1-sample
  • v1-spec-decode
AMD mirrors: would add (0)

none

2 changed files · base ce49174247 · head 999cff2c9b · Python record: build 92769 at 84bcbc6264 · kernel record: table 84bcbc6 (build 92769), map 84bcbc6 · not counted: 10 build steps, 5 A100 steps the generator no longer emits, 7 optional steps the selector would also run

@ivanium
ivanium merged commit 18f8f96 into vllm-project:main Oct 4, 2026
145 checks passed
michael-gpu pushed a commit to practical-inference/vllm-ampere-extended that referenced this pull request Oct 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working ready ONLY add when PR is ready to merge/full CI is needed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants