征程 6 算法工具链 | PTQ 深度使用指南

这份指南聚焦开发者使用 PTQ 时的实际需求,从 "解决什么问题""怎么用 PTQ 解决" 的角度,提供实战步骤与技巧,手册(训练后量化 PTQ)中已有的通用内容将直接引用在线链接,避免重复。

一、快速评测:摸透模型性能上限

1.解决的核心问题

开发者拿到 float ONNX 模型后,首要需求是快速了解模型在地平线 征程 6 平台上的​最高运行性能​,无需投入大量时间配置参数,同时获取可复用的基础配置文件。

2.PTQ 实战操作

直接使用 hb_compile 工具的--fast-perf 参数,一步完成性能评测与基础配置生成。

执行命令:

Python 复制代码
hb_compile --march nash-b -m xxx.onnx --fast-perf

核心作用:

  • 自动将 BPU 可执行算子优先分配到 BPU(int8 精度),最大化性能。
  • 自动删除模型首尾冗余算子(如 Quantize/Dequantize、Cast、Transpose、Reshape 等),减少性能损耗。
  • 输出两个关键结果:板端最高性能数据、基础版 config.yaml(默认生成路径在。fast_perf 目录下,后续可直接修改使用)。

3.参考手册

详细原理与参数细节可查看:hb_compile 工具模型转换说明

二、校准部署:快速生成与修改 config.yaml

1.解决的核心问题

开发者需要基于快速评测结果,配置模型校准参数(如校准数据路径、输入格式),完成从浮点模型到可部署模型的转换,同时避免从零编写 config.yaml 的繁琐工作。

2.PTQ 实战操作

(1)快速生成基础 config.yaml

无需手动创建,直接复用 "快速评测" 步骤中--fast-perf 参数输出的基础版 config.yaml(默认生成路径在。fast_perf 目录下),该文件已包含 march(平台型号)、onnx_model(模型路径)等核心配置,减少 70% 以上的基础配置工作量。

(2)按需修改关键配置项

根据实际部署需求,修改 config.yaml 中的核心模块,以下为常见场景示例:

配置模块 核心修改项 场景示例
calibration_parameters cal_data_dir(校准数据路径)、quant_config(量化配置文件路径) 若校准数据存于。/calib_data,则设置 cal_data_dir: 。/calib_data
input_parameters input_shape(输入尺寸)、norm_type(预处理方式)、input_type_rt(运行时输入类型)、input_batch(多 batch 数) 灰度图输入场景:input_type_rt: gray,norm_type: data_mean_and_scale,并补充mean_value: 116.28和scale_value: 0.01750700280112。``多 batch=5 场景:input_batch: 5,separate_batch: True;输入尺寸设input_shape: 1x256x640x1(NCHW 格式)
compiler_parameters compile_mode(编译目标:latency 延迟 /throughput 吞吐量)、core_num(使用核心数) 追求低延迟时,设置 compile_mode: latency; 多核心部署时,调整 core_num: 2(查看用户手册确认 OE 版本是否已支持多核编译功能)
model_parameters working_dir(输出目录)、remove_node_type(需删除的冗余算子) 需删除 Softmax 算子时,设置remove_node_type: Quantize;Transpose;Dequantize;Cast;Reshape;Softmax

(3)执行校准部署命令

完成配置后,执行标准转换命令:hb_compile -c config.yaml,工具将自动完成模型校准、量化与编译,最终输出可部署的。hbm 模型文件。

3.参考手册

完整配置项说明与更多场景示例:PTQ 精度调优实战

三、模型部署:平衡性能与精度的实战流程

1.解决的核心问题

开发者在部署时需兼顾性能(速度)精度(模型效果) ,避免出现 "性能达标但精度不足" 或 "精度够但速度太慢" 的问题,需找到最优性价比的混合精度方案。

2.PTQ 实战三步法

第一步:用 fast-perf 确认性能上限

执行 hb_compile --march nash-b -m xxx.onnx --fast-perf,获取 int8 精度下的最高性能(如推理延迟、吞吐量),作为性能基准。

第二步:用全 int16 确认精度上限

