Skip to content

[serve.llm] Set up KV-connector backend in mock engine for PD direct-streaming test#64266

Merged
eicherseiji merged 2 commits into
ray-project:masterfrom
eicherseiji:llm-pd-direct-streaming-mock-kv-backend
Jun 23, 2026
Merged

[serve.llm] Set up KV-connector backend in mock engine for PD direct-streaming test#64266
eicherseiji merged 2 commits into
ray-project:masterfrom
eicherseiji:llm-pd-direct-streaming-mock-kv-backend

Conversation

@eicherseiji

@eicherseiji eicherseiji commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Why are these changes needed?

test_pd_direct_streaming is broken deterministically on master: every request returns 500. PDDecodeServer._get_connector_backend() asserts a KV-connector backend on its LLMConfig, and only LLMConfig.setup_engine_backend() populates it, which runs only during real vLLM engine init. The end-to-end test uses the mock engine, which skips that init, so _kv_connector_backend stays None and the decode server raises on every request.

This makes the mock engine install a default KV-connector backend when the config requests KV transfer, mirroring the real engine's setup_engine_backend(). The default backend is used because the real Nixl/LMCache setup() needs hardware the CPU test environment lacks. This matches the workaround the sibling unit test test_prefill_decode_disagg.py already applies by hand.

This is a test-infrastructure change only, in the mock engine under ray/llm/tests.

Related issue number

Closes #64264.

After this fix, test_pd_direct_streaming reaches the request path. The only residual failure is the separate intermittent unknown_replica_id ingress-router race, tracked in #64265 and fixed by #64218.

Checks

…streaming test

test_pd_direct_streaming uses the mock vLLM engine, which skips the real engine init that runs LLMConfig.setup_engine_backend(). So _kv_connector_backend stays None and PDDecodeServer._get_connector_backend() asserts on every request, 500ing the test deterministically. Install a DefaultConnectorBackend in the mock when the config requests KV transfer, mirroring the real engine and the test_prefill_decode_disagg unit-test stub. The default backend avoids the real Nixl/LMCache setup() that needs hardware unavailable in CPU CI.

Signed-off-by: Seiji Eicher <seiji@anyscale.com>

@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 updates the mock vLLM engine (MockVLLMEngine) to mirror the real engine's backend setup. Specifically, if kv_transfer_config is present in the configuration, it initializes a DefaultConnectorBackend on llm_config. This ensures the P/D orchestrator can find a KV-connector backend during testing without requiring the specialized hardware needed for the real setup. There are no review comments, and I have no additional feedback to provide.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

@eicherseiji eicherseiji self-assigned this Jun 23, 2026
@eicherseiji eicherseiji added the go add ONLY when ready to merge, run all tests label Jun 23, 2026
…mock engine

Signed-off-by: Seiji Eicher <seiji@anyscale.com>
@eicherseiji
eicherseiji marked this pull request as ready for review June 23, 2026 02:18
@eicherseiji
eicherseiji requested a review from a team as a code owner June 23, 2026 02:18
@eicherseiji
eicherseiji merged commit 334c799 into ray-project:master Jun 23, 2026
6 checks passed
eicherseiji added a commit that referenced this pull request Jun 24, 2026
…oxy instead of 503 (#64218)

## Why are these changes needed?

With HAProxy ingress and direct streaming, the ingress request router
pins a replica by name and HAProxy routes to it through its statically
reloaded server map. Right after the replica set changes, the router's
in-process view runs ahead of HAProxy's config reload, so it can name a
replica HAProxy has not loaded yet. HAProxy returned a 503
`unknown_replica_id`. This is an intermittent failure in the
direct-streaming session-affinity tests and a real client-facing error
during the gap.

This routes `unknown_replica_id` to the fallback Serve proxy instead of
503ing. The fallback re-pins through its own router on the same
consistent-hash ring, so affinity is preserved. A router app with no
fallback still fails loud rather than silently using the primary
backend, and other router failures still 503.

Reproduced and validated with `test_dp_direct_streaming` against HAProxy
2.8. The deterministic `test_pd_direct_streaming` failure is a separate
KV-connector gap fixed in #64266.

## Related issue number

Closes #64265.

## Checks

- [x] I've signed off every commit (DCO).
- [x] Added `test_pin_miss_falls_back_to_fallback_server`. Lint clean.

---------

Signed-off-by: Seiji Eicher <seiji@anyscale.com>
limarkdcunha pushed a commit to limarkdcunha/ray that referenced this pull request Jun 30, 2026
limarkdcunha pushed a commit to limarkdcunha/ray that referenced this pull request Jun 30, 2026
…oxy instead of 503 (ray-project#64218)

## Why are these changes needed?

With HAProxy ingress and direct streaming, the ingress request router
pins a replica by name and HAProxy routes to it through its statically
reloaded server map. Right after the replica set changes, the router's
in-process view runs ahead of HAProxy's config reload, so it can name a
replica HAProxy has not loaded yet. HAProxy returned a 503
`unknown_replica_id`. This is an intermittent failure in the
direct-streaming session-affinity tests and a real client-facing error
during the gap.

This routes `unknown_replica_id` to the fallback Serve proxy instead of
503ing. The fallback re-pins through its own router on the same
consistent-hash ring, so affinity is preserved. A router app with no
fallback still fails loud rather than silently using the primary
backend, and other router failures still 503.

Reproduced and validated with `test_dp_direct_streaming` against HAProxy
2.8. The deterministic `test_pd_direct_streaming` failure is a separate
KV-connector gap fixed in ray-project#64266.

## Related issue number

Closes ray-project#64265.

## Checks

- [x] I've signed off every commit (DCO).
- [x] Added `test_pin_miss_falls_back_to_fallback_server`. Lint clean.

---------

Signed-off-by: Seiji Eicher <seiji@anyscale.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

go add ONLY when ready to merge, run all tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[CI] linux://python/ray/llm/tests:serve/cpu/deployments/prefill_decode_disagg/test_pd_direct_streaming is failing/flaky on master.

2 participants