
昇腾 NPU 图模式推理优化实战cann-recipes-infer 中 npugraph_ex 与 GE 图模式的适配指南【免费下载链接】cann-recipes-infer本项目针对LLM与多模态模型推理业务中的典型模型、加速算法提供基于CANN平台的优化样例项目地址: https://gitcode.com/cann/cann-recipes-infer本文基于 cann-recipes-infer 开源仓库的图模式适配技能文档.agents/skills/model-infer-graph-mode/SKILL.md及其三份参考指南系统讲解如何在昇腾 NPU 上通过torch.compile把 LLM 推理模型重点是 Decode 阶段适配到npugraph_exaclgraph 捕获回放与 GEAscend IR两种图模式覆盖方案设计、图中断Graph Break与重编译修复、FA 融合算子参数配置、编译缓存以及验证测试全流程。读完本文你将掌握一套可直接落地的图模式适配方法论知道何时该用哪种模式、模型代码要满足哪些约束、actual_seq_lengths系列参数在不同图模式下应如何组织并能结合仓库执行框架executor/utils/graph_utils.py、executor/core/config/inference_config.py理解底层编译接入与配置校验逻辑。一、图模式适配的核心原则在动手改造任何模型之前先建立以下共识。这些原则来自技能文档的「重要原则」章节是后续所有操作的前提前置条件模型必须已在 NPU 上运行且已导入torch_npu导入后才会注册torch.npu设备相关 API。图模式仅适用于 Decode 阶段Prefill 阶段输入长度动态变化不适合图模式保持 eager 执行。这是全篇最重要的原则。保持模型完整性不为适配图模式而简化模型逻辑图模式改造应是对模型结构的适配而非阉割。NPU 不支持的后端aot_eager、inductor、cudagraphs等后端在昇腾 NPU 上不可用不要沿用 CUDA 生态的编译路径。固定 tensor 图外预创建attention_mask、KV cache 等推理全程不变的 tensor 应在图外预创建需要时用torch._dynamo.mark_static()标记。LLM Decode 重编译注意kv_len/actual_seq_lengths_kv每步都会变化npugraph_ex可能因此触发重编译遇到hit recompile_limit时参考重编译解决方案排查见第八章。npugraph_ex decode 用 host list 长度字段从ForwardMetaData取actual_seq_lengths_list_kv/q、actual_seq_lengths_cu_list_kv/qList[int]形态传给静态图路径普通 eager / GE 路径仍用对应的 Tensor 字段。这一点在仓库执行引擎中有直接实现见第十章。图模式验证项确认 warmup 阶段首次编译功能正常正式推理 decode 阶段直接复用 warmup 编译的图不出现重编译检查日志中是否有recompile标识。编译缓存使用时机先用常规图模式确认图可稳定捕获且无非预期重编译再按官方指南使用cache_compile降低冷启动 / 重复编译耗时。精度问题调试遇到精度问题可调用仓库中model-infer-precision-debugskill 进行排查。二、图模式适配工作流程技能文档给出了一套四步走的标准化流程特别强调方案设计必须先经用户确认再开发方案设计分析模型结构识别模型中可能阻碍图模式的代码模式如torch.cat扩展 KV cache、.item()调用、基于 Tensor 值的 Python 分支等识别问题点找出 Graph Break、重编译、动态 shape 等问题设计改造方案明确需要修改哪些文件、修改的具体内容、对现有功能的影响评估输出设计方案文档以 Markdown 格式呈现。方案确认等待用户确认方案后再进行开发有修改意见则返回第一步。实施开发按照确认的设计方案逐步实施代码修改。验证测试由 Agent 实际执行以下测试并记录真实结果编译验证运行torch.compile检查是否成功记录编译日志功能验证运行模型对比图模式前后输出性能验证记录 Prefill / Decode 阶段耗时编译缓存验证可选图结构稳定后可验证cache_compile是否降低二次启动编译耗时测试报告整理测试环境、测试用例、对比数据。三、图模式选型npugraph_ex 与 GE 图模式在开始适配前先确定使用哪种模式。如果用户未指定默认采用 npugraph_ex。场景推荐模式详细文档LLM 大语言模型npugraph_ex优先阅读 LLM 指南.agents/skills/model-infer-graph-mode/references/llm-model-guide.md通用模型npugraph_ex.agents/skills/model-infer-graph-mode/references/npugraph_ex-guide.md需要 GE 图模式GEAscend IR.agents/skills/model-infer-graph-mode/references/ge-graph-guide.md两种模式的核心差异如下表特性npugraph_ex 后端 (aclgraph)GE 图模式 (Ascend IR)启用方式backendnpugraph_extorchair.get_npu_backend()实现原理捕获模式 (Capture Replay)FX 图转换为 Ascend IRGE 引擎编译执行成熟度试验特性暂不支持商用更成熟稳定PyTorch 版本需要 2.6.0无特殊要求支持场景在线推理通用场景类似技术torch.cuda.CUDAGraph传统图编译配置方式options{}参数CompilerConfig对象npugraph_ex 快速示例import torch import torch_npu model YourModel().to(npu) opt_model torch.compile(model, backendnpugraph_ex, fullgraphTrue, dynamicFalse) # 注LLM Decode 场景 actual_seq_lengths 每步变化时需 dynamicTrue output opt_model(input_tensor)关键约束PyTorch 2.6.0、仅支持在线推理、不支持随机数算子和动态控制流、forward 中不可使用.item()。GE 图模式快速示例import torch import torch_npu import torchair from torchair import patch_for_hcom patch_for_hcom() # 集合通信入图有 TP/EP 并行时需调用 model YourModel().to(npu) config torchair.CompilerConfig() npu_backend torchair.get_npu_backend(compiler_configconfig) opt_model torch.compile(model, backendnpu_backend) output opt_model(input_tensor)仓库中的模式接入实现从源码结构看仓库执行框架把两种模式的编译入口统一封装在 executor/utils/graph_utils.py 的compile_model_forward()函数中图编译前有一段通用准备import torchair as tng import torchair.ge_concrete_graph.ge_converter.experimental.patch_for_hcom_allreduce tng.patch_for_hcom() torch._dynamo.config.inline_inbuilt_nn_modules False其中tng.patch_for_hcom()处理集合通信入图PyTorch 2.6 及之后版本中通常可省略inline_inbuilt_nn_modules False避免内建模块被过度内联。随后按exe_mode分派exe_mode npugraph_ex时走torch.compile(model_forward, dynamicenable_dynamic_graph, fullgraphTrue, backendnpugraph_ex, optionscompile_options)否则构建CompilerConfig并设置frozen_parameter、tiling_schedule_optimize、topology_sorting_strategy等实验性配置再通过tng.get_npu_backend(compiler_configcompiler_config)获取 GE 后端。执行模式的配置项定义在 executor/core/config/inference_config.py 的ModelConfig中配置项默认值说明exe_modeeager执行模式仅支持eager、ge_graph、npugraph_ex三者之一非法值会抛ValueErrorenable_cache_compileFalse是否启用编译缓存enable_static_kernelFalse是否启用静态 kernel 加速仅支持exe_modenpugraph_ex其他模式会报错enable_dynamic_graphTrue是否使用动态图编译ge_graph模式下只支持静态图该开关会被忽略并告警此外ModelConfig._validate()还有两个值得注意的副作用当exe_mode npugraph_ex或平台为 Ascend 950 时会设置环境变量TASK_QUEUE_ENABLE1npugraph_ex 只支持 0 或 1否则设为2eager 下优化 host 性能的默认值。真实配置示例可参考 models/deepseek_v4/config/ci_a3/deepseek_v4_flash_rank_128_128ep_w8a8.yaml其中exe_mode: npugraph_ex、enable_static_kernel: True、enable_dynamic_graph: False。四、npugraph_ex 后端使用详解适用场景在线推理场景追求简单快速适配熟悉 CUDAGraph 模式使用习惯类似LLM Decode 阶段固定 shape 的单 token 输入。使用约束约束项说明PyTorch 版本需要 2.6.0 及以上版本支持场景在线推理场景不支持反向流程 capture随机数算子不支持 capturerandn、dropout 等动态控制流不支持需保证图静态Stream 同步不支持 stream sync 操作成熟度试验特性暂不支持商用产品options 配置速查opt_model torch.compile( model, backendnpugraph_ex, fullgraphTrue, options{ # 调试 force_eager: False, # 强制 eager 模式调试 # FX图优化 inplace_pass: True, # 原地操作优化 input_inplace_pass: True, # 输入原地优化 pattern_fusion_pass: True, # 算子融合 # 内存优化 reuse_graph_pool_in_same_fx: True, # 图池复用 clone_input: True, # 克隆输入 clone_output: False, # 克隆输出 use_graph_pool: None, # 图池配置 # 性能优化 static_kernel_compile: False, # 静态Kernel编译 remove_noop_ops: True, # 移除空操作 frozen_parameter: False, # 冻结参数 # 捕获控制 capture_limit: 64, # 重捕获次数限制 } )在仓库的compile_model_forward()中npugraph_ex 的compile_options至少包含frozen_parameterTrue、static_kernel_compileenable_static_kernel、super_kernel_optimizeenable_superkernel等项读者可以对照上表理解每个开关的定位。核心 APIAPI用途compile_fx()自定义 backendregister_replacement()自定义算子融合cache_compile()编译缓存limit_core_num()限核功能常见问题如何判断是否应该使用 npugraph_ex适合LLM decode 阶段、固定 shape 推理、简单快速适配不适合需要动态 shape、生产环境稳定性优先、训练场景。报错不支持 capture怎么办检查代码中是否包含随机数算子randn、dropout、动态控制流基于 tensor 值的 if/while、.item()调用。性能劣化怎么办开启重编译日志torch._logging.set_logs(recompilesTrue)检查是否发生重编译再参考 LLM 模型改造指南排查。五、GE 图模式使用详解GE 图模式通过 TorchAir 的CompilerConfig开启将 FX 图转换为 Ascend IR 图并通过 GE 图引擎实现图编译和执行。它更适合生产环境稳定性优先、通用场景功能丰富和复杂模型需要更多配置选项。CompilerConfig 配置入口config torchair.CompilerConfig() # debug 类功能 config.debug.xxx ... # export 类功能离线导图 config.export.xxx ... # dump_config 类功能 config.dump_config.xxx ... # fusion_config 类功能 config.fusion_config.xxx ... # experimental_config 类功能 config.experimental_config.xxx ... # inference_config 类功能 config.inference_config.xxx ... # ge_config 类功能 config.ge_config.xxx ...其中experimental_config承载frozen_parameter冻结参数、tiling_schedule_optimizetiling 调度优化、topology_sorting_strategy拓扑排序策略等图内优化——这与仓库 executor/utils/graph_utils.py 中CompilerConfig()的用法一一对应。核心 APIAPI用途CompilerConfig类配置图模式功能get_npu_backend()获取 NPU 后端get_compiler()获取编译器dynamo_export()导出模型register_fx_node_ge_converter()注册转换器register_replacement()自定义算子融合两种模式选择建议从仓库文档 docs/cann/zh/npu_graph_optimization.md 看两种模式没有绝对优劣当前建议是优先选择npugraph_ex以降低适配成本、保留更接近 eager 的开发体验。一个值得注意的细节是npugraph_ex 当前常保持dynamicTrue并不是因为图本身必须动态而是与推理场景中部分 FIA 算子接口有关——部分actual_seq_lengths入参仍以list[int]形式传入强行静态化容易触发重编译后续算子接口补齐 Tensor 输入后这类配置可以继续收敛。例如 deepseek_v4 不存在这类 list 输入其配置便选择了静态图enable_dynamic_graph: False。六、编译缓存使用建议cache_compile适合在图模式已跑通、输入 shape / guard / 通信域稳定后启用用于降低冷启动或多次拉起时的编译耗时它不用于修复 Graph Break 或非预期重编译。启用时需按官方指南改造封装函数npugraph_ex 使用torch.npu.npugraph_ex.inference.cache_compileGE / Ascend IR 使用torchair.inference.cache_compile使用后原torch.compile编译流程不再需要。被缓存的函数应满足是 module method、未被其他装饰器修饰、能形成 full graph且同一缓存函数只能触发一次 Dynamo tracePrefill / Decode 或 guard 不同的场景应拆分封装。若模型代码、输入规格、分布式 rank/world_size、CANN/torch_npu 版本发生变化需重新生成或清理缓存。仓库中的对应实现同样在 executor/utils/graph_utils.pynpugraph_ex 路径调用torch.npu.npugraph_ex.inference.cache_compile(model_forward, cache_dircache_dir, dynamicenable_dynamic_graph, optionscompile_options)GE 路径调用tng.inference.cache_compile(model_forward, cache_dircache_dir, configcompiler_config, dynamicFalse, fullgraphTrue, ge_cacheTrue)。cache_dir默认位于model_config.output_path/compile_cache下还支持通过cache_namespace为独立的静态图 shape 指定子目录。无论哪种模式缓存命中都取决于模型代码、输入规格shape/dtype、编译配置和cache_dir是否保持一致任意一项变化都会导致缓存失效并重新编译。七、LLM 模型适配要点对于 LLM 推理模型必须严格区分 prefill 和 decode 阶段。图编译后会生成静态计算图任何动态行为都可能导致图中断graph break或重编译因此改造的关键是识别并隔离动态因素。Prefill 与 Decode 阶段限制阶段是否支持图模式原因Prefill禁止使用输入长度动态变化、首 token 生成逻辑复杂、shape 不固定Decode推荐使用输入长度固定通常为 1、shape 稳定、适合图捕获实现建议将 prefill 和 decode 的 forward 逻辑分离成不同方法仅对 decode 方法应用torch.compile图模式prefill 阶段使用 eager 模式执行。class YourModel: def prefill(self, input_ids, ...): Prefill 阶段使用 eager 模式 # 输入长度动态变化不适合图模式 return self._forward(input_ids, ...) def decode(self, input_ids, ...): Decode 阶段可使用图模式 # 输入长度固定通常为 1适合图捕获 return self._forward(input_ids, ...) # 仅对 decode 方法应用图模式, model.prefill保持 eager model.decode torch.compile(model.decode, backendnpugraph_ex, ...)核心改造原则核心原则将动态变化的东西提取为模型输入模型内部尽量保证静态。动态因素问题表现解决思路内存地址变化Guard 失败、重编译预分配固定大小原地更新Shape 变化图中断、多次编译固定 shape 或通过参数控制Python 控制流Graph Break使用 Tensor 操作或模式参数.item()调用强制 Graph Break保持 Tensor 或外部传入重编译问题定位与解决如果图模式性能劣化必须定位是否发生了重编译# 开启重编译日志 torch._logging.set_logs(recompilesTrue) # 运行模型 output compiled_model(input) # 如果发生重编译会打印类似 # [recompiles] Recompiling function func_name for reason: reason重编译解决方案dynamicFalse: 检测到重编译 │ └─→ 分析重编译原因 ├── 固定 shape 但仍重编译 → dynamicFalse skip_guard_eval_unsafeTrue └── 输入 shape 变化 → dynamicTrue区分 Prefill/Decode 实践指南为模型添加独立的prefill()和decode()方法通过is_prefill参数区分执行路径# 模型层 class MyModelForCausalLM(nn.Module): def forward(self, input_ids, position_ids, past_key_values, is_prefillFalse, **kwargs): # is_prefill 控制不同执行路径 if is_prefill: # Prefill 专属SP all-gather、取最后 token logits pass else: # Decode 专属多流并行、原地更新 KV cache pass return logits def prefill(self, **kwargs): return self.forward(is_prefillTrue, **kwargs) def decode(self, **kwargs): return self.forward(is_prefillFalse, **kwargs) # Runner 层 class MyRunner: def model_inference(self, model_inputs, is_prefillFalse): if is_prefill: return self.model.prefill(**model_inputs) else: return self.model.decode(**model_inputs) # 适合图模式八、模块级改造指南1. KV Cache 模块改造改造目标消除 KV Cache 动态扩展导致的 shape 变化实现固定大小 cache 的原地更新。核心思路① 预分配策略——在模型初始化时分配固定大小的 cache② 原地更新原则——使用原地更新算子写入新值避免重新分配③ 有效长度控制——通过参数控制实际参与计算的长度④ 返回优化——图模式下不返回 KV cache已原地更新。# 问题模式动态扩展 KV cache key torch.cat([past_key, new_key], dim1) # shape 变化 # 改造模式固定大小预分配 原地更新 # 1. 初始化时预分配 def _init_kv_cache(self, batch_size, max_seq_len, device): cache_shape (batch_size, 1, max_seq_len, head_dim) self.kv_cache torch.zeros(cache_shape, dtypedtype, devicedevice) # 2. forward 中原地更新 def forward(self, ..., kv_len, past_key_value): torch_npu.scatter_update_(past_key_cache, kv_len, new_key_states, dim-2)常见问题问题现象根因解决方案每次 decode 触发重编译torch.cat扩展 KV cache预分配固定大小原地更新内存占用过大预分配浪费结合 PagedAttention 按 block 管理返回 KV cache 开销大图模式下返回大量 tensor已原地更新无需返回2. Rotary Embedding 模块改造改造目标消除动态计算实现静态图 cos/sin 查询。如果已经使用了融合算子、没有触发静态图的限制则无需改造。def forward(self, x, kv_len, is_prefillTrue): if is_prefill: cos self.cos_cached[:seq_len] # prefill切片 else: cos torch.index_select(self.cos_cached, dim0, indexkv_len.view(-1)) # decode索引 return cos.to(x.dtype), sin.to(x.dtype)核心思路预计算 cos/sin初始化时计算所有位置值并缓存、索引查询通过index_select或切片获取、外层计算优化在模型外层统一计算传入各层。3. Attention 模块改造改造目标使 Attention 计算图模式友好支持 Flash Attention 等融合算子。核心思路优先使用 NPU 提供的融合 attention 算子通过参数控制有效长度避免大规模 attention mask使用模式参数区分 prefill/decode 计算路径。融合算子选型可参考仓库中的model-infer-fusionskill.agents/skills/model-infer-fusion/SKILL.md。4. Buffer/Parameter 模块改造改造目标避免 buffer/parameter 地址变化触发 guard 失败。核心思路初始化时分配最大可能大小使用copy_()、fill_()等原地操作通过index_select、切片等只读方式访问。5. 动态信息外部化设计改造目标将动态变化的信息从模型内部移到输入参数。动态信息内部计算外部传入位置索引position_ids torch.arange(seq_len)作为参数传入序列长度seq_len hidden_states.size(1)actual_seq_lengths参数写入位置内部计算kv_lenkv_len参数模式切换内部判断is_prefill参数forward 签名设计参考def forward( self, input_ids: torch.LongTensor, # 位置相关Tensor 形式支持图追踪 position_ids: Optional[torch.LongTensor] None, kv_len: Optional[torch.IntTensor] None, # KV 写入位置 # 序列长度List[int] 传给 NPU 算子 actual_seq_lengths_kv: Optional[List[int]] None, actual_seq_lengths_q: Optional[List[int]] None, # 模式控制 is_prefill: bool False, # KV Cache past_key_values: Optional[Tuple[torch.Tensor]] None, # 预计算的 cos/sin避免重复计算 cos: Optional[torch.Tensor] None, sin: Optional[torch.Tensor] None, ... ): pass6. 不要在 forward 中使用.item().item()将 Tensor 转换为 Python 标量会强制触发 Graph Break# 错误写法 - 会导致 Graph Break max_pos_id position_ids.max().item() 1 # 正确写法 - 使用静态参数或预计算 max_pos_id MAX_SEQ_LEN # 作为常量传入7. 推荐配置npugraph_ex 后端推荐用于 LLM Decodeimport torch import torch_npu model YourModel().npu() opt_model torch.compile( model, backendnpugraph_ex, fullgraphTrue, dynamicFalse, # LLM decode 固定 shape options{ # FX图优化 inplace_pass: True, input_inplace_pass: True, pattern_fusion_pass: True, # 内存优化 reuse_graph_pool_in_same_fx: True, clone_input: True, clone_output: False, # 性能优化 remove_noop_ops: True, } )GE 图模式import torch import torch_npu import torchair from torchair import patch_for_hcom patch_for_hcom() # 集合通信入图有 TP/EP 并行时需调用 config torchair.CompilerConfig() # 根据需要配置 inference_config, ge_config 等 npu_backend torchair.get_npu_backend(compiler_configconfig) opt_model torch.compile(model, backendnpu_backend)九、问题定界流程问题定界应优先基于本 skill 内置的知识进行独立分析避免盲目复制其他模型的图模式配置问题发生 │ ├─→ aot_eager 验证 ──失败──→ 修复用户脚本 │ ↓ 正常 │ ├─→ force_eager/run-eagerly ──失败──→ 修复用户脚本 │ ↓ 正常 │ └─→ 图模式问题 ├── 重编译问题 → 阅读 LLM 指南 npugraph_ex 指南 ├── Graph Break 问题 → 阅读 TorchAir 在线文档中的典型案例 └── 其他问题 → 阅读对应模式文档npugraph_ex-guide.md 或 ge-graph-guide.md调试知识来源按优先级① 本文档SKILL.md中的方法、原则和检查清单② .agents/skills/model-infer-graph-mode/references/npugraph_ex-guide.md③ .agents/skills/model-infer-graph-mode/references/llm-model-guide.md④ .agents/skills/model-infer-graph-mode/references/ge-graph-guide.md⑤ TorchAir 官方文档按需查阅其在线文档中的案例与 FAQ 章节。十、图模式 FA 融合算子快速 Debug图模式与 FA 融合算子结合时actual_seq_lengths参数的处理是最常见的出错点。问题现象编译报错actual_seq_lengths类型不匹配运行时报错重编译recompile触发性能问题动态 shape 导致无法充分优化。关键参数actual_seq_lengthsFA 算子的actual_seq_lengths/actual_seq_qlen/actual_seq_kvlen参数在不同图模式下有不同的要求图模式FA 接口来源actual_seq_lengths 类型dynamic 设置执行模式约束说明GE 模式推荐torchair FA 接口TensordynamicFalse仅支持 GE 图模式最佳方案静态图GE 模式不推荐torch_npu FA 接口list[int]dynamicTruemark_static无限制需额外配置易出错npugraph_ex 模式torch_npu FA 接口list[int]dynamicTrue无限制动态捕获模式npugraph_ex 模式torch_npu FA 接口Tensor如有dynamicFalse无限制需确认接口是否支持GE 模式配置方案一torchair FA 接口推荐import torch import torch_npu import torchair from torchair.ge_concrete_graph.ge_graph import mark_static # 使用 torchair 提供的 FA 接口 # actual_seq_lengths 为 Tensor 类型 attn_output torchair.ops.npu_fused_infer_attention_score( query, key, value, actual_seq_qlenactual_seq_qlen_tensor, # Tensor 类型 actual_seq_kvlenactual_seq_kvlen_tensor, # Tensor 类型 # ... 其他参数 ) # 编译配置 opt_model torch.compile(model, backendnpu_backend, dynamicFalse)优点dynamicFalse可获得更好的静态图优化无需额外的mark_static配置图编译更稳定。约束TorchAir FA 接口仅支持 GE 图模式不支持 Eager 模式和 npugraph_ex 模式调用。GE 模式配置方案二torch_npu FA 接口不推荐import torch import torch_npu import torchair from torchair.ge_concrete_graph.ge_graph import mark_static # 使用 torch_npu 的 FA 接口 # actual_seq_lengths 为 list[int] 类型 attn_output torch.ops.npu.npu_fused_infer_attention_score( query, key, value, actual_seq_lengths[seq_len], # list[int] 类型 actual_seq_lengths_kv[kv_len], # ... 其他参数 ) # 必须配置 dynamicTrue # 并使用 mark_static 标记除 actual_seq_lengths 外的静态输入 mark_static(input_ids) # 静态输入 mark_static(position_ids) # 静态输入 mark_static(attention_mask) # 静态输入 # actual_seq_lengths 保持动态 # 编译配置 opt_model torch.compile(model, backendnpu_backend, dynamicTrue)缺点需要配置dynamicTrue性能略逊于静态图需要手动调用mark_static标记所有静态输入配置繁琐易遗漏导致问题。npugraph_ex 模式配置方案一list[int] 类型 dynamicTrueimport torch import torch_npu # 使用 torch_npu 的 FA 接口 # actual_seq_lengths 为 list[int] 类型 attn_output torch.ops.npu.npu_fused_infer_attention_score( query, key, value, actual_seq_lengths[seq_len], # list[int] 类型 actual_seq_lengths_kv[kv_len], # ... 其他参数 ) # 必须配置 dynamicTrue opt_model torch.compile(model, backendnpugraph_ex, dynamicTrue)npugraph_ex 模式配置方案二Tensor 类型 dynamicFalse如有接口支持import torch import torch_npu # 查询是否有 Tensor 类型的 actual_seq_lengths 接口 # 通过 subagent 调用 model-infer-fusion 查询 # 如果有支持的接口 attn_output torch.ops.npu.npu_fused_infer_attention_score( query, key, value, actual_seq_lengthsactual_seq_lengths_tensor, # Tensor 类型 actual_seq_lengths_kvactual_seq_kvlen_tensor, # ... 其他参数 ) # 可配置 dynamicFalse opt_model torch.compile(model, backendnpugraph_ex, dynamicFalse)仓库中的 host list 转换实现从源码看仓库执行引擎 executor/core/engine/execution_engine.py 在 Decode 阶段为 npugraph_ex 做了专门的 host list 转换当self.exe_mode npugraph_ex且处于 decode非 prefill路径时会将actual_seq_lengths_cu_kv/q、actual_seq_lengths_kv/q等 Tensor 通过detach().cpu().numpy().tolist()转为List[int]形态再通过set_forward_metadata()写入 executor/utils/forward_metadata.py 中定义的actual_seq_lengths_cu_list_kv、actual_seq_lengths_cu_list_q、actual_seq_lengths_list_kv、actual_seq_lengths_list_q字段供静态图路径使用prefill 阶段这些 list 字段保持None。这与技能文档「npugraph_ex decode 用 host list 长度字段」的原则完全对应。常见错误与修复错误现象根因修复方案编译报错actual_seq_lengths 类型错误GE 模式下 torch_npu FA 接口传 Tensor改用 torchair FA 接口或改用 list[int] dynamicTrue运行时频繁重编译dynamicFalse 但 actual_seq_lengths 为 list[int]改用 Tensor 类型 torchair 接口或设置 dynamicTrue性能不达预期dynamicTrue 导致无法充分优化尽量使用 torchair FA 接口 dynamicFalsenpugraph_ex 模式报错actual_seq_lengths 为 Tensor 但接口不支持确认接口支持情况或改用 list[int] dynamicTrueEager 或 npugraph_ex 模式调用 TorchAir FA 报错TorchAir FA 接口仅支持 GE 图模式改用 torch_npu FA 接口或切换到 GE 图模式Debug 检查清单在图模式 FA 场景下按以下清单逐一排查确认使用的图模式GE 还是 npugraph_ex确认 FA 接口来源torch_npu 还是 torchair若使用 torchair FA 接口确认当前为 GE 图模式不支持 Eager 和 npugraph_ex检查 actual_seq_lengths 类型GEtorchair→TensorGEtorch_npu→list[int]dynamicTruenpugraph_ex→list[int]dynamicTrue检查 dynamic 配置是否与 actual_seq_lengths 类型匹配若使用 GE torch_npu FA list[int]检查是否已 mark_static 标记所有静态输入如有疑问调用model-infer-fusionskill 查询接口详情十一、进阶阅读与文档索引围绕图模式仓库还提供了以下可直接查阅的资料原理向docs/cann/zh/npu_graph_optimization.md 详细解释了 eager 模式与图模式的执行差异、npugraph_ex 的「捕获一次、多次回放」原理Dynamo compile → Guards → aclgraph Capture → Input 处理 → Replay、编译缓存的落盘与命中机制以及ge_graph与npugraph_ex的选择建议。技能文档本主题的完整技能定义见 .agents/skills/model-infer-graph-mode/SKILL.md三份参考指南分别对应 npugraph_ex-guide.md、llm-model-guide.md、ge-graph-guide.md。框架代码图编译统一入口 executor/utils/graph_utils.py执行模式与图相关配置定义及校验 executor/core/config/inference_config.pyDecode 阶段 host list 长度字段的构造 executor/core/engine/execution_engine.py元数据载体 executor/utils/forward_metadata.py。真实配置样例使用 npugraph_ex 并开启静态 kernel 的示例 models/deepseek_v4/config/ci_a3/deepseek_v4_flash_rank_128_128ep_w8a8.yaml。图模式与增强特性叠加图模式通常与编译缓存、静态 kernel、多流docs/cann/zh/multi_stream_principles.md、预取docs/cann/zh/prefetch_principles.md、superkerneldocs/cann/zh/super_kernel.md等能力组合使用。推荐的推进顺序是先跑通 eager 并完成功能与精度验证 → 打开图模式消除 graph break 和 recompile → 对比 eager 与 graph 输出至少覆盖一轮 Prefill 和多轮 Decode→ 再按需开启enable_cache_compile、enable_static_kernel、多流、限核或enable_superkernel。其中enable_static_kernel当前仅用于 npugraph_ex 相关路径enable_superkernel当前主要在 ge_graph 模式下尝试。最后再次强调图模式适配的收尾标准确认 warmup 阶段首次编译功能正常正式推理 decode 阶段直接复用 warmup 编译的图、日志中无recompile标识。只有满足这一条件图模式的性能收益才会真正落在正式推理的关键路径之外。【免费下载链接】cann-recipes-infer本项目针对LLM与多模态模型推理业务中的典型模型、加速算法提供基于CANN平台的优化样例项目地址: https://gitcode.com/cann/cann-recipes-infer创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考