5. 应用开发实践
该章节通过介绍简单的应用开发实践,让开发者能够快速了解如何通过后摩软件平台量化、编译和推理模型。
5.1. CV类模型
下面以 ResNet50 为例,展示从原始模型到可部署推理模型的完整流程,包含以下三个阶段:
模型量化: 将浮点模型量化为低精度模型,以提升推理效率。
模型编译: 编译量化后的模型,使其适配后摩M50硬件推理要求。
模型推理: 使用编译后的模型完成图片分类推理,输出预测类别及对应概率,实现完整的图片分类任务。
开发代码可在软件平台提供的Docker镜像中运行,Docker镜像部署详情参看 安装与部署。
5.1.1. 量化模型
软件平台提供HMQuantool工具用于模型量化。下面示例展示关键步骤代码,仅供参考,不可以直接拷贝运行。
注意
模型量化仅支持在Ubuntu 24.04 GPU和Ubuntu 24.04 CPU上完成,其他环境依赖可参看《后摩大道® M50 HMQuantool 量化工具用户手册》。
5.1.1.1. 模型量化步骤
量化主要步骤如下:
准备原始ResNet50 ONNX 模型。
模型需为 FP16 类型的 ONNX 文件,若原始模型为其他数据类型,需用户在使用前自行转换为 FP16 格式。此外,为获得更优性能,推荐使用 ONNX 格式作为输入。
可使用下面方式下载示例模型:
下载 应用开发示例包(示例代码)。
进入
houmo-examples-xh2/models/backbone/resnet50目录。运行下面脚本下载ResNet50模型:
python3 get_model.py --type raw
创建模型量化脚本,如命名为
ptq.py,并编写脚本:导入依赖库。
import os import shutil import torch from xhquant.api import ( DeviceType, QuantScheme, convert_onnx_to_hmonnx, create_quant_config, )
准备输入参数。根据模型实际路径更改
onnx_file参数。# Set the path of input model onnx_file = "./resnet50.onnx" # Generate random input data random_data = torch.randn(input_shape, dtype=torch.float32) # Set directory to save quantized model output_dir = "output/xh2" quant_type = "w8a8h1_sefp" hmonnx_model_path = os.path.join(output_dir, f"resnet50_xh2_{quant_type}.onnx") # Set input and output node names of the quantized model input_name = "input.1" output_name = "495"
初始化量化环境。
xhquant_init(None, debug=args.debug)
设置量化参数。
# Set quantization configurations quant_scheme = QuantScheme(target_device=DeviceType.XH2a, quant_type=quant_type) quant_config = create_quant_config(quant_scheme)
量化模型。
convert_onnx_to_hmonnx( model_path, # Input model path [random_data], # Random data device_type=DeviceType.XH2a, # Device type for quantization out_hmonnx_file=hmonnx_model_path, # Output path quant_config=quant_config, # Quantization configurations input_names=[input_name], # Input node name of the quantized model output_names=[output_name], # Output node name of the quantized model )
运行脚本量化模型:
python3 ptq.py
量化后模型文件(.onnx)保存在
output/xh2目录下。
完整示例代码,可参看 应用开发示例包(示例代码) 中 houmo-examples-xh2/apis/converts/resnet50/xh2/ptq.py。
5.1.2. 编译模型
模型量化后,可通过 后摩大道® M50 TCIM推理加速引擎编译模型。下面示例展示关键步骤代码,仅供参考,不可以直接拷贝运行。
5.1.2.1. 模型编译步骤
ResNet50模型编译步骤如下:
注意
仅支持在Linux X86 架构下编译模型。
创建模型编译脚本,如命名为
build.py,并编写脚本:导入依赖库。
import os import tcim import tcim_lite import numpy as np import logging
准备输入参数。根据模型实际路径更改
hmonnx_model_path参数。# Set input and output model path output_dir = "output/xh2" hmonnx_model_path = os.path.join(output_dir, f"resnet50_xh2_{quant_type}.onnx") # Set compilation configurations ncore = 1 opt_level = "O2" work_dir = os.path.join(output_dir, "tcim") # Set output model names hmmodel_name = f"resnet50_xh2_1batch_{ncore}core_{opt_level}"
调用
build_from_hmonnx编译量化后模型。tcim.build_from_hmonnx( hmonnx_model_path, # Input model for compilation output_name=hmmodel_name, # Output model name ncore=ncore, # The number of cores for compilation opt_level=opt_level, # The optimization level applied during compilation target="xh2", # Optimization level applied during compilation batch=1, # The batch size of the model output_dir=output_dir, # The directory to save the output work_dir=work_dir, # The directory for saving intermediate files )
运行脚本编译模型。
python3 build.py
编译后模型文件(.hmm)保存在
output_dir目录下。
完整示例代码,可参看 应用开发示例包(示例代码) 中 houmo-examples-xh2/apis/converts/resnet50/xh2/build.py。
5.1.2.2. 直接获取已编译模型
如果不具备编译环境,可直接下载已编译的ResNet50模型:
下载 应用开发示例包(示例代码)。
进入
houmo-examples-xh2/models/backbone/resnet50目录。运行下面脚本下载已编译模型:
python3 get_model.py --type hmm
5.1.3. 推理模型
模型编译后,可使用TCIM Python接口推理模型。下面示例展示如何推理ResNet50模型,完成图片分类任务。TCIM会自动管理推理过程中所需的内存,无需用户手动为输入和输出张量分配内存空间,默认使用主机内存。
创建模型推理脚本,如命名为
resnet50.py,并编写推理脚本:导入依赖库。
import os import sys import numpy as np import cv2 import torch import tcim_lite as tcim
加载编译后模型。根据模型实际路径更改
model_path参数。model_path = "./resnet50.hmm" module = tcim.runtime.load(model_path)
图像预处理。示例对
snake.png图像进行下面处理:图像格式从BGR转为RGB。
图像大小调整为 224 x 224。
按通道进行标准化处理。
数据变为 NCHW 格式。
转换为 float16 类型以匹配模型输入要求。
# Load the image input_data = cv2.imread("../../data/snake.jpg") # Convert image format from BGR to RGB input_data = cv2.cvtColor(input_data, cv2.COLOR_BGR2RGB) # Resize the image to (224, 224) input_data = cv2.resize(input_data, (224, 224)) # Define the mean values for each RGB channel mean_arr = np.array([123.675, 116.28, 103.53]) # Define the standard deviation values for each RGB channel std_arr = np.array([58.395, 57.12, 57.375]) # Normalize the image image_norm = (image_rgb - mean_arr) / std_arr # Change the data layout from HWC to CHW image_norm = np.transpose(image_norm, (2, 0, 1)) # Add a batch dimension image_norm = np.expand_dims(image_norm, axis=0) # Convert the data type to float16 to match model input requirements input_data = image_norm.astype(np.float16)
用户可在 应用开发示例包(示例代码) 中
houmo-examples-xh2/apis/data目录下获得snake.png图像。设置输入数据。
# get the total number of inputs input_num = module.get_num_inputs() # For each input for id in range(0, input_num): # Get the input name input_name = module.get_input_name(id) # Get the information about input data input_info = module.get_input_info(input_name).ascontiguous() # Set input data to the input with the given input name module.set_input(input_name, input_data)
模型推理及同步。
module.run() module.sync()
获取输出数据。
result_check = True # Get the totoal number of outputs output_num = module.get_num_outputs() # For each output: for id in range(output_num): # Get the output name output_name = module.get_output_name(id) # Get the information about output data output_info = module.get_output_info(output_name).ascontiguous().astype(np.float32) # Get the output data output_data = module.get_output(output_name).astype(np.float32).numpy()
预测结果展示,包括prob(置信度)和cls(预测类别ID)等。
from postprocess import softmax # Convert output data into probabilities output_data = softmax(output_data) topk = 5 # Sort the output data in descending order and select the top topk predictions pred_list = np.argsort(-output_data, axis=1, kind="quicksort").flatten()[0:topk] prob_list = output_data.flatten() # Iterate through the top predictions for i, id in enumerate(pred_list): print("top {}: predict cls = {}, prob = {:.6f}".format(i+1, id, prob_list[id])) # check result, modify it when you change model or data assert(pred_list[0] == 65) print("<=== resnet50 python example completed.\n")
运行脚本编译模型。
python3 resnet50.py
完整示例代码,可参看 应用开发示例包(示例代码) 中 houmo-examples-xh2/apis/inferences/resnet50.py。
5.2. LLM模型
LLM的量化、编译和推理详细介绍,参看 Qwen3模型样例运行。