在这里插入图片描述

前言

METADEF 是 CANN(Compute Architecture for Neural Networks)算子开发框架中的核心组件——算子元数据定义系统。它为昇腾 AI 处理器上的算子开发、部署和管理提供了一套标准化的元数据规范和管理能力。METADEF 的核心价值在于统一了算子定义、版本管理、依赖解析和算子发现等关键环节,使得算子库的维护、升级和跨版本兼容性变得清晰可控。

本文将详细介绍 METADEF 的设计理念、核心概念、使用方法以及最佳实践,帮助开发者深入理解并高效利用这一系统来管理昇腾 AI 处理器的算子生态。

METADEF 简介

METADEF(Metadata Definition)是 CANN(Compute Architecture for Neural Networks)算子开发框架中的核心元数据管理系统。它专门用于管理昇腾 AI 处理器上各类算子的结构化元数据,为算子的全生命周期(开发、注册、版本管理、依赖解析、查找发现)提供统一的标准和工具支持。

METADEF 的主要功能包括:

1. 算子签名定义

算子签名是算子与外部交互的“接口契约”。METADEF 使用 YAML 格式精确定义算子的输入(inputs)、输出(outputs)、属性(attributes)和参数(parameters)。签名不仅描述了数据类型(如 tensor、scalar)、精度(float16、float32)和形状(静态或动态维度),还可以包含默认值、约束条件等元信息。统一的签名格式确保了不同算子之间、算子与上层框架(如 PyTorch、TensorFlow 适配层)之间的接口一致性,降低了集成复杂度。

2. 版本信息管理

METADEF 采用语义化版本(Semantic Versioning)对算子进行版本控制。每个算子定义都包含主版本、次版本和修订版本号。版本管理机制支持:

  • 向后兼容性检查:确保算子升级不会破坏现有模型。
  • 多版本共存:允许同一算子的不同版本在系统中并存,供不同模型或场景选用。
  • 版本查询与筛选:开发者可以通过版本范围条件查找算子,例如查找 >=1.0.0<2.0.0 的所有 Conv2d 算子。

3. 依赖关系解析

复杂算子往往依赖其他基础算子或库。METADEF 允许在算子定义中显式声明依赖项(如依赖 MatMul >=1.0Relu >=1.0),并提供自动依赖解析功能。该系统能够:

  • 递归解析依赖树:找出算子所有直接和间接依赖。
  • 版本冲突检测:当多个算子依赖同一算子的不同版本时发出警告。
  • 依赖安装/加载:可自动下载或加载缺失的依赖算子,确保算子可执行。

4. 算子查找和发现

METADEF 提供丰富的查询接口,帮助开发者快速定位所需算子:

  • 按名称精确查找metadef.find("MatMul")
  • 按条件过滤查找:支持按算子类型(如 convolution)、版本范围、输入输出数据类型等条件筛选。
  • 按分类浏览:算子可按功能分类(如 normalizationactivation)组织,方便按类查看。
  • 动态注册与发现:支持运行时动态注册新算子,并自动纳入发现机制。

通过这些功能,METADEF 实现了算子元数据的集中化、标准化管理,显著提升了算子库的可维护性、可扩展性和跨版本兼容性,是昇腾 AI 软件栈中连接算子开发与模型部署的关键桥梁。

仓库地址:https://atomgit.com/cann/metadef

核心概念

算子签名

算子签名定义了算子的接口

operator: MatMul
version: "1.0"

inputs:
  - name: x1
    type: tensor
    dtype: float16
    shape: [-1, -1]
  
  - name: x2
    type: tensor
    dtype: float16
    shape: [-1, -1]

outputs:
  - name: y
    type: tensor
    dtype: float16
    shape: [-1, -1]

算子属性

attributes:
  - name: trans_a
    type: bool
    default: false
  
  - name: trans_b
    type: bool
    default: false

算子注册

定义文件格式

算子通过 YAML 文件定义

