Skip to content

ENH: Support Qwen3.5 recurrent-state PD handoff - #5630

Merged
qinxuye merged 2 commits into
xorbitsai:mainfrom
qinxuye:feat/xavier-hybrid-handoff
Oct 4, 2026
Merged

qinxuye merged 2 commits into
xorbitsai:mainfrom
qinxuye:feat/xavier-hybrid-handoff

Conversation

@qinxuye

@qinxuye qinxuye commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

Qwen3.5 text P/D previously failed because Xavier rejected recurrent caches, and the multimodal chat wrapper dropped the producer's KV handoff metadata. This change transfers attention KV and Gated DeltaNet state together through Xavier's xoscar NIXL GPU path, and enables the native NIXL integration for models launched with language_model_only=True.

  • P computes N-1 prompt tokens and hands off the corresponding recurrent state; D computes the last token. Truncation is idempotent across scheduling retries, and one-token prompts recompute on D.
  • Preserve independent cache-group block IDs and authorize reads per layer. Reject mismatched group metadata before claiming a ticket and recompute locally; preserve the scheduler-provided local-hit offset through allocation. Shared layout detection rejects ambiguous two-block axes. Attention physical kernel blocks are grouped into logical transfer units through zero-copy views; convolution and SSM tensors retain their own layouts/dtypes. Existing ticket lifetime and async completion handling retain all engine blocks until the load finishes.
  • Enable Xavier's hybrid cache manager by default only for recurrent models on vLLM 0.21, preserving explicit user settings; newer vLLM checks connector HMA support itself. Default recurrent prefix caching and async scheduling off, with clear errors for enabling either. Support TP=PP=1, text-only requests and mamba_cache_mode="none"; recurrent prefix history and speculative decoding remain unsupported. A configured Xavier history budget is not allocated for recurrent models. Full-attention GPU/CPU history behavior is unchanged.
  • Preserve handoff metadata in the multimodal chat response conversion. Native NIXL text-only multimodal launches require vLLM >=0.22.0, and its subprocess environment defaults to DS convolution-state layout while respecting explicit overrides.
  • Update user-facing launch limitations and all nine translations; implementation details stay in the Xavier README.

Upstream GDN support was merged in vLLM #41869. The merge is included in v0.22.0 but not v0.21.0. Stock 0.21.0 was verified to reject GDN in native NIXL's convolution-state setup; Xavier's custom whole-state transfer works on 0.21.0.

