CANN ATC 模型转换指南:cann-recipes-harmony-infer 端侧推理离线模型生成实战
【免费下载链接】cann-recipes-harmony-infer本项目为鸿蒙开发者提供基于CANN平台的业务实践案例,方便开发者参考实现端云能力迁移及端侧推理部署。项目地址: https://gitcode.com/cann/cann-recipes-harmony-infer
ATC(Ascend Tensor Compiler)是异构计算架构 CANN 体系下的模型转换工具,它能够将开源框架的网络模型(如 ONNX、MindSpore 导出的 AIR 模型)以及基于 Ascend IR 定义的单算子描述文件(JSON 格式)统一转换为昇腾、麒麟 AI 处理器支持的离线模型格式(om/omc)。在 cann-recipes-harmony-infer 项目中,ATC 是连接「自定义算子/ONNX 模型开发」与「鸿蒙端侧 NPU 推理」的关键桥梁:无论是ops/ascendc目录下的自定义算子验证,还是 Soble 端侧推理示例 中图片滤波识别的 NPU 加速,都依赖 ATC 先生成离线模型。读完本文,你将掌握 ATC 工具的环境准备、三类典型转换场景(ONNX 模型、AIR 模型、单算子描述文件)的完整命令用法,以及核心参数的取值含义与仓库内的真实应用佐证。
ATC 工具简介
ATC 的核心职责是离线编译:它把训练框架产出的网络模型(或 Ascend IR 单算子描述)在 PC 侧提前编译成适配特定 AI 处理器型号的离线模型文件,端侧应用运行时无需再做模型解析与图优化,直接加载离线模型即可执行推理。
在鸿蒙端侧推理场景中,这一环节尤其重要。以仓库中的 Soble 示例 为例,工程说明中明确指出:「使用 DevEco 构建应用前请将ATC 转换后的 omc 模型文件放置到应用entry/src/main/resources/rawfile目录下,再进行应用构建和安装」。也就是说,ATC 转换产物是端侧应用打包的必要输入,转换结果直接决定了端侧推理能否运行。
环境准备
安装开发套件
参见 环境准备 完成环境搭建,核心步骤为:
- 下载对应版本的鸿蒙社区版 CANN 开发套件包
Ascend-cann-toolkit_${cann_version}_linux-${arch}-mobile-station.run; - 执行安装命令:
chmod +x Ascend-cann-toolkit_${cann_version}_linux-${arch}-mobile-station.run ./Ascend-cann-toolkit_${cann_version}_linux-${arch}-mobile-station.run --install --force --install-path=${install_path}其中${cann_version}表示 CANN 包版本号,${arch}表示 CPU 架构(如 aarch64、x86_64),${install_path}表示指定安装路径,默认安装在/usr/local/Ascend目录。
安装完成后,该场景下ATC 工具位于${install_path}/cann/bin目录下。以 root 安装为例,安装目录为/usr/local/Ascend/ascend-toolkit。仓库中自定义算子的构建脚本(如 build_and_install.sh)也默认在ASCEND_HOME_PATH未设置时回退到/usr/local/Ascend/cann并加载setenv.bash,可见该路径是 CANN 环境的默认约定。
配置环境变量
安装 CANN 软件后,使用 CANN 运行用户进行编译、运行时,需要以 CANN 运行用户登录环境,执行如下环境变量:
# 默认路径安装,以root用户为例(非root用户,将/usr/local替换为${HOME}) source /usr/local/Ascend/cann-${cann_version}/set_env.sh # 指定路径安装 # source ${install_path}/cann-${cann_version}/set_env.sh执行后atc命令即进入 PATH。需要说明的是,${cann_version}需替换为实际安装的 CANN 版本号目录名。
模型转换实战
以下三类转换场景覆盖了仓库中从算子验证到端侧部署的全部模型来源。
ONNX 网络模型转换成离线模型
ONNX 是仓库自定义算子工程输出网络模型的默认格式。例如 add_custom 自定义算子工程 通过onnx.helper.make_node("AddCustom", ...)构造包含自定义算子节点的 ONNX 模型,sobel_custom 工程 则构造包含SobelCustom算子的 ONNX 模型(输入UINT8类型、shape 为[1, 763, 1024, 3])。这些 ONNX 文件正是通过 ATC 转换成离线模型后参与端侧验证的。
将 ONNX 网络模型转换为离线模型的命令:
atc --model=$HOME/module/resnet50*.onnx --framework=5 --output=$HOME/module/out/onnx_resnet50 --soc_version=<soc_version>参数说明:
--model:Resnet50 网络模型文件所在路径。--framework:原始框架类型,5 表示 ONNX。--output:生成的离线模型路径。--soc_version:Kirin AI 处理器的型号,如KirinX90、Kirin9030等。
仓库中 AddKernelInvocation 样例的 run.sh 对soc_version的取值有直接约束:脚本内置VersionMap,仅接受KirinX90与Kirin9030两个取值,若传入其他值会报错ERROR: SOC_VERSION should be in [...],并在后续以该值指定-DASCEND_PRODUCT_TYPE参与编译。这印证了上述--soc_version取值在该项目中的实际可用范围。
*.air 格式的模型文件转换成离线模型
*.air为 Ascend Intermediate Representation 格式的模型文件(由 MindSpore 等框架导出),转换为离线模型的命令:
atc --model=$HOME/module/ResNet50.air --framework=1 --output=$HOME/module/out/ResNet50_air --soc_version=<soc_version>参数说明:
--model:*.air格式的模型文件所在路径。--framework:原始框架类型,1 表示*.air格式的模型文件。--output:生成的离线模型路径。--soc_version:Kirin AI 处理器的型号,如KirinX90、Kirin9030等。
注意与 ONNX 场景的区别仅在于--framework的取值,其余参数语义完全一致。
单算子描述文件转换成离线模型
单算子描述文件是基于 Ascend IR 定义的单个算子的定义文件,包括算子的输入、输出及属性等信息。借助该文件转换成适配昇腾、麒麟 AI 处理器的离线模型后,可以脱离完整网络模型单独验证单算子的功能,这也是自定义算子开发调试阶段常用的验证手段。
转换命令:
atc --singleop=$HOME/singleop/add.json --output=$HOME/singleop/out/op_model --soc_version=<soc_version>参数说明:
--singleop:用于指定add.json单算子描述文件。--output:转换后的离线模型存放路径。--soc_version:Kirin AI 处理器的型号,如KirinX90、Kirin9030等。
从仓库结构看,ops/ascendc下每个自定义算子工程均包含op_host(算子宿主侧实现与 tiling)与op_kernel(算子核函数实现),并配套 build_and_install.sh 编译生成custom_opp_${OS_ID}_${arch}.run算子包安装到 CANN 环境。算子包安装成功后,ATC 才能正确识别自定义算子,进而支持将包含这些算子的 ONNX 模型(如上述SobelCustom.onnx)或单算子描述文件转换为离线模型。
转换产物在端侧推理中的应用
转换得到的离线模型在鸿蒙端侧通过 CANN 提供的 HiAI Foundation 与 NNCore 接口加载执行。以 Soble 示例 为例,其端侧推理链路为:
- 将 ATC 转换后的
SobelCustom.omc模型放入应用entry/src/main/resources/rawfile目录; - 应用启动后通过
OH_NNCompilation_ConstructWithOfflineModelBuffer(const void* modelBuffer, size_t modelSize)直接基于离线模型 buffer 构建编译对象; - 通过
OH_NNCompilation_SetDevice、OH_NNCompilation_Build完成设备绑定与编译,再由OH_NNExecutor_Construct创建执行器; - 通过
OH_NNExecutor_RunSync同步执行推理,将滤波识别结果与耗时展示到界面。
该链路说明:--soc_version必须与端侧实际搭载的 Kirin AI 处理器型号严格一致,否则离线模型无法在目标设备上加载执行。
ATC 核心参数详解
下表完整列出 ATC 工具的主要参数(摘自 docs/atc_tools_guide.md 附录),并补充了仓库实践中的补充说明:
| ATC 参数名称 | 参数简述 | 是否必选 | 默认值 |
|---|---|---|---|
--help或--h | 显示帮助信息。 | 否 | 不涉及 |
--model | 原始模型文件路径与文件名。 | 是 | 不涉及 |
--framework | 原始框架类型。 | 是 | 不涉及 |
--input_format | 输入数据格式。 | 否 | Caffe、MindSpore、ONNX 默认为 NCHW;TensorFlow 默认为 NHWC |
--input_shape | 模型输入数据的 shape。 | 否 | 不涉及 |
--singleop | 单算子定义文件,将单个算子 JSON 文件转换成适配昇腾 AI 处理器的离线模型。 | 否 | 不涉及 |
--output | 如果是开源框架的网络模型,存放转换后的离线模型的路径以及文件名;如果是单算子描述文件,存放转换后的单算子模型的路径。 | 是 | 不涉及 |
--output_type | 指定网络输出数据类型或指定某个输出节点的输出类型。 | 否 | 不涉及 |
--soc_version | 模型转换时指定芯片版本。 | 是 | 不涉及 |
--core_type | 设置网络模型使用的 Core 类型,若网络模型中包括 Cube 算子,则只能使用 AiCore。 | 否 | AiCore |
--out_nodes | 指定输出节点。 | 否 | 不涉及 |
--external_weight | 生成 om 离线模型时,是否将原始网络中的 Const/Constant 节点的权重保存在单独的文件中,同时将节点类型转换为 FileConstant 类型。 | 否 | 0 |
--precision_mode | 设置网络模型的精度模式。 | 否 | force_fp16 |
--precision_mode_v2 | 设置网络模型的精度模式。与--precision_mode不能同时使用,推荐使用--precision_mode_v2。 | 否 | fp16 |
--log | 设置 ATC 模型转换过程中显示日志的级别。 | 否 | null |
关键参数的仓库实践注记
--soc_version(必选):从 run.sh 的VersionMap定义可见,本项目支持KirinX90与Kirin9030两种型号,且二者均强制使用CORE_TYPE="AiCore"(对应--core_type的默认值 AiCore)。该型号还影响运行模式:KirinX90/Kirin9030不支持 CPU 仿真分支(脚本中明确提示Kirin Soc Currently not support cpu!),只支持sim(NPU 仿真)与npu模式。--framework(必选):仓库中实际使用到的是 5(ONNX)与 1(AIR),对应 create_onnx.py 生成的*.onnx模型文件。转换前请先通过build_and_install.sh完成自定义算子包安装,否则 ATC 无法识别模型中的自定义算子节点。--input_format/--input_shape:对于动态 shape 的模型,可在转换时通过--input_shape固定输入维度;端侧推理时输入张量的 shape 必须与转换时设定一致。Soble 示例中SobelCustom.onnx的输入为[1, 763, 1024, 3],输出为[1, 1, 761, 1022],转换时若指定--input_shape应与此保持一致。--precision_mode_v2(默认 fp16):默认以 fp16 精度完成转换,可在精度与性能之间权衡;若网络中存在精度敏感层,可通过--precision_mode_v2调整为fp32等模式。需要注意该参数与--precision_mode互斥,官方推荐使用--precision_mode_v2。--log(默认 null):设置转换过程日志级别,用于排查转换失败时的问题定位;转换异常时可结合日志中报错的算子信息回到op_host/op_kernel侧修正实现。
常见问题与注意事项
soc_version必须与端侧芯片一致:离线模型与芯片型号强绑定,--soc_version与设备实际处理器型号不匹配将导致模型无法加载。本项目以KirinX90、Kirin9030为基准(参见 AddKernelInvocation/run.sh)。- 自定义算子需先安装算子包:包含自定义算子的模型在转换前,必须通过对应工程(如 sobel_custom、add_custom)的
build_and_install.sh生成并安装custom_opp_${OS_ID}_${arch}.run算子包,否则 ATC 会因无法识别算子而报错。 - 端侧模型文件名与放置目录:转换后的离线模型(如
.omc)需放入鸿蒙应用entry/src/main/resources/rawfile目录后再构建应用,参见 Soble 示例说明。 - 含 Cube 算子的网络必须使用 AiCore:
--core_type默认即为 AiCore,一般无需显式指定;若网络仅包含矢量算子,可评估其他 Core 类型的收益。 - 精度模式选型:默认 fp16 转换可获得较好性能,但对精度敏感的网络建议先使用默认精度验证结果,再逐步放宽,避免端侧推理结果偏差。
参考与延伸阅读
- 环境准备与依赖安装:toolkit 安装、
install_deps.sh依赖安装与环境变量配置的完整步骤。 - AscendC 自定义算子开发指南:理解
op_host/op_kernel结构与算子包构建流程。 - AddKernelInvocation 算子调用样例:演示自定义算子从编译到 NPU 仿真/运行验证的完整闭环,其中
main.cpp展示了aclInit、流创建、数据搬运与核函数调用的完整流程。 - Soble 端侧推理示例:ATC 转换产物在鸿蒙应用中的加载与执行方式。
- 自定义算子工程 create_onnx.py 与 sobel_custom 的 create_onnx.py:构造待转换 ONNX 模型的参考实现。
【免费下载链接】cann-recipes-harmony-infer本项目为鸿蒙开发者提供基于CANN平台的业务实践案例,方便开发者参考实现端云能力迁移及端侧推理部署。项目地址: https://gitcode.com/cann/cann-recipes-harmony-infer
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考