CANN ATC模型编译器深度解析:ONNX到OM的编译全流程与黑盒参数详解
有个团队把PyTorch模型转成ONNX后用ATC编译,编译出来的OM模型推理结果跟原始模型差了0.5%。排查了三天,最后发现是ATC编译时默认开了INT8量化,而他们没有提供校准数据,量化参数是从随机采样推导的——精度自然不行。
ATC(Ascend Tensor Compiler)是昇腾CANN的离线模型编译器,负责把训练框架导出的模型转换成NPU能直接执行的OM(Offline Model)格式。它做的事情远不止"格式转换"——里面包含了算子融合、图优化、精度选择、Tiling策略等大量优化。
1. ATC在CANN工具链中的位置
- ATC的输入:ONNX / Caffe / MindSpore / TF
- ATC的输出:OM文件(
.om) + 编译日志 + 优化报告
2. 最基本的ATC命令
atc--model=resnet50.onnx\--framework=5\--output=resnet50\--socVersion=Ascend910\--output_type=FP16参数详解:
--model: 输入模型文件路径(ONNX/Caffe/MindSpore)。--framework: 框架类型(0=Caffe,3=TF,5=ONNX,0=MindSpore IR)。--output: 输出文件名(不加.om后缀,自动加)。--socVersion: NPU型号Ascend310: 端侧NPUAscend310P: 升级版端侧Ascend910: 云侧训练/推理Ascend910B: 升级版云侧
--output_type: 输出精度(FP32/FP16/INT8),这个参数影响所有算子的计算精度。
3. 完整的ATC编译参数(生产级配置)
atc\--model=resnet50.onnx\--framework=5\--output=resnet50_fp16\--socVersion=Ascend910\--output_type=FP16\--input_shape="actual_input_1:1,3,224,224"\--input_format=NCHW\--dynamic_batch_size="1,2,4,8,16"\--dynamic_image_size="224,224;448,448"\--log=error\--insert_op_conf=preprocess.cfg\--keep_dtype=Add:fp32;Softmax:fp32\--fusion_switch_file=fusion.cfg\--precision_mode=allow_mix_precision\--op_select_implmode=high_performance\--optypelist_for_implmode="Gelu,LayerNorm,Softmax"\--buffer_optimize=l2_optimize\--enable_small_channel=1\--compress_weight_conf=compress.cfg\--out_nodes="MobilenetV2/Predictions/Reshape_1:0"\--disable_reuse_memory=0\--online_infer_mode=1★ 每个参数的作用详解表
| 参数 | 作用说明 |
|---|---|
--input_shape | 指定输入shape。格式:“name:d1,d2,d3”。ONNX模型有时shape不确定,必须指定。 |
--input_format | 输入数据格式。NCHW / NHWC / NC1HWC0。NHWC会自动转成NC1HWC0。 |
--dynamic_batch_size | 动态batch(多batch共用一个OM)。"1,2,4,8,16"表示支持这些batch size,推理时可以切换,不需要重新编译。 |
--dynamic_image_size | 动态分辨率(检测模型常用)。"224,224;448,448"支持两种分辨率。 |
--insert_op_conf | AIPP预处理配置。在OM里嵌入图像预处理(归一化等),推理时不需要在外部做预处理。 |
--keep_dtype | 指定某些算子保持特定精度。例如"Add:fp32"→ Add算子用FP32,防止混合精度出问题。 |
--precision_mode | 精度模式。force_fp16: 强制FP16allow_mix_precision: 允许自动混合must_keep_origin_dtype: 保持原精度 |
--op_select_implmode | 算子实现选择模式。high_performance: 选最快的kernelhigh_precision: 选精度最高的kernel |
--buffer_optimize | 内存优化策略。l2_optimize: 利用L2 Cacheoff: 不优化 |
--enable_small_channel | 小通道优化。当通道数<16时启用特殊优化,对MobileNet这类小通道模型很重要。 |
--compress_weight_conf | 权重压缩配置。可以把FP32权重压缩成INT8/INT4。 |
--out_nodes | 指定输出节点。多输出模型时需要指定,节点名来自ONNX图的输出tensor名。 |
--disable_reuse_memory | 禁用内存复用。0: 开启复用(省显存)1: 禁用复用(调试用) |
4. AIPP:嵌入式预处理配置
AIPP(AI Pre-Processing)配置文件可以将图像预处理直接编译进OM,推理时不需要外部做。
# preprocess.cfg aipp_op { aipp_mode: static # static=编译时确定,dynamic=运行时确定 related_input_rank: 0 # 作用于第0个输入 # ★ 颜色空间转换 color_space: RGB_TO_YUV_420 # 或者不转换(保持RGB) # ★ 归一化(减均值、除以标准差) mean_chn_0: 123.675 mean_chn_1: 116.28 mean_chn_2: 103.53 min_chn_0: 58.395 min_chn_1: 57.12 min_chn_2: 57.375 # 实际操作:output = (input - mean) / std # ★ Resize(输入图片大小不固定时) resize: true resize_output_w: 224 resize_output_h: 224 # ★ Padding padding: true padding_top: 0 padding_left: 0 padding_right: 0 padding_bottom: 0 padding_value: 0 # ★ Crop (可选) crop: false load_start_pos_w: 0 load_start_pos_h: 0 crop_size_w: 224 crop_size_h: 224 }通过合理使用上述参数和配置,可以确保从ONNX到OM的转换过程中,模型精度损失最小化,同时充分利用NPU的硬件特性(如AIPP、动态Shape、内存复用等)以获得最佳推理性能。
