本文基于昇腾CANN和昇腾NPU,围绕 ATC 模型转换 技术展开。

PyTorch 导出 ONNX,ATC 把 ONNX 编译成 OM模型——这步模型转换是昇腾推理的第一道工序。ATC(Ascend Tensor Compiler)是 CANN 的模型编译工具,Graph Compiler 在编译期参与图优化,输入可以是 ONNX、MindSpore MindIR 或 TensorFlow PB,输出是一个 .om 文件。

这个 OM 不是简单的格式转换。ATC 在编译期跑了图解析、常量折叠、算子选择、精度策略判断、融合模式匹配——五步做完,生成的 OM 已经包含了 Runtime 执行所需的全部信息:融合后的算子列表、每个 Kernel 的 Tile 配置、Buffer 分配方案、Stream 调度计划。


第一个 ATC 转换命令

atc --model=resnet50.onnx \
    --framework=5 \
    --output=resnet50_ascend \
    --soc_version=Ascend910 \
    --input_shape="input:1,3,224,224" \
    --input_format=NCHW \
    --precision_mode=allow_fp32_to_fp16

# 输出:
# [ATC] Graph parse success. 486 nodes loaded.
# [ATC] Constant folding: 112 nodes eliminated.
# [ATC] Op substitution: 45 ops replaced with native kernels.
# [ATC] Fusion: 48 patterns matched, 32 ops fused.
# [ATC] Build success → resnet50_ascend.om (48.2 MB)

关键参数详解

--framework=5:5 是 ONNX。0=Caffe、1=MindSpore、3=TensorFlow、5=ONNX。选错了解析不了图,报 Unknown framework type

--input_shape:必须写成 "name:dim1,dim2,dim3,dim4" 带引号。name 必须跟 ONNX 的 Input Node 名字完全一致——用 Netron 打开 ONNX 确认,别猜。动态维度标 -1,配合 --dynamic_batch_size="1,2,4,8" 使用。

--precision_mode:三个选项。force_fp16 全转 FP16(精度可能炸——Softmax 和 LayerNorm 的 exp 在 FP16 下数值范围不够),allow_fp32_to_fp16 智能转换(ATC 只动它认为安全的算子),must_keep_origin_dtype 保持原精度。大多数场景选 allow_fp32_to_fp16

--fusion_switch_file:融合控制文件。一行一个开关:

FusedLayerNormMatMul=true
ConvBNReLU=false

不开这个文件时 ATC 用默认融合策略,已经覆盖了常用模式。只在精度调试或极致性能调优时才需要手动控制。


转换中的典型问题

ONNX Opset 兼容性。 PyTorch 默认导出 opset_version=17,ATC 的最高支持版本视 CANN 版本而定(CAN 8.0 支持到 opset 15)。导出时显式指定 torch.onnx.export(..., opset_version=11)

动态 Shape。 ONNX 里有 -1 维度时 ATC 报 dynamic shape not supported。加 --dynamic_batch_size="1,2,4,8" 声明动态范围。如果是 SeqLen 维度动态——加 --dynamic_image_size(名字叫 image,实际管所有动态维度)。

自定义算子。 PyTorch 里的 torch.ops.my_custom_op 导出 ONNX 后 ATC 不识别。用 --op_name_map 写映射文件:

my_custom_op:ascend_equivalent_kernel

学习路线

第一天:跑通 ResNet-50 的转换和推理——验证 npu-smi info、ATC 编译、pyACL 推理三条链路都通。

第一周:学会调 precision_mode 和读融合日志。注意 [ATC] Fusion: 48 patterns matched——这个数字越高推理越快。

第一个月:看懂 OP_SELECT 日志——每个 ONNX 算子映射到哪个 Ascend Kernel。Gather 算子被映射到 Scalar Kernel 还是 Cube Kernel 取决于 index 大小——这是推理性能调优绕不开的知识。


参考仓库

ATC 编译工具

GE 图引擎

CANN Samples

CANN 学习中心

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