Skip to content

Commit 9a6ee75

Browse files
committed
fix(sidecar): rename P2P kv_transfer_params sub-dict keys to match vLLM
The OffloadingConnector P2P branch renamed the request-level sub-dict keys for clarity (liranschour/vllm@530fa0d7 + @5bcf5b31): "prefill" -> "remote_prefiller", "decode" -> "remote_decoder", "p2p" -> "remote_kv_source", each named for the remote party it describes. Inner fields (kv_request_id, remote_host, remote_port) and the secondary-tier type "p2p" are unchanged. A sidecar emitting the old keys against a renamed engine is silently inert - the engine ignores unknown sub-dicts and every request recomputes - so the sidecar and engine must move together. Signed-off-by: nilig <nili.ifergan@gmail.com>
1 parent 08dce7a commit 9a6ee75

5 files changed

Lines changed: 14 additions & 12 deletions

File tree

docs/disaggregation.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -539,9 +539,9 @@ Specifies which KV transfer protocol the sidecar uses to coordinate prefill/deco
539539
| `mooncake` | `MooncakeConnector` | [Mooncake](https://github.com/kvcache-ai/Mooncake) KV transfer using RDMA |
540540
| `offloading` | `OffloadingConnector` | KV transfer over the vLLM CPU offloading tier. The decoder pulls KV from the prefiller via the `p2p` secondary tier. |
541541

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`.
542+
With `offloading`, the sidecar dispatches prefill and decode concurrently. It injects role-keyed `kv_transfer_params`, each key named for the remote party it describes: the prefiller receives `{"remote_decoder": {"kv_request_id": <id>}}` (no peer address), and the decoder receives `{"remote_prefiller": {"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`.
543543

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).
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 `remote_kv_source` key so vLLM pulls that cached prefix over the P2P tier instead of recomputing it. Under disaggregation the prefiller leg carries `{"remote_decoder": {...}, "remote_kv_source": {"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 `{"remote_kv_source": {...}}` 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).
545545

546546
Both prefill and decode pods require the following `--kv-transfer-config`:
547547

pkg/sidecar/proxy/connector_p2p.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -232,8 +232,8 @@ func (s *Server) addP2PPullToPrefill(prefillKVParams map[string]any, kvCacheSour
232232
}
233233
}
234234

235-
// p2pSourceParams builds the kv_transfer_params.p2p block for a pull from
236-
// sourceHostPort's OffloadingConnector P2P tier. The kv_request_id is its
235+
// p2pSourceParams builds the kv_transfer_params.remote_kv_source block for a
236+
// pull from sourceHostPort's OffloadingConnector P2P tier. The kv_request_id is its
237237
// own fresh UUID: in P2P mode it is consumer-side only.
238238
func (s *Server) p2pSourceParams(sourceHostPort string) map[string]any {
239239
return map[string]any{
@@ -244,7 +244,7 @@ func (s *Server) p2pSourceParams(sourceHostPort string) map[string]any {
244244
}
245245

246246
// decodeWithP2PSource serves a decoder-only request through the local vLLM
247-
// with kv_transfer_params.p2p injected, so the engine looks up and pulls
247+
// with kv_transfer_params.remote_kv_source injected, so the engine looks up and pulls
248248
// cached prefix blocks from the peer at sourceHostPort instead of recomputing
249249
// them. It replaces any client-supplied kv_transfer_params (the sidecar owns
250250
// that field) and routes through dispatchDecode so chunked decode still

pkg/sidecar/proxy/connector_p2p_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ var _ = Describe("P2P Connector", func() {
6060
return len(testInfo.prefillHandler.GetCompletionRequests())
6161
}).Should(Equal(1))
6262

63-
// Prefill leg: kv_transfer_params.decode carries only kv_request_id,
63+
// Prefill leg: kv_transfer_params.remote_decoder carries only kv_request_id,
6464
// with no peer address.
6565
prefillReqs := testInfo.prefillHandler.GetCompletionRequests()
6666
Expect(prefillReqs).To(HaveLen(1))
@@ -82,7 +82,7 @@ var _ = Describe("P2P Connector", func() {
8282
Expect(preq).To(HaveKeyWithValue(requestFieldMaxCompletionTokens, BeNumerically("==", 1)))
8383
Expect(preq[requestFieldStream]).To(BeFalse())
8484

85-
// Decode leg: kv_transfer_params.prefill carries the prefiller's
85+
// Decode leg: kv_transfer_params.remote_prefiller carries the prefiller's
8686
// OffloadingConnector P2P tier address plus the matching kv_request_id.
8787
Expect(testInfo.decodeHandler.RequestCount.Load()).To(BeNumerically("==", 1))
8888
decodeReqs := testInfo.decodeHandler.GetCompletionRequests()

pkg/sidecar/proxy/proxy.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,12 @@ const (
9292
requestFieldRemoteBootstrapAddr = "remote_bootstrap_addr"
9393

9494
// OffloadingConnector kv_transfer_params fields. The role is encoded by the
95-
// nesting key: "decode" on the prefiller leg, "prefill" on the decoder leg.
96-
requestFieldP2PDecodeParams = "decode"
97-
requestFieldP2PPrefillParams = "prefill"
98-
requestFieldP2PParams = "p2p"
95+
// nesting key, named for the remote party it describes: "remote_decoder" on
96+
// the prefiller leg, "remote_prefiller" on the decoder leg, "remote_kv_source"
97+
// for a symmetric cached-prefix pull.
98+
requestFieldP2PDecodeParams = "remote_decoder"
99+
requestFieldP2PPrefillParams = "remote_prefiller"
100+
requestFieldP2PParams = "remote_kv_source"
99101
requestFieldKVRequestID = "kv_request_id"
100102

101103
KVConnectorNIXLV2 = constants.KVConnectorNIXLV2

release-notes.d/unreleased/1937.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ url: https://github.com/llm-d/llm-d-router/pull/1937
44
author: nilig
55
date: 2026-07-14
66
---
7-
The routing sidecar honors the `x-kv-cache-source-host-port` header, injecting `kv_transfer_params.p2p` so vLLM pulls cached prefix KV from the named peer over the OffloadingConnector P2P tier instead of recomputing it.
7+
The routing sidecar honors the `x-kv-cache-source-host-port` header, injecting `kv_transfer_params.remote_kv_source` so vLLM pulls cached prefix KV from the named peer over the OffloadingConnector P2P tier instead of recomputing it.

0 commit comments

Comments
 (0)