修改 config.yaml 关联的 quant_config.json,将模型所有算子设置为 int16 精度(通过 model_config 配置"all_node_type": "int16"),执行 hb_compile -c config.yaml,测试模型精度,作为精度基准。

第三步:用 hmct-debugger 调混合精度

  1. 问题定位:使用 hmct-debugger 工具,分析哪些算子用 int8 时精度损耗大(如 Softmax、MatMul),哪些算子用 int8 无明显精度影响(如 Conv、Add)。
  2. 混合配置:在 quant_config.json 中,对精度敏感算子单独设置 int16,其余用 int8。示例配置如下:
Plain 复制代码
{
    "model_config": {
        "all_node_type": "int8"
    },
    "op_config": {
        "Conv": {"qtype":"int8"},
        "Mul": {"qtype":"int8"},
        "Add": {"qtype":"int8"}
    },
    "node_config": {
        "/transformer/encoder_1/layers.0/self_attn/MatMul_1": {"input0":"int16", "input1":"int8"},
        "/transformer/encoder_1/layers.0/self_attn/Softmax": {"qtype":"int16"}
    }
}
  1. 验证效果:执行 hb_compile -c config.yaml,测试混合精度模型的性能与精度,确保性能接近 int8 上限、精度接近 int16 上限。

3.参考手册

四、常见问题与 PTQ 解决方案

问题 1:模型转换后精度掉太多

PTQ 解决方法​:

  • 开启权重偏差校正(bias correction);
  • 对敏感算子改用 int16 或 fp16

操作步骤​:

  • 在 quant_config.json 的 weight 模块添加 "bias_correction": {"num_sample": 1, "metric": "cosine-similarity"};
  • 在 node_config 中指定敏感算子(如 MatMul、Softmax)的 qtype 为 int16 或 fp16

问题 2:多输入模型(如多特征图)配置复杂

PTQ 解决方法​:复用--fast-perf 基础配置,用分号分隔多输入参数

操作步骤​:在 input_parameters 中设置:

  • input_name: input0;input1;input2
  • input_shape: 1x1x1296x1600;50176;18816 并对应配置 input_type_rt 和 norm_type

问题 3:校准结果不稳定

PTQ 解决方法​:

  • 增加校准样本数;
  • 启用多校准方法搜索

操作步骤​:

  • 在 config.yaml 中调整 calibration_parameters 的样本量;
  • 在 quant_config.json 的 activation 模块设置 calibration_type: ["max", "kl"]校准方式,配置多组量化参数,启用 modelwise_search 会同时对多组量化参数做搜索,找到一个量化损失最小的校准方法。

五、关键配置文件模板

1.config.yaml 模板

Plain 复制代码
calibration_parameters:
  cal_data_dir: random_calib_data/_transformer_decoder_layer_1_Add_1_output_0  # 校准数据路径
  quant_config: quant_config.json  # 关联量化配置文件

compiler_parameters:
  advice: 0
  balance_factor: 0
  compile_mode: latency  # 编译目标:latency(低延迟)/throughput(高吞吐)
  core_num: 1  # 使用核心数,需匹配硬件支持
  jobs: 96
  max_time_per_fc: 0
  optimize_level: O2  # 编译器优化级别

input_parameters:
  input_name: _transformer_decoder_layer_1_Add_1_output_0  # 输入节点名
  input_type_train: featuremap
  input_layout_train: NCHW  # 输入数据格式
  input_shape: 1x256x640x1  
  input_type_rt: featuremap
  norm_type: no_preprocess  # 预处理方式:无预处理
  input_batch: 5  # 多batch设置
  separate_batch: True  # 开启多batch分离

model_parameters:
  march: nash-b  # 平台型号,nash-m平台需改为nash-m
  onnx_model: ./attention_no_bn.onnx  # ONNX模型路径
  output_model_file_prefix: attention_no_bn_int8_nash_b  # 输出模型前缀
  remove_node_type: Quantize;Transpose;Dequantize;Cast;Reshape;Softmax  # 需删除的冗余算子
  working_dir: output_int8_softmax_int16  # 输出目录

2.含校准搜索与混合精度的 quant_config.json 模板

Plain 复制代码
{
  "model_config": {
    "all_node_type": "int16",  # 默认所有算子int16
    "model_output_type": "int16"  # 模型输出int16
  },
  "op_config": {
    "Conv": {"qtype": "int8"},  # Conv算子int8
    "Mul": {"qtype": "int8"},   # Mul算子int8
    "MatMul": {"qtype": "int8"},# MatMul算子默认int8
    "Reshape": {"qtype": "int8"},# Reshape算子int8
    "Transpose": {"qtype": "int8"},# Transpose算子int8
    "Add": {"qtype": "int8"}    # Add算子int8
  },
  "node_config": {
    # 混合精度:特定MatMul节点输入0设int16,输入1设int8
    "/transformer/encoder_1/layers.0/self_attn/MatMul_1": {"input0": "int16", "input1": "int8"},
    "/transformer/encoder_1/layers.1/self_attn/MatMul_1": {"input0": "int16", "input1": "int8"},
    "/transformer/encoder_1/layers.2/self_attn/MatMul_1": {"input0": "int16", "input1": "int8"}
  },
  "activation": {
    "calibration_type": ["max", "kl"],  # 校准参数搜索:同时启用max和kl
    "num_bin": [1024, 2048],  # kl校准参数(多值用于搜索)
    "max_num_bin": 16384,     # kl校准最大bin数
    "max_percentile": [0.99995, 1.0],  # max校准百分位(多值用于搜索)
    "per_channel": [true, false],  # 是否开启per-channel量化(多值用于搜索)
    "asymmetric": [true, false]    # 是否开启非对称量化(多值用于搜索)
  },
  "weight": {
    "bias_correction": {
      "num_sample": 1,  # 参与bias correction的样本数
      "metric": "cosine-similarity"  # 偏差校正误差度量方法
    }
  },
  "modelwise_search": {
    "metric": "cosine-similarity"  # 模型层面校准搜索:用余弦相似度选最优校准方法
  },
  "layerwise_search": {
    "metric": "cosine-similarity"  # 节点层面校准搜索:逐层选最优校准方法(优先级高于modelwise)
  }
}

六、附录:核心参数与 quant_config 配置详解

1.核心参数总表

指定算子以 int16 输出,其功能已合入 node_info,后续版本将废弃指定算子以 int16 输入输出,或强制指定算子运行在 CPU 或 BPU 上,j6 使用 quant_config 配置校准参数组(所有参数并非独立可选,不能都不配置)强制指定算子在 CPU 上运行,其功能已合入 node_info,后续版本将废弃强制指定算子在 BPU 上运行,其功能已合入 node_info,后续版本将废弃编译参数组(要求至少有一个参数,不能都不配置)编译 bin 模型时的进程数,J6 编译 bc 模型时的进程数自定义算子参数组(可以都不配置)