Validation:

  • Local focused Xavier and native-PD suite after rebasing onto REF: extract shared Xavier core and Torch backend #5629: 413 passed, 24 skipped, 1 deselected (including the shared Xavier core tests). The legacy test_xavier.py::test_block_tracker assertion also fails on the unchanged base and was excluded from the final focused run.
  • GPU: two RTX 3090 Ti GPUs with NVLink, xoscar 0.11.1, NIXL 1.1.0, Qwen3.5-0.8B, BF16, TP=PP=1, eager execution, max model length 2048, prefix caching disabled. Native NIXL uses DS convolution layout; Xavier has also been revalidated with the environment override removed (default SD layout). Each backend is compared against a standalone engine using the same vLLM version. Both short/fixed-answer and long prompts are repeated and issued concurrently, with actual remote-transfer log assertions.
  • Xavier / vLLM 0.21.0: six P/D outputs match standalone; GPU regression passed both in the original DS run and in the review-fix run with default SD layout (80.02 seconds after rebasing onto REF: extract shared Xavier core and Torch backend #5629, including setup/teardown).
  • Native NIXL / stock vLLM 0.22.0 in an isolated overlay: six P/D outputs match standalone; GPU regression passed.
  • An earlier open-ended arithmetic prompt matched serially but produced different, correct wording in one native NIXL concurrent response. The final exact-output regression uses a fixed-answer short prompt plus a long explanatory prompt. These runs establish functional coverage, not universal batch-invariant generation, recurrent cache-hit reuse, or a throughput advantage.
  • Modified-file pre-commit; all locale catalogs checked with msgfmt, compiled with build_i18n.py --all, and the page built in English and all nine maintained languages.

Reproduce GPU checks with XINFERENCE_TEST_PD_RECURRENT_GPU=1 and XINFERENCE_TEST_PD_RECURRENT_MODEL_PATH pointing to Qwen3.5-0.8B, then run xinference/model/llm/vllm/xavier/test/test_pd_recurrent_gpu.py. The native case skips vLLM versions below 0.22.0.

@XprobeBot XprobeBot added enhancement New feature or request gpu labels Oct 4, 2026
@XprobeBot XprobeBot added this to the v3.x milestone Oct 4, 2026
@qinxuye
qinxuye requested a review from rogercloud October 4, 2026 16:58

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

Major

  • xinference/model/llm/vllm/xavier/engine.py:110 — forcing disable_hybrid_kv_cache_manager=False for every Xavier engine breaks direct handoff for non-recurrent hybrid-attention models on vLLM 0.21 (see inline). Scope it to models with recurrent cache groups.

Minor

  • xinference/model/llm/vllm/core.py:817 — recurrent mode needs enable_prefix_caching=False and async_scheduling=False, but Xavier defaults prefix caching to True and neither setting is validated, so the documented launch fails with only a mamba_cache_mode=none error and async scheduling is silently left on. Default both off for recurrent Xavier launches, or reject them in XavierConnector.__init__ with a message naming the settings.
  • xinference/model/llm/vllm/xavier/v1_connector.py:556 — malformed/mismatched blocks_by_group raises inside the scheduler hook (see inline).
  • xinference/model/llm/vllm/xavier/v1_connector.py:564 — stale request.num_computed_tokens in update_state_after_alloc (see inline).
  • xinference/model/llm/vllm/xavier/v1_connector.py:1195 — layout detection skips the 2-block ambiguity guard (see inline).
  • xinference/model/llm/vllm/xavier/test/test_recurrent_handoff.py:77, xinference/model/llm/vllm/xavier/test/test_pd_recurrent_gpu.py:56 — missing rejection-path tests and forced conv layout for Xavier (see inline).

Simplification

  • xinference/model/llm/vllm/xavier/v1_connector.py L394/L633/L733/L1189: shrink: getattr(self, "_has_recurrent_cache", False) is unnecessary since __init__ always sets it. Use self._has_recurrent_cache as the other call sites do.
    net: -0 lines possible (consistency only)

Blocking: no — recommended event: APPROVE

Comment thread xinference/model/llm/vllm/xavier/engine.py
Comment thread xinference/model/llm/vllm/xavier/v1_connector.py
Comment thread xinference/model/llm/vllm/xavier/v1_connector.py Outdated
Comment thread xinference/model/llm/vllm/xavier/v1_connector.py Outdated
Comment thread xinference/model/llm/vllm/xavier/test/test_recurrent_handoff.py Outdated
Comment thread xinference/model/llm/vllm/xavier/test/test_pd_recurrent_gpu.py Outdated
@qinxuye
qinxuye force-pushed the feat/xavier-hybrid-handoff branch from 97c4e70 to bee6299 Compare October 4, 2026 17:39
@qinxuye

qinxuye commented Oct 4, 2026

Copy link
Copy Markdown
Contributor Author

Addressed all six review threads in final head bee629956 and the summary feedback. Rebased onto the merged shared-Xavier extraction (#5629); per-layer block authorization and the common layout helper now live in the shared Torch backend while compatibility aliases remain intact.

Recurrent launch defaults now disable prefix caching and async scheduling, with clear errors for enabling either. HMA is defaulted on only for recurrent vLLM 0.21 launches and preserves explicit user settings. Mismatched handoff groups trigger local recomputation before claiming a ticket; grouped loads retain the scheduler-provided local-hit offset. The redundant _has_recurrent_cache getattr fallbacks were removed.

Validation: 413 passed, 24 skipped, one previously confirmed unchanged-base failure deselected; modified-file pre-commit passed. After rebasing, Xavier's GPU regression passed again (80.02s) with the DS environment override removed, covering default SD layout with actual KV loads and six outputs matching standalone.

@qinxuye
qinxuye merged commit 89090ef into xorbitsai:main Oct 4, 2026
14 of 15 checks passed
@qinxuye
qinxuye deleted the feat/xavier-hybrid-handoff branch October 4, 2026 19:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request gpu

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants