[Ascend] Migrate attention to FIA and unify graph updates - #350
Open
wanfengcxz wants to merge 8 commits into
Open
[Ascend] Migrate attention to FIA and unify graph updates#350wanfengcxz wants to merge 8 commits into
wanfengcxz wants to merge 8 commits into
Conversation
|
Super User seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account. You have signed the CLA already but the status is still pending? Let us recheck it. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR 改动说明
背景
Ascend Attention 之前仍有多条 ATB 实现,包括 prefill、Dense paged decode 和
MLA paged decode。为了支持 DeepSeek-V2 MLA 以及统一 eager/graph 行为,本 PR
将相关路径迁移到 torch-npu FIA/FIA v2,并补齐 MLA paged prefill。
CUDAGraph 同时还维护了两套动态参数更新机制:
torch.npu.NPUGraph.update();GraphParams。旧 ATB graph 路径通过
_graph_params在 Attention kernel 和 Graph Runner 之间传递 Tensor、task handle、event 以及 MLA 标记;capture-size 计算函数还通过
副作用初始化这些资源。这会造成以下问题:
_graph_params持有 KV cache 等 Tensor 引用,rollout reset 时容易残留旧资源;max_batches命中lru_cache时,初始化副作用不会再次执行,不利于 RLrollout 后的 re-capture;
GraphParams.is_mla依赖算子 capture 时写入全局状态;本 PR 完成 Attention 算子迁移、序列长度参数优化和 Graph 生命周期重构,并将
运行时基线固定到支持
NPUGraph.update()的 torch/torch-npu 版本。主要改动
1. Prefill Attention 从 ATB 迁移到 FIA
普通 prefill 使用
torch_npu.npu_fused_infer_attention_score替换_npu_flash_attention/_npu_flash_attention_unpad:TNDlayout;TND或BSH;sparse_mode=3;sparse_mode=0;attn_output,保持现有接口和内存复用语义。当
query/key的 head dim 大于 value head dim 时,按照 MLA 语义切分:NoPE 部分作为 FIA 主输入,RoPE 部分通过
query_rope/key_rope独立传入。prefill 路径会对切分后的 Q/K NoPE 和 RoPE Tensor 做必要的 contiguous,满足
FIA 输入要求。
2. Dense/MLA decode 迁移到 FIA/FIA v2
Dense paged decode 使用:
MLA paged decode 使用:
MLA decode 会将 Q 拆为 NoPE/RoPE,将 paged key cache 从
[block, block_size, kv_head, dim]转为 FIA v2 所需的[block, kv_head, block_size, dim],并将 FIA v2 输出恢复到原有attn_outputlayout。3. 新增 MLA paged prefill
paged_prefill_attention新增可选参数head_size_v,并通过公共 LLM API 传入vendor 实现。Camb/MACA 同步接收该参数以保持 vendor 接口一致。
Ascend 通过
key_cache.shape[-1] != value_cache.shape[-1]识别 MLA cache:[block, kv_head, block_size, dim];TND_NTDlayout、sparse_mode=3和 causal mask;block_table为int32;attn_output和直接返回 output 两种调用方式。非 MLA paged prefill 仍使用 FIA,保留
TND、paged block table 和sparse_mode=3。4. 移除 Attention 热路径中的
.tolist()以下 FIA/FIA v2 参数改为直接传递 Tensor:
避免每层 Attention 执行时把序列长度同步到 CPU 并构造 Python list。
NPUGraph.update()的 MLAcpu_update_input仍按 torch-npu 接口要求使用 list;它属于 graph replay 更新元信息,不是每层 FIA 算子调用。
5. 固定 torch/torch-npu 运行时版本
新增集中式校验,要求:
校验在 Ascend vendor 初始化时执行。配套 LMDeploy 改动也会在 Ascend backend
初始化时显式调用。运行时不满足要求会直接抛出带版本信息的
RuntimeError,不再静默退回旧 ATB 路径。
依赖范围同步调整为:
DICP 版本识别同步增加当前环境使用的 torch 2.9.0,依赖中增加
packaging用于可靠解析版本字符串。6. 删除旧 ATB graph-task Attention 路径
删除以下全局状态和辅助函数:
同时删除
graph_task_group_*、graph_task_update_*、_npu_paged_attention和_npu_paged_attention_mla的旧 graph 路径。重构后的整体算子关系为:
7. 显式传递 MLA 模型信息
LMDeploy Ascend backend 在构造 Graph Runner 时根据模型配置判断:
is_mla通过构造参数传递给AscendGraphRunner和AscendSingleGraphRunner。Graph replay 根据实例级字段选择更新参数:Attention kernel 不再通过
GraphParams.is_mla向 Graph Runner 回传模型类型。8. 分离 capture-size 策略和图资源生命周期
_get_capture_batch_size_impl(max_batches)现在是纯函数,只负责返回 capturesizes,不再初始化任何图资源。
AscendGraphRunner.get_capture_batch_sizes()会优先使用CacheConfig.cudagraph_capture_batch_sizes,未显式配置时才使用 Ascend 默认策略。因此 capture sizes 可以随
CacheConfig跨 rollout 保存,而 NPUGraph、output buffer 和 Tensor 引用仍在 reset 时释放。
9. 修正 Graph Runner reset/capture 生命周期
AscendGraphRunner.reset()先调用基类 reset,清除 rollout 局部的padding_batch_size;CacheConfig中的 capture-size 配置;try/finally恢复AscendGraphRunner.capturing,避免异常后状态残留。
AscendGraphRunner.capturing仍然保留,因为 MoE graph capture 路径仍需要该标记;Attention 已不再依赖它维护全局状态。
跨仓改动与合入顺序
该重构同时涉及 DLINFER 和 LMDeploy。
DLINFER:
AscendGraphRunner(..., is_mla=False)接口;head_size_vvendor 接口;.tolist();LMDeploy:
ModelConfig判断is_mla并传给 DLINFER Graph Runner;建议先合入 DLINFER,再合入 LMDeploy 配套修改,或者在两个 PR 中相互添加依赖
链接。LMDeploy 新调用方式依赖 DLINFER Graph Runner 的
is_mla参数。兼容性变化
这是一次有意的运行时兼容性收紧:
torch<2.8.0;torch-npu<2.8.0.post1;_npu_prompt_flash_attentionprefillfallback;带 mask 的
prefill_attention当前仅支持 Ascend910 系列。无 mask的 FIA 视觉 Attention 分支不受该限制。
当前依赖上限仍保留
<2.10.0,torch 2.10 及更高版本需要验证后再放开。测试
测试环境:
运行前加载:
source /afs-weights/wangqing/deepseekv2_dev/ascend_env.sh单元和算子测试:
结果:
覆盖 capture-size 纯函数、reset 后配置保留、标准/Dense/MLA prefill、MLA paged
prefill、MLA FIA v2 graph replay 动态 KV 长度更新和 MLA decode 精度。版本校验
通过当前 torch 2.9.0/torch-npu 2.9.0 环境的 vendor 导入和两项端到端模型测试
覆盖。
端到端回归:
静态检查:
风险与后续验证
已覆盖:
仍建议在真实 RL 环境中进行多轮:
重点检查每轮 capture sizes、旧权重/KV cache 引用、NPU 显存增长和 re-capture
输出精度。
Reviewer 建议重点关注
model_config.k_head_dim != model_config.v_head_dim是否覆盖当前所有 MLA 模型;sparse_mode=3与固定 split-fuse causal mask 是否覆盖各类 prefill 输入;NPUGraph.update()参数名和数据类型是否符合 torch-npu 接口;reset()是否完整释放 rollout 局部资源并保留 capture-size 配置;本 PR 范围
本 PR 已整合以下连续改动,应作为一个完整功能链进行 review:
sparse_mode=3和固定 causal mask;head_size_vvendor 接口;.tolist();其中 Attention 迁移依赖 FIA 能力,Graph 路径统一又依赖
torch-npu>=2.8.0.post1的NPUGraph.update(),因此版本约束属于该功能链的一部分,不再作为独立 PR 拆分。
最终精度测试