Skip to content

feat: add opt-in FIA decode for Qwen3.5. - #2240

Open
Enguikong wants to merge 7 commits into
xLLM-AI:mainfrom
Enguikong:feat/qwen35-fia-decode
Open

feat: add opt-in FIA decode for Qwen3.5.#2240
Enguikong wants to merge 7 commits into
xLLM-AI:mainfrom
Enguikong:feat/qwen35-fia-decode

Conversation

@Enguikong

@Enguikong Enguikong commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Qwen3.5 可选 FIA Decode 路径(默认 PA)

改动

  • 为 Qwen3.5 Target 与 MTP Draft 的 eager decode、常规 ACL Graph decode、expanded spec/MTP Graph decode 增加 FIA 路径。
  • 默认仍使用原有 PagedAttention(PA);仅显式传入 --enable_fia_decode=true 时启用 FIA。
  • 非 Qwen3.5 模型继续使用 PA;既有 prefill 路由不变。
  • FIA Graph 使用固定 output/workspace、task-group capture/replay、动态 KV 长度更新和 bucket 内跨层 workspace 共享。
  • FIA 关闭时不准备 FIA-only expanded KV metadata,避免影响默认 PA/MTP host 热路径。

动机与范围

PA decode 无法输出后续 DCP 所需的 per-rank softmax LSE,FIA 可以提供该输出。本 PR 只提供可选 FIA decode 基础能力,不实现 DCP、跨 rank LSE 合并或 online-softmax 通信

启用 FIA 时,Qwen3.5 Target 与 Draft 会一起切换;支持的 model type 为:

qwen3_5qwen3_5_textqwen3_5_moeqwen3_5_moe_textqwen3_5_mtpqwen3_5_moe_mtp

验证

当前 HEAD:68357655,基于 upstream/main 3906f5a9

  • 标准 NPU build、git diff --check、clang-format:PASS。
  • 定向测试:206 PASS / 3 平台专项 SKIP / 0 FAIL
  • 4B、9B、27B、35B-A3B 已覆盖 eager/Graph decode、mixed batch、chunked-prefill→decode、prefix cache 和 expanded spec/MTP Graph。
  • 4B 与 35B-A3B TP2 的 Graph-FIA vs eager-FIA correctness:均 8/8 完全一致。
  • Qwen3-Next-80B-A3B TP4 隔离测试:FIA decode 命中 0,保持 PA。
  • GSM8K graph-on、并发 32、每模型 PA/FIA 各 200 题:未发现 FIA 存在统计显著的负向精度变化。
  • 服务日志:0 fallback、0 OOM、0 signature error、0 error 507009。

默认 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 结果显示:

  • PA/FIA 的阻塞式 memcpy 与 stream synchronize 调用次数一致,没有新增阻塞式 host 同步。
  • FIA Graph task-update + value-write 约 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 时:

--enable_fia_decode=true

FIA 开关与既有 Graph 配置独立:Graph 关闭时使用 eager FIA;Graph 开启时使用 FIA Graph;超过既有 Graph batch limit 时沿用原逻辑回落 eager FIA。

已知限制 / 非目标

  • bs1/ctx8192 是明确记录的性能 exception,尤其 35B-A3B TP2 约 +8.4%
  • Ascend950/A5 专项需外部硬件补测;本机无 MiniMax M2 真实权重。
  • 不修改 prefill、非 Qwen3.5 decode 或既有 Graph 默认值。
  • 不在本 PR 中引入 shape-aware PA rescue,也不实现 DCP。

Copilot AI 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.

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_decode rollback 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.

Comment thread xllm/core/layers/npu_torch/attention.cpp
Comment thread xllm/core/platform/npu/acl_graph_task_update_context.h Outdated
Comment thread xllm/core/layers/npu_torch/qwen3_next_attention.cpp Outdated
Comment thread xllm/core/runtime/acl_graph_executor_impl.cpp

Copilot AI 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.

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

  • FusedInferAttentionWorkspaceSignature is declared as a struct but defines a member function (operator==). The project style guide states structs should be plain data aggregation only; if methods are needed, use a class instead. Converting this to a class keeps behavior the same while aligning with the established convention.
  double scale;

  bool operator==(const FusedInferAttentionWorkspaceSignature&) const = default;
};

@yingxudeng

