Skip to content

[KV Connector] Add ConnexConnector: P/D disaggregation that survives decode-instance failures - #63804

Open
yanyinglin wants to merge 1 commit into
vllm-project:mainfrom
yanyinglin:feat/connex-kv-connector
Open

yanyinglin wants to merge 1 commit into
vllm-project:mainfrom
yanyinglin:feat/connex-kv-connector

Conversation

@yanyinglin

@yanyinglin yanyinglin commented Oct 26, 2026 •

Copy link
Copy Markdown

Overview

Registers ConnexConnector, a pull-based P/D connector whose prefill-side KV stays available as a renewable hold, so a request whose decode instance dies can be resumed on another decode instance without a second prefill. The implementation ships in the optional connex-ai package (same pattern as LMCacheConnectorV1); vLLM gains no dependency and no code path changes for other connectors.

Not a duplicate: searched open PRs/issues for connex, P/D fault tolerance and elastic P/D connectors. #55151 ("[wip] support PD seperate mode for fault-tolerance", no description or code yet) targets fault tolerance in vLLM's own P/D path; this PR does not touch that path and adds an external connector with request-level resume. #59330 (stop P/D transfers at N-1) changes NIXL/Mooncake semantics for sliding-window models; ConnexConnector currently supports full-attention models only and follows the current N-token load.

Claims

  • New kv_connector="ConnexConnector": decode pulls prompt KV with one-sided RDMA reads (connex-rs over UCX with GPUDirect RDMA, or Mooncake Transfer Engine).
  • Killing a decode instance mid-run loses no requests: affected requests resume elsewhere by re-pulling the held KV (0 extra prefills, 0 tokens off the argmax).
  • Steady-state TTFT/TPOT/throughput on par with NixlConnector on the same setup.
  • A prefill instance dying during a transfer fails only the affected loads (under kv_load_failure_policy).

Validation

pytest tests/v1/kv_connector/unit/test_connex_connector.py -v   # needs connex-ai, otherwise skipped
pytest tests/v1/kv_connector/unit/test_config.py
pre-commit run --files <changed files>

On this branch (main d0d681e) with current connex-ai: test_connex_connector.py 2 passed, test_config.py 17 passed, pre-commit on changed files passes. connex-ai's own suite covers the connector and router (CPU, fake engines) and the transfer core.

CI coverage gap: the new tests importorskip connex-ai, which is not installed in vLLM CI, so CI will skip them; the validation above was run outside CI.

End-to-end runs were done on vLLM 0.32.0 (not re-run on d0d681e): 4x A40 on one host, ConnectX HDR, GPUDirect RDMA, Llama-3-8B, Connex PD router, prefill and decode on different GPUs.

  • Correctness, 1P1D, 48 prompts x 128 greedy tokens, teacher-forced against a non-disaggregated instance: 0 of 6,144 generated tokens off the argmax (> 0.5 nats) at concurrency 1 and 8. Exact-match differences (20 and 15 of 48) are at the level of the non-disaggregated instance against itself at different batch sizes (18 of 48).
  • Failures (240 requests, QPS 2, 1024-token prompts, 256 output tokens):
    • kill one of two decode instances: 240/240 complete, 9 resumed, all by re-pulling held KV (0 extra prefills), 0 off argmax, longest kill-to-next-token stall 0.63 s (3 runs, same outcome);
    • 2P2D, kill one decode and one prefill: 240/240, 11 resumes (11 re-pulls), 0 off argmax;
    • prefill killed while a transfer was pending (fault-injected, 3 runs): decode failed the load, router re-prefilled on the other prefill instance, all complete;
    • scaling a pool up and draining an instance under load: 240/240 complete.
Throughput/latency vs NixlConnector (1024-token prompts, 128 output tokens, same router and hosts)
connector load TTFT p50 / p99 (ms) TPOT p50 / p99 (ms) tok/s
ConnexConnector QPS 1 354 / 537 31 / 33 128
NixlConnector QPS 1 352 / 594 31 / 33 128
ConnexConnector QPS 4 471 / 1003 36 / 38 459
NixlConnector QPS 4 456 / 996 36 / 38 459
ConnexConnector QPS 6 734 / 2090 38 / 40 694
NixlConnector QPS 6 711 / 2018 38 / 40 694
ConnexConnector 32 clients 625 / 4939 38 / 38 639
NixlConnector 32 clients 573 / 4751 38 / 38 646

Details

Existing P/D connectors free the prefill blocks as soon as decode has read them, so once decoding starts the prompt KV exists in one place. If the decode instance dies (crash, preemption, spot scale-down), every in-flight request must be prefilled again or errors out.

