[Core] Add NIXL omni connector (#6093)

Signed-off-by: yuanwu <yuan.wu@intel.com>
Signed-off-by: Yuan Wu <yuan.wu@intel.com>
This commit is contained in:
Yuan Wu authored and GitHub committed 2026-09-13 16:35:02 +08:00
1 parent 01a2f93256
commit 6753bbd18c
33 files changed
+3032 -66

No files matched your search

+1
View File
@@ -136,6 +136,7 @@ nav:
- Mooncake Store Connector: design/feature/omni_connectors/mooncake_store_connector.md
- Mooncake Transfer Engine Connector: design/feature/omni_connectors/mooncake_transfer_engine_connector.md
- Mori Transfer Engine Connector: design/feature/omni_connectors/mori_transfer_engine_connector.md
- NIXL Connector: design/feature/omni_connectors/nixl_connector.md
- Shared Memory Connector: design/feature/omni_connectors/shared_memory_connector.md
- Yuanrong Store Connector: design/feature/omni_connectors/yuanrong_connector.md
- Yuanrong Transfer Engine Connector: design/feature/omni_connectors/yuanrong_transfer_engine_connector.md
@@ -90,6 +90,13 @@ depends on the installed kernels and model path.
| `VLLM_VIDEO_ASYNC_CHUNK` | `on` or `off`; default `on` | Streaming video output; read on attribute access | Environment-only setting. Values are trimmed and case-normalized; an invalid value warns once and uses `on`. | Experimental |
| `VLLM_VIDEO_AUDIO_DELTA_MODE` | `fast` or `slow`; default `fast` | Streaming video audio deltas; read on attribute access | Environment-only setting. Values are trimmed and case-normalized; an invalid value warns once and uses `fast`. | Experimental |
### NIXL stage transfer
| Name | Type and default | Applies to and read time | Precedence and invalid values | Lifecycle |
| --- | --- | --- | --- | --- |
| `VLLM_OMNI_NIXL_LEASE_S` | Float seconds; default `3600` | Unclaimed producer payload expiry; connector construction | Nonempty environment value overrides `lease_seconds`; empty falls back to config/default. Invalid floats raise `ValueError`. Claimed READ allocations never expire by time. | Experimental |
| `VLLM_OMNI_NIXL_XFER_TIMEOUT_S` | Float seconds; default `300` | Receiver READ wait; connector construction | Nonempty environment value overrides `transfer_timeout_s`; empty falls back to config/default. Invalid floats raise `ValueError`. Timeout does not cancel DMA or release active allocations. | Experimental |
### Server storage
Storage names use Pydantic's nested-settings delimiter (`__`). They are read
@@ -9,6 +9,7 @@ Backend-specific setup lives in separate docs:
- [MooncakeStoreConnector](omni_connectors/mooncake_store_connector.md)
- [MooncakeTransferEngineConnector](omni_connectors/mooncake_transfer_engine_connector.md)
- [MoriTransferEngineConnector](omni_connectors/mori_transfer_engine_connector.md)
- [NixlConnector](omni_connectors/nixl_connector.md)
- [YuanrongConnector](omni_connectors/yuanrong_connector.md)
- [YuanrongTransferEngineConnector](omni_connectors/yuanrong_transfer_engine_connector.md)
@@ -25,6 +26,7 @@ Current connectors operate in D2H2D (device to host to device) mode.
| Multi node (Mooncake Store) | MooncakeStoreConnector | TCP-based, requires Mooncake Master + metadata server. |
| Multi node (Mooncake RDMA) | MooncakeTransferEngineConnector | RDMA/TCP direct transfer with managed memory pool. Fastest. |
| Multi node (Mori RDMA) | MoriTransferEngineConnector | RDMA direct transfer via Mori IOEngine. |
| Multi node (NIXL) | NixlConnector | NIXL `READ` over UCX; the only backend covering Intel XPU. |
| Multi node (Yuanrong) | YuanrongConnector | Requires Yuanrong Datasystem + etcd. |
| Ascend NPU P2P (Yuanrong TE) | YuanrongTransferEngineConnector | Uses Yuanrong TransferEngine directly. Configure NPU device IPv4 and `memory_pool_device: "npu"`. |
@@ -0,0 +1,135 @@
# NixlConnector
## When to Use
Multi-node or intra-node stage transfer over NIXL, which brokers RDMA/shared-memory
transports through a single API. Useful when the deployment already standardises on
NIXL for KV transfer, or when the target accelerator has no Mooncake/Mori backend --
NIXL reaches Intel XPU through UCX's Level Zero support.
## Mechanism
Uses vLLM's `NixlWrapper` (`vllm.distributed.nixl_utils`) to register the producer's
tensors and let the consumer pull them with a NIXL `READ`.
- Data Plane: NIXL agent-to-agent `READ`, GPU-to-GPU where the backend allows it.
- Control Plane: a ZMQ ROUTER socket atomically claims the source allocation before
returning descriptors. Forwarded `put()` metadata includes the generation and
endpoint; the consumer claims that generation before submitting any READ.
Transfer metadata uses schema version 1. Tensor descriptors are grouped by NIXL
memory type (`DRAM`, `VRAM`, and so on), while each descriptor retains its global
tensor index so mixed CPU/accelerator payloads can be reconstructed in order.
Payloads are not restricted to tensors. A single tensor or a list of tensors is
transferred as-is; a nested structure has its tensor leaves extracted and shipped
alongside a msgpack-encoded skeleton; anything else is msgpack-encoded into one
uint8 tensor. Mapping and sequence structure is preserved. `msgspec.Struct` values,
including `OmniPayloadStruct`, are normalised to mappings so their tensor leaves use
the direct NIXL path rather than CPU object serialisation.
Each NIXL agent uses strict thread synchronization. A consumer performs one short
metadata query per scheduler poll (10ms by default), which prevents an unavailable
producer from blocking unrelated requests. The regular transfer-completion handshake
keeps the configured transfer timeout.
## Installation
CUDA hosts can install the published wheel:
```bash
pip install nixl
```
For Intel XPU, use `docker/Dockerfile.xpu`. Its upstream vLLM XPU base image
provides a matching torch-xpu, UCX with Level Zero support, and NIXL runtime.
## Configuration
```yaml
connectors:
nixl_connector:
name: NixlConnector
extra:
host: "auto"
zmq_port: 50061
backends: ["UCX"]
stages:
- stage_id: 0
output_connectors:
to_stage_1: nixl_connector
- stage_id: 1
input_connectors:
from_stage_0: nixl_connector
```
Parameters:
- `host`: address the producer binds its handshake socket to (`"auto"` to detect).
- `zmq_port`: handshake port. If a producer omits it, an ephemeral port is opened
for ownership claims and returned in `put()` metadata. The value in the deploy YAML is a
base port. Purpose, replica, rank, and producer-stage offsets are added centrally,
so colocated connectors and tensor-parallel workers receive distinct endpoints
without one config entry per rank.
- `sender_host` / `sender_zmq_port`: consumer-side override naming the producer's
handshake endpoint. Only needed when the consumer cannot learn it from metadata.
In replicated deployments, the producer endpoint is carried with each request and
selected at `get()` time; it is not mutable connector-wide state.
Explicit sender ports are preserved, not recomputed using the receiver replica.
Intermediate NIXL stages retain their incoming receiver configuration and a
separate outgoing bind configuration, so one worker can receive and publish.
- `backends`: NIXL backends to register memory with. Defaults to `["UCX"]`.
- `receive_device`: forces where received tensors land. By default the consumer
keeps the producer's device *type* but uses its own current device of that type.
- `memory_type`: overrides the NIXL memory type, otherwise `DRAM` for CPU tensors
and `VRAM` for accelerator tensors.
- `lease_seconds`: how long a `put()` payload stays registered while waiting to be
read (default 3600). The consumer reports completion, so this only bounds payloads
nobody has claimed. An internal reaper releases only unclaimed registrations.
`VLLM_OMNI_NIXL_LEASE_S` overrides it.
- `transfer_timeout_s`: how long a `get()` waits for its `READ` to complete
(default 300). NIXL 1.3 has no transfer cancellation API, so a timed-out transfer's
buffers and registrations remain owned by the connector until NIXL reports a
terminal state; `close()` waits for that state before releasing them.
`VLLM_OMNI_NIXL_XFER_TIMEOUT_S` overrides it.
### Source ownership and failure limits
Claims and expiry use the same lock. Completion identifies both a payload
generation and a unique READ claim; duplicate or stale ACKs cannot release a
different reader or replacement payload. Replacing a claimed key is rejected.
Terminal errors also release claims; timeout, unknown status, and active sibling
transfers retain the complete destination bundle and source claim until terminal.
Zero-element tensors retain their shape/dtype/skeleton positions but never create
DMA descriptors or registrations.
A lost metadata response, lost completion ACK, or abandoned consumer can retain a
claim indefinitely. NIXL 1.3 cannot prove remote cancellation, so neither TTL nor
`cleanup()` frees those allocations. Producer `close()` rejects new work and
retains its agent, listener and claimed allocations; a later `close()` finishes
teardown after claims drain. Permanently abandoned claims remain until process
exit. This favors memory safety over bounded shutdown/memory usage. Only trusted
peers may access this unauthenticated control plane. Both endpoints must use the
claim-aware protocol; rolling compatibility with older GET_META clients is not
provided. Legacy externally-owned metadata without a generation is accepted only
under the caller's lifetime guarantee, not managed as a leased allocation here.
## Validation
The native CUDA smoke test requires NIXL and at least two visible CUDA devices:
```bash
UCX_RCACHE_MAX_UNRELEASED=1024 pytest -o addopts='' -q -s \
tests/distributed/omni_connectors/test_nixl_connector_native.py
```
It starts independent producer and consumer processes, loads the real UCX backend,
performs the ZMQ `GET_META` handshake and a native NIXL `READ` from GPU 0 to GPU 1,
checks mixed CPU/GPU tensor leaves from an `OmniPayloadStruct`, sends `XFER_DONE`,
and verifies that producer registrations are released. This validates same-host,
cross-GPU operation. Inter-node UCX transport is supported by the design but was not
validated by this test.
For more details, refer to the [NIXL repository](https://github.com/ai-dynamo/nixl).
+1
View File
@@ -36,6 +36,7 @@ implementation contract; it is not, by itself, a general support claim.
- [Mooncake Store Connector](feature/omni_connectors/mooncake_store_connector.md)
- [Mooncake Transfer Engine Connector](feature/omni_connectors/mooncake_transfer_engine_connector.md)
- [Mori Transfer Engine Connector](feature/omni_connectors/mori_transfer_engine_connector.md)
- [NIXL Connector](feature/omni_connectors/nixl_connector.md)
- [Shared Memory Connector](feature/omni_connectors/shared_memory_connector.md)
- [Yuanrong Store Connector](feature/omni_connectors/yuanrong_connector.md)
- [Yuanrong Transfer Engine Connector](feature/omni_connectors/yuanrong_transfer_engine_connector.md)