Copy link
Copy Markdown
Collaborator

FIA 算子性能更好吧,直接替换掉?开关太多了,有些开关没必要

Comment thread xllm/core/framework/config/execution_config.cpp Outdated
@yingxudeng yingxudeng changed the title feat(npu): migrate Qwen3.5 decode attention from PA to FIA feat: migrate Qwen3.5 decode attention from PA to FIA. Aug 14, 2026
@zhang-minchao

Copy link
Copy Markdown
Collaborator
性能
常规 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% 的门限验收。

32/36 shape PASS。
4 个已记录的 bs=1, context=8192 exception:
4B:TPOT +3.1%。
9B:TPOT +3.4%。
27B TP2:TPOT +3.9%。
35B-A3B TP2:TPOT +8.4%。

没看懂,使用FIA之后性能变差了吗?

@Enguikong

Copy link
Copy Markdown
Contributor Author
性能
常规 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% 的门限验收。

32/36 shape PASS。
4 个已记录的 bs=1, context=8192 exception:
4B:TPOT +3.1%。
9B:TPOT +3.4%。
27B TP2:TPOT +3.9%。
35B-A3B TP2:TPOT +8.4%。

没看明白,使用FIA之后性能变差了吗?

一般情况下FIA性能更好。在并发1,上下文8192的时候,这几个模型出现使用 FIA 后性能变差的特例

@Enguikong Enguikong changed the title feat: migrate Qwen3.5 decode attention from PA to FIA. feat(npu): add opt-in FIA decode for Qwen3.5 Aug 20, 2026
@Enguikong Enguikong changed the title feat(npu): add opt-in FIA decode for Qwen3.5 feat: add opt-in FIA decode for Qwen3.5 Aug 20, 2026
@Enguikong
Enguikong force-pushed the feat/qwen35-fia-decode branch 2 times, most recently from a3667fa to f09bd90 Compare August 20, 2026 08:32
@Enguikong

Copy link
Copy Markdown
Contributor Author

已完成本轮收敛并更新 PR,麻烦各位 reviewer 重新审查:

  • FIA decode 改为正向显式 opt-in:默认保持 PA,仅传入 --enable_fia_decode=true 时,Qwen3.5 Target 与 MTP Draft 的 eager、regular Graph、expanded spec/MTP Graph 同时使用 FIA;非 Qwen3.5 与 prefill 路由不变。
  • 不新增或修改既有 Graph 全局开关默认值;本 PR 仅做 FIA 替换,不包含 DCP。
  • 已 rebase 到当前 upstream/main 78aa2a85,PR HEAD 为 f09bd907,23 个文件,+1327/-137,GitHub 判定可合并。
  • 标准 NPU build、git diff --check、23 文件 clang-format 全部通过;定向测试 163 PASS / 3 平台专项 SKIP / 0 FAIL
  • 最新 4B Target + MTP Draft Graph-on FIA 冒烟:8 个 MTP bucket 全 capture,5/5 请求成功,0 fallback/OOM/signature/507009。
  • 历史全家族 Graph 性能矩阵仍按真实结果披露:32/36 shape PASS;4 个 bs=1, context=8192 exception,其中 35B-A3B TP2 为 TPOT +8.4%,未隐去或改写为 PASS。

CI 当前 format-check、python-lint、build 已通过,其余 check-sensitive 正在排队。

@yingxudeng yingxudeng changed the title feat: add opt-in FIA decode for Qwen3.5 feat: add opt-in FIA decode for Qwen3.5. Aug 20, 2026
@yingxudeng
yingxudeng requested a review from pjgao August 20, 2026 11:04
yingxudeng
yingxudeng previously approved these changes Aug 20, 2026
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;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里即使没有打开 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 内切换开关,抓不到这种“默认路径也变慢”的回退。

@Enguikong Enguikong Aug 24, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

已按建议修改:

  • expanded KV 转换已移到 PA early return 之后,关闭 FIA 时不再产生额外 vector 分配和拷贝。
  • SpecVerifyGraphTaskSignal 不再保存 expanded vector,仅在 Graph 实际包含 FIA task 时准备相关参数。
  • 补充了 main vs PR、双方关闭 FIA 的 MTP A/B:bs1/512 和 bs32/512 均通过性能门限。

Enguikong and others added 7 commits August 24, 2026 11:18
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants