Skip to content

Feat/pcp qwen36 hybrid - #299

Open
Yopry wants to merge 7 commits into
flagos-ai:mainfrom
Yopry:feat/pcp-qwen36-hybrid
Open

Feat/pcp qwen36 hybrid#299
Yopry wants to merge 7 commits into
flagos-ai:mainfrom
Yopry:feat/pcp-qwen36-hybrid

Conversation

@Yopry

@Yopry Yopry commented Jul 17, 2026

Copy link
Copy Markdown

PR Type

New Features

Description

Enables tensor-parallel + Prefill Context Parallel (PCP) serving of Qwen3.6-style hybrid models (interleaved full-attention +
GatedDeltaNet/linear-attention layers, e.g. Qwen3.6-35B-A3B) on an unmodified vLLM 0.20.2, entirely through monkey-patches installed by the plugin.

vLLM 0.20.2 hard-rejects context parallelism (pcp/dcp > 1) for hybrid/mamba KV-cache layouts (multiple block sizes). This PR lifts that restriction
for Qwen3.6 and adds the sequence-splitting + cross-rank gather logic needed to make prefill run correctly under PCP. Every patch self-gates on
prefill_context_parallel_size > 1, so it is a no-op for non-PCP runs.

Scope is prefill correctness (verified: first-token argmax matches the tp=4, pcp=1 baseline). Decode is out of scope in this PR.

Known limitations:

  • Verified only up to a world size of 4 (tp*pcp ≤ 4: tp2pcp2 / tp4pcp1 / tp1pcp4). Larger configurations are untested.
  • generate() teardown can stall on the max_tokens=1 abort path (use max_tokens ≥ 2); the prefill result itself is correct.
  • Decode under PCP is not handled: full-attention KV is sequence-split, so multi-token generation drifts / can produce NaN (batched decode path).
  • Multi-request batches with unequal lengths are not yet handled (the current gather/last-token logic assumes equal-length batches).

Changes

  • Add vllm_fl/patches/qwen36_pcp.py: the full PCP patch set —
    • Guard patches: bypass the three vLLM hybrid+PCP hard-guards (resolve_kv_cache_block_sizes, HybridKVCacheCoordinator.init,
      MambaManager.find_longest_cache_hit) by presenting pcp==1 to block-size accounting; sequence splitting is done separately at the model-runner level.
    • Sequence splitting: patch the V1 GPUModelRunner._prepare_inputs to give each PCP rank a contiguous local token slice (local num_scheduled_tokens
  • shifted num_computed_tokens), plus a logits gather so the final prompt token's hidden state feeds the LM head.
    • Full-attention layers: sequence-split with a K/V all-gather across PCP ranks + end-aligned causal flash_attn_varlen_func.
    • GDN/linear-attention layers: full-sequence "island" (all-gather hidden into per-request full sequences, run the original GDN scan, slice the
      local segment back out).
  • vllm_fl/init.py: install the patches, including in register_model so worker processes pick them up.

Prefill Context Parallel (PCP) for Qwen3.6 hybrid models

The plugin adds Prefill Context Parallel for the Qwen3.6 hybrid architecture
(Gated DeltaNet linear-attention layers + periodic full-attention layers). The
prompt is split across the PCP ranks; full-attention layers all-gather K/V and
run causal attention over the reconstructed sequence, while the GDN /
linear-attention layers run a redundant full-sequence scan so every rank ends
with the correct recurrent state.

Enable it with --prefill-context-parallel-size N (vllm serve) or
prefill_context_parallel_size=N (LLM(...)).

# PCP currently supports the FlashAttention backend only. FL routes attention
# to FlagGems (Triton) by default, which does not declare PCP support and makes
# engine init fail with "TritonAttentionImpl does not support PCP". Disable the
# FlagGems preference so attention falls back to FlashAttention:
export VLLM_FL_PREFER_ENABLED=0

# If flag_gems fails to detect the device at plugin load ("No device were
# detected"), pin the vendor explicitly:
export GEMS_VENDOR=nvidia

VLLM_PLUGINS=fl vllm serve /path/to/Qwen3.6-35B-A3B \
    --tensor-parallel-size 2 \
    --prefill-context-parallel-size 2 \
    --enforce-eager --trust-remote-code

Set VLLM_PCP_DEBUG=1 to print per-layer [PCP-DBG] traces (sequence split,
K/V all-gather, GDN full-sequence island) for verifying that PCP actually runs.

If you run a CUDA-13 build on a driver that only supports CUDA <= 12.8 and hit
cudaErrorInsufficientDriver, put the bundled forward-compatibility libcuda on
the loader path: export LD_LIBRARY_PATH=/usr/local/cuda-13.0/compat:$LD_LIBRARY_PATH.

Scope / limitations

  • Prefill correctness is verified (e.g. tp=2/pcp=2 matches the non-parallel
    baseline first token, within bf16 rounding).
  • Decode under PCP is a known limitation and not yet supported.
  • PCP currently supports the FlashAttention backend only; the FlagGems Triton
    attention backend does not yet declare supports_pcp.

Testing

  • Hardware: 4×H200, enforce_eager, FlashAttention 2, GDN prefill backend = triton.
  • Correctness: first-token argmax parity between PCP and the tp=4, pcp=1 baseline on Qwen3.6-35B-A3B, verified across context lengths (16k / 64k /
    128k / 256k) and across all three world-size-4 layouts (tp2pcp2, tp4pcp1, tp1pcp4). Matches the baseline golden token.
  • Not covered by the repo test suite: the existing tests/ (incl. the qwen3_6 tp2 configs) run with pcp=1, where these patches are a no-op, so they do
    not exercise the PCP path. Correctness was verified with standalone scripts as above.

Checklist

  • I have run the existing tests and they pass
  • I have added tests for my changes (if applicable)
  • I have updated the documentation (if applicable)

Yopry and others added 3 commits July 8, 2026 12:18
Add vllm_fl/patches/qwen36_pcp.py enabling tensor-parallel +
prefill-context-parallel serving of Qwen3.6-style hybrid models
(interleaved full-attention + GatedDeltaNet layers) on vLLM 0.20.2:

- relax the three hybrid+PCP hard guards (block-size resolve, hybrid
  KV-cache coordinator, mamba cache-hit) so tp*pcp boots
- sequence-split prefill in GPUModelRunner._prepare_inputs
- all-gather K/V causal-prefix attention in FlashAttentionImpl
- GDN full-sequence island (all-gather + redundant scan) for correct
  linear-attention state under the split
- broadcast last-rank sample_hidden_states for correct sampling

Wired into vllm_fl.register(); self-gates on
prefill_context_parallel_size > 1, so it is a no-op without PCP.

Scope: prefill correctness only (token[0] matches tp=4 baseline).
Decode is out of scope (full-attn KV is seq-split, decode KV path not
handled). Known limits: tp*pcp>4 crash, generate() teardown stall.

Signed-off-by: yopry <yopry@users.noreply.github.com>
…fect in workers

The PCP patches were only installed from register() (the platform plugin),
which runs during early platform detection -- before vllm.v1.* attention/
model-runner/kv-cache classes are importable. So every patch hit
`except ImportError` and silently skipped, meaning FlashAttentionImpl.supports_pcp
was never set and the PCP attention-compat guard (cp_utils.check_attention_cp_compatibility)
failed with "impl does not support PCP".

Re-apply the (idempotent) patches from register_model(), the general-plugins
hook, which runs in every worker via load_general_plugins() during init_worker
-- after vLLM is fully imported and before the guard runs. Verified: tp=2/pcp=2
prefill matches the tp=4 baseline (271/271).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add an "Advanced use" section covering the env vars required to run PCP:
VLLM_FL_PREFER_ENABLED=0 (force FlashAttention, since PCP does not support the
FlagGems Triton backend yet), GEMS_VENDOR=nvidia (flag_gems device detection),
the forward-compat LD_LIBRARY_PATH note for CUDA-13-on-old-driver, plus the
--prefill-context-parallel-size flag, VLLM_PCP_DEBUG tracing, and scope/limits.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@CLAassistant

CLAassistant commented Jul 17, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

Yopry added 3 commits July 17, 2026 16:49
Removed section on Prefill Context Parallel (PCP) for Qwen3.6 hybrid models, including usage instructions and limitations.
@github-actions github-actions Bot removed the docs label Jul 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants