Skip to content

[Bugfix][EC Connector] Allocate producer control ports at startup - #61764

Merged
Isotr0py merged 5 commits into
vllm-project:mainfrom
gty111:fix/ec-auto-port-main-20261015
Nov 2, 2026
Merged

Isotr0py merged 5 commits into
vllm-project:mainfrom
gty111:fix/ec-auto-port-main-20261015

Conversation

@gty111

@gty111 gty111 commented Oct 15, 2026 •

Copy link
Copy Markdown
Collaborator

Overview

Avoid NIXL EC producer control-port collisions when multiple instances or DP replicas share a host, while retaining explicit endpoint configuration.

Claims

  • Allocate an OS-assigned port by default and advertise the actual bound port through ec_transfer_params.peer_port.
  • Keep VLLM_EC_SIDE_CHANNEL_HOST and VLLM_EC_SIDE_CHANNEL_PORT overrides. A nonzero port uses base_port + data_parallel_index; 0 remains automatic.
  • Preserve ec_transfer_config.engine_id in the NIXL agent name and append the DP index to distinguish replicas.

Validation

Transport and configuration validation
.venv/bin/python -m pytest tests/v1/ec_connector/unit/test_{control,data,session,scheduler_nixl_ctor,scheduler_nixl_producer,scheduler_nixl_consumer}.py -q

112 passed, including real ZMQ request/reply and NIXL peer registration. The updated tests reproduce ignored endpoint overrides and engine IDs before the fix. GPU serving was not rerun for this revision.

Details

Bind port 0 directly on the serving socket and read LAST_ENDPOINT, avoiding a separate port-reservation race. The host defaults to get_ip() (honoring VLLM_HOST_IP); set VLLM_EC_SIDE_CHANNEL_HOST=localhost for loopback-only binding. Wildcard addresses are rejected because peers need a reachable address.

Fixed-port conflicts fail startup rather than silently choosing another port. Independent instances using fixed ports must use non-overlapping ranges; consumers use the advertised endpoint without matching port configuration.

No equivalent open fix was found in the EC control-port search.


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.

@mergify

mergify Bot commented Oct 15, 2026

Copy link
Copy Markdown
Contributor

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

@mergify mergify Bot added the documentation Improvements or additions to documentation label Oct 15, 2026
@mergify

mergify Bot commented Oct 15, 2026

Copy link
Copy Markdown
Contributor

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

@mergify mergify Bot added cpu Related to CPU backends bug Something isn't working labels Oct 15, 2026
Bind each EC producer ROUTER socket to an OS-assigned port and advertise the actual endpoint. Keep NIXL peer identities local to each instance and DP rank.

Signed-off-by: Tianyu Guo <guoty@inferact.ai>
Remove the EC-specific host environment variable and use get_ip() with the existing VLLM_HOST_IP override.

Signed-off-by: Tianyu Guo <guoty@inferact.ai>
@gty111
gty111 force-pushed the fix/ec-auto-port-main-20261015 branch from 397e1e1 to a14af0c Compare October 15, 2026 07:26
@gty111
gty111 marked this pull request as ready for review October 15, 2026 07:33

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

@omerpaz95

Copy link
Copy Markdown
Contributor

Thanks @gty111 , that's a real bug.
Some concerns about the implementation:

  1. Ports can no longer be pinned. Port 0 is unconditional, so we can no longer write firewall rules or NetworkPolicies for the control plane.
    My suggestion: Keep env var VLLM_EC_SIDE_CHANNEL_PORT, add + data_parallel_index like the KV NIXL connector (nixl/base_scheduler.py) and the P2P offload tier (kv_offload/tiering/p2p/manager.py), and treat 0 as an opt-in "OS-assigned":

host = envs.VLLM_EC_SIDE_CHANNEL_HOST
base = envs.VLLM_EC_SIDE_CHANNEL_PORT
transport = ZmqServerTransport(host, base + dp_index if base else 0)
self._peer_port = transport.port # always announce the bound port

  1. The default bind becomes network-reachable. Without the host env var, main binds localhost. This PR binds whatever get_ip() finds. If detection fails, get_ip() returns 0.0.0.0: the socket binds every interface, and consumers are told to dial 0.0.0.0.
    I suggest to keep VLLM_EC_SIDE_CHANNEL_HOST with its localhost default. If auto-detection is wanted, make it opt-in.

  2. Removing env vars that already exist in released versions of vLLM breaks existing deployments: They may fail or crash. I think it's best (As a practice) to deprecate in one release and then remove. But if you follow the suggestions in 1, 2, this won't be necessary.

  3. ec_transfer_config.engine_id is now ignored by this connector, even if the user sets it.

  4. (From Claude code review): Tests don't cover the identity fix. test_producers_allocate_distinct_ports_across_dp_and_instances passes without the agent-name change, since OS-assigned ports always differ. The parametrized dp_index test asserts nothing about dp_index.
    → Assert distinct agent names across DP ranks, or register two producers with one consumer. Add tests that a non-zero base binds base + dp_index, and that 0 announces the bound port rather than 0.

Assisted-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Tianyu Guo <guoty@inferact.ai>
@omerpaz95

Copy link
Copy Markdown
Contributor

LGTM. Thanks @gty111

@mergify mergify Bot added the nixl NIXL KV connector / multi-tiered KV offloading (KVCR) label Oct 29, 2026
@mergify

mergify Bot commented Oct 29, 2026

Copy link
Copy Markdown
Contributor

This pull request has merge conflicts that must be resolved before it can be
merged. Please rebase the PR, @gty111.

https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork

Assisted-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Tianyu Guo <guoty@inferact.ai>
@gty111 gty111 added the ready ONLY add when PR is ready to merge/full CI is needed label Nov 2, 2026
@gty111

gty111 commented Nov 2, 2026

Copy link
Copy Markdown
Collaborator Author

/ci run

@github-actions

github-actions Bot commented Nov 2, 2026

Copy link
Copy Markdown

✅ Triggered Buildkite CI #99036 for commit 55e65c0a4041.

ℹ️ This PR is 1 commit behind upstream main. Merged upstream main into this branch as 55e65c0a4041 before starting CI. Pull the branch before pushing more changes.

@mergify mergify Bot removed the needs-rebase label Nov 2, 2026
@Isotr0py
Isotr0py merged commit a9cf9df into vllm-project:main Nov 2, 2026
213 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working cpu Related to CPU backends documentation Improvements or additions to documentation nixl NIXL KV connector / multi-tiered KV offloading (KVCR) 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.

4 participants