参数名称 参数作用 可选/必选 默认值 支持平台
模型参数组
prototxt 指定 Caffe 浮点模型的 prototxt 文件名称 两种模型二选一 / XJ3、J5、J6
caffe_model 指定 Caffe 浮点模型的 caffemodel 文件名称 / XJ3、J5、J6
onnx_model 指定 ONNX 浮点模型的 onnx 文件名称 / XJ3、J5、J6
march 指定产出混合异构模型需要支持的平台架构 必选 / XJ3、J5、J6
output_model_file_prefix 指定转换产出混合异构模型的名称前缀 可选 model XJ3、J5、J6
working_dir 指定模型转换输出的结果的存放目录 可选 model_output XJ3、J5、J6
layer_out_dump 指定混合异构模型是否保留输出中间层值的能力 可选 FALSE XJ3、J5
output_nodes 指定模型的输出节点 可选 / XJ3、J5、J6
remove_node_type 设置删除节点的类型 可选 / XJ3、J5、J6
remove_node_name 设置删除节点的名称 可选 / XJ3、J5、J6
debug_mode 保存用于精度 debug 分析的校准数据 可选 / XJ3、J5、J6
set_node_data_type 可选 / J5
node_info 可选 / J5
输入信息参数组
input_name 指定原始浮点模型的输入节点名称 可选 / XJ3、J5、J6
input_type_train 指定原始浮点模型的输入数据类型 必选 / XJ3、J5、J6
input_layout_train 指定原始浮点模型的输入数据排布 必选 / XJ3、J5、J6
input_type_rt 转换后混合异构模型需要适配的输入数据格式 必选 / XJ3、J5、J6
input_layout_rt 转换后混合异构模型需要适配的输入数据排布 可选 / XJ3、J5
input_space_and_range 指定输入数据格式的特殊制式 可选 regular XJ3、J5、J6
input_shape 指定原始浮点模型的输入数据尺寸 可选 / XJ3、J5、J6
input_batch 指定转换后混合异构模型需要适配的输入 batch 数量 可选 1 XJ3、J5、J6
separate_batch 设置是否开启独立 batch 模式 可选 / J6
separate_name 不开启独立 batch 模式时,用于指定拆分的节点名称 可选 / J6
norm_type 在模型中添加的输入数据预处理方法 可选 no_preprocess XJ3、J5、J6
mean_value 指定预处理方法的图像减去的均值 可选 / XJ3、J5、J6
scale_value 指定预处理方法的数值 scale 系数 可选 / XJ3、J5、J6
cal_data_dir 指定模型校准使用的标定样本的存放目录 可选 / XJ3、J5、J6
quant_config J6 平台支持对多种与量化相关的参数进行灵活配置,您可以通过该参数配置模型算子的计算精度、校准方法以及校准参数搜索方法。 可选 / J6
cal_data_type 指定校准数据二进制文件的数据存储类型 可选 / XJ3、J5
preprocess_on 开启图片校准样本自动处理 可选 FALSE XJ3、J5
calibration_type 校准使用的算法类型 可选 default XJ3、J5
max_percentile 用于调整 max 校准的截取点 可选 1.0 XJ3、J5
per_channel 是否对 featuremap 的每个 channel 分别校准 可选 FALSE XJ3、J5
run_on_cpu 可选 / XJ3、J5
run_on_bpu 可选 / XJ3、J5
optimization 提供多种性能/精度的调优手段 可选 / XJ3、J5
compile_mode 编译策略选择 可选 latency XJ3、J5、J6
balance_factor balance 编译策略时的比例系数 可选 / J5、J6
debug 是否打开编译的 debug 信息 可选 TRUE XJ3、J5
core_num 模型运行核心数 可选 1 XJ3、J5、J6
optimize_level 模型编译的优化等级选择 可选 O0 XJ3、J5、J6
input_source 设置上板 bin 模型的输入数据来源 可选 / XJ3、J5、J6
max_time_per_fc 指定模型每个 function-call 的最大可连续执行时间(单位 μs) 可选 0 XJ3、J5、J6
jobs 可选 / XJ3、J5、J6
advice 提示模型编译后预估的耗时增加的情况(单位 μs) 可选 / XJ3、J5、J6
extra_params 通过此参数,可以额外对一些模型编译相关的参数进行灵活地配置 可选 / J6
custom_op_method 自定义算子策略选择 可选 / XJ3、J5
op_register_files 自定义算子的 Python 实现文件名称 可选 / XJ3、J5
custom_op_dir 自定义算子的 Python 实现文件存放路径 可选 / XJ3、J5

2.quant_config 配置说明

编译模型时可以通过 quant_config 进行量化参数的配置,支持在 model_config、op_config、subgraph_config、node_config 四个层面配置模型量化参数:

  • model_config:配置模型总体的量化参数,key 是自定义名称。
  • op_config:配置某类算子的量化参数,key 是算子的类型。
  • subgraph_config:配置某个子图的量化参数,key 是子图的名字。
  • node_config:配置某个具体节点的量化参数,key 是节点的名字。

配置时四个层面存在优先级关系,配置粒度越小优先级越高,即优先级 model_config < op_config < subgraph_config < node_config,当某个节点同时被多个维度配置时,优先级高的维度最终生效。

