metadef 模块是 CANN 异构计算栈中的元数据定义权威 。它不直接参与计算,而是为所有算子、张量和属性建立一套严格、一致且可序列化 的静态契约。这套契约是图引擎(GE)进行复杂优化(如融合、内存复用)以及底层 Runtime 正确执行计算任务的先决条件。metadef 的核心价值在于将高层逻辑准确地转换为底层硬件可理解的、可验证的结构化描述。
CANN 组织链接 : https://atomgit.com/cann
metadef 仓库链接 : https://atomgit.com/cann/metadef
1. 算子原型(OpProto)定义:计算契约的静态锁定
算子原型是描述算子"行为"的核心文档,它在编译阶段就锁定了算子的输入输出约束和配置空间。
1.1 张量拓扑与类型安全的严格约束
- 维度与数据类型签名 :OpProto 明确规定了算子期望的输入数量、张量的顺序(如 NHWC vs. NCHWc0)、以及每种输入支持的精确数据类型集合(e.g., DT_BF16 , DT_INT8 \text{DT\_BF16}, \text{DT\_INT8} DT_BF16,DT_INT8)。
- 前向兼容性保障:通过定义支持的数据类型列表,保证了当上层框架传入不兼容的类型时,GE 能够提前报错,避免了运行时程序崩溃或数值错误。
1.2 属性(Attributes)的固化与配置依赖性
- 原子属性定义:属性是影响算子行为的静态参数(如卷积的 Padding、Stride、激活函数的开启状态)。metadef 确保了这些属性在 IR 中是可序列化、可版本化的。
- 编译期绑定 :GE 在构建执行图时,会将这些属性值直接绑定到算子节点上。这些固化值直接指导了底层算子(如
ops-math或Catlass模板)的实例化,避免了运行时解析属性带来的开销。
2. 内存布局规范化:驱动 NPU 访存效率的底层标准
异构处理器对内存数据的排列方式有极高的要求。metadef 在抽象层规范了这些格式,是实现高性能数据加载的基础。
2.1 硬件原生格式与通用格式的映射
- 私有格式定义:metadef 定义了针对 Cube Unit 计算优化的内部格式(如 NC1HWC0)。其中,通道分块(C0)的设计直接映射了硬件处理单元的宽度,确保数据访问能匹配计算单元的吞吐能力。
- 格式传播语义:GE 依赖 metadef 明确的格式定义来推导数据流。如果算子 A 输出的格式与算子 B 所需的格式不一致,则必须在两者之间插入格式转换算子。
2.2 格式转换成本的最小化策略
- 转换节点的量化:metadef 规范帮助 GE 识别哪些转换是必要的。优化目标是使转换次数最少化,因为每一次格式转换都意味着一次全量数据的内存读写和额外的计算开销。
3. 形状推导(InferShape)与静态内存规划的耦合
图编译阶段的内存优化(如显存复用)严重依赖于对所有张量形状的提前锁定。
3.1 递归的形状推导机制
- 依赖驱动的计算 :metadef 要求每个算子原型必须提供形状推导函数(
InferShape)。该函数根据输入张量的形状和算子属性,计算出输出张量的形状。 - 全图推导:GE 遍历图,从输入层开始递归计算,直至推导出整个图的所有中间张量形状。这是实现静态内存规划的必要输入。
3.2 内存复用的精确边界确定
- 生命周期边界 :一旦形状和数据类型确定,GE 就能准确计算出每个中间张量的存活区间。metadef 提供的这些信息是 GE 进行内存地址复用调度(Aliasing)的唯一依据,确保了内存空间的精确分配和释放时机。
4. Tiling 结构的标准化承载与传递机制
Tiling 是将大计算分解为硬件友好 Tile 的过程,metadef 规范了这一决策在系统中的承载方式。
4.1 Tiling 元数据的结构化序列化
- 编译器与运行时契约 :Tiling 参数(如 Tile 块大小 M , N , K M, N, K M,N,K 的具体数值)由 GE 离线计算得出。metadef 提供了标准结构来序列化这些参数。
- 运行时解析:这些序列化后的 Tiling 数据被嵌入到最终的执行序列(OM 文件)中。Runtime 加载 OM 文件后,直接读取这些参数,并将其传递给底层核函数(如 Ascend C/PyPTO 实现),以指导其实际的本地内存访问和循环调度。
5. 控制流抽象与子图(Subgraph)的建模能力
现代网络结构复杂,metadef 必须能够描述非线性(非顺序)的计算流程。
5.1 图层级结构与控制依赖
- 节点与边:图结构由节点(代表算子实例)和边(代表数据依赖或控制依赖)构成。metadef 规范了如何描述这些边。
- 控制依赖的编码 :对于
If/Else分支或循环结构,metadef 允许将这部分逻辑封装成一个子图节点,明确了该节点与主图之间的控制依赖关系,而非单纯的数据依赖。
6. 版本兼容性与图序列化的持久化
metadef 是确保算子定义在不同软件版本间稳定性的核心。
6.1 算子版本的语义锁定
- 版本号标识:每个 OpProto 都有明确的版本号。如果算子的底层实现逻辑发生变化(例如,从一个 Softmax 算法切换到另一个),但外部接口保持不变,则可以不改变 OpProto,或者增加版本号以示区分。
- 向前/向后兼容:这种机制允许 GE 兼容旧模型,同时允许新算子在不破坏现有 IR 结构的情况下被引入。
6.2 二进制图(OM 文件)的结构化存储
- 自描述性 :最终的 OM 文件是
metadef描述符的二进制序列化结果。它包含了所有算子的元数据、优化后的静态权重以及执行序列,使得 Runtime 能够完全独立于构建环境进行高效加载和执行。
CANN 组织链接 : https://atomgit.com/cann
metadef 仓库链接 : https://atomgit.com/cann/metadef