CANN/ge Tiling下沉特性分析
Tiling 下沉Tiling Sink特性分析【免费下载链接】geGEGraph Engine是面向昇腾的图编译器和执行器提供了计算图优化、多流并行、内存复用和模型下沉等技术手段加速模型执行效率减少模型内存占用。 GE 提供对 PyTorch、TensorFlow 前端的友好接入能力并同时支持 onnx、pb 等主流模型格式的解析与编译。项目地址: https://gitcode.com/cann/ge1 特性背景1.1 问题场景在昇腾 AI 处理器上AI Core 算子的执行需要经过 Tiling 阶段——根据输入张量的形状、数据类型等信息将计算任务拆分为多个可并行执行的块并确定每个块的执行参数如 block_dim、tiling_key、workspace 大小等。传统的 Tiling 流程在 Host 侧完成每次执行前Host 需要读取输入 shape、调用 Tiling 函数、将 Tiling 结果下发到 Device然后才能启动 AI Core 计算。对于静态 shape 图执行期间 shape 不变这种 Host 侧 Tiling 在每次推理时都会重复执行引入不必要的 Host-Device 同步开销成为性能瓶颈。典型场景大模型推理部署模型输入 shape 固定如 batch1, seq_len 固定但某些算子的 Tiling 依赖输入数据tiling_depend无法在编译期确定 Tiling 参数。传统流程下每次推理都要回到 Host 做 Tiling打断执行流水线高性能推理推理延迟敏感场景下减少一次 Host-Device 往返就能节省数十微秒对整体吞吐有显著影响1.2 解决思路Tiling 下沉的核心思想是将 Tiling 计算从 Host 侧搬到 Device 侧的 AICPU 上执行。具体而言编译期不再在 Host 侧执行 Tiling而是在任务流中插入一个 AICPU Tiling 任务运行期AICPU Tiling 任务在 Device 侧完成 Tiling 计算产出 tiling_key、block_dim 等参数通过rtModelTaskUpdate机制将 Tiling 结果动态刷新到后续的 AI Core 计算任务中整个过程无需 Host 介入避免了 Host-Device 同步开销传统流程: Host(Tiling) → 下发参数 → Device(AI Core 执行) ↑ Host-Device 同步开销 Tiling 下沉流程: Device(AICPU Tiling) → Device(AI Core 执行) ← 全程在 Device 侧完成1.3 适用范围维度要求执行模式静态 shape 图kStaticOffloadExecute算子类型带有ATTR_NAME_DYNAMIC_TILING_DEPEND_OP标记的算子Tiling 依赖输入数据算子能力算子注册时声明支持TILING_ON_AICPUAICPU 侧 Tiling硬件能力设备支持FEATURE_TYPE_MODEL_TASK_UPDATETSCPU 模块支持产品Atlas A2 训练/推理、Atlas A3 训练/推理系列2 对外接口2.1 编译选项选项名称ge.tiling_schedule_optimize选项值0默认关闭或1开启设置方式atc 离线编译通过命令行参数--tiling_schedule_optimize1参考api/atc/main_impl.ccaclgrphBuildModel 在线编译通过 options map 传入参考compiler/api/aclgrph/ge_ir_build.ccSession 配置在创建 Session 时通过ge::SessionOptions设置校验逻辑选项值必须为空字符串、0或1否则返回参数非法错误参考compiler/api/aclgrph/option_utils.cc中的CheckTilingScheduleOptimizeParamValid2.2 算子注册接口算子需要通过DeviceOpImplRegister声明支持 Tiling 下沉具体通过注册TILING_ON_AICPU放置能力实现// 算子在注册时通过 OpDefFactory::OpTilingSinkRegister(opType) 注册到 g_ops_sink_list // 系统通过 DataDependentInterpreter 查询 TILING_ON_AICPU 放置能力参考graph_metadef/中的OpDefFactory、DataDependentInterpreter2.3 约束与限制开启 Tiling 下沉的算子不支持设置永不超时属性op_exec_never_timeoutTiling 下沉仅在静态 shape 图中生效动态 shape 图不适用对于 SuperKernel 复用二进制SPK_REUSED_BINARY场景必须走 Tiling 下沉路径离线编译场景下跳过设备能力检查直接根据选项值判断3 整体架构3.1 端到端流程3.2 核心数据结构结构体文件位置用途TilingSinkTaskInforuntime/v1/.../args_format/args_format_utils.h存储已下发 AI Core 任务的 task_id、stream、FFTS handle供 UpdatePC 任务回查TilingContextAddrruntime/v1/.../args_format/args_format_utils.hDevice 侧 Tiling 上下文各部分的设备地址tiling_context、tiling_data、tiling_key、block_dim、op_typeParamDefcompiler/engines/nn_engine/utils/common/fe_gentask_utils.hAICPU Tiling 任务的参数定义so 路径、kernel 名称、是否自定义算子等TilingSinkTaskInfo和TilingContextAddr通过OpDesc的扩展属性ExtAttr在任务之间传递kTilingSinkTaskInfo _tiling_sink_task_info由 AI Core 任务设置UpdatePC 任务读取kTilingContextAddrs _tiling_context_addr由ArgsFormatUtils::SinkTilingContext设置多个任务共享3.3 关键常量kTilingSinkBlockDim 0xFFFFFFFF占位 block_dim 值表示运行时由 Tiling 结果决定。运行期 UpdatePC 任务会将真实 block_dim 刷新到此地址参考runtime/v1/.../davinci_model.cc4 编译期实现4.1 阶段一图分区——判断与标记在动态 shape 分区DynamicShapePartition阶段系统对每个带有ATTR_NAME_DYNAMIC_TILING_DEPEND_OP标记的算子进行判定。判定函数IsSupportTilingSink()compiler/graph/partition/dynamic_shape_partition.cc执行三重门控检查选项门控检查ge.tiling_schedule_optimize是否为1设备能力门控仅在线编译通过rtGetDeviceCapability检查设备 TSCPU 模块是否支持FEATURE_TYPE_MODEL_TASK_UPDATE算子能力门控通过DataDependentInterpreter::IsSupportTilingDependPlacement(TILING_ON_AICPU)检查算子是否注册了 AICPU 侧 Tiling 能力标记函数JudgeUnknownShapeForTilingDependNode()同文件对于通过了三重检查的算子设置_tiling_sink_op true属性作为后续 FE 阶段的判断依据将is_dynamic设为false阻止该算子被强制划入动态 shape 分区——这是 Tiling 下沉的核心收益让原本需要走动态图的算子留在静态图中对于未通过检查的 Tiling 依赖算子设置ATTR_NAME_FORCE_UNKNOWN_SHAPE true强制走动态执行路径4.2 阶段二FE 计算运行参数在 FEFusion Engine的CalcExtOpRunningParam阶段系统对标记了 Tiling 下沉的算子进行参数计算。入口AICoreOpsKernelBuilder::CalcTilingSinkRunningParam()文件compiler/engines/nn_engine/optimizer/ops_kernel_builder/aicore_ops_kernel_builder.cc前置判断CheckTilingSink()compiler/engines/nn_engine/utils/common/fe_gentask_utils.ccCheckTilingSink检查三个条件执行模式为kStaticOffloadExecute静态 shape 图算子具有_tiling_sink_op true属性算子具有非空的compile_info_jsonTiling 编译信息三个条件全部满足才走 Tiling 下沉路径。参数计算包含两个步骤SetTilingSinkCalcResources设置附属流Attached Stream信息和同步资源创建名为tiling的附属流其depend_value_input_indices指向算子 Tiling 依赖的输入索引创建名为tiling的 Event 同步资源用于 Tiling 任务与 AI Core 任务之间的同步CalculateTilingSinkWorkspace在 Host 侧执行一次 Tiling 计算确定 Workspace 大小调用TilingForOneNode()在 Host 侧执行 Tiling获取 workspace_bytes对于自定义算子额外追加 20KBCUSTOM_TILING_OP_DUMP_SIZE的 workspace 用于日志 dump将 workspace 信息设置到ExeResGenerationContext4.3 阶段三FE 生成任务序列在GenerateExtTask阶段系统为 Tiling 下沉算子生成特殊的任务序列。入口GenerateOpExtTask()fe_gentask_utils.cc当CheckTilingSink返回 true 时调用GenerateTaskForTilingSink()。任务序列生成GenerateTaskForSinkOp()fe_gentask_utils.cc生成的任务序列为tiling → wait → [nops × N] → [原有 AI Core 任务] → refresh → record任务类型创建函数说明RT_MODEL_TASK_PREPROCESS_KERNELCreateTilingTaskAICPU Tiling 任务kernel 名称为RunAicpuRpcSrvLaunch。Args format 包含TILING_CONTEXT、OP_TYPE、PLACEHOLDER自定义算子还追加WORKSPACERT_MODEL_TASK_EVENT_WAITCreateWaitTask在主流上等待 Tiling 任务完成的事件RT_MODEL_TASK_NOP× NCreateNopTask硬件预取延迟补偿910B 插入 8 个 NOP310P 插入 5 个RT_MODEL_TASK_KERNEL/RT_MODEL_TASK_ALL_KERNEL原有任务AI Core 计算任务以占位参数block_dim0xFFFFFFFF启动RT_MODEL_TASK_UPDATECreateRefreshTask通过rtModelTaskUpdate刷新 AI Core 任务的 tiling_key 和 block_dim。Args format 包含TILING_KEY和BLOCK_DIMRT_MODEL_TASK_EVENT_RECORDCreateRecordTask记录事件完成NOP 延迟补偿的设计考量硬件预取机制会在收到任务后提前取指令而 AICPU Tiling 结果通过 event notify 通知 AI Core 流。从 event 触发到 AI Core 实际感知存在时间差插入 NOP 任务是为了填满这个时间窗口确保 AI Core 开始执行时 Tiling 结果已经就绪。NOP 数量根据芯片型号不同而不同910B 为 8、310P 为 5来源于平台信息的prefetch_num字段。4.4 SuperKernel 场景对于 SuperKernel融合内核场景Tiling 下沉有特殊处理文件fe_gentask_utils.cc中的GenerateTaskSuperKernel()Tiling 任务的 Args format 额外包含EVENT_ADDR用于在 AICPU Tiling 任务中获取 event 地址AI Core 任务的 Args format 会被修改在WORKSPACE后插入TILING_DATA、TILING_KEY、BLOCK_DIM、EVENT_ADDR硬性约束SuperKernel 使用复用二进制SPK_REUSED_BINARY时必须走 Tiling 下沉路径否则编译报错参考compiler/engines/nn_engine/optimizer/graph_optimizer/task_builder/superkernel_task_builder.cc中的CheckTilingSinkForSK()4.5 FFTS 场景FFTS混合 AICAIV算子同样支持 Tiling 下沉在fftsplus_ops_kernel_builder.cc中通过CheckTilingSink判断后走相同的 Tiling 下沉路径运行时 FFTS 任务分发后TilingSinkTaskInfo中的ffts_task_handle指向实际的 FFTS 任务句柄而非 nullptrUpdatePC 任务据此识别任务类型5 运行期实现5.1 Device 侧 Tiling 上下文构建核心函数ArgsFormatUtils::SinkTilingContext()文件runtime/v1/graph/load/model_manager/task_info/args_format/args_format_utils.cc该函数在 Device 侧分配并初始化 Tiling 上下文内存是 Tiling 下沉运行时的关键准备工作。内存布局|--- tiling_data (含 TilingData 头) ---|--- workspace addrs ---|--- tiling_context ---|--- compute_node_info ---|构建步骤计算各段大小device_tiling_size通过DeviceTilingContextBuilder::CalcTotalTiledSize计算aligned_max_tiling_sizeTiling 数据最大空间从kMaxTilingSize属性获取默认kMaxTilingDataSizeworkspace_addr_sizeworkspace 地址数组空间kMaxWorkspaceCount项compute_node_info_size计算节点信息空间分配 Device 内存通过davinci_model.MallocDynamicMemory(total_plain_size, RT_MEMORY_TS)分配初始化 Host 端各段创建TilingDatacap设置 Tiling 数据区如果启用了 args_exceptionDFX 调试在 Tiling 数据末尾写入 atomic_index创建ContinuousVector用于 workspace 地址数组通过bg::CreateComputeNodeInfo创建计算节点扩展信息构建 Device 侧 Tiling 上下文通过DeviceTilingContextBuilder链式设置PlatformInfo平台信息对于自定义算子通过LoadCustPlatformInfos加载对于内置算子通过LaunchPlatformInfos加载TilingDataTiling 数据区地址Deterministic/DeterministicLevel确定性计算标志Workspaceworkspace 地址区AddrRefreshedInputTensorTiling 依赖的输入张量地址可刷新TiledHolderTiling 上下文和计算节点信息Host 到 Device 拷贝将整个 buffer 通过aclrtMemcpy拷贝到 Device存储地址信息创建TilingContextAddr结构体记录各部分的 Device 地址存为 OpDesc 的ExtAttr5.2 AI Core 任务分发文件runtime/v1/graph/load/model_manager/task_info/fe/kernel_task_info.ccAI Core 任务KernelTaskInfo分发时涉及 Tiling 下沉的关键处理解析 Args FormatParseArgsFormat遇到TILING_CONTEXT类型且子类型为TILING_DATA时保存 arg_descs 到davinci_model.tiling_sink_task_arg_descs_list_供后续 AICPU Tiling 任务使用遇到TILING_CONTEXT类型且子类型为TILING_CONTEXT时通过IsTilingInputDataDependency确定哪些输入具有 Tiling 数据依赖记录到tiling_depends_input_idx组装 Tiling Sink 张量AssembleTilingSinkTensors为每个 Tiling 依赖的输入创建gert::AddrRefreshedTensordevice_addr指向任务 args buffer 中的对应位置host_tensor在io_addrs_中创建其数据地址指向实际的输入数据地址这些张量使 AICPU Tiling 任务能够读取输入张量数据组装 Tiling 上下文参数AssembleTilingContextArgsTILING_CONTEXT调用ArgsFormatUtils::SinkTilingContext构建并初始化 Device 侧 Tiling 上下文TILING_DATA追加 Tiling 数据区地址TILING_KEY追加 Tiling Key 地址BLOCK_DIM追加 Block Dim 地址记录任务信息分发完成后将 task_id、stream、ffts_task_handle 封装为TilingSinkTaskInfo存为 OpDesc 的ExtAttr5.3 UpdatePC 任务分发文件runtime/v1/graph/load/model_manager/task_info/fe/update_pc_task_info.ccUpdatePCTaskInfo是 Tiling 下沉运行时的点睛之笔——它将 AICPU Tiling 产出的参数动态刷新到已下发的 AI Core 任务中。分发流程从 OpDesc 的ExtAttr获取TilingSinkTaskInfo包含目标任务的 task_id 和 stream从 OpDesc 的ExtAttr获取TilingContextAddr包含 tiling_key 和 block_dim 的 Device 地址获取 AI Core 算子的二进制 handle调用rtModelTaskUpdate(sink_task_info-stream, sink_task_info-task_id, stream_, update_info)update_info包含hdlAI Core 算子的二进制 handlefftsPlusTaskInfoFFTS 任务句柄非 FFTS 场景为 nullptrblockDimAddr指向 Device 侧 block_dim 存储位置的指针tilingKeyAddr指向 Device 侧 tiling_key 存储位置的指针rtModelTaskUpdate的底层机制是修改已下发任务的 SQESubmission Queue Entry中的 PCProgram Counter和关键参数使其在下发后、执行前被热更新。这避免了重新下发任务的开销。5.4 Block Dim 占位与刷新文件runtime/v1/graph/load/model_manager/davinci_model.cc在GetBlockDim()中对于标记了ATTR_NAME_DYNAMIC_TILING_DEPEND_OP的 AI Core 算子返回占位值kTilingSinkBlockDim 0xFFFFFFFF真实的 block_dim 由 AICPU Tiling 任务计算后写入TilingContextAddr.block_dim_addr所指的 Device 内存UpdatePC 任务通过rtModelTaskUpdate刷新到 AI Core 任务5.5 FFTS 任务分发文件runtime/v1/graph/load/model_manager/task_info/ffts_plus/ffts_plus_task_info.ccFFTS 任务分发完成后同样创建TilingSinkTaskInfo并存为ExtAttr。与普通 AI Core 任务的区别在于ffts_task_handle字段指向实际的 FFTS 任务句柄UpdatePC 任务据此判断需要更新的任务类型。5.6 SuperKernel 任务分发文件runtime/v1/graph/load/model_manager/task_info/fe/super_kernel_task_info.ccSuperKernel 的AssembleTilingSinkTensors和AssembleTilingContextArgs逻辑与KernelTaskInfo相同但需要按子节点sub_node_op_index_list_逐一处理使用各自对应的args_format_holder。5.7 Runtime V2 实现文件runtime/v2/engine/aicore/converter/aicore_compile_results.ccRuntime V2 采用了不同的执行模型Tiling 结果通过bg::ValueHolder在编译期就编入执行图而非运行时通过rtModelTaskUpdate动态刷新。SinkBinForFFTS将 FFTS 二进制数据和 tiling_key 输出通过ValueHolder::CreateSingleDataOutput(GetFFTSAICorePcAndPref, sink_inputs)下沉到执行图SinkBinForMixAiCore根据静态/动态分支分别通过OpRunInfo直接获取 tiling_key 或通过TilingContext输出获取Runtime V2 不引用tiling_schedule_optimize选项Tiling 下沉能力内建在执行图生成过程中。6 用户使用场景6.1 场景一静态 shape 图推理加速用户部署一个输入 shape 固定的推理模型其中包含 Tiling 依赖输入数据的算子如某些自定义算子。开启 Tiling 下沉后编译期系统自动识别支持 Tiling 下沉的算子在任务流中插入 AICPU Tiling 任务运行期推理时无需回到 Host 执行 Tiling整个执行流水线在 Device 内闭环收益消除 Host-Device 同步开销降低推理延迟6.2 场景二SuperKernel 复用二进制对于使用复用二进制SPK_REUSED_BINARY的 SuperKernel 算子Tiling 下沉是强制要求。多个算子复用同一份编译产物通过不同的 tiling_key 区分执行参数需要运行时动态确定 tiling_key。6.3 场景三离线模型编译用户使用 atc 工具离线编译模型时通过--tiling_schedule_optimize1开启特性。离线场景跳过设备能力检查直接根据选项值决定是否启用 Tiling 下沉。7 设计要点总结7.1 核心设计决策设计决策动机将 Tiling 搬到 AICPU 执行AICPU 与 AI Core 在同一 Device 上避免 Host-Device 往返使用 rtModelTaskUpdate 动态刷新避免重新下发任务的额外开销直接修改已下发任务的参数占位 block_dim Event 同步AI Core 任务先以占位参数启动Tiling 完成后刷新实现 Tiling 与计算的最大并行度NOP 延迟补偿弥补硬件预取机制与 event notify 之间的时间差确保数据一致性三重门控检查确保只在选项、设备、算子三方都支持时才启用避免运行时异常7.2 数据流总结7.3 关键文件索引模块文件路径核心内容选项定义inc/graph_metadef/external/ge_common/ge_api_types.hTILING_SCHEDULE_OPTIMIZE常量选项校验compiler/api/aclgrph/option_utils.ccCheckTilingScheduleOptimizeParamValidatc 入口api/atc/main_impl.cc命令行参数解析图分区标记compiler/graph/partition/dynamic_shape_partition.ccIsSupportTilingSink、JudgeUnknownShapeForTilingDependNode参数计算compiler/engines/nn_engine/optimizer/ops_kernel_builder/aicore_ops_kernel_builder.ccCalcTilingSinkRunningParam、SetTilingSinkCalcResources、CalculateTilingSinkWorkspace任务生成compiler/engines/nn_engine/utils/common/fe_gentask_utils.ccCheckTilingSink、GenerateTaskForSinkOp、任务创建函数数据结构runtime/v1/.../args_format/args_format_utils.hTilingSinkTaskInfo、TilingContextAddrTiling 上下文构建runtime/v1/.../args_format/args_format_utils.ccSinkTilingContextAI Core 任务runtime/v1/.../task_info/fe/kernel_task_info.ccAssembleTilingSinkTensors、AssembleTilingContextArgsUpdatePC 任务runtime/v1/.../task_info/fe/update_pc_task_info.ccUpdatePCTaskInfo::DistributeFFTS 任务runtime/v1/.../task_info/ffts_plus/ffts_plus_task_info.ccFFTS 场景 Tiling 下沉适配SuperKernel 任务runtime/v1/.../task_info/fe/super_kernel_task_info.ccSuperKernel 场景 Tiling 下沉适配Block Dim 占位runtime/v1/.../davinci_model.ccGetBlockDim中返回kTilingSinkBlockDimRuntime V2runtime/v2/engine/aicore/converter/aicore_compile_results.cc编译期 Tiling 下沉ValueHolder 模式约束文档docs/graph_engine_api/属性名列表.mdTiling 下沉与永不超时属性的互斥约束【免费下载链接】geGEGraph Engine是面向昇腾的图编译器和执行器提供了计算图优化、多流并行、内存复用和模型下沉等技术手段加速模型执行效率减少模型内存占用。 GE 提供对 PyTorch、TensorFlow 前端的友好接入能力并同时支持 onnx、pb 等主流模型格式的解析与编译。项目地址: https://gitcode.com/cann/ge创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考