feat: add opt-in FIA decode for Qwen3.5. - #2240
Conversation
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 算子性能更好吧,直接替换掉?开关太多了,有些开关没必要 |
没看懂,使用FIA之后性能变差了吗? |
一般情况下FIA性能更好。在并发1,上下文8192的时候,这几个模型出现使用 FIA 后性能变差的特例 |
a3667fa to
f09bd90
Compare
|
已完成本轮收敛并更新 PR,麻烦各位 reviewer 重新审查:
CI 当前 format-check、python-lint、build 已通过,其余 check-sensitive 正在排队。 |
| attn_metadata.expanded_decode.kv_seq_lens_host_vec) { | ||
| expanded_kv_seq_lens.emplace_back(kv_seq_len); | ||
| } | ||
| kv_seq_lens_vec = &expanded_kv_seq_lens; |
There was a problem hiding this comment.
这里即使没有打开 FIA,也会先把 expanded KV 长度从 int32 vector 拷成新的 int64 vector,然后才在下面回到 PA。Qwen3.5 MTP verify 的每个 full-attention layer、每个 decode step 都会走到这里,相当于默认路径平白多了一次 CPU 内存分配和拷贝,可能吃掉 #1962 刚省下来的 host gap。
建议把这段构造挪到 PA 的两个 early return 之后,只在真正走 FIA 时执行。同类的 SpecVerifyGraphTaskSignal::expanded_kv_seq_lens 也建议只在 graph 确实包含 FIA task 时准备。
另外请补一组 main vs 本 PR、两边都关闭 FIA 的 MTP A/B。现在 PR 里的 PA/FIA 对比是在本 PR 内切换开关,抓不到这种“默认路径也变慢”的回退。
There was a problem hiding this comment.
已按建议修改:
- expanded KV 转换已移到 PA early return 之后,关闭 FIA 时不再产生额外 vector 分配和拷贝。
- SpecVerifyGraphTaskSignal 不再保存 expanded vector,仅在 Graph 实际包含 FIA task 时准备相关参数。
- 补充了 main vs PR、双方关闭 FIA 的 MTP A/B:bs1/512 和 bs32/512 均通过性能门限。
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>
f09bd90 to
6835765
Compare
Qwen3.5 可选 FIA Decode 路径(默认 PA)
改动
--enable_fia_decode=true时启用 FIA。动机与范围
PA decode 无法输出后续 DCP 所需的 per-rank softmax LSE,FIA 可以提供该输出。本 PR 只提供可选 FIA decode 基础能力,不实现 DCP、跨 rank LSE 合并或 online-softmax 通信。
启用 FIA 时,Qwen3.5 Target 与 Draft 会一起切换;支持的 model type 为:
qwen3_5、qwen3_5_text、qwen3_5_moe、qwen3_5_moe_text、qwen3_5_mtp、qwen3_5_moe_mtp。验证
当前 HEAD:
68357655,基于 upstream/main3906f5a9。git diff --check、clang-format:PASS。默认 PA 热路径
Reviewer 指出的 FIA-only metadata 提前构造已修复。真实 upstream main vs 本 PR、双方关闭 FIA 的 4B Target + MTP Draft Graph A/B:
bs1/ctx512:median TPOT+1.61%,p95+1.61%。bs32/ctx512:median TPOT+0.00%,p95-1.28%。均通过 3%/5% gate;结论为“未检测到超过 gate 的默认 PA 回退”。
性能与 Profiling
全家族 Graph PA/FIA 矩阵为 32/36 shape PASS。已知 exception 均为
bs=1, context=8192:4B+3.1%、9B+3.4%、27B TP2+3.9%、35B-A3B TP2+8.4%TPOT;其余 shape 基本持平。最新 HEAD 定向复测再次确认该现象:4B
+4.1%,35B-A3B TP2+8.4%。msprof 结果显示:
0.07–0.14 ms/decode step。bs1/ctx8192,FIA attention kernel 每步比 PA 多约0.49 ms(4B)和0.87 ms(35B-A3B),与端到端差值基本吻合。因此长上下文退化主要来自 FIA 在
D=256, bs=1下的 kernel shape 特性;host task-update 是次要固定开销。使用方式
默认行为不变。需要启用 Qwen3.5 Target/Draft FIA decode 时:
FIA 开关与既有 Graph 配置独立:Graph 关闭时使用 eager FIA;Graph 开启时使用 FIA Graph;超过既有 Graph batch limit 时沿用原逻辑回落 eager FIA。
已知限制 / 非目标
bs1/ctx8192是明确记录的性能 exception,尤其 35B-A3B TP2 约+8.4%。