十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

GE 内存冲突分析与处理机制

GE 内存冲突分析与处理机制 GE 内存冲突分析与处理机制【免费下载链接】geGEGraph Engine是面向昇腾的图编译器和执行器提供了计算图优化、多流并行、内存复用和模型下沉等技术手段加速模型执行效率减少模型内存占用。 GE 提供对 PyTorch、TensorFlow 前端的友好接入能力并同时支持 onnx、pb 等主流模型格式的解析与编译。项目地址: https://gitcode.com/cann/ge1 概述在昇腾 AI 处理器的图编译与执行过程中多个算子可能共享同一块物理内存通过符号表合并、Inplace 优化、引用关系等机制。共享内存带来显著的显存节省但也引入了多种冲突风险读写时序不确定、内存属性不兼容、子图地址隔离不足、原子操作累加错误、多流并发回收等。GEGraph Engine在编译器和运行时两个层面建立了完整的内存冲突防护体系覆盖语义级读写冲突检测、符号级内存布局冲突检测、子图地址隔离、零拷贝地址传递、Inplace 复用冲突检查以及运行时阶段的多流并发内存生命周期管理。本文档从系统设计视角对这一机制进行全面分析。2 冲突分类内存冲突按照产生原因和所处阶段可分为以下类别冲突类型产生场景检测阶段危害等级语义读写冲突一个输出同时被读算子和写算子消费编译器优化高精度错误内存布局冲突共享同一符号的锚点具有不兼容的内存属性编译器优化高运行时异常子图地址隔离冲突While/If/Case 子图内外共享同一输入地址编译器 Pass高数据覆盖HCCL 局部写冲突集合通信算子原地修改输入内存编译器 Pass高精度错误原子操作冲突原子算子的输出内存在迭代间未清零编译器 Pass高累加错误条件分支输入-输出映射冲突If/Case 不同分支对同一输出索引来自不同输入运行时图构建高地址错误多流内存生命周期冲突跨流访问的内存在源流尚未释放时被目标流回收运行时执行高数据损坏3 编译器侧冲突处理编译器侧的内存冲突处理分为三个层次按照流水线顺序依次执行3.1 第一层专用内存冲突 Pass位于compiler/graph/passes/memory_conflict/目录在图优化的早期和中期阶段运行。这些 Pass 针对特定场景进行预处理避免后续通用冲突处理遗漏边界情况。3.1.1 HcclMemcpyPass目的处理带有_input_mutable属性的 HCCL 算子如 HcomAllReduce、HcomBroadcast的读写冲突。冲突场景HCCL 算子在执行时会原地修改输入内存Scope Write。如果该输入同时被其他算子消费那么如果先读后写不插入 Identity 也可以保证精度如果先写后读必须插入 Identity 隔离否则读算子会读到被覆盖的错误数据处理策略常量/变量保护如果 HCCL 算子的输入来自 Const 或 Variable 节点无条件在中间插入 Identity 节点防止常量被覆盖拓扑序判断对于非常量输入通过节点 ID反映拓扑排序判断兄弟节点与 HCCL 算子的执行先后顺序。只有兄弟节点 ID 小于 HCCL 节点即先执行时才需要插入 IdentityShape 计算分支豁免Shape、Rank 等仅计算形状信息的算子不受内存改写影响不插入隔离Broadcast 回写对于 HcomBroadcast 算子额外插入 Assign 节点将广播结果写回 Variable标记跳过已处理的 HCCL 算子标记_skip_rw_conflicttrue避免后续HandleMemoryRWConflict重复处理执行时机在 GraphPrepare 阶段首次运行在 OptimizeStage1_3 阶段再次运行临时方案覆盖无子图场景的_mutable_input处理。3.1.2 HcclContinuousMemcpyPass目的处理需要连续输入内存的 HCCL 算子如 HcomAllReduce当其输入来自 Data/Const/Variable 时插入 Identity 将地址空间分离。同时处理 P2P 内存类型的输入场景。3.1.3 SubgraphPass目的处理 While/If/Case 子图的地址隔离需求。核心处理逻辑场景处理方式While 输入被多个消费者共享在 While 输入侧插入 MemcpyIdentity隔离While body 子图 Data 节点输出到需要连续输入的算子在 Data 后插入 MemcpyWhile body 子图 Data 直连 NetOutput 且索引不变跳过bypass避免无谓拷贝While body 子图其他输入/输出在 Data 后和 NetOutput 前各插入一个 Identity 节点确保循环体内的内存地址独立于外部If/Case 子图内多个输入共享同一源节点到 NetOutput插入 Memcpy 将地址分离子图 NetOutput 来自 Const静态图插入 Memcpy 防止常量地址被子图修改子图 NetOutput 来自 Atomic 算子插入 Memcpy 隔离原子操作的输出地址子图 NetOutput 来自需要连续输出的算子插入 Memcpy 隔离连续内存地址常量输入到 While 算子在外部插入 Memcpy防止循环体内覆写常量3.1.4 InplaceSupportCheckPass目的识别可以进行 Inplace输出复用输入内存的算子并标记_inplace_support_input_index属性。判断条件单输出算子输入和输出的数据类型和 Shape 完全匹配且输入不是 Data/Const/Variable 等源节点这些节点的地址不能被覆盖输入的前驱节点仅有一个消费者。3.1.5 AtomicAddrCleanPass目的融合原子操作的地址清零。原子算子如 ScatterAdd使用原子写方式更新输出迭代开始前需要将输出内存清零。处理策略非循环图在图头部插入一个统一的 AtomicAddrClean 节点通过控制边连接到所有原子算子及其前驱节点确保清零操作在所有原子算子之前执行循环图每个原子算子前单独插入 AtomicAddrClean 节点确保每次迭代开始前都清零直连 NetOutput 的原子算子单独插入 AtomicAddrClean因为零拷贝可能改变输出地址导致清零范围不连续3.1.6 MemcpyAddrAsyncPass目的在零拷贝场景下插入 MemcpyAddrAsync 节点实现用户数据的地址异步传递。处理场景StreamMerge 节点的输入来自用户 Data 时插入 MemcpyAddrAsync 传递地址而非拷贝数据根图 NetOutput 前的 Const/Data 直连场景在离线编译等需要强制拷贝的场景下插入 MemcpyAddrAsyncHCCL 算子与 RefData 之间的地址隔离当 Feature Map 不可刷新时需要插入隔离节点3.1.7 MarkSameAddrPass目的在动态静态内存复用模式下为 StreamSwitch/LabelSwitchByIndex 等需要固定物理地址的算子标记ATTR_DYNAMIC_SHAPE_FIXED_ADDR属性。3.1.8 SetInputOutputOffsetPass目的为带有ATTR_NAME_NODE_CONNECT_INPUT/ATTR_NAME_NODE_CONNECT_OUTPUT标记的节点设置正确的内存偏移量。特殊处理融合节点、HCOM 节点和 Concat 节点。3.2 第二层语义级读写冲突处理入口GraphOptimize::HandleMemoryRWConflict()文件compiler/graph/optimize/mem_rw_conflict_optimize.cc这是基于节点读写行为分类的通用冲突检测与处理系统。3.2.1 读写类型分类系统首先为每个节点的输入和输出锚点分类读写类型输入类型InputRWType类型含义典型算子kReadOnly仅读取输入不修改大部分常规算子kWriteable修改输入修改对外可见Assign、ApplyMomentumkScopeWriteable修改输入但仅在局部范围可见HcomAllReduce、While输出类型OutputRWType类型含义判断条件kReadOnlyConst常量输出Const/Constant 节点kReadOnly只读输出有多个消费者非 ref 输出且下游多于一个kSoftRead柔性只读仅一个消费者非 ref 输出且下游仅一个kWriteable可写输出ref 输出输出通过 reference 引用输入3.2.2 冲突决策矩阵基于输出类型和下游输入类型的组合决定是否需要插入 Identity 节点隔离Input:ReadOnly Input:Writeable Input:ScopeWriteable Output:ReadOnlyConst: 不处理 插入Identity 插入Identity Output:ReadOnly: 不处理 不处理 插入Identity Output:SoftRead: 不处理 不处理 不处理 Output:Writeable: 不处理 不处理 插入Identity设计考量kSoftRead单消费者与任何输入类型组合均不冲突因为不存在多消费者竞争kWriteable输出与kReadOnly/kWriteable输入不冲突因为写操作是预期的语义行为kScopeWriteable是最容易产生冲突的类型它在局部范围内修改内存但上游可能不知道内存已被修改kReadOnlyConst输出是最需要保护的类型常量不允许被修改3.2.3 处理流程关键细节子图处理采用反向遍历从最内层子图向外层传播 RW 类型已被HcclMemcpyPass标记_skip_rw_conflict的节点会被跳过Identity 节点标记ATTR_NO_NEED_CONSTANT_FOLDINGfalse和ATTR_NAME_CANNOT_BE_DELETEDtrue防止后续优化 Pass 删除3.3 第三层符号级内存布局冲突处理入口GraphOptimize::HandleMemoryLayoutConflict()文件compiler/graph/optimize/mem_layout_conflict_optimize/这是更精细的基于内存符号等价类的冲突检测系统。当多个锚点通过SymbolToAnchors/AnchorToSymbol映射共享同一内存符号时系统检测这些锚点的内存属性是否兼容。3.3.1 锚点属性分类系统定义了 14 种锚点属性AnchorAttribute每种属性代表一种内存约束属性含义标记对象USER_MEMORY_INPUT用户提供的输入根图 Data 节点USER_MEMORY_OUTPUT用户可见的输出根图 NetOutput 节点IMMUTABLE_ADDRESS_OUTPUT不可变地址输出Const/Constant/VariableUNSUPPORTED_ADDRESS_REFRESH_OPERATOR_INPUT不支持地址刷新的输入特定算子的输入UNSUPPORTED_ADDRESS_REFRESH_OPERATOR_OUTPUT不支持地址刷新的输出特定算子的输出CONTINUOUS_INPUT需要连续输入内存标记了continuous_input属性的算子CONTINUOUS_OUTPUT产生连续输出内存标记了continuous_output属性的算子NOPADDING_CONTINUOUS_INPUT无填充连续输入标记了_no_padding_continuous_input的算子NOPADDING_CONTINUOUS_OUTPUT无填充连续输出标记了_no_padding_continuous_output的算子RTS_SPECIAL_TYPE_INPUTRTS 特殊内存类型输入P2P 内存等特殊类型输入RTS_SPECIAL_TYPE_OUTPUTRTS 特殊内存类型输出P2P 内存等特殊类型输出REFERENCE_OUTPUT引用变量输出通过ref_var_src_var_name引用变量的输出NORMAL_INPUT普通输入默认NORMAL_OUTPUT普通输出默认3.3.2 冲突分类系统将冲突分为三类绝对不冲突以下属性对组合永远不会产生冲突可以直接跳过检测属性 A属性 BRTS_SPECIAL_TYPE_INPUTNORMAL_OUTPUTUSER_MEMORY_OUTPUTUSER_MEMORY_OUTPUTUSER_MEMORY_INPUTUSER_MEMORY_OUTPUT此外REFERENCE_OUTPUT属性始终属于不冲突类型。绝对冲突以下属性对组合必然冲突无需条件判断属性 A属性 B冲突原因USER_MEMORY_INPUTUNSUPPORTED_ADDRESS_REFRESH_OPERATOR_INPUT用户输入地址不能被不支持刷新的算子覆盖USER_MEMORY_INPUTRTS_SPECIAL_TYPE_INPUT用户输入不能使用特殊内存类型USER_MEMORY_OUTPUTRTS_SPECIAL_TYPE_INPUT/OUTPUT用户输出地址不能与特殊内存共享USER_MEMORY_OUTPUTCONTINUOUS_OUTPUT用户输出可能不满足连续性要求USER_MEMORY_OUTPUTNOPADDING_CONTINUOUS_OUTPUT同上IMMUTABLE_ADDRESS_OUTPUTRTS_SPECIAL_TYPE_INPUT不可变地址不能被特殊内存类型占用IMMUTABLE_ADDRESS_OUTPUTCONTINUOUS_INPUT不可变地址可能不满足连续性要求CONTINUOUS_INPUTNOPADDING_CONTINUOUS_OUTPUT连续输入和无填充连续输出的对齐要求可能不兼容CONTINUOUS_OUTPUTNOPADDING_CONTINUOUS_INPUT同上条件冲突需要通过注册的 Checker 函数进行条件判断。系统提供了注册宏REGISTER_FUNC(type_a, type_b, func_name)用于注册条件冲突检查函数目前注册了 22 个 Checker。3.3.3 Checker 注册框架已注册的 22 个 Checker 函数Checker检查的属性对continuous_input_and_continuous_inputCONTINUOUS_INPUT vs CONTINUOUS_INPUTcontinuous_output_and_continuous_inputCONTINUOUS_OUTPUT vs CONTINUOUS_INPUTcontinuous_out_and_continuous_outCONTINUOUS_OUTPUT vs CONTINUOUS_OUTPUTcontinuous_in_out_and_rts_special_mem_in_outCONTINUOUS 系列与 RTS_SPECIAL 系列8 对user_in_and_continuous_in_out_checkerUSER_MEMORY_INPUT 与 CONTINUOUS 系列4 对user_in_and_unrefresh_out_checkerUSER_MEMORY_INPUT 与 UNSUPPORTED_ADDRESS_REFRESH_OUTPUTuser_in_and_rts_special_out_checkerUSER_MEMORY_INPUT 与 RTS_SPECIAL_TYPE_OUTPUTuser_out_and_unrefresh_out_checkerUSER_MEMORY_OUTPUT 与 UNSUPPORTED_ADDRESS_REFRESH_OUTPUTuser_out_and_unrefresh_in_checkerUSER_MEMORY_OUTPUT 与 UNSUPPORTED_ADDRESS_REFRESH_INPUTuser_out_and_immutable_out_checkerUSER_MEMORY_OUTPUT 与 IMMUTABLE_ADDRESS_OUTPUTuser_out_and_continuous_inputUSER_MEMORY_OUTPUT 与 CONTINUOUS_INPUT 系列2 对immutable_out_and_rts_specail_out_checkerIMMUTABLE_ADDRESS_OUTPUT 与 RTS_SPECIAL_TYPE_OUTPUTimmutable_out_and_nopadding_continuous_in_checkerIMMUTABLE_ADDRESS_OUTPUT 与 NOPADDING_CONTINUOUS_INPUTimmutable_out_and_continuous_out_checkerIMMUTABLE_ADDRESS_OUTPUT 与 CONTINUOUS_OUTPUT 系列2 对nopadding_continuous_input_and_nopadding_continuous_inputNOPADDING_CONTINUOUS_INPUT vs NOPADDING_CONTINUOUS_INPUTnopadding_continuous_input_and_nopadding_continuous_outNOPADDING_CONTINUOUS_INPUT vs NOPADDING_CONTINUOUS_OUTPUTnopadding_continuous_out_and_nopadding_continuous_outNOPADDING_CONTINUOUS_OUTPUT vs NOPADDING_CONTINUOUS_OUTPUTrts_special_in_and_rts_special_in_checkerRTS_SPECIAL_TYPE_INPUT vs RTS_SPECIAL_TYPE_INPUTrts_special_in_and_rts_special_out_checkerRTS_SPECIAL_TYPE_INPUT vs RTS_SPECIAL_TYPE_OUTPUTrts_special_out_and_rts_special_out_checkerRTS_SPECIAL_TYPE_OUTPUT vs RTS_SPECIAL_TYPE_OUTPUTunrefresh_in_checkerUNSUPPORTED_ADDRESS_REFRESH_INPUT 与特殊类型unrefresh_out_checkerUNSUPPORTED_ADDRESS_REFRESH_OUTPUT 与特殊类型Checker 冲突检测执行流程部分关键 Checker 的判断逻辑continuous_output_and_continuous_input判断连续输出和连续输入之间是否存在实际内存范围重叠冲突user_in_and_unrefresh_out_checker判断用户输入与不支持地址刷新的输出之间是否共享地址优先在不支持刷新的节点侧插入 Identityuser_out_and_immutable_out_checker用户输出不能与常量/变量共享地址会导致不可变数据被覆盖nopadding_continuous_input_and_nopadding_continuous_input两个需要无填充连续输入的算子共享同一符号时地址对齐要求可能导致冲突3.3.4 控制流子图冲突处理在主符号级冲突检测之前CtrlNodeConflict专门处理 If/Case/While 控制流节点的子图冲突If/Case 冲突处理检查每个分支子图的 Data 节点是否直连 NetOutput检查是否有单个输出节点被 NetOutput 的多个输入引用共享地址对于检测到的冲突在子图内插入 Identity 隔离While 冲突处理检查 While body 中 Data 到 NetOutput 的索引映射关系如果输入索引与输出索引不同循环体内数据发生了位置变化插入 Identity 保证地址对应在 While body 的 Data 后和 NetOutput 前各插入 Identity 节点3.3.5 处理流程3.4 Inplace 内存复用与冲突检查文件compiler/graph/build/memory/mem_inplace.ccInplace 优化允许输出张量复用输入张量的内存地址是减少显存占用的重要手段。但 Inplace 引入了额外的读写冲突风险需要严格的冲突检查。处理流程识别只读符号标记来自 Data/Variable/Const 的符号为只读获取 Inplace 候选通过GetSupportInplaceOutput获取支持 Inplace 的输出尺寸过滤仅允许输入输出尺寸完全匹配的 Inplace读冲突过滤如果输入符号来自只读数据源变量不允许 Inplace写冲突过滤如果输出需要连续内存或与变量共享内存不允许 Inplace符号冲突检查合并输入输出符号后使用MemLayoutConflictUtil::IsGraphExistMemConflictSymbol检查是否产生新的冲突合并符号表如果所有检查通过合并符号表实现 Inplace3.5 编译后验证GraphLint文件compiler/graph/preprocess/checker/graph_lint.cc编译完成后GraphLint进行最终的读写冲突验证这是一种诊断性检查发出警告而非报错终止。验证逻辑预计算每个节点输入的 RW 类型kReadOnly/kWritable/kCanIgnore构建图级别的连接矩阵ConnectionMatrix记录节点间的可达性对于每个有 2 个以上消费者的输出锚点收集所有写节点和读节点检查任意两个写节点之间是否有控制依赖通过连接矩阵判断可达性检查每个写节点与每个读节点之间是否有控制依赖如果没有控制依赖说明执行顺序不确定发出W18888警告4 运行时侧冲突处理运行时侧的冲突处理主要集中在条件分支地址映射、多流并发内存生命周期管理两个方面。4.1 条件分支冲突处理文件runtime/v2/graph_builder/bg_condition.cc4.1.1 分支链冲突检测CalcChainConflictSolvePolicy对于 If/Case 节点不同分支子图可能将同一输出索引映射到不同的输入源检测规则对于每个输出索引如果各分支映射到的输入索引集合大小超过 1则该索引为冲突索引conflict_indexes。解决方案对每个冲突索引在所有分支子图的 InnerNetOutput 前插入PointFromInputs节点。PointFromInputs在运行时是零开销的直通节点仅传递指针其目的是在图结构层面明确数据来源。4.1.2 资源生命周期扩展CalcSubgraphGuardersPolicy当子图内的资源带有FreeMemory守卫的内存块跨越子图边界时需要将生命周期扩展到父图场景处理方式子图内存在守卫资源需要传出移除子图内守卫在父图创建新守卫 子图内插入IdentityAddr增加引用计数资源来自父图输入子图内有守卫在父图增加守卫 子图内增加引用计数当前分支无守卫其他分支有插入IdentityAddr对齐各分支的生命周期4.2 多流内存生命周期管理运行时采用三层分配器架构和基于事件的同步机制来管理多流并发下的内存冲突。4.2.1 三层分配器架构4.2.2 MIFMulti-stream Independent Flags文件runtime/v2/kernel/memory/mif.hMIF 是每个内存块上的位图结构追踪哪些流正在使用占据该块stream_ids_to_bits_[maintained_stream]是一个位图biti表示从maintained_stream的视角看流i仍在使用该块Set(stream_a, stream_b)标记流b正在使用该块从流a的视角SetAll(stream)从所有流的视角标记流stream正在使用该块IsAnySet(stream)检查从某流的视角看是否还有其他流在使用该块4.2.3 三种回收模式文件runtime/v2/kernel/memory/multi_stream_mem_block.cc回收模式触发条件行为Birth Recycle出生回收出生流不再需要该块且无其他流持有引用物理内存归还到池Borrow Recycle借出回收块从当前流迁移到 BorrowAllocatorMIF 重置等待其他流复用Local Recycle本地回收仍有其他流引用加入local_recycle_blocks_等待事件同步后处理4.2.4 跨流内存访问AccessMemCrossStream当一个张量在流 A 上分配、但在流 B 上消费时Host 内存直接ShareFrom共享指针无流约束Device 内存通过WanderFrom进行跨流漫游调用MultiStreamMemBlock::NewAccessStream标记 MIF4.2.5 事件驱动的流同步文件runtime/v2/kernel/common_kernel_impl/event.ccruntime/v2/graph_builder/multi_stream/bg_event.cc三个事件同步阶段阶段时机作用kFirstSyncStage执行开始主流向子流同步kLastSyncStage执行结束子流向主流同步kLastResourceCleanStage最终清理强制同步所有流回收所有内存4.2.6 版本块追踪VersionBlocks文件runtime/v2/kernel/memory/version_blocks.h内存块每次回收再分配后版本号递增。通过版本匹配避免处理过期事件StreamedVersionBlock包含版本号和已发送标志位FindNext()自动跳过已发送或过期的条目FindNextForAll()用于LastWaitEvents的全局清理4.3 IO 地址复用验证文件runtime/v2/core/model_v2_executor.cc模型加载时编译器通过ATTR_MODEL_OUTPUT_REUSE_INPUT_MEM_INDEXES属性标记哪些输出复用了输入内存Inplace 场景。运行时在每次执行前通过CheckIoReuseAddrs验证地址匹配确保 Inplace 约束得到满足。4.4 跨存储位置数据搬运文件runtime/v2/lowering/placement/placed_lowering_result.cc当张量需要在不同存储位置间移动时Host/HBM/P2P系统自动生成对应的拷贝节点源 → 目标生成节点Host → HBMCopyH2DHBM → HostSyncStream CopyD2H FreeMemoryHBM → P2PP2P CopyP2P → HostSyncStream CopyD2HHost → Host无需拷贝Device 到 Host 的拷贝前必须插入SyncStream节点确保设备端计算完成后再拷贝。5 关键属性汇总以下属性贯穿编译器和运行时是理解内存冲突处理与地址隔离的核心属性名字符串值设置者消费者用途ATTR_NAME_MODIFY_INPUT_input_mutable算子注册HcclMemcpyPass, mem_rw_conflict_optimize标记算子修改输入_skip_rw_conflict_skip_rw_conflictHcclMemcpyPassmem_rw_conflict_optimize跳过已处理的 HCCL 节点ATTR_NAME_CONTINUOUS_INPUTcontinuous_input算子注册SubgraphPass, mem_layout_conflict标记需要连续输入内存ATTR_NAME_CONTINUOUS_OUTPUTcontinuous_output算子注册SubgraphPass, mem_layout_conflict标记产生连续输出内存ATTR_NAME_NOPADDING_CONTINUOUS_INPUT_no_padding_continuous_input算子注册mem_layout_conflict无填充连续输入ATTR_NAME_NOPADDING_CONTINUOUS_OUTPUT_no_padding_continuous_output算子注册mem_layout_conflict无填充连续输出ATTR_NAME_REFERENCEreference算子注册mem_rw_conflict, mem_inplace输出引用输入INPLACE_SUPPORT_INPUT_INDEX_inplace_support_input_indexInplaceSupportCheckPassmem_inplace标记支持 Inplace 的输入索引REF_VAR_SRC_VAR_NAMEref_var_src_var_name算子注册mem_layout_conflict, AtomicAddrCleanPass输出引用的变量名ATTR_NAME_CANNOT_BE_DELETED-各冲突 Pass后续优化 Pass防止冲突隔离节点被优化删除ATTR_NO_NEED_CONSTANT_FOLDING-各冲突 Pass常量折叠 Pass防止冲突隔离节点被常量折叠ATTR_DYNAMIC_SHAPE_FIXED_ADDR-MarkSameAddrPass内存分配器动态形状下需要固定物理地址ATTR_MODEL_OUTPUT_REUSE_INPUT_MEM_INDEXESoutput_reuse_input_mem_indexes编译器内存分配运行时 model_v2_executor标记 Inplace 的 IO 地址对应关系6 整体流水线将编译器和运行时的冲突处理串联完整的内存冲突防护流水线如下7 总结GE 的内存冲突防护与地址隔离体系体现了以下设计思想分层防护层层递进从早期的专用 Pass处理 HCCL、子图、原子操作等已知模式到语义级 RW 类型分析通用读写冲突再到符号级精细检测内存布局属性兼容性每一层处理不同粒度的冲突。早期 Pass 处理已知特定模式避免通用分析遗漏边界情况通用分析则覆盖所有场景。Identity 节点作为地址隔离的基本手段几乎所有的冲突解决方案都归结为在冲突点插入 Identity/Memcpy 节点将共享同一地址的两个锚点分离到不同的地址空间。隔离节点被标记为不可删除、不可常量折叠确保隔离效果在整个编译流程中保持。编译期预防 运行期验证编译器承担了绝大部分冲突检测和解决工作运行时则负责多流并发场景下的动态内存生命周期管理和 IO 地址验证。符号等价类驱动的内存规划通过SymbolToAnchors/AnchorToSymbol将共享同一物理地址的所有锚点组织成等价类冲突检测在等价类内部进行确保不兼容的内存属性不会共享同一地址。Inplace 复用与冲突防护的平衡Inplace 优化通过复用输入内存减少显存占用但必须经过严格的冲突检查只读符号保护、连续内存约束、符号合并冲突检测确保复用不会引入新的冲突。【免费下载链接】geGEGraph Engine是面向昇腾的图编译器和执行器提供了计算图优化、多流并行、内存复用和模型下沉等技术手段加速模型执行效率减少模型内存占用。 GE 提供对 PyTorch、TensorFlow 前端的友好接入能力并同时支持 onnx、pb 等主流模型格式的解析与编译。项目地址: https://gitcode.com/cann/ge创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表