From 284f9d588c6fd387860c1a02c12ea1d4b3f64300 Mon Sep 17 00:00:00 2001 From: "shengyan.zhao" Date: Wed, 8 Apr 2026 16:56:36 +0800 Subject: [PATCH 1/6] fix TEST-13639 Signed-off-by: shengyan.zhao --- models/cv/classification/ixrt_common/quant.py | 136 +++++++++++++++--- 1 file changed, 120 insertions(+), 16 deletions(-) diff --git a/models/cv/classification/ixrt_common/quant.py b/models/cv/classification/ixrt_common/quant.py index 2726bf02..e36539f7 100644 --- a/models/cv/classification/ixrt_common/quant.py +++ b/models/cv/classification/ixrt_common/quant.py @@ -1,28 +1,92 @@ import os -import cv2 import random import argparse import numpy as np -from random import shuffle -from tensorrt.deploy import static_quantize +import onnx +if not hasattr(onnx, "mapping"): + import types + onnx.mapping = types.ModuleType("onnx.mapping") + onnx.mapping.TENSOR_TYPE_TO_NP_TYPE = { + k: v.np_dtype for k, v in onnx._mapping.TENSOR_TYPE_MAP.items() + } import torch -import torchvision.datasets +from onnxruntime.quantization import ( + quantize_static, + QuantType, + CalibrationDataReader, + QuantFormat, + CalibrationMethod, +) from calibration_dataset import getdataloader +OBSERVER_MAP = { + "minmax": CalibrationMethod.MinMax, + "entropy": CalibrationMethod.Entropy, + "percentile": CalibrationMethod.Percentile, + "hist_percentile": CalibrationMethod.Percentile, + "ema": CalibrationMethod.MinMax, +} + + +class TorchCalibrationDataReader(CalibrationDataReader): + def __init__(self, dataloader, input_name): + self.dataloader = dataloader + self.input_name = input_name + self.iterator = iter(dataloader) + + def get_next(self): + try: + data, _ = next(self.iterator) + if isinstance(data, torch.Tensor): + return {self.input_name: data.cpu().numpy()} + return None + except StopIteration: + return None + + +def fix_quantize_axis_attribute(model_path, output_path): + """Reset axis to 0 on all QuantizeLinear/DequantizeLinear nodes. + + ONNX opset>=13 defaults axis to 1 when the attribute is absent, + which is out of range for 1-D tensors like biases. Setting axis=0 + is safe for both per-tensor (scalar scale/zp) and per-channel cases. + """ + model = onnx.load(model_path) + quantize_node_types = {"QuantizeLinear", "DequantizeLinear", "DynamicQuantizeLinear"} + for node in model.graph.node: + if node.op_type in quantize_node_types: + found = False + for attr in node.attribute: + if attr.name == "axis": + attr.i = 0 + found = True + if not found: + node.attribute.append(onnx.helper.make_attribute("axis", 0)) + onnx.save(model, output_path) + + +def get_onnx_input_name(model_path): + model = onnx.load(model_path) + return model.graph.input[0].name + + def setseed(seed=42): random.seed(seed) np.random.seed(seed) torch.manual_seed(seed) + def parse_args(): parser = argparse.ArgumentParser() parser.add_argument("--model_name", type=str) parser.add_argument("--model", type=str) parser.add_argument("--dataset_dir", type=str, default="imagenet_val") - parser.add_argument("--observer", type=str, choices=["hist_percentile", "percentile", "minmax", "entropy", "ema"], default="hist_percentile") + parser.add_argument("--observer", type=str, + choices=["hist_percentile", "percentile", "minmax", "entropy", "ema"], + default="hist_percentile") parser.add_argument("--disable_quant_names", nargs='*', type=str) - parser.add_argument("--save_dir", type=str, help="save path", default=None) + parser.add_argument("--save_dir", type=str, help="save path", default=None) parser.add_argument("--bsz", type=int, default=32) parser.add_argument("--step", type=int, default=20) parser.add_argument("--seed", type=int, default=42) @@ -32,13 +96,53 @@ def parse_args(): print(args.disable_quant_names) return args -args = parse_args() -setseed(args.seed) -calibration_dataloader = getdataloader(args.dataset_dir, args.step, args.bsz, img_sz=args.imgsz) -static_quantize(args.model, - calibration_dataloader=calibration_dataloader, - save_quant_onnx_path=os.path.join(args.save_dir, f"quantized_{args.model_name}.onnx"), - observer=args.observer, - data_preprocess=lambda x: x[0].to("cuda"), - quant_format="qdq", - disable_quant_names=args.disable_quant_names) \ No newline at end of file + +def main(): + args = parse_args() + setseed(args.seed) + + model = onnx.load(args.model) + opset = model.opset_import[0].version + if opset < 13: + print(f"opset version: {opset}, converting to 13 for QDQ quantization") + model = onnx.version_converter.convert_version(model, 13) + onnx.save(model, args.model) + + input_name = get_onnx_input_name(args.model) + print(f"Model input name: {input_name}") + + calibration_dataloader = getdataloader( + args.dataset_dir, args.step, args.bsz, img_sz=args.imgsz + ) + calib_reader = TorchCalibrationDataReader(calibration_dataloader, input_name) + + output_path = os.path.join(args.save_dir, f"quantized_{args.model_name}.onnx") + calibrate_method = OBSERVER_MAP.get(args.observer, CalibrationMethod.MinMax) + + nodes_to_exclude = args.disable_quant_names or [] + + print(f"Calibration method: {calibrate_method}") + print(f"Nodes to exclude: {nodes_to_exclude}") + + quantize_static( + model_input=args.model, + model_output=output_path, + calibration_data_reader=calib_reader, + weight_type=QuantType.QInt8, + activation_type=QuantType.QInt8, + quant_format=QuantFormat.QDQ, + per_channel=True, + calibrate_method=calibrate_method, + nodes_to_exclude=nodes_to_exclude, + extra_options={ + "ActivationSymmetric": True, + "WeightSymmetric": True, + "QuantizeBias": False, + }, + ) + fix_quantize_axis_attribute(output_path, output_path) + print(f"Quantized model saved to: {output_path}") + + +if __name__ == "__main__": + main() \ No newline at end of file -- Gitee From d1754323793fa62fb527ae9917ce63072980a4ff Mon Sep 17 00:00:00 2001 From: "shengyan.zhao" Date: Thu, 9 Apr 2026 10:25:54 +0800 Subject: [PATCH 2/6] set dynamo and install onnxscript Signed-off-by: shengyan.zhao --- models/cv/classification/ixrt_common/export.py | 3 ++- models/cv/classification/ixrt_common/requirements.txt | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/models/cv/classification/ixrt_common/export.py b/models/cv/classification/ixrt_common/export.py index dd10b13a..d324d8f8 100644 --- a/models/cv/classification/ixrt_common/export.py +++ b/models/cv/classification/ixrt_common/export.py @@ -75,7 +75,8 @@ def main(): input_names = input_names, dynamic_axes = dynamic_axes, output_names = output_names, - opset_version=13 + opset_version=13, + dynamo=False ) print("Export onnx model successfully! ") diff --git a/models/cv/classification/ixrt_common/requirements.txt b/models/cv/classification/ixrt_common/requirements.txt index 560b910c..891449a8 100644 --- a/models/cv/classification/ixrt_common/requirements.txt +++ b/models/cv/classification/ixrt_common/requirements.txt @@ -3,4 +3,5 @@ tabulate pycuda onnx onnxsim -opencv-python==4.6.0.66 \ No newline at end of file +opencv-python==4.6.0.66 +onnxscript -- Gitee From 0e0a70173e5d0f7d1ed6d99d981dccfb45676c6c Mon Sep 17 00:00:00 2001 From: "shengyan.zhao" Date: Fri, 10 Apr 2026 16:24:36 +0800 Subject: [PATCH 3/6] fix for yolov5m ixrt Signed-off-by: shengyan.zhao --- .../ixrt_common/modify_batchsize.py | 19 +++++++++++++++++++ .../ixrt_common/requirements.txt | 3 ++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/models/cv/object_detection/ixrt_common/modify_batchsize.py b/models/cv/object_detection/ixrt_common/modify_batchsize.py index 64a32433..bc44b719 100644 --- a/models/cv/object_detection/ixrt_common/modify_batchsize.py +++ b/models/cv/object_detection/ixrt_common/modify_batchsize.py @@ -2,6 +2,7 @@ import onnx import argparse import numpy as np + def change_input_dim(model, bsz): batch_size = bsz @@ -37,6 +38,23 @@ def change_input_dim(model, bsz): raw_data[0] = batch_size data.raw_data = raw_data.tobytes() +def change_reshape_batch(model, bsz): + batch_size = int(bsz) if not isinstance(bsz, int) else bsz + initializer_map = {init.name: init for init in model.graph.initializer} + for node in model.graph.node: + if node.op_type == 'Reshape' and len(node.input) >= 2: + shape_name = node.input[1] + if shape_name not in initializer_map: + continue + init = initializer_map[shape_name] + shape_val = np.array(onnx.numpy_helper.to_array(init)) + if len(shape_val) >= 1 and shape_val[0] > 0 and shape_val[0] != batch_size: + old_val = shape_val[0] + shape_val[0] = batch_size + new_init = onnx.numpy_helper.from_array(shape_val, name=shape_name) + init.CopyFrom(new_init) + print(f" Reshape {node.name}: shape[0] {old_val} -> {batch_size}") + def parse_args(): parser = argparse.ArgumentParser() parser.add_argument("--batch_size", type=int) @@ -48,4 +66,5 @@ def parse_args(): args = parse_args() model = onnx.load(args.origin_model) change_input_dim(model, args.batch_size) +change_reshape_batch(model, args.batch_size) onnx.save(model, args.output_model) \ No newline at end of file diff --git a/models/cv/object_detection/ixrt_common/requirements.txt b/models/cv/object_detection/ixrt_common/requirements.txt index 46ef4ec8..42644615 100644 --- a/models/cv/object_detection/ixrt_common/requirements.txt +++ b/models/cv/object_detection/ixrt_common/requirements.txt @@ -5,4 +5,5 @@ ultralytics pycocotools opencv-python==4.6.0.66 pycuda -seaborn \ No newline at end of file +seaborn +onnxscript -- Gitee From 6e0d8beb1d3e27828730bff0b623b2b39c6d6ca8 Mon Sep 17 00:00:00 2001 From: "shengyan.zhao" Date: Fri, 10 Apr 2026 18:12:03 +0800 Subject: [PATCH 4/6] fix for ixrt yolov7 Signed-off-by: shengyan.zhao --- models/cv/classification/ixrt_common/quant.py | 3 ++- models/cv/object_detection/ixrt_common/config/YOLOV7_CONFIG | 5 +++-- models/cv/object_detection/yolov7/ixrt/ci/prepare.sh | 4 ++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/models/cv/classification/ixrt_common/quant.py b/models/cv/classification/ixrt_common/quant.py index e36539f7..583584c8 100644 --- a/models/cv/classification/ixrt_common/quant.py +++ b/models/cv/classification/ixrt_common/quant.py @@ -52,6 +52,7 @@ def fix_quantize_axis_attribute(model_path, output_path): which is out of range for 1-D tensors like biases. Setting axis=0 is safe for both per-tensor (scalar scale/zp) and per-channel cases. """ + model = onnx.load(model_path) quantize_node_types = {"QuantizeLinear", "DequantizeLinear", "DynamicQuantizeLinear"} for node in model.graph.node: @@ -145,4 +146,4 @@ def main(): if __name__ == "__main__": - main() \ No newline at end of file + main() diff --git a/models/cv/object_detection/ixrt_common/config/YOLOV7_CONFIG b/models/cv/object_detection/ixrt_common/config/YOLOV7_CONFIG index 4803e368..a017ed57 100644 --- a/models/cv/object_detection/ixrt_common/config/YOLOV7_CONFIG +++ b/models/cv/object_detection/ixrt_common/config/YOLOV7_CONFIG @@ -18,7 +18,8 @@ MODEL_INPUT_NAMES=(images) LAYER_FUSION=1 DECODER_FASTER=1 DECODER_NUM_CLASS=80 -DECODER_INPUT_NAMES=(/model/model.105/m.0/Conv_output_0 /model/model.105/m.1/Conv_output_0 /model/model.105/m.2/Conv_output_0) +#DECODER_INPUT_NAMES=(/model/model.105/m.0/Conv_output_0 /model/model.105/m.1/Conv_output_0 /model/model.105/m.2/Conv_output_0) +DECODER_INPUT_NAMES=(/model.105/m.0/Conv_output_0 /model.105/m.1/Conv_output_0 /model.105/m.2/Conv_output_0) DECODER_8_ANCHOR=(12 16 19 36 40 28) DECODER_16_ANCHOR=(36 75 76 55 72 146) DECODER_32_ANCHOR=(142 110 192 243 459 401) @@ -46,4 +47,4 @@ QUANT_BATCHSIZE=1 QUANT_STEP=32 QUANT_SEED=42 DISABLE_QUANT_LIST=() -QUANT_EXIST_ONNX= \ No newline at end of file +QUANT_EXIST_ONNX= diff --git a/models/cv/object_detection/yolov7/ixrt/ci/prepare.sh b/models/cv/object_detection/yolov7/ixrt/ci/prepare.sh index 88caeb5e..131e231d 100644 --- a/models/cv/object_detection/yolov7/ixrt/ci/prepare.sh +++ b/models/cv/object_detection/yolov7/ixrt/ci/prepare.sh @@ -20,7 +20,7 @@ pip3 install -r ../../ixrt_common/requirements.txt mkdir -p checkpoints cp -r /root/data/3rd_party/yolov7 ./ cd yolov7 -ln -s /root/data/checkpoints/yolov7.pt ./ -python3 export.py --weights yolov7.pt --grid --end2end --simplify --topk-all 100 --iou-thres 0.65 --conf-thres 0.35 --img-size 640 640 --max-wh 640 --batch-size 16 +#ln -s /root/data/checkpoints/yolov7.pt ./ +#python3 export.py --weights yolov7.pt --grid --end2end --simplify --topk-all 100 --iou-thres 0.65 --conf-thres 0.35 --img-size 640 640 --max-wh 640 --batch-size 16 mv yolov7.onnx ../checkpoints/yolov7m.onnx cd .. -- Gitee From bada9d7e45b98b961e2c048584e52cc9b8c5bffc Mon Sep 17 00:00:00 2001 From: "shengyan.zhao" Date: Tue, 14 Apr 2026 15:20:58 +0800 Subject: [PATCH 5/6] fix for yolov3 ixrt Signed-off-by: shengyan.zhao --- .../object_detection/yolov3/ixrt/ci/prepare.sh | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/models/cv/object_detection/yolov3/ixrt/ci/prepare.sh b/models/cv/object_detection/yolov3/ixrt/ci/prepare.sh index 219cffa0..523078fa 100644 --- a/models/cv/object_detection/yolov3/ixrt/ci/prepare.sh +++ b/models/cv/object_detection/yolov3/ixrt/ci/prepare.sh @@ -18,10 +18,13 @@ set -x pip3 install -r ../../ixrt_common/requirements.txt mkdir checkpoints -unzip -q /root/data/3rd_party/onnx_tflite_yolov3.zip -d ./ -cp /root/data/checkpoints/yolov3.weights onnx_tflite_yolov3/weights -cd onnx_tflite_yolov3 -python3 detect.py --cfg cfg/yolov3.cfg --weights weights/yolov3.weights -mv weights/export.onnx ../checkpoints/yolov3.onnx -cd .. -cp config/YOLOV3_CONFIG ../../ixrt_common/config/YOLOV3_CONFIG \ No newline at end of file +#unzip -q /root/data/3rd_party/onnx_tflite_yolov3.zip -d ./ +#cp /root/data/checkpoints/yolov3.weights onnx_tflite_yolov3/weights +#cd onnx_tflite_yolov3 +#python3 detect.py --cfg cfg/yolov3.cfg --weights weights/yolov3.weights +#mv weights/export.onnx ../checkpoints/yolov3.onnx +#cd .. +#cp config/YOLOV3_CONFIG ../../ixrt_common/config/YOLOV3_CONFIG +cp /root/data/3rd_party/yolov3/yolov3_caffe.onnx checkpoints/ +cp /root/data/3rd_party/yolov3/yolov3.onnx checkpoints/ +cp /root/data/3rd_party/yolov3/YOLOV3_CONFIG ../../ixrt_common/config/YOLOV3_CONFIG -- Gitee From adf65c6653eef32cb560a681149cfd54d0c371ee Mon Sep 17 00:00:00 2001 From: "shengyan.zhao" Date: Tue, 14 Apr 2026 15:42:00 +0800 Subject: [PATCH 6/6] fix for yolov7m ixrt Signed-off-by: shengyan.zhao --- models/cv/object_detection/yolov7/ixrt/ci/prepare.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/cv/object_detection/yolov7/ixrt/ci/prepare.sh b/models/cv/object_detection/yolov7/ixrt/ci/prepare.sh index 131e231d..a19a1707 100644 --- a/models/cv/object_detection/yolov7/ixrt/ci/prepare.sh +++ b/models/cv/object_detection/yolov7/ixrt/ci/prepare.sh @@ -22,5 +22,5 @@ cp -r /root/data/3rd_party/yolov7 ./ cd yolov7 #ln -s /root/data/checkpoints/yolov7.pt ./ #python3 export.py --weights yolov7.pt --grid --end2end --simplify --topk-all 100 --iou-thres 0.65 --conf-thres 0.35 --img-size 640 640 --max-wh 640 --batch-size 16 -mv yolov7.onnx ../checkpoints/yolov7m.onnx +mv yolov7m.onnx ../checkpoints/yolov7m.onnx cd .. -- Gitee