You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/disaggregation.md
+47-5Lines changed: 47 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -539,9 +539,30 @@ Specifies which KV transfer protocol the sidecar uses to coordinate prefill/deco
539
539
| `mooncake` | `MooncakeConnector` | [Mooncake](https://github.com/kvcache-ai/Mooncake) KV transfer using RDMA |
540
540
| `offloading` | `OffloadingConnector` | KV transfer over the vLLM CPU offloading tier. The decoder pulls KV from the prefiller via the `p2p` secondary tier. |
541
541
542
-
With `offloading`, the sidecar dispatches prefill and decode concurrently. It injects role-keyed `kv_transfer_params`: the prefiller receives `{"decode": {"kv_request_id": <id>}}` (no peer address), and the decoder receives `{"prefill": {"kv_request_id": <id>, "remote_host": <prefiller host>, "remote_port": <p2p-connector-port>}}` so it can pull KV from the prefiller. The prefiller host comes from the `x-prefiller-host-port` header; the port is `--p2p-connector-port`.
543
-
544
-
When the request also carries the `x-kv-cache-source-host-port` header (set by the EPP `p2p-source-producer` to a peer holding more cached prefix than the pod computing the prefix), the sidecar injects an additional `p2p` key so vLLM pulls that cached prefix over the P2P tier instead of recomputing it. Under disaggregation the prefiller leg carries `{"decode": {...}, "p2p": {"kv_request_id": <own id>, "remote_host": <source host>, "remote_port": <p2p-connector-port>}}` (the only supported multi-key combination); without a prefiller the decoder-only request carries `{"p2p": {...}}` alone. A malformed or disallowed source header is ignored and the request proceeds unchanged, as is any source header on a connector that cannot pull over the P2P tier: only `offloading`, or NIXLv2 with `--enable-p2p-pull`, honors it. For the pulled blocks to be servable, the source pod must offload its generated (decode-phase) KV: set `offload_prompt_only: false` in its `kv_connector_extra_config` (the default `true` offloads only prefill blocks).
542
+
With `offloading`, the sidecar dispatches prefill and decode concurrently. It
543
+
injects role-keyed `kv_transfer_params`, each key named for the remote party it
544
+
describes: the prefiller receives `{"remote_decoder": {"kv_request_id": <id>}}`
545
+
(no peer address), and the decoder receives `{"remote_prefiller":
"remote_port": <p2p-connector-port>}}` (the only supported multi-key
558
+
combination); without a prefiller the decoder-only request carries
559
+
`{"remote_kv_source": {...}}` alone. A malformed or disallowed source header is
560
+
ignored and the request proceeds unchanged, as is any source header on a
561
+
connector that cannot pull over the P2P tier: only `offloading`, or NIXLv2 with
562
+
`--enable-p2p-pull`, honors it. For the pulled blocks to be servable, the source
563
+
pod must offload its generated (decode-phase) KV: set `offload_prompt_only:
564
+
false` in its `kv_connector_extra_config` (the default `true` offloads only
565
+
prefill blocks).
545
566
546
567
Both prefill and decode pods require the following `--kv-transfer-config`:
547
568
@@ -559,7 +580,28 @@ Both prefill and decode pods require the following `--kv-transfer-config`:
559
580
560
581
`host`must be the pod's own IP at runtime (use the Kubernetes downward API env var `status.podIP`). `port` must match `--p2p-connector-port` (default `7777`). `cpu_bytes_to_use` controls the CPU KV offload buffer size; size it to hold the KV for the expected concurrent in-flight transfers. `OffloadingConnector` is available in vLLM nightly builds from 2026-06-30 onward (commit `bec232a`, [PR #42285](https://github.com/vllm-project/vllm/pull/42285)).
561
582
562
-
**Restriction:** `--kv-connector=offloading` requires `--data-parallel-size=1`. Wide-EP pods (DP > 1) are rejected at startup: every DP rank would bind the same `POD_IP:<p2p-connector-port>`. DP-aware support is not yet implemented.
583
+
**Data parallelism:** the P2P tier supports `--data-parallel-size` N > 1 when
584
+
each pod is a complete DP group (the per-pod DP deployment).
585
+
586
+
- vLLM gives each DP replica its own P2P listener and offload region:
587
+
replica `i` serves on `<p2p-connector-port>+i`, where `i` is the
without those changes bind every replica to the same
592
+
`POD_IP:<p2p-connector-port>`, and DP > 1 fails at engine startup.
593
+
- The sidecar serves rank `r` on its own port + `r`, so the routed
594
+
endpoint's port names the target rank. The sidecar injects
595
+
`remote_port`= `--p2p-connector-port` + `r`; a port outside the rank
596
+
range falls back to rank 0.
597
+
- The endpoint port encodes the pod-local rank, which matches the global
598
+
index only when the pod is a whole DP group. In multi-pod DP groups (for
599
+
example LWS wide-EP, where pod `k`'s replicas hold global indices
600
+
`k*N..k*N+N-1`behind the same serving ports), the global index cannot
601
+
be read from the port and would have to be supplied with the request, so
602
+
those deployments are not covered.
603
+
- Every replica maps its own offload region, so the pod's `/dev/shm` must
604
+
exceed N x `cpu_bytes_to_use`.
563
605
564
606
### General Sidecar Flags
565
607
@@ -576,7 +618,7 @@ Both prefill and decode pods require the following `--kv-transfer-config`:
576
618
|---|---|---|---|---|
577
619
| `mooncake` | `--mooncake-bootstrap-port` | `MOONCAKE_BOOTSTRAP_PORT` | `8998` | Port used to query the Mooncake bootstrap endpoint on prefill pods. Corresponds to vLLM's `VLLM_MOONCAKE_BOOTSTRAP_PORT`. |
578
620
| `sglang` | — | `SGLANG_BOOTSTRAP_PORT` | `8998` | Port used for the SGLang bootstrap endpoint on prefill pods. |
579
-
| `offloading` | `--p2p-connector-port` | `P2P_CONNECTOR_PORT` | `7777` | Prefiller's OffloadingConnector P2P tier listening port, injected as `remote_port` on the decode leg so the decoder can pull KV. |
621
+
| `offloading` | `--p2p-connector-port` | `P2P_CONNECTOR_PORT` | `7777` | Prefiller's OffloadingConnector P2P tier listening port (rank-0 port under data parallelism), injected as `remote_port` on the decode leg so the decoder can pull KV. |
580
622
| `nixlv2` | `--enable-p2p-pull` | — | `false` | Declare the OffloadingConnector P2P tier available for cached-prefix pulls when the PD connector is NIXLv2, i.e. the engines run `MultiConnector(NixlConnector + OffloadingConnector)`. NIXL moves KV prefill to decode while the OffloadingConnector pulls the cached prefix named by `x-kv-cache-source-host-port`. Rejected at startup with any other connector; `offloading` provides the tier natively and needs no flag. |
0 commit comments