激活参数配置

  • calibration_type:校准方式支持 max、kl、[max、kl]
  • num_bin、max_num_bin:这些是 kl 量化的参数
  • max_percentile:用于 max 校准百分位
  • per_channel:是否开启 per-channel 量化
  • asymmetric:是否开启非对称量化

注:如果配置了多个校准方法,会启动 Modelwise 搜索方法,从多个候选校准模型中找出最优的量化模型;如果配置了 Layerwise 参数,则启动 Layerwise 搜索方法,逐层搜索最优的量化参数。

权重校准参数配置

  • num_sample:配置参与 bias correction 的样本数
  • metric:偏差校正误差度量方法 cosine-similarity、mse、mae、mre、sqnr 以及 chebyshev,默认值 cosine-similarity。

校准参数搜索方法

  • modelwise_search:在模型层面对量化参数进行搜索,该方法允许一次性配置多种校准方法,通过比较量化前后模型输出的量化损失 metric(可配置),找到一个量化损失最小的校准方法。
  • layerwise_search:在节点层面对量化参数进行搜索,该方法会根据每个节点量化前后模型输出,计算量化损失 metric(可配置),为该节点分配量化损失最小的校准方法。

注:多个校准方法时 modelwise_search 和 layerwise_search 可以都不配置,但默认会执行 modelwise_search 的逻辑(metric 会采用默认的 cosine-similarity)。

注:modelwise 和 layerwise 同时配置的时候,layerwise 优先级高。

参考手册

3.DeformConv2d 自定义算子

需要导入算子库进行算子注册from hmct.plugin.deformconv2d import *

Python 复制代码
import torch
import torchvision
import numpy as np
from hmct.plugin.deformconv2d import *
from hmct.api import build_model, load_model

class Model(torch.nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = torch.nn.Conv2d(3, 18, 3)
        self.conv2 = torchvision.ops.DeformConv2d(3,3,3)

    def forward(self, x):
        return self.conv2(x, self.conv1(x))
    
model = Model()
input = torch.rand(1, 3, 10, 10)
torch.onnx.export(model, input, 'model.onnx')

onnx_model = load_model("model.onnx")
input_array = np.random.rand(1,3,10,10).astype(np.float32)
cali_data = {'input':[input_array]}

build_model(march="nash",
            onnx_model=onnx_model,
            cali_data=cali_data,
            name_prefix="custom_model_with_deform_conv_2d")

from hbdk4.compiler.onnx import export
from hbdk4.compiler import save, convert, visualize, ompile, hbm_perf
import onnx

onnx_model = onnx.load("custom_model_with_deform_conv_2d_ptq_model.onnx")
hb_ptq_model = export(onnx_model, name="my_model")
save(hb_ptq_model, "ptq_model.bc")
hb_quantized_model = convert(hb_ptq_model, "nash-e", advice=True)
#可选,可视化模型
visualize(hb_quantized_model)
save(hb_quantized_model,"quantized.bc")

# 模型编译
compile(
    hb_quantized_model, 
    march="nash-e",
    path="model.hbm",
    opt=2, 
    jobs=96, 
    debug=True,
    progress_bar=True
)

# 性能评测
hbm_perf("model.hbm")
相关推荐
Xの哲學2 小时前
Linux 软中断深度剖析: 从设计思想到实战调试
linux·网络·算法·架构·边缘计算
暴风游侠2 小时前
如何进行科学的分类
笔记·算法·分类
leaves falling2 小时前
冒泡排序(基础版+通用版)
数据结构·算法·排序算法
C雨后彩虹3 小时前
无向图染色
java·数据结构·算法·华为·面试
坚持就完事了3 小时前
扫描线算法
算法
鱼跃鹰飞3 小时前
Leetcode尊享面试100题:252. 会议室
算法·leetcode·面试
程序员-King.3 小时前
二分查找——算法总结与教学指南
数据结构·算法
Zevalin爱灰灰3 小时前
现代控制理论——第三章 线性控制系统的能控性和能观性
线性代数·算法·现代控制
kklovecode3 小时前
C语言之头文件,宏和条件编译
c语言·开发语言·算法