4. 图像数据预处理
后摩硬件设备内置Resizer组件专用于在模型推理前对图像预处理,以达到模型推理所需要的数据格式要求。Resizer内部按以下固定顺序完成图像预处理操作:
Crop:以(top, left)为起点裁剪出一个(
crop_height
crop_width)区域的图像。Resize:调整图像大小。
Pad:填充图像。
后摩大道® M50 HMQuantool量化工具 提供硬件Resizer的配置和模拟功能。此外,除了Crop、Resize、Pad图像预处理操作,HMQuantool量化工具还支持归一化等一系列图像预处理辅助功能。
对于图像数据输入,HMQuantool量化工具会根据预处理参数设置,在量化生成的模型文件中添加ImageResize或DynamicImageResize算子。在调用后摩TCIM接口推理时,输入图像数据将通过硬件 Resizer 模块完成预处理操作,确保图像数据满足模型输入要求。
4.1. 功能说明
4.1.1. 功能限制
图像缩放:
缩小: 图像宽度(W)和高度(H)方向最大可缩小至原始尺寸的 1/32。
放大: 图像宽度(W)和高度(H)方向最大可放大 16 倍。
图像填充: 支持单方向填充,可选择上下或左右方向填充,但不能同时在两个方向进行。
4.1.2. 输入图像规格
支持格式: YUV420SP、YUV422SP、YUV444SP、R8、RGB888-Planar和RGBA8888-Planar。
最大输入尺寸(width x height):
YUV420SP、YUV422SP、R8、RGB8888-Planar、RGBA8888‑Planar:1024 x 4096 pixels;
YUV444SP:512 x 4096 pixels;
像素精度: 8 位无符号整数(uint8),像素值范围为 0 ~ 255。
4.1.3. 输出图像规格
最大输出尺寸(width x height): 1024 x 4096 pixels。
像素精度:
uint8,无符号数,取值范围为 0 ~ 255;
int8,有符号数,取值范围为 -128 ~ 127;
4.2. 图像预处理操作
4.2.1. 图像尺寸固定的场景
下面示例展示在图像尺寸固定的场景下,模型量化过程中配置并启用图像预处理的主要步骤。
示例中通过 ResizerScheme 配置了图像裁剪的区域,并设置 dynamic_crop 为 False。预处理阶段将输入的 RGB 图像 resize 到固定的 512 x 512,不启用裁剪和填充操作。图像数据按通道进行归一化处理,将像素值缩放到 [0, 1] 范围。预处理输入与输出的图像格式均为 RGB,因此不会发生格式转换。该配置适用于输入尺寸固定的常规图像模型量化与推理场景。
示例展示关键步骤代码,仅供参考,不可以直接拷贝运行。
导入依赖库。
import cv2 import torch import numpy as np from xhquant.api import ResizerScheme from xhquant.api import ( DeviceType, HMONNXGoldenInference, HMONNXInference, QuantScheme, convert_onnx_to_hmonnx, create_quant_config, convert_fx_model_to_quanted_model, convert_quanted_model_to_hmonnx, ConfigDict )加载模型。示例如下:
onnx_model = onnx.load(onnx_path)
读取输入图像并构造模型输入 Tensor。示例如下:
img = cv2.imread("image.jpg") img_tensor = torch.from_numpy(img).permute(2, 0, 1).unsqueeze(0)调用 xhquant_init 接口,初始化量化环境。示例如下:
xhquant_init(None, debug=args.debug)
通过 Class ResizerScheme 设置图像预处理参数,设置
dynamic_crop为False。示例如下:resizer_config = ResizerScheme( size=(512,512), align_corners=False, fmt="rgb", int_trans=True, crop_size=(0, 0), crop_offset=(0, 0), pad_size=(0, 0, 0, 0), pad_value=0, mean=[0.0,0.0,0.0], std=[1.0/255,1.0/255,1.0/255], dynamic_crop=False, model_inp_fmt="rgb", ).to_dict()通过 Class QuantScheme 设置量化方案。示例如下:
quant_scheme = QuantScheme( target_device=DeviceType.XH2a, quant_type=w8a8h1_sefp, input_ppc_config=[ resizer_config ] )示例中,设置推理目标设备类型为后摩M50芯片(
DeviceType.XH2a),并设置权重与激活均保留 8-bit尾数位,使用SEFP格式的量化方案(w8a8h1_sefp)。调用 create_quant_config 接口,构建量化配置。示例如下:
quant_config = create_quant_config(quant_scheme) quant_config = ConfigDict(quant_config)
调用 convert_onnx_to_hmonnx 接口,量化模型并导出量化后HMONNX模型。示例如下:
convert_onnx_to_hmonnx( onnx_model, [img_tensor], DeviceType.XH2a, quant_config=quant_config, )
4.2.2. 图像尺寸可变的场景
下面示例展示在图像尺寸可变的场景下,模型量化过程中配置并启用图像预处理的主要步骤。
示例中通过 ResizerScheme 配置了图像预处理参数,并设置 dynamic_crop 为 True。预处理阶段将输入的 YUV420 图像 resize 到目标尺寸 224 x 224,未启用裁剪和填充操作。图像数据按通道进行归一化处理,减去均值 [0.485, 0.456, 0.406] 并除以标准差 [1/255, 1/255, 1/255]。输入图像格式为 YUV420,预处理输出的图像格式为 RGB,因此在处理过程中会进行图像格式转换。该配置适用于图像尺寸可变场景的模型量化与推理。示例展示关键步骤代码,仅供参考,不可以直接拷贝运行。
导入依赖库。
import torch import cv2 import onnx import numpy as np import onnxruntime as ort from xhquant.api import ResizerScheme from xhquant.api import ( DeviceType, HMONNXGoldenInference, HMONNXInference, QuantScheme, convert_onnx_to_hmonnx, create_quant_config, convert_fx_model_to_quanted_model, convert_quanted_model_to_hmonnx, ConfigDict )加载模型。示例如下:
onnx_model = onnx.load(onnx_path)
构造量化校准输入数据。在动态裁剪或图像尺寸可变场景下,量化阶段需要为模型提供校准数据集(calibration dataset),用于生成量化参数。示例如下:
dims = onnx_model.graph.input[0].type.tensor_type.shape.dim input_shape = [dim.dim_value for dim in dims] seed = 100 torch.manual_seed(seed) dst_h = op_conf['compile_config']['dst_h'] dst_w = op_conf['compile_config']['dst_w'] params = [[0, 0, dst_h, dst_w, dst_h, dst_w, 0, 0, 0, 0]] crop_input = torch.tensor(params) calib_dataset = [ torch.randint(low=0, high=255, size=input_shape, dtype=torch.unit8), crop_input, ]上面
calib_dataset是对图像进行裁剪、缩放及填充的设置。params参数表示动态裁剪输入,依次表示:cropY:裁剪区域左上角的垂直坐标,单位为像素。cropX:裁剪区域左上角的水平坐标,单位为像素。crop_height:裁剪区域的高度,单位为像素。crop_width:裁剪区域的宽度,单位为像素。resize_height:缩放后图像的目标高度,单位为像素。resize_width:缩放后图像的目标宽度,单位为像素。pad_top:顶部填充的像素数。pad_left:左侧填充的像素数。pad_bottom:底部填充的像素数。pad_right:右侧填充的像素数。
设置模型输入和输出。示例如下:
注意
用户需在模型输入名称列表
input_names末尾使用append()添加一个自定义名称,该名称用于标识预处理输入tensor,以便在后续推理前方便定位这些 tensor,并对其进行动态图像处理。input_names = [_input.name for _input in onnx_model.graph.input] output_names = [_output.name for _output in onnx_model.graph.output] input_names.append("dyn_info")调用 xhquant_init 接口,初始化量化环境。示例如下:
xhquant_init(None, debug=args.debug)
通过 Class ResizerScheme 设置图像预处理参数,设置
dynamic_crop为True。示例如下:resizer_config = ResizerScheme( size=(224, 224), mode="bilinear", align_corners=False, fmt="yuv420", int_trans=True, crop_size=(0, 0), crop_offset=(0, 0), pad_size=(0, 0, 0, 0), pad_value=0, mean=[0.485, 0.456, 0.406], std=[1.0 / 255.0, 1.0 / 255.0, 1.0 / 255.0], dynamic_crop=True, model_inp_fmt="rgb", ).to_dict()通过 Class QuantScheme 设置量化方案。示例如下:
quant_scheme = QuantScheme( target_device=DeviceType.XH2a, quant_type=w8a8h1_sefp, input_ppc_config=[ resizer_config ] )示例中,设置推理目标设备类型为后摩M50芯片(
DeviceType.XH2a),并设置权重与激活均保留 8-bit尾数位,使用SEFP格式的量化方案(w8a8h1_sefp)。调用 create_quant_config 接口,构建量化配置。示例如下:
quant_config = create_quant_config(quant_scheme) quant_config = ConfigDict(quant_config)
调用 convert_onnx_to_hmonnx 接口,量化模型并导出量化后HMONNX模型。示例如下:
convert_onnx_to_hmonnx( onnx_path, calib_dataset, device_type=DeviceType.XH2a, out_hmonnx_file="hm.onnx", quant_config=quant_config, input_names=input_names, output_names=output_names, )