name: Conv2d
type: operator
version: "1.0"

# 算子参数
parameters:
  in_channels: int
  out_channels: int
  kernel_size: int
  stride: int = 1
  padding: int = 0
  dilation: int = 1
  groups: int = 1

# 输入定义
inputs:
  - name: input
    type: tensor
    dtype: float16/float32
    shape: [N, C, H, W]

# 输出定义
outputs:
  - name: output
    type: tensor
    dtype: float16/float32
    shape: [N, C_out, H_out, W_out]

算子查找

import metadef

# 通过名字查找算子
op = metadef.find("MatMul")

# 通过条件查找
ops = metadef.find_all(
    type="convolution",
    version=">=1.0"
)

print(f"Found {len(ops)} operators")

版本管理

版本号规则

版本号采用语义化版本

主版本.次版本.修订版本

例如1.2.3
- 主版本不兼容的 API 变更
- 次版本向后兼容的功能新增
- 修订版本向后兼容的问题修正

版本兼容性

# 查找兼容版本
ops = metadef.find_compatible(
    "Conv2d",
    min_version="1.0.0",
    max_version="2.0.0"
)

# 获取最新版本
latest = metadef.find_latest("Conv2d")

依赖管理

依赖声明

name: MyOperator
version: "1.0"

# 依赖其他算子
depends:
  - name: MatMul
    version: ">=1.0"
  
  - name: Relu
    version: ">=1.0"

依赖解析

# 自动解析依赖
deps = metadef.resolve_dependencies("MyOperator")

for dep in deps:
    print(f"{dep.name}: {dep.version}")

# 自动安装缺失依赖
metadef.install_dependencies("MyOperator")

算子类

类定义

name: NormOperator
type: operator_class
category: normalization

operators:
  - BatchNorm2d
  - LayerNorm
  - InstanceNorm

类继承

name: ConvNormActiviation
type: operator_class
extends: [Conv2d, BatchNorm2d, Relu]

fusion_rules:
  - pattern: [Conv2d, BatchNorm2d]
    result: ConvBN
  
  - pattern: [ConvBN, Relu]
    result: ConvBNReLU

算子发现

自动发现

# 扫描目录发现算子
metadef.scan_directory("/path/to/operators")

# 列出所有算子
all_ops = metadef.list_all()

# 按分类查找
conv_ops = metadef.list_by_category("convolution")
norm_ops = metadef.list_by_category("normalization")

动态注册

# 动态注册算子
metadef.register_operator({
    "name": "CustomOp",
    "version": "1.0",
    "impl": custom_op_impl,
})

# 动态注销
metadef.unregister_operator("CustomOp")

与其他组件集成

与 AscendCL 集成

import acl
import metadef

# 查找算子
op_def = metadef.find("MatMul")

# 加载算子到 AscendCL
acl.op.create(op_def.name, op_def.params)

与 Catlass 集成

import catlass
import metadef

# 查找算子实现
op_def = metadef.find("Conv2d")

# 使用 Catlass 构建算子
kernel = catlass.build(op_def)

与 Runtime 集成

import runtime
import metadef

# 算子编译和执行
op_def = metadef.find("MatMul")
exe = runtime.compile(op_def)
result = exe.execute(input_data)

性能影响

使用 METADEF 的性能考虑

操作 开销
算子查找 <1us
依赖解析 <10us
版本检查 <1us
动态注册 <100us

总结

METADEF 是 CANN 的算子元数据管理系统提供了统一的算子定义版本管理依赖解析等能力

更多技术细节https://atomgit.com/cann/metadef

Logo

鲲鹏昇腾开发者社区是面向全社会开放的“联接全球计算开发者,聚合华为+生态”的社区,内容涵盖鲲鹏、昇腾资源,帮助开发者快速获取所需的知识、经验、软件、工具、算力,支撑开发者易学、好用、成功,成为核心开发者。

更多推荐