RT2.0 动态 Shape 执行器特性分析

RT2.0 动态 Shape 执行器特性分析 RT2.0 动态 Shape 执行器特性分析【免费下载链接】geGEGraph Engine是面向昇腾的图编译器和执行器提供了计算图优化、多流并行、内存复用和模型下沉等技术手段加速模型执行效率减少模型内存占用。 GE 提供对 PyTorch、TensorFlow 前端的友好接入能力并同时支持 onnx、pb 等主流模型格式的解析与编译。项目地址: https://gitcode.com/cann/ge1. 特性背景1.1 为什么需要 RT2.0在昇腾 AI 处理器的图引擎GE架构中v1 运行时runtime/v1/包含两种执行器静态 shape 执行器TaskSink 模式和动态 shape 执行器Hybrid 模式。TaskSink 模式将整张图的算子任务预下发到设备端运行时只需一次rtModelExecute调用即可触发设备端自主执行在静态 shape 场景下性能极致仍被保留使用。而 Hybrid 模式通过 Host 端逐算子调度支持动态 shape但存在性能瓶颈。RT2.0runtime/v2/正是为了取代 v1 的 Hybrid 动态 shape 执行器而设计核心设计目标是通过 Lowering 机制将高层 ComputeGraph 转换为可直接执行的 ExecuteGraph使运行时只需一个极简的执行循环以更低的开销原生支持动态 shape 场景。1.2 设计哲学编译即执行准备RT2.0 的核心思想可以概括为一句话——将翻译工作从运行时移到编译期。v1 在运行时通过DistributeTask将 Task 逐个下发到设备而 v2 在编译期Lowering 阶段就已经将 ComputeGraph 转换为可以直接执行的 ExecuteGraph。运行时不需要任何翻译步骤只需要执行一个极简的节点循环。这种设计带来的直接收益是运行时执行路径极短无翻译开销执行器可以用纯 C 实现消除 C 的隐式运行时开销2. 用户使用场景2.1 典型使用场景RT2.0 执行器主要服务于以下场景场景说明动态 Shape 推理NLP 变长序列、视觉模型动态分辨率等 shape 在推理时变化的场景单算子执行PyTorch 动态图场景下的单算子编译执行通过aclopCompileAndExecuteV2入口2.2 与 v1 的入口对应关系用户通过不同 API 入口系统自动选择 v1 或 v2 执行路径┌──────────────────────────────────────────────────────────────┐ │ API 入口层 │ ├────────────────────┬─────────────────────────────────────────┤ │ ACL 层 │ GE Session 层 │ │ aclmdlExecuteV2 │ GeSession::RunGraph │ │ aclmdlExecuteAsyncV2 │ GeSession::RunGraphAsync │ │ │ GeSession::RunGraphAsyncWithStream │ │ gert::LoadExecutorFromModelData │ │ gert::LoadStreamExecutorFromModelData │ └─────────┬──────────┴──────────────┬──────────────────────────┘ │ │ ▼ ▼ 静态 shape 模型 动态 shape 模型 → v1 NnExecute → v2 ModelV2Executor → v1 Run 循环 → HybridModelRtV2Executor对于动态 shape 模型ModelManager::IsNeedHybridLoad判断是否走 Hybrid 路径当前 Hybrid 场景的主力执行器是HybridModelRtV2Executor它复用了 v2 运行时的ExecuteGraph基础设施。3. 对外接口3.1 核心 APIgert 命名空间RT2.0 通过gert命名空间对外暴露接口定义在inc/framework/runtime/gert_api.h中。3.1.1 加载接口gert::LoadExecutorFromFile(model_path, error_code) → 从 OM 文件加载为 ModelV2Executor gert::LoadExecutorFromModelData(model_data, error_code) → 从内存中的 ModelData 加载为 ModelV2Executor gert::LoadExecutorFromModelData(model_data, ExecutorOption, error_code) → 带执行器选项的加载可指定执行策略 gert::LoadExecutorFromModelDataWithRtSession(model_data, rt_session, error_code) → 绑定 RtSession 加载变量等资源通过 Session 共享 gert::LoadExecutorFromModelData(model_data, LoadExecutorArgs, error_code) → 带完整加载参数RtSession FileConstantMems gert::LoadStreamExecutorFromModelData(model_data, error_code) → 加载为 StreamExecutor多流场景 gert::LoadStreamExecutorFromModelData(model_data, LoweringOption, error_code) → 带优化选项的 StreamExecutor 加载3.1.2 辅助接口gert::IsDynamicModel(model, model_size, is_dynamic_model) → 判断模型是否为动态 shape 模型 gert::LoadDataFromFile(model_path, model_data) → 从文件加载 ModelData gert::AllocatorFactory::Create(graph_name, placement) → 根据内存位置HBM/P2P/Host创建 Allocator gert::CreateExternalAllocator(allocatorDesc) → 创建外部 Allocator3.2 ModelV2Executor 接口ModelV2Executor是 RT2.0 的核心执行器类定义在inc/framework/runtime/model_v2_executor.h中。3.2.1 生命周期管理Create(exe_graph, root_model, session) → 从 ExecuteGraph 创建执行器实例 Load() / Load(ModelExecuteArg) / Load(ModelExecuteArg, ModelLoadArg) → 加载模型执行 Init Graph 准备 Main Graph Execute(ModelExecuteArg, inputs, input_num, outputs, output_num) → 异步执行 Main Graph ExecuteSync(inputs, input_num, outputs, output_num) → 同步执行内部创建 default stream 并自动同步 UnLoad() → 卸载模型执行 DeInit Graph 清理资源3.2.2 查询接口GetModelDesc() → 获取模型描述信息Stream/Event/Notify 数量等 GetIterationNum() → 获取当前执行迭代数配合 Profiler 使用 GetSubscribers() → 获取事件订阅调度器 GetAippInfo(index, aipp_info) → 获取 AIPP 配置信息 GetAippType(index, aipp_type, aipp_index) → 获取 AIPP 输入类型3.3 StreamExecutor 接口StreamExecutor为多流并发场景提供管理定义在inc/framework/runtime/stream_executor.h中。StreamExecutor(builder) → 构造 StreamExecutor持有 ModelV2ExecutorBuilder GetOrCreateLoaded(stream, arg) → 获取或创建指定 Stream 上的 Executor线程安全 Erase(stream) → 移除指定 Stream 上的 Executor内部维护streams_to_executor_: mapaclrtStream, unique_ptrModelV2Executor每个 Stream 一个 Executor 实例确保异步执行模式下多个 Stream 并发推理时状态互不干扰。3.4 关键数据结构ModelExecuteArg执行参数stream → 执行流用户可指定或使用内部默认流 external_allocator → 外部内存分配器与 stream 绑定 external_stream_allocator → 外部辅流分配器 external_event_allocator → 外部 Event 分配器 external_notify_allocator → 外部 Notify 分配器关键约束一个 allocator 仅对应唯一的 stream在对应流同步之前allocator 内存池中的内存不可归还到操作系统在对应流同步之前allocator 不可被析构ModelLoadArg加载参数rt_session → 运行时 Session变量管理、资源隔离 outer_weight_mem → 外部权重内存指针 大小ExecutorOption执行器选项ExecutorType::kSequentialPriority → 顺序优先级执行器最快不支持控制流 ExecutorType::kTopological → 基于拓扑的执行器动态计算 ready 节点 ExecutorType::kTopologicalPriority → 拓扑优先级执行器ready 节点按优先级排序 ExecutorType::kTopologicalMultiThread → 拓扑多线程执行器4. 整体架构4.1 三层架构┌─────────────────────────────────────────────────────────────────┐ │ API 层 │ │ gert::LoadExecutorFromModelData / LoadStreamExecutorFromModelData │ │ ModelV2Executor::Load / Execute / UnLoad │ │ StreamExecutor::GetOrCreateLoaded / Erase │ ├─────────────────────────────────────────────────────────────────┤ │ 执行器层 │ │ ┌─────────────────┐ ┌──────────────────┐ ┌────────────────┐ │ │ │ ModelV2Executor │ │ StreamExecutor │ │ ExeGraphExecutor│ │ │ │ (模型级执行器) │ │ (多流管理器) │ │ (子图执行代理) │ │ │ └────────┬────────┘ └────────┬─────────┘ └────────┬───────┘ │ │ │ │ │ │ │ ▼ ▼ ▼ │ │ ┌───────────────────────────────────────────────────────────┐ │ │ │ 三子图生命周期管理 │ │ │ │ Init Graph → Main Graph → DeInit Graph │ │ │ └───────────────────────────────────────────────────────────┘ │ ├─────────────────────────────────────────────────────────────────┤ │ 引擎层 │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │ │ │ Sequential │ │ Topological │ │ MultiThreadTopological│ │ │ │ Executor (C) │ │ Executor (C) │ │ Executor │ │ │ └──────────────┘ └──────────────┘ └──────────────────────┘ │ │ │ │ ┌───────────────────────────────────────────────────────────┐ │ │ │ Node Kernel 注册系统 │ │ │ │ Node: { node_id, func(KernelRunContext*), context } │ │ │ │ KernelRegistry: run_func, outputs_creator, trace_printer │ │ │ └───────────────────────────────────────────────────────────┘ │ ├─────────────────────────────────────────────────────────────────┤ │ Lowering 层编译期 │ │ ┌───────────────────────────────────────────────────────────┐ │ │ │ ComputeGraph → [NodeConverter 逐节点转换] → ExecuteGraph │ │ │ │ GraphConverter / ModelConverter / NodeConverterRegistry │ │ │ └───────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘4.2 三子图生命周期RT2.0 将模型执行分为三个子图阶段为什么需要三子图分离v2 的核心执行引擎是纯 C 实现的顺序/拓扑执行循环无法处理分配内存这种需要与运行时 API 交互的操作。将初始化操作内存分配、流分配、常量加载和清理操作资源释放提取到独立的 Init/DeInit 子图中可以保持 Main Graph 的纯粹性——Main Graph 只包含纯计算节点。4.3 数据流总览5. 核心实现5.1 Lowering从 ComputeGraph 到 ExecuteGraphLowering 是 RT2.0 的核心转换机制定义在runtime/v2/lowering/目录下。5.1.1 转换流程GraphConverter::ConvertComputeGraphToExecuteGraph完成以下核心步骤Init Graph 生成将所有初始化操作常量加载、流分配、内存分配器创建提取到独立的 Init 子图Main Graph 生成对每个 ComputeGraph 节点通过NodeConverterRegistry查找对应的NodeConverter调用其 lowering 函数生成一个或多个 ExecuteGraph 节点事件同步 LoweringLoweringEventSync处理跨流的 Send/Wait 事件同步离线优化OfflineOptimizer对生成的 ExecuteGraph 进行优化常量折叠、死代码消除等拓扑排序对节点进行拓扑排序确定执行顺序优先级计算NodePriorityCalculator为节点计算优先级图级数据追加将 Stream、Event、Notify 等图级资源追加到 ExecuteGraph5.1.2 NodeConverter 注册机制每个算子类型通过NodeConverterRegistry注册对应的转换函数NodeConverterRegistry::GetInstance().FindRegisterData(type) → 按算子类型查找 NodeConverterRegistry::GetInstance().FindRegisterData(lowering_func) → 按 _ge_attr_lowering_func 属性查找 NodeConverterRegistry::GetInstance().FindRegisterData(kernel_lib_name) → 按算子库名查找转换函数签名LowerResult (*)(const ge::NodePtr node, const LowerInput input)5.1.3 数据依赖处理Lowering 过程中通过DataDependentInterpreter判断节点是否存在数据依赖shape 依赖运行时数据对数据依赖节点生成特殊的 ValueHolder确保执行时能正确处理动态 shape。5.2 Sequential Executor极致简洁的执行引擎定义在runtime/v2/core/executor/sequential/executor/sequential_executor.c中。 每个 Node 只包含节点 ID、执行函数指针、运行上下文。这种扁平化设计消除了虚函数调用、指针追逐等开销。5.3 Topological Executor动态拓扑调度定义在runtime/v2/core/executor/topological/executor/topological_executor.c中。与 Sequential Executor 不同Topological Executor 在执行时动态计算 ready 节点.适用场景包含控制流If/While的模型节点执行顺序在编译期无法完全确定。5.4 ModelV2Executor三子图生命周期管理定义在runtime/v2/core/model_v2_executor.cc中。5.4.1 Load 流程Load(ModelExecuteArg, ModelLoadArg): 1. 加载 Init Graphinit_executor.Load() 2. 初始化 RtVarManager变量管理器 3. 准备常量输入ArrangeModelLoadArg 4. 指定运行时参数SpecifyArgsInputs - Stream 资源可复用流 附加流 - Event 资源 - Notify 资源 - External Allocator 5. 执行 Init Graphinit_executor.Execute() 6. 卸载 Init Graphinit_executor.UnLoad() 7. 加载 Main Graphgraphs_[kMainExeGraph].Load() 8. 状态切换为 kLoaded5.4.2 Execute 流程Execute(ModelExecuteArg, inputs, input_num, outputs, output_num): 1. 检查状态必须为 kLoaded 2. 校验输入/输出 Tensor 数量和有效性 3. 指定输入 Tensorgraph_executor.SpecifyInputs 4. 指定运行时参数SpecifyArgsInputs 5. 指定输出 Tensorgraph_executor.SpecifyOutputs 6. 校验 I/O 复用地址合法性CheckIoReuseAddrs 7. 执行 Main Graphgraph_executor.Execute() - 如果启用了 Subscriber则带回调执行 - 否则直接执行5.4.3 UnLoad 流程UnLoad(): 1. 销毁 default stream 2. 卸载 Main Graph 3. 加载 DeInit Graph 4. 执行 DeInit Graph资源清理 5. 卸载 DeInit Graph 6. 状态切换为 kInit5.4.4 Stream/Event/Notify 资源管理OccupyStreamResource负责准备执行所需的流、事件、通知资源如果用户传入外部 allocator则使用外部的如果用户未传入任何 allocator则使用内置的builtin_stream_allocator_等不允许只传入部分 allocator必须全部传入或全部不传资源数量由ModelDesc中的reusable_stream_num、reusable_event_num、reusable_notify_num、attached_stream_num决定。5.5 Kernel 注册与执行系统定义在inc/graph_metadef/register/kernel_registry.h中。5.5.1 Kernel 注册通过REGISTER_KERNEL(type)宏注册算子内核REGISTER_KERNEL(MyKernel) .RunFunc(my_kernel_run) .OutputsCreator(my_outputs_creator) .TracePrinter(my_trace_printer) .ProfilingInfoFiller(my_profiling_filler) .DataDumpInfoFiller(my_data_dump_filler) .ExceptionDumpInfoFiller(my_exception_dump_filler) .ConcurrentCriticalSectionKey(my_critical_section);每个 Kernel 可注册以下函数run_func核心执行函数outputs_creator输出创建函数trace_printer维测信息打印profiling_info_filler性能分析信息填充data_dump_info_filler数据 dump 信息填充exception_dump_info_filler异常 dump 信息填充critical_section多线程临界区标识5.5.2 Kernel 执行上下文KernelRunContext和KernelContext为 Kernel 提供执行所需的上下文信息包括输入/输出地址、shape 描述、运行时参数等。5.6 HybridModelRtV2ExecutorHybrid 场景的执行入口定义在runtime/v1/hybrid/executor/hybrid_model_rt_v2_executor.h中。HybridModelRtV2Executor是动态 shape 模型在 Session 层的执行入口内部通过RtV2ExecutorFactory创建具体的执行器RtV2ExecutorFactory::Create(model, allocator, session): → 检查是否包含 PartitionedCall 节点Stage 分区 → 如果是创建 RtV2PipelineExecutor → 如果否创建 RtV2SimpleExecutorRtV2SimpleExecutor直接包装ModelV2Executor适用于单图场景RtV2PipelineExecutor管理多个 Stage 的执行器通过StageState和StageNotification实现 Stage 间的流水线并行HybridModelRtV2Executor还负责变量管理GraphVarVisitor管理 Host/Device 变量、共享常量、文件常量输入/输出 Tensor 的构建和转换内存分配器管理ScalableAllocatorManagerGuard 检查安全校验Profiler 数据采集5.7 ExecutorSubscribersScheduler事件订阅系统RT2.0 提供可扩展的事件订阅机制允许在执行过程中插入回调ExecutorSubscribersScheduler: → AddSubscriberProfiler(kMainExeGraph, ...) → AddSubscriberDataDumper(kMainExeGraph, ...) → AddSubscriberCannTracingProfiler(kMainExeGraph, ...)执行时如果启用了 Subscriber则调用SequentialExecuteWithCallback或TopologicalExecuteWithCallback在每个节点执行前后触发回调kModelStart → [kExecuteStart → node.func → kExecuteEnd] * N → kModelEnd内置 Subscriber 包括CannProfilerV2性能分析CannTracingProfiler执行追踪DataDumper数据 dump6. 内存管理6.1 Allocator 体系RT2.0 提供统一的 Allocator 接口支持多种内存位置TensorPlacement::kOnDeviceHbm → CachingMemAllocator(RT_MEMORY_HBM) TensorPlacement::kOnDeviceP2p → CachingMemAllocator(RT_MEMORY_P2P_DDR) TensorPlacement::kOnHost → HostMemAllocator TensorPlacement::kFollowing → HostMemAllocator用户可通过CreateExternalAllocator创建自定义 Allocator实现外部内存管理。6.2 外部 Allocator 约束当用户使用外部 Allocator 时需要满足以下要求一个 allocator 仅对应唯一的 stream在对应流同步之前allocator 内存池中的内存不可归还到操作系统在对应流同步之前allocator 不可被析构不可并发调用 Execute 接口如果同一个 allocator 匹配不同 stream6.3 I/O 复用地址校验CheckIoReuseAddrs在 Execute 前校验输入/输出 Tensor 的地址复用关系防止输出覆盖尚未读取的输入数据。编译期会记录io_same_addr_pairs_运行时检查实际地址是否违反约束。7. 多流并发管理7.1 StreamExecutor 设计StreamExecutor为每个 ACL Stream 创建独立的ModelV2Executor实例streams_to_executor_: mapaclrtStream, unique_ptrModelV2Executor每个 Stream 一个 Executor 是因为在异步执行模式下多个 Stream 可能并发执行同一个模型的不同推理请求。每个 Executor 维护自己的执行状态输入/输出绑定、迭代计数等互不干扰。7.2 线程安全StreamExecutor::GetOrCreateLoaded使用recursive_mutex保护确保多线程场景下 Executor 的创建和查找是线程安全的。7.3 资源隔离不同 Stream 的 Executor 可以共享同一个RtSession变量等资源通过 Session 共享使用不同的外部 Allocator每个 Stream 绑定独立的 Allocator使用内置的 Stream/Event/Notify Allocator自动管理8. 与 v1 架构的关键差异维度v1 Runtimev2 Runtime (RT2.0)核心抽象DavinciModel TaskDefExecuteGraph Node/Kernel执行模型rtModelExecute硬件 SinkHost 顺序/拓扑执行适用场景静态 shape 模型动态 shape / 控制流 / 单算子内存管理分段式FM/Weight/Var统一 Allocator代码语言C重运行时C 核心 C kernel图转换编译期 TaskSink 到 OM运行时 LoweringComputeGraph → ExecuteGraph子图管理无Init/Main/DeInit 三子图多流管理多 rtStream 绑定 rtModel多 Executor 实例StreamExecutor扩展机制TaskInfo 分发Kernel 注册系统 NodeConverter 注册事件订阅无ExecutorSubscribersScheduler9. 关键文件索引文件路径职责inc/framework/runtime/gert_api.h对外 API 入口加载接口inc/framework/runtime/model_v2_executor.hModelV2Executor 类定义inc/framework/runtime/stream_executor.hStreamExecutor 类定义inc/framework/runtime/exe_graph_executor.hExeGraphExecutor 类定义inc/framework/runtime/executor_option/executor_option.h执行器选项定义inc/graph_metadef/register/kernel_registry.hKernel 注册系统runtime/v2/api/api.ccAPI 实现加载流程runtime/v2/core/model_v2_executor.ccModelV2Executor 实现runtime/v2/core/stream_executor.ccStreamExecutor 实现runtime/v2/core/executor/executor_base_def.hNode 基础结构定义runtime/v2/core/executor/sequential/executor/sequential_executor.c顺序执行器Cruntime/v2/core/executor/topological/executor/topological_executor.c拓扑执行器Cruntime/v2/core/executor/sequential/execution_data/sequential_execution_data.h顺序执行数据runtime/v2/core/executor/topological/execution_data/topological_execution_data.h拓扑执行数据runtime/v2/lowering/graph_converter.hGraphConverter 定义runtime/v2/lowering/model_converter.hModelConverter 定义runtime/v2/lowering/graph_converter.ccGraphConverter 实现runtime/v1/hybrid/executor/hybrid_model_rt_v2_executor.hHybrid RT2 执行器runtime/v1/hybrid/executor/runtime_v2/rt_v2_simple_executor.h简单执行器封装runtime/v1/hybrid/executor/runtime_v2/rt_v2_pipeline_executor.hPipeline 执行器api/session/session/inner_session.hSession 层接口docs/architecture/constraints/rt2_runtime.mdRT2 运行时约束文档docs/architecture/modules/runtime/runtime.md运行时架构文档【免费下载链接】geGEGraph Engine是面向昇腾的图编译器和执行器提供了计算图优化、多流并行、内存复用和模型下沉等技术手段加速模型执行效率减少模型内存占用。 GE 提供对 PyTorch、TensorFlow 前端的友好接入能力并同时支持 onnx、pb 等主流模型格式的解析与编译。项目地址: https://gitcode.com/cann/ge创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考