Skip to content

fix: graph of ascend - #1461

Open
Jingbo-gao wants to merge 4 commits into
InfiniTensor:mainfrom
Jingbo-gao:fix-graph-ascend
Open

fix: graph of ascend#1461
Jingbo-gao wants to merge 4 commits into
InfiniTensor:mainfrom
Jingbo-gao:fix-graph-ascend

Conversation

@Jingbo-gao

Copy link
Copy Markdown
Contributor

PR 内容

修复昇腾后端开启 graph 后,FIA decode 输出异常的问题。

本 PR 基于已有的 Ascend paged FlashAttention decode 实现,补充 FIA在 native graph replay 中的动态参数更新能力,并修复非连续 tensor 的临时contiguous buffer 生命周期不足问题。

Closes #1460

配套 InfiniLM PR:InfiniTensor/InfiniLM#526

问题原因

1. actualSeqLengthsKv 未在 graph replay 时更新

FIA V4 的 actualSeqLengthsKv 通过 host aclIntArray 传入。普通 nativegraph replay 只会重放已经捕获的 device task,不会根据更新后的 deviceseqlens_k tensor 自动重新构造 host aclIntArray 和 FIA executor。
因此,decode 阶段即使更新了 device 序列长度 tensor,FIA 仍可能继续使用 graphcapture 时的 KV 有效长度,导致 Attention 上下文范围错误和输出精度异常。

2. 临时 contiguous buffer 的地址在 replay 时可能失效

原 FIA 实现会在 run() 内通过 tensor->contiguous() 创建临时 tensor。eager模式下 FIA 会在临时 tensor 释放前完成执行,但 graph capture 会记录临时buffer 的 device 地址。
run() 返回后,临时 buffer 可能被释放或复用,后续 graph replay 继续使用捕获时的旧地址,可能造成旧数据读取、错误写入或输出精度异常。

主要文件修改

Graph task-update 支持

  • include/infinicore/graph/graph.hpp

    • GraphOperator 增加 requires_task_update() 能力;
    • DispatchableGraphOperator 增加 task-update opt-in 标记;
    • 增加 graph host integer array 的 stage、update 和 lookup 接口;
    • 增加 FIA task-group capture/task-update 状态接口。
  • src/infinicore/graph/graph.cc

    • capture 时单独记录需要动态更新的 operator;
    • 保存每个 FIA operator 对应的 ModelRI task group handle;
    • replay 前重新运行可更新 operator,在 task-update 状态下刷新 captured FIA
      task;
    • 使用 graph-owned host metadata 保存当前序列长度;
    • 普通 operator 和未启用 task-update 的后端保持原有 graph 执行路径。

infinirt ModelRI 接口

  • include/infinirt.h

    • 增加 infinirtGraphTaskGroup_t
    • 增加 graph task-group begin/end 和 task-update begin/end 接口。
  • src/infinirt/infinirt.cc

    • 增加通用 runtime 分发;
    • 仅当前设备为 Ascend 时调用 ModelRI task-group/task-update 实现;
    • 其他后端不会进入新增路径。
  • src/infinirt/ascend/infinirt_ascend.h

  • src/infinirt/ascend/infinirt_ascend.cc

    • 将新增接口映射到:
aclmdlRICaptureTaskGrpBegin();
aclmdlRICaptureTaskGrpEnd();
aclmdlRICaptureTaskUpdateBegin();
aclmdlRICaptureTaskUpdateEnd();

Ascend FIA graph 更新

  • src/infinicore/ops/mha_kvcache/mha_kvcache.cc

    • 仅在编译 ENABLE_ASCEND_FLASH_ATTN 且运行设备为 Ascend 时,为 MhaKVCache 启用 task-update;
    • 其他后端的 MhaKVCache 行为不变。
  • src/infinicore/ops/mha_kvcache/ascend/mha_kvcache_flashattn_ascend.cc

    • replay 时优先读取 graph 绑定的当前 host actualSeqLengthsKv
    • eager、warmup 等非 task-update 路径保留原有 device-to-host fallback;
    • task-update 阶段缺失 host binding 时直接报错,避免静默使用旧序列长度;
    • task group 只包围 aclnnFusedInferAttentionScoreV4 execute 调用;
    • ACL tensor/aclIntArray 构造和 GetWorkspaceSize 保持在 task group 外;
    • replay 时使用新的序列长度重新生成 FIA executor,并通过 ModelRI 更新
      captured FIA task;
    • 保持现有 FIA V4 和 BNSD layout,不引入 V5 或 TND 行为变化。

Contiguous Buffer 修复

PlannedMeta 新增长生命周期的:

Tensor out_work;
Tensor q_work;
Tensor k_work;
Tensor v_work;
Tensor block_table_work;

处理方式:

  • 原 tensor 已连续时,work tensor 直接引用原 tensor;
  • 原 tensor 不连续时,在 plan 阶段分配固定 work buffer;
  • work buffer 由 PlannedMeta 持有,生命周期覆盖整个 Graph;
  • capture 时将输入到 work buffer 的 copy 记录为普通 graph task;
  • task-update 阶段只更新 FIA task,不重复提交 contiguous copy;
  • output copy-back 在 capture 时进入 graph,task-update 阶段不重复执行。

该修改保证 FIA capture 和 replay 始终使用稳定的 device 地址。

执行命令:ASCEND_RT_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 python examples/bench.py --device ascend --model=/data/FM9G_70B_SFT_MHA/ --tp=8 --input-len=32,32 --output-len=256 --batch-size=16 --enable-paged-attn --attn=flash-attn --enable-graph

验证结果:
image

@Jingbo-gao
Jingbo-gao requested a review from a team August 4, 2026 09:06

@wooway777 wooway777 left a comment

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.

之前应该是基于主分支以较少的改动调通过吧。为什么现在突然要这么多额外操作了?

Comment thread src/infinirt/infinirt.cc

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.

请参考其他rt方法的声明和分发方式,需要定义统一接口,在其他平台先定义空实现。然后用宏做dispatch。

不然以后这个文件很容易就炸了

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.

[BUG] 昇腾平台图模式开启输出异常

2 participants