feat: migrate Qwen3.5 decode attention from PA to FIA. - #2240
Conversation
Replace batch_decode (ATB PagedAttention) with npu_fused_infer_attention (aclnnFusedInferAttentionScoreV3) for all Qwen3.5 decode paths: eager, regular graph (task-group capture/replay + bucket workspace sharing), and expanded spec/MTP graph (per-token expanded kv_seq_lens). This is a prerequisite for DCP which needs per-rank softmax LSE that only FIA can emit via softmaxLseFlag. DCP itself is NOT included. Key changes: - 4-branch decode routing in attention.cpp gated by is_qwen3_5_model_type() - FIA .out wrapper + _get_max_workspace in npu_fused_infer_attention.cpp - FusedInferAttentionGraphTask with workspace signature for graph capture - GDN/FIA capture-order coexistence in acl_graph_executor_impl - Expanded kv_seq_lens for spec/MTP verify in mtp_worker_impl - --disable_fia_decode runtime switch to fall back to PA without rebuild - Comprehensive tests for FIA ops, graph capture/replay, routing isolation Verified: 4-model family (4B/9B/27B/35B) correctness, GSM8K precision (4-model untruncated layer answer diff=0), Qwen3-Next isolation (FIA=0), MTP 0.86 memory, graph perf matrix 32/36 PASS + 4 bs1/8192 waived. Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
This PR migrates Qwen3.5 decode attention on NPU from PagedAttention (PA) to fused-infer-attention (FIA), including ACL-graph capture/replay support and a runtime rollback switch.
Changes:
- Route Qwen3.5 eager decode + ACL-graph decode (regular + expanded spec/MTP) through FIA while keeping other model families on PA.
- Add FIA graph-task capture/update plumbing (fixed outputs/workspaces, capture ordering, workspace sharing, spec-verify static task signaling).
- Introduce a fail-closed Qwen3.5 allowlist and
--disable_fia_decoderollback flag; expand tests for graph task update and routing.
Reviewed changes
Copilot reviewed 24 out of 24 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| xllm/core/runtime/worker_impl.h | Adds ownership hook for linear-state cache to avoid composite restoring state incorrectly. |
| xllm/core/runtime/worker_impl.cpp | Gates linear-state slot restore on owns_linear_state_cache(). |
| xllm/core/runtime/speculative_worker_impl.h | Disables linear-state cache ownership for speculative composite workers. |
| xllm/core/runtime/mtp_worker_impl.cpp | Builds expanded KV seq-lens signal for static spec-verify FIA tasks. |
| xllm/core/runtime/executor_impl.h | Extends spec-verify task signal with expanded KV seq-lens. |
| xllm/core/runtime/acl_graph_persistent_param.h | Adds update_paged_attention_plan switch to skip PA planning when FIA tasks are present. |
| xllm/core/runtime/acl_graph_persistent_param.cpp | Implements conditional PA plan update gated by the new flag. |
| xllm/core/runtime/acl_graph_executor_impl.h | Adds FIA task presence check + replaces static graph signaling API with a signal payload. |
| xllm/core/runtime/acl_graph_executor_impl.cpp | Adds FIA graph-task update + static-task preparation + skips PA plan update when FIA tasks exist. |
| xllm/core/platform/npu/acl_graph_task_update_context.h | Adds FIA graph-task structs, capture ordering, and per-bucket shared workspace tracking. |
| xllm/core/layers/npu_torch/qwen3_next_attention.h | Exposes Qwen3.5 model-type allowlist helper. |
| xllm/core/layers/npu_torch/qwen3_next_attention.cpp | Enables FIA decode only for whitelisted Qwen3.5 model types and honor disable_fia_decode. |
| xllm/core/layers/npu_torch/qwen3_gated_delta_net_base.cpp | Captures ordered causal-conv task update information. |
| xllm/core/layers/npu_torch/attention.h | Adds enable_fia_decode constructor flag and stores it in the module. |
| xllm/core/layers/npu_torch/attention.cpp | Implements FIA eager + ACL-graph decode paths, workspace sharing, and task registration. |
| xllm/core/layers/common/attention_metadata_builder.cpp | Threads acl_graph_task_update_context into attention metadata. |
| xllm/core/layers/common/attention_metadata.h | Adds acl_graph_task_update_context to AttentionMetadata. |
| xllm/core/kernels/npu/npu_ops_api.h | Adds FIA decode get_max_workspace and *_out APIs. |
| xllm/core/kernels/npu/npu_fused_infer_attention.cpp | Implements decode workspace query + out-variant via dispatcher schema. |
| xllm/core/framework/config/execution_config.h | Adds disable_fia_decode config property. |
| xllm/core/framework/config/execution_config.cpp | Adds flag/json plumbing for disable_fia_decode. |
| tests/core/runtime/acl_graph_task_update_test.cpp | Adds tests for FIA task capture, workspace sharing, and padding replay correctness across buckets. |
| tests/core/runtime/acl_graph_executor_test.cpp | Adds tests for Qwen3.5 model-type whitelist and updates static task signature fixtures. |
| tests/core/kernels/npu/npu_xllm_ops_test.cpp | Adds correctness test for FIA decode out-variant across block boundary. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 24 out of 24 changed files in this pull request and generated no new comments.
Suppressed comments (1)
xllm/core/platform/npu/acl_graph_task_update_context.h:87
FusedInferAttentionWorkspaceSignatureis declared as astructbut defines a member function (operator==). The project style guide states structs should be plain data aggregation only; if methods are needed, use aclassinstead. Converting this to aclasskeeps behavior the same while aligning with the established convention.
double scale;
bool operator==(const FusedInferAttentionWorkspaceSignature&) const = default;
};
|
FIA 算子性能更好吧,直接替换掉?开关太多了,有些开关没必要 |
| "or any torch.compile backend name."); | ||
|
|
||
| DEFINE_bool( | ||
| disable_fia_decode, |
There was a problem hiding this comment.
disable_fia_decode 这个开关有必要吗
没看懂,使用FIA之后性能变差了吗? |
一般情况下FIA性能更好。在并发1,上下文8192的时候,这几个模型出现使用 FIA 后性能变差的特例 |
Qwen3.5 Decode Attention 从 PA 迁移至 FIA
改动概述
npu_fused_infer_attention(FIA)。model_type精确白名单,并新增--disable_fia_decode运行时回退开关。背景与动机
PagedAttention decode 无法输出每个 rank 的 softmax LSE,而 FIA 提供了所需的输出接口。将 Qwen3.5 decode 迁移至 FIA,可为后续 Decode Context Parallel 工作准备统一的 attention 路径。
本 PR 仅包含 FIA 替换,不实现 DCP、跨 rank LSE 合并或 online-softmax 通信。
路由范围
--disable_fia_decode=true后,无需重新编译即可让 Qwen3.5 decode 回到 PA。FIA opt-in 使用精确的模型类型白名单:
qwen3_5、qwen3_5_text、qwen3_5_moe、qwen3_5_moe_text、qwen3_5_mtp、qwen3_5_moe_mtp。Graph 实现
.outschema 固定 attention/LSE 输出 Tensor 和 workspace 地址。验证结果
最终 Rebase、构建与单元测试
c23624bf4cbe92ec8f0c7e60b0aa6a76d796d89d。df9f919cfea6。2ed1b29154654f11a394f51b07bb18d4bd991f98cab36b39fb9da4549d07b2d0。git diff --check:PASS。clang-format --dry-run --Werror。acl_graph_task_update_test:8/8。acl_graph_executor_test:23/23。mtp_async_state_test:13/13。npu_xllm_ops_test:7 PASS,2 个 Ascend950/A5 专项 SKIP。hf_model_loader_test:8/8。spec_input_builder_test:29/29。kv_cache_test:22 PASS,1 个 MLU 专项 SKIP。pd_topology_guard_test:18/18。服务正确性与兼容性
{4,8,16,32,48,96}。任务级精度
使用 EvalScope GSM8K,在 graph-on、并发 32、
max_tokens=16384配置下,对 Qwen3.5-4B、9B、27B、35B-A3B 分别运行 PA/FIA 各 200 题。McNemar 配对检验未发现 FIA 存在统计显著的负向精度变化;双方均未截断的样本中,FIA 与 PA 持平或 FIA 更优。性能
常规 Graph PA/FIA 矩阵覆盖 4 个模型 × 9 个 shape。测试显式使用
enable_graph=true、acl_graph_decode_batch_size_limit=32,确认 6 个 bucket 全部 capture,并按 median TPOT 3%、p95 5%、median decode 3% 的门限验收。bs=1, context=8192exception:生产启动参数
Graph 性能结论依赖以下显式配置:
当前源码默认关闭 Graph,且 batch limit 默认为 16。如果生产环境没有显式设置这些参数,decode 会使用 eager FIA,或者在 batch size 超过 Graph limit 时静默回落 eager。
已知限制
bs=1, context=8192是已记录的 FIA Graph 性能 exception;35B-A3B 的 +8.4% 不作为 PASS 上报。非目标