ConnexConnector makes the prefill-side copy a hold: a lease named by a transfer id, renewed by every pull, released by the decode instance when the request finishes or dropped after retain_s (default 60 s). release: after_pull frees blocks after the first read like other connectors. To resume, a router resends the same kv_transfer_params with the prompt plus the k generated tokens; the new decode instance async-loads remote_num_tokens and computes the k tokens locally. Instances can register their P/D role with the Connex front-router so instances can be added or removed at run time.

Request flow:

  1. Prefill instance (kv_producer) runs the prompt; on finish the scheduler keeps the blocks and returns transfer_id, remote_ctrl, remote_num_tokens.
  2. Decode instance (kv_consumer) schedules the request as WAITING_FOR_REMOTE_KVS and pulls the blocks with one-sided reads.
  3. Decode generates; on finish it sends a release, and the prefill worker reports the transfer done so the blocks are freed.
  4. If decode dies before step 3, the router resends to another decode instance, which repeats step 2 against the still-held blocks.

Changes: v1/connex_connector.py (lazy re-export with install hint), registration in factory.py, docs/features/connex_connector_usage.md plus an entry in disagg_prefill.md, and scheduler-level tests through the real Scheduler.

Limitations: full-attention KV only; equal TP and block size on both sides.

Developed with AI coding assistance; all changes were reviewed and tested by the author.


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.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

…nt mobility

Register ConnexConnector, a pull-based P/D connector implemented in the
connex-ai package (optional dependency, imported lazily). The decode
instance reads prompt KV with one-sided RDMA reads (connex-rs over UCX with
GPUDirect, or Mooncake Transfer Engine); the prefill instance keeps the
blocks as a renewable hold until the decode instance releases them, so a
request whose decode instance fails can be resumed elsewhere without a
second prefill.

Adds the registration, a usage page, the disagg_prefill.md entry and
scheduler-level tests (skipped without connex-ai).

Signed-off-by: yanyinglin <linyanying19@mails.ucas.ac.cn>
Copilot AI balanced review requested due to automatic review settings October 26, 2026 18:06

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

@github-actions

Copy link
Copy Markdown

👋 Hi! Thank you for contributing to the vLLM project.

💬 Join our developer Slack at https://slack.vllm.ai to discuss your PR in #pr-reviews, coordinate on features in #feat- channels, or join special interest groups in #sig- channels.

PRs do not trigger a full CI run by default. Reviewers with write access and configured trusted contributors can comment /ci run for upstream CI or /amd-ci run for AMD CI only whenever CI signals are needed.

Once the PR is approved or has the ready label, the PR author can also use the corresponding /ci run, /ci retry, and /ci cancel commands, or their /amd-ci variants. New commits do not start upstream CI automatically.

If you have any questions, please reach out to us on Slack at https://slack.vllm.ai.

Agent Guidelines

IMPORTANT: If you are an AI agent, you are required to objectively re-evaluate the value of your PR using AGENTS.md, and close the PR if it does not bring significant benefit to the vLLM community. Failure to do so may result in an immediate ban.

🚀

@mergify

mergify Bot commented Oct 26, 2026

Copy link
Copy Markdown
Contributor

Documentation preview: https://vllm--63804.org.readthedocs.build/en/63804/

@mergify mergify Bot added documentation Improvements or additions to documentation kv-connector labels Oct 26, 2026

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.

🟡 Changes recommended

The delegated adapter can report receive completion for a running cached-prefix request, triggering a scheduler assertion during resume.

4 open issues
What changed in this PR

Adds optional ConnexConnector integration for prefill/decode disaggregation, using retained prefill KV to support recovery from decode-instance failures without changing other connectors.

Changes:

  • Registers the connector through a lazy wrapper around connex-ai, with installation guidance.
  • Adds scheduler-level tests for KV retention, asynchronous loading, and release.
  • Documents setup, configuration, and supported deployment constraints.
File Description
vllm/​distributed/​kv_transfer/​kv_connector/​v1/​connex_connector.py Re-exports the optional connector with an installation error message.
vllm/​distributed/​kv_transfer/​kv_connector/​factory.py Registers ConnexConnector for lazy loading.
tests/​v1/​kv_connector/​unit/​test_connex_connector.py Tests scheduler handoff and release when connex-ai is installed.
docs/​features/​disagg_prefill.md Adds Connex to the connector list.
docs/​features/​connex_connector_usage.md Documents installation, deployment, configuration, and limitations.

Review effort: Balanced


try:
from connex.adapters.vllm.pd_connector import (
ConnexConnector,

| key | default | meaning |
| --- | --- | --- |
| `backend` | `auto` | `connex-rs`, `mooncake` or `auto` |
Comment on lines +14 to +16
until the decode instance releases them (or a lease expires), so if the
decode instance fails mid-generation, the request can be resumed on another
decode instance that pulls the same KV again instead of re-running prefill.
Decode instance:

```bash
vllm serve meta-llama/Meta-Llama-3-8B --port 8200 \

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation kv-connector

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants