Repository navigation
[Hardware][Ascend] Enable LingBot-World realtime benchmark on 4x Ascend 910B1 - #8112
Conversation
|
This PR appears to belong to: docs/design/module/benchmarking.md, docs/design/module/diffusion/diffusion_model_integration.md, docs/design/module/diffusion/index.md. Module owners: @wtomin @david6666666 @Isotr0py Routing: @wtomin via module of the changed files, module named in the PR description, CODEOWNERS; @david6666666 via module of the changed files, module named in the PR description; @Isotr0py via module of the changed files, module named in the PR description @Dong1017, please review your own changes and leave a short self-review comment describing what you checked. PRs without author self-review may not be assigned a reviewer. Please take a look when you have a chance. If you would like an automated review, mention @vllm-omni-review-bot in a comment. |
- paged_attention: the NPU branch of ar_diffusion_paged_attention gathers the visible window and calls npu_fusion_attention; _to_device_async covers NPU pinned async copies - transformer: the NPU direct-replay path routes through the paged attention entry so replay stays a numerical oracle on this device Signed-off-by: GUOGUO <xwdong1998@163.com>
92381bb to
2c06982
Compare
The contiguous-gather NPU path masked rows of the unflattened gather with a (max_seq_len,) mask, packing along the wrong axis; flatten to (max_seq_len, H, D) first and slice the visible prefix (seq_lens[0]) instead of assuming the full window. npu_fusion_attention with input_layout="TND" also requires per-sequence actual_seq_qlen / actual_seq_kvlen; derive them from query_start_loc and seq_lens. Signed-off-by: GUOGUO <xwdong1998@163.com>
4x910B1 (64GB) Ulysses SP-4 deploy config mirroring the GPU usp4_compiled realtime topology in eager mode: torch.compile / CUDA-graph paths are GPU-only, so enforce_eager is set. Four cards are required because the single-card geometry (weights plus one session's KV window) does not fit in 64GB. Signed-off-by: GUOGUO <xwdong1998@163.com>
RotaryEmbeddingWan.forward_native received (local_tokens, rope_dim) on the Ulysses SP path and multiplied it against (B, S, H, D/2), failing with a dim-2 size mismatch (40 heads vs 1170 local tokens) on the NPU fallback where mindiesd is absent. Expand 2D cos/sin to (1, S, 1, D/2) so it broadcasts over batch and heads, matching the CUDA kernel-facing layout. Signed-off-by: GUOGUO <xwdong1998@163.com>
2c06982 to
ef173f6
Compare
Upstream returns (None, None) when staging is disabled and narrows the attention window inside the custom op. NPU eager dispatch of the fused write+attend custom op rejects None for a tensor argument declared mutable, so return zero-size buffers on that path; the op already treats an empty stage_key/stage_value as fresh-allocation and gathers the visible window itself. Signed-off-by: GUOGUO <xwdong1998@163.com>
ef173f6 to
9678c60
Compare
Self-review notesRan the project's Issues found and fixed during self-review
Checks performed
Known limitations (disclosed)
|
Omni ReviewBot triage noteAutomated triage of commit
These are automated triage suggestions only — the final decision belongs to the maintainers. |
RotaryEmbeddingWan._rotary_embedding and its SP input hook produce 2D (seq_len, rope_dim) tables - the same layout the CUDA and MindIE kernels face - and the native fallback must broadcast them over (B, S, H, D) instead of mis-aligning against the head dim (SP shards the sequence, not the heads). Assert the 2D result equals the manually expanded (1, S, 1, D/2) form bit for bit. Signed-off-by: GUOGUO <xwdong1998@163.com>
95a2d2f to
91498a3
Compare
Signed-off-by: GUOGUO <xwdong1998@163.com>
05dbe11 to
e1da6cd
Compare
…A and NPU Signed-off-by: GUOGUO <xwdong1998@163.com>
Omni ReviewBot routing recordAssigned Direct under experiment |
vllm-omni-review-bot
left a comment
There was a problem hiding this comment.
Omni ReviewBot review
PR description
This PR enables LingBot-World realtime on Ascend by fixing Wan native RoPE to broadcast SP-sharded 2D cos/sin over batch and heads, adding an NPU gather + npu_fusion_attention path in AR-Diffusion paged attention (with NPU-only empty staging buffers for the mutable custom-op contract), and routing the transformer direct-replay oracle through that same entry on NPU. It also adds a 4×910B1 Ulysses SP-4 eager deploy YAML because the single-card weight+KV footprint exceeds 64 GB. User-visible result: the previously broken Ascend realtime stack can serve the benchmark end-to-end in eager mode; CUDA/ROCm attention math paths are intended to stay unchanged.
Change flow
flowchart TD
A["[EXISTING] Realtime serve / SP-4 session"]:::existing --> B["[NEW] npu_usp4_eager.yaml"]:::new
A --> C["[CHANGED] RotaryEmbeddingWan 2D cos/sin broadcast"]:::changed
A --> D["[CHANGED] ar_diffusion_paged_attention NPU gather+fusion"]:::changed
D --> E["[CHANGED] LingBot self-attn NPU direct-replay routing"]:::changed
B --> F["[EXISTING] 4x 910B1 eager realtime chunks"]:::existing
C --> F
E --> F
classDef existing fill:#e5e7eb,stroke:#6b7280,color:#111827
classDef changed fill:#fef3c7,stroke:#d97706,color:#451a03,stroke-width:2px
classDef new fill:#dcfce7,stroke:#16a34a,color:#052e16,stroke-width:2px
classDef removed fill:#fee2e2,stroke:#dc2626,color:#450a0a,stroke-width:2px
CI at
da549760647d(2026-09-30T20:14:11.573540+00:00): required check(s) blocking:buildkite/vllm-omni(missing).
See inline comments below.
🤖 This review was generated by InferMatrix Copilot, an open-source repo-maintenance agent for PR review, CI debugging and issue triage. Try it on your own repo, and ⭐ star it if it helped!
| else: | ||
| query_flat = query | ||
|
|
||
| if query_flat.is_npu: |
There was a problem hiding this comment.
[P1] Shared paged-attention entry uses Tensor.is_npu before CUDA/CPU dispatch
ar_diffusion_paged_attention now gates on query_flat.is_npu before any CUDA/ROCm/reference branch. Stock PyTorch does not define Tensor.is_npu unless torch_npu (or an equivalent PrivateUse1 rename) has registered it, so CUDA/CPU callers can raise AttributeError before reaching FlashAttention or _reference_paged_attention. The same file already uses the portable guard k_pool.device.type == "npu" for staging; the hot path should match (query_flat.device.type == "npu") so GPU-only machines stay on the existing paths. Author CPU/e2e evidence used a torch_npu-bearing stack, which masks this on non-Ascend CI images.
| # realtime path so direct replay is a numerical oracle for | ||
| # paged execution, rather than a comparison between two | ||
| # different attention kernels. | ||
| if (query.is_cuda or query.is_npu) and query.shape[0] == 1: |
There was a problem hiding this comment.
[P2] Direct-replay NPU guard can AttributeError on CPU tensors
The direct-replay condition is now (query.is_cuda or query.is_npu). CUDA short-circuits safely, but on CPU is_cuda is false so Python evaluates query.is_npu; without torch_npu that raises instead of falling through to the prior dense self.attn oracle path. Prefer query.device.type == "npu" (same portable check as staging) so CPU direct-replay keeps working on non-NPU installs.
Omni ReviewBot: finding feedback[p1] Shared paged-attention entry uses Tensor.is_npu before CUDA/CPU dispatch —
This finding appears in the bot's COMMENT review, but GitHub could not place it as an inline diff comment. If you are the PR author and disagree, react 👎 to this comment. The disagreement will be shown to the maintainer; it does not approve or merge the PR. |
Omni ReviewBot: no human activity for 13 days@Dong1017 this pull request has had no human commit, comment or review since 2026-09-24. Please confirm the current plan and next step. The author or a maintainer decides whether to change the PR state. To keep it moving, any one of these is enough: push an update, reply to the open blocker, or post the current plan and timeline. |
|
@tzhouam, could you review the Ascend enablement in this PR, especially the NPU paged-attention/staging path and the Wan RoPE broadcast fix? Thank you. |
Use device.type for NPU dispatch so CPU and CUDA callers without torch_npu can reach their existing attention paths. Signed-off-by: Dong1017 <55723162+Dong1017@users.noreply.github.com>
vllm-omni-review-bot
left a comment
There was a problem hiding this comment.
Omni ReviewBot review
Changes since the previous review
- 0 new inline finding(s); 0 finding(s) below.
- Fixed: Shared paged-attention entry uses Tensor.is_npu before CUDA/CPU dispatch —
vllm_omni/experimental/ar_diffusion/kv_cache/paged_attention.py - Fixed: Direct-replay NPU guard can AttributeError on CPU tensors —
vllm_omni/diffusion/models/lingbot_world/transformer.py
CI at
c31d46153438(2026-10-08T03:58:42.806795+00:00): required check(s) blocking:pre-commit(pending),buildkite/vllm-omni(missing),docs/readthedocs.org:vllm-omni(pending).
Full review analysis
PR description
This PR makes the LingBot-World realtime stack runnable on four Ascend 910B1 cards in eager Ulysses sequence-parallel 4. Shared Wan native RoPE now expands 2D (local_tokens, rope_dim) cos/sin to (1, S, 1, D/2) so sequence-parallel tokens broadcast over batch and heads instead of lining up with the head axis. On NPU, paged self-attention gathers the valid prefix of the block table and calls npu_fusion_attention with TND lengths; direct replay uses that same entry, and disabled history staging passes empty tensors so the fused write+attend op can dispatch. A new deploy file pins four devices, eager execution, and the 480×832 KV fraction used for the reported end-to-end benchmark.
Change flow
flowchart LR
cfg["[NEW] npu_usp4_eager.yaml"]:::new
serve["[EXISTING] LingBot realtime forward"]:::existing
rope["[CHANGED] Wan forward_native 2D RoPE"]:::changed
route["[CHANGED] Direct-replay NPU guard"]:::changed
attn["[CHANGED] NPU paged fusion attention"]:::changed
video["[EXISTING] Eager Ulysses SP-4 chunks"]:::existing
cfg --> serve
serve --> rope
serve --> route
route --> attn
rope --> video
attn --> video
classDef existing fill:#e5e7eb,stroke:#6b7280,color:#111827
classDef changed fill:#fef3c7,stroke:#d97706,color:#451a03,stroke-width:2px
classDef new fill:#dcfce7,stroke:#16a34a,color:#052e16,stroke-width:2px
classDef removed fill:#fee2e2,stroke:#dc2626,color:#450a0a,stroke-width:2px
🤖 This review was generated by InferMatrix Copilot, an open-source repo-maintenance agent for PR review, CI debugging and issue triage. Try it on your own repo, and ⭐ star it if it helped!
c31d461 to
30f48c1
Compare
vllm-omni-review-bot
left a comment
There was a problem hiding this comment.
Omni ReviewBot review
0 actionable finding(s).
CI at
7d7d9941a2af(2026-10-08T20:19:22.518876+00:00): required check(s) blocking:buildkite/vllm-omni(missing).
Full review analysis
PR description
This change makes the LingBot-World realtime benchmark runnable in eager mode on four Ascend 910B1 cards with Ulysses sequence parallel 4. Wan's native rotary path expands sequence-by-rope 2D cos/sin so those tables broadcast across batch and heads. On NPU, paged self-attention gathers the visible KV window and calls npu_fusion_attention; the direct-replay path uses that same entry; and disabled history staging passes empty tensors so the fused write-and-attend op can accept its mutable arguments. The new deploy file pins the four-card eager topology, 480×832 resolution, and KV memory fraction used for that run.
Change flow
flowchart LR
serve["[EXISTING] LingBot realtime serve"]:::existing
yaml["[NEW] npu_usp4_eager.yaml"]:::new
rope["[CHANGED] Wan native RoPE broadcast"]:::changed
attn["[CHANGED] NPU paged attention gather"]:::changed
route["[CHANGED] NPU direct-replay routing"]:::changed
bench["[EXISTING] Eager SP-4 chunk loop"]:::existing
serve --> yaml
yaml --> rope
rope --> attn
attn --> route
route --> bench
classDef existing fill:#e5e7eb,stroke:#6b7280,color:#111827
classDef changed fill:#fef3c7,stroke:#d97706,color:#451a03,stroke-width:2px
classDef new fill:#dcfce7,stroke:#16a34a,color:#052e16,stroke-width:2px
classDef removed fill:#fee2e2,stroke:#dc2626,color:#450a0a,stroke-width:2px
No actionable findings.
🤖 This review was generated by InferMatrix Copilot, an open-source repo-maintenance agent for PR review, CI debugging and issue triage. Try it on your own repo, and ⭐ star it if it helped!
…he NPU path Replace the per-token advanced-indexing gather of the visible KV window with one whole-block index_select followed by flatten+truncate on NPU. The row mapping is identical (same block_table), so outputs are byte-identical: 477-frame precodec capture and independent RGB/PTS decode match the per-token implementation exactly on 910C. Measured on 4x Ascend 910C1 (SP4/Ulysses4, eager, 832x480, seed42, 4 DMD steps, 40 chunks/477 frames, teaser input): - full-request latency 108291 -> 103890 ms median (-4.06%), 3 alternating AB/BA trials via OmniRSI, trial spread < 0.4% - SP8 (8 dies): steady chunk-interval median 1713.9 -> 1587.5 ms (-7.4%), P99 2002.6 -> 1907.0 ms
Omni ReviewBot: three questions on the performance claim@Dong1017 this PR reads as a performance or value claim:
Before the full evidence checklist, three short questions:
When you answer, the evidence that settles it is: base and head SHA, hardware, model, workload, warm-up and repeat count, mean or percentiles with their spread, and a correctness/quality-equivalence signal; an end-to-end claim also needs stage attribution. |
Purpose
Upstream
maincannot run the LingBot-World realtime benchmark on Ascend NPU: the first failure isRotaryEmbeddingWan.forward_nativereceiving SP-sharded 2D cos/sin (dim-2 mismatch, 40 heads vs 1170 local tokens), and the AR-Diffusion paged-attention NPU path has no working attention call. This PR carries the NPU enablement for the realtime streaming stack (#7645) somainruns end-to-end on 4x Ascend 910B1 with Ulysses SP-4 in eager mode.The change surface is kept minimal — four files: the rope broadcast fix, the paged-attention NPU path, the transformer routing, and the validated 4-card deploy config. All NPU branches are device-guarded (
query.is_npu,device.type == "npu", lazyimport torch_npuinside NPU-only branches); GPU/CUDA paths are untouched.Changes (6 commits):
ar_diffusion_paged_attentionNPU branch gathers the visible window and callsnpu_fusion_attention;_to_device_asynccovers NPU pinned async copies; the transformer direct-replay path routes through the paged attention entry on NPU.npu_fusion_attentionwithinput_layout="TND"now receives per-sequenceactual_seq_qlen/actual_seq_kvlenderived fromquery_start_loc/seq_lens.npu_usp4_eager.yaml, the 4-card Ulysses SP-4 eager deploy config. Four cards are required because the single-card geometry (weights plus one session's KV window) does not fit in 64 GB; torch.compile / CUDA-graph paths are GPU-only, soenforce_eageris set.(None, None)when staging is disabled — NPU eager dispatch of the fused write+attend custom op rejectsNonefor a tensor argument declared mutable, and the op treats an empty stage buffer likeNone(fresh allocation). Other devices keep the upstreamNonecontract. Upstream's op-internal window narrowing ([Bugfix][Core] Preserve static KV staging inputs in AR-Diffusion #7921) is untouched, and the e2e check below confirms numerical equivalence on NPU.Test Plan
benchmarks/lingbot_world/benchmark_lingbot_world_realtime.py, LingBot-World 2.0 14B, 4x Ascend 910B1 (64 GB), Ulysses SP-4, eager, 32 chunks/session, two independent server+bench runs:pytest tests/diffusion/ar_diffusion/test_paged_attention.py tests/diffusion/ar_diffusion/test_kv_cache.py tests/diffusion/layers/test_rope_broadcast.py tests/benchmarks/test_lingbot_world_realtime.py→ 166 passed, 14 skipped (includes the 2D-layout regression test above)vLLM Version: vllm 0.29.0 / vllm-omni main + this branch, torch 2.10.0, torch_npu 2.10.0.post4, vllm-ascend 0.19.1rc2.dev2045, triton_ascend 3.2.2
vLLM-Omni Commit: 91498a3 (test-only commit on top of 9678c60, where the e2e runs below were validated)
Test Result
main+ this branch starts the server and serves the realtime benchmark end-to-end on 4x 910B1 (previously impossible on NPU).Eager mode only; compiled execution on NPU (torchair / ACL graph) and the framework-side memory-management follow-ups are tracked in #7382.
Performance: whole-block index_select KV gather on NPU (2026-10-14, commit 7c7d9d3)
ar_diffusion_paged_attention's NPU branch now gathers the visible KV window with one whole-blockindex_select+ flatten + truncate instead of per-token advanced indexing. The row mapping is identical (sameblock_table), so outputs are byte-identical; 477-frame precodec capture and independent RGB/PTS decode match the per-token implementation exactly.Measured on 4x Ascend 910C1 (SP4/Ulysses4, TP1, BF16 eager, 832×480, seed42, 4 DMD steps, 40 chunks/477 frames, fixed teaser input; OmniRSI 3× alternating AB/BA, trial spread < 0.4%):
SP8 screening (8 dies on one 910C1 node, same workload, steady chunk inter-arrival, n=33):
Environment note: the contiguous-KV behavioral patch in the NPU platform (
requires_contiguous_pa_kv_cache) exists in vllm-ascend dev2045 (the CI image above) but not in newer dev builds (dev2552); environments on newer vllm-ascend need that helper restored or the patch guarded.