From 877adbd80d5b2e217c69ba4d5a791981aeabd8a0 Mon Sep 17 00:00:00 2001 From: yuwenzho Date: Mon, 29 May 2023 09:10:16 +0800 Subject: [PATCH] Refine PT2ONNX export (#901) Signed-off-by: yuwenzho --- .../scripts/codeScan/pyspelling/inc_dict.txt | 2 + docs/source/export.md | 241 +++-- docs/source/imgs/export.png | Bin 115429 -> 114236 bytes .../torchvision_models/export/fx/main.py | 5 +- .../text-classification/export/fx/run_glue.py | 2 + neural_compressor/adaptor/pytorch.py | 38 +- neural_compressor/config.py | 2 - .../experimental/export/torch2onnx.py | 896 +++--------------- .../experimental/export/utils.py | 73 -- neural_compressor/model/torch_model.py | 23 +- neural_compressor/training.py | 12 + test/export/test_torch2onnx.py | 293 +----- 12 files changed, 336 insertions(+), 1251 deletions(-) delete mode 100644 neural_compressor/experimental/export/utils.py diff --git a/.azure-pipelines/scripts/codeScan/pyspelling/inc_dict.txt b/.azure-pipelines/scripts/codeScan/pyspelling/inc_dict.txt index 904933a9c68..4e3b4bfbbb9 100644 --- a/.azure-pipelines/scripts/codeScan/pyspelling/inc_dict.txt +++ b/.azure-pipelines/scripts/codeScan/pyspelling/inc_dict.txt @@ -2611,3 +2611,5 @@ efb netflix DeBERTa unilm +aten +hardswish diff --git a/docs/source/export.md b/docs/source/export.md index b133dd36407..6dd1fc35c2f 100644 --- a/docs/source/export.md +++ b/docs/source/export.md @@ -9,32 +9,70 @@ Export 4. [Appendix](#appendix) -# Introduction -Open Neural Network Exchange (ONNX) is an open standard format for representing machine learning models. Exporting FP32 PyTorch/Tensorflow models has become popular and easy to use. However, for Intel Neural Compressor, we hope to export the INT8 model into the ONNX format to achieve higher applicability in multiple frameworks. - -Here we briefly introduce our export API for PyTorch FP32/INT8 models. First, the INT8 ONNX model is not directly exported from the INT8 PyTorch model, but quantized after obtaining the FP32 ONNX model using the mature torch.onnx.export API. To ensure the majority of the quantization process of ONNX is consistent with PyTorch, we reuse three key pieces of information from the Neural Compressor model to perform ONNX quantization. - - - Quantized operations: Only operations quantized in PyTorch will be quantized in the quantization process of ONNX. - - Scale info: Scale information is collected from the quantization process of PyTorch. - - Weights of quantization aware training(QAT): For quantization aware training, the updated weights are passed to the ONNX model. +## Introduction +Open Neural Network Exchange (ONNX) is an open standard format for representing machine learning models. Exporting FP32 PyTorch/Tensorflow models has become popular and easy to use. For Intel Neural Compressor, we hope to export the INT8 model into the ONNX format to achieve higher applicability in multiple frameworks. +Here is the workflow of our export API for PyTorch/Tensorflow FP32/INT8 model.
- Architecture + Architecture
-# Supported Framework Model Matrix +## Supported Framework Model Matrix + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Frameworkmodel typeexported ONNX model type
PyTorchFP32FP32
Post-Training Static Quantized INT8QLinear/QDQ INT8
Post-Training Dynamic Quantized INT8/
Quantization-aware Training INT8QLinear/QDQ INT8
TensorFlowFP32FP32
Post-Training Static Quantized INT8QDQ INT8
Quantization-aware Training INT8QDQ INT8
+ +> **Note**: Follow this step to export a post training dynamic quantized ONNX model from PyTorch model: \ + 1. export FP32 PyTorch model to FP32 ONNX model. \ + 2. use FP32 ONNX model as the input model for post training dynamic quantization. -| Export | PyTorch | TensorFlow | -| :---: | :---: |:----------:| -| FP32 Model -> FP32 ONNX Model | ✔ | ✔ | -| INT8 Model -> INT8 QDQ ONNX Model | ✔ | ✔ | -| INT8 Model -> INT8 QLinear ONNX Model | ✔ | :x: | +## Examples -# Examples +### PyTorch Model + +#### FP32 Model Export -## FP32 Model Export ```python from neural_compressor.experimental.common import Model from neural_compressor.config import Torch2ONNXConfig @@ -50,7 +88,7 @@ fp32_onnx_config = Torch2ONNXConfig( inc_model.export('fp32-model.onnx', fp32_onnx_config) ``` -## INT8 Model Export +#### INT8 Model Export ```python # q_model is a Neural Compressor model after performing quantization. @@ -58,7 +96,7 @@ from neural_compressor.config import Torch2ONNXConfig int8_onnx_config = Torch2ONNXConfig( dtype="int8", opset_version=14, - quant_format="QDQ", # or QLinear + quant_format="QLinear", # or QDQ example_inputs=torch.randn(1, 3, 224, 224), input_names=['input'], output_names=['output'], @@ -71,122 +109,57 @@ q_model.export('int8-model.onnx', int8_onnx_config) - [Image recognition](/examples/pytorch/image_recognition/torchvision_models/export/fx/) - [Text classification](/examples/pytorch/nlp/huggingface_models/text-classification/export/fx/) -# Appendix - -Since there is a known quantization gap between PyTorch 'nn.Linear' module and ONNX 'MatMul + Add' subgraph, we provide three recipes. - -For different recipes and ONNX INT8 model formats, 'nn.quantized.Linear' will be exported to the following subgraph: - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RecipeQDQQLinear
QDQ_OP_FP32_BIAS -
-     QuantizeLinear
-           |
-    DequantizeLinear
-           |             
-         MatMul
-           |
-          Add
-
-
-
-   QuantizeLinear
-         |
-MatMulIntegerToFloat
-         |
-        Add 
-
-
QDQ_OP_INT32_BIAS -
-     QuantizeLinear
-           |
-     MatMulInteger
-           |
-          Add
-           |
-          Cast
-           |
-          Mul
-
-
-
-   QuantizeLinear
-         |
-    MatMulInteger
-         |
-        Add
-         |
-        Cast
-         |
-        Mul
-
-
QDQ_OP_FP32_BIAS_QDQ -
-     QuantizeLinear
-           |
-    DequantizeLinear   
-           |
-         MatMul
-           |
-          Add
-           |
-     QuantizeLinear
-           |
-    DequantizeLinear
-
-
-
-   QuantizeLinear
-         |
-MatMulIntegerToFloat
-         |
-        Add
-         |
-   QuantizeLinear
-         |
-  DequantizeLinear
-
-
+### Tensorflow Model + +#### FP32 Model Export + +```python +from neural_compressor.experimental.common import Model +from neural_compressor.config import TF2ONNXConfig +inc_model = Model(model) +config = TF2ONNXConfig(dtype='fp32') +inc_model.export('fp32-model.onnx', config) +``` + +### INT8 Model Export -The default recipe is `QDQ_OP_FP32_BIAS`. If the accuracy of the exported ONNX INT8 model cannot meet your criterion, we recommend you try recipe `QDQ_OP_INT32_BIAS` and `QDQ_OP_FP32_BIAS_QDQ` as follows: ```python # q_model is a Neural Compressor model after performing quantization. -from neural_compressor.config import Torch2ONNXConfig -int8_onnx_config = Torch2ONNXConfig( - dtype="int8", - opset_version=14, - quant_format="QDQ", # or QLinear - example_inputs=torch.randn(1, 3, 224, 224), - input_names=['input'], - output_names=['output'], - dynamic_axes={"input": {0: "batch_size"}, - "output": {0: "batch_size"}}, - recipe='QDQ_OP_INT32_BIAS', # or QDQ_OP_FP32_BIAS_QDQ -) -q_model.export('int8-model.onnx', int8_onnx_config) +from neural_compressor.config import TF2ONNXConfig +config = TF2ONNXConfig(dtype='int8') +q_model.export('int8-model.onnx', config) ``` + +> **Note**: Some export examples of computer vision task exist in examples. Users can leverage them to verify the accuracy and performance of the exported ONNX model. + - [resnet50_v1_5](/examples/tensorflow/image_recognition/tensorflow_models/resnet50_v1_5/export) + - [resnet50_v1](/examples/tensorflow/image_recognition/tensorflow_models/resnet50_v1/export) + - [vgg16](/examples/tensorflow/image_recognition/tensorflow_models/vgg16/export) + - [ssd_mobilenet_v1](/examples/tensorflow/object_detection/tensorflow_models/ssd_mobilenet_v1/export) + - [mobilenet_v2](/examples/tensorflow/image_recognition/tensorflow_models/mobilenet_v2/export) + - [faster_rcnn_resnet50](examples/tensorflow/object_detection/tensorflow_models/faster_rcnn_resnet50/export) + +## Appendix + +### Supported quantized ops + +This table lists the TorchScript operators that are supported by ONNX export with torch v2.0. Refer to this [link](https://pytorch.org/docs/stable/onnx_supported_aten_ops.html) for more supported/unsupported ops. + +| Operator | opset_version(s) | +| ---------------------------- | ---------------- | +| ``quantized::add`` | Since opset 10 | +| ``quantized::add_relu`` | Since opset 10 | +| ``quantized::cat`` | Since opset 10 | +| ``quantized::conv1d_relu`` | Since opset 10 | +| ``quantized::conv2d`` | Since opset 10 | +| ``quantized::conv2d_relu`` | Since opset 10 | +| ``quantized::group_norm`` | Since opset 10 | +| ``quantized::hardswish`` | Since opset 10 | +| ``quantized::instance_norm`` | Since opset 10 | +| ``quantized::layer_norm`` | Since opset 10 | +| ``quantized::leaky_relu`` | Since opset 10 | +| ``quantized::linear`` | Since opset 10 | +| ``quantized::mul`` | Since opset 10 | +| ``quantized::sigmoid`` | Since opset 10 | + +> **Note**: The export function may fail due to unsupported operations. Please fallback unsupported quantized ops by setting 'op_type_dict' or 'op_name_dict' in 'QuantizationAwareTrainingConfig' or 'PostTrainingQuantConfig' config. Fallback examples please refer to [Text classification](/examples/pytorch/nlp/huggingface_models/text-classification/export/fx/) + diff --git a/docs/source/imgs/export.png b/docs/source/imgs/export.png index 447551087057669f77ceddbccd021930e2bcf6d3..6f47e840bca8b3099ce6424309c0573efc2c8a07 100644 GIT binary patch literal 114236 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 literal 115429 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%0AX5zfr4zvfnsQ)&{jFPCS4Hf*qO7RFN^4`l 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 fLJ&){=b6fKe_c~`U?;QoE_$!)jztxE5wP3 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 diff --git a/examples/pytorch/image_recognition/torchvision_models/export/fx/main.py b/examples/pytorch/image_recognition/torchvision_models/export/fx/main.py index 2a559a1a9a8..b9fc4016792 100644 --- a/examples/pytorch/image_recognition/torchvision_models/export/fx/main.py +++ b/examples/pytorch/image_recognition/torchvision_models/export/fx/main.py @@ -3,9 +3,6 @@ import random import shutil import time -import warnings -import sys - import torch import torch.nn as nn import torch.nn.parallel @@ -202,7 +199,7 @@ def eval_func(model): int8_onnx_config = Torch2ONNXConfig( dtype="int8", opset_version=14, - quant_format="QDQ", + quant_format=args.quant_format, example_inputs=torch.randn(1, 3, 224, 224), input_names=['input'], output_names=['output'], diff --git a/examples/pytorch/nlp/huggingface_models/text-classification/export/fx/run_glue.py b/examples/pytorch/nlp/huggingface_models/text-classification/export/fx/run_glue.py index c59a7e1ed89..22c6ba12fbc 100644 --- a/examples/pytorch/nlp/huggingface_models/text-classification/export/fx/run_glue.py +++ b/examples/pytorch/nlp/huggingface_models/text-classification/export/fx/run_glue.py @@ -535,6 +535,7 @@ def eval_func(model): if model_args.export_dtype == 'int8': from neural_compressor.quantization import fit from neural_compressor.config import PostTrainingQuantConfig, TuningCriterion + from neural_compressor.utils.constant import FP32 tuning_criterion = TuningCriterion( strategy="mse_v2", strategy_kwargs={"confidence_batches": 1}, @@ -544,6 +545,7 @@ def eval_func(model): approach="static", quant_level=1, tuning_criterion=tuning_criterion, + op_type_dict={"Embedding":FP32}, calibration_sampling_size=[300], ) q_model = fit(model, conf=conf, calib_dataloader=eval_dataloader, eval_func=eval_func) diff --git a/neural_compressor/adaptor/pytorch.py b/neural_compressor/adaptor/pytorch.py index 3d37edb3466..7f474d8ef4a 100644 --- a/neural_compressor/adaptor/pytorch.py +++ b/neural_compressor/adaptor/pytorch.py @@ -829,6 +829,12 @@ def __init__(self, framework_specific_info): if not self.benchmark: assert False, "Unsupport approach: {}".format(self.approach) + # TODO: will be removed once 'op_type_dict' and 'op_name_dicts' + # for quant_aware_training can be handled in strategy + if self.approach == 'quant_aware_training': + self.qat_optype_wise = framework_specific_info.get('qat_optype_wise', None) + self.qat_op_wise = framework_specific_info.get('qat_op_wise', None) + self.fp32_results = [] self.fp32_preds_as_label = False @@ -2874,7 +2880,7 @@ def _cfg_to_qconfig(self, tune_cfg): json.dump(self.cfgs, write_f, indent=4) return None - def get_pattern(self, fallback_op, fuse_ops): + def get_pattern(self, fallback_op, fuse_ops): # pragma: no cover for fuse_pattern in fuse_ops: if fuse_pattern[0] == fallback_op: if fuse_pattern[1] in ['relu_', 'add_']: @@ -3134,7 +3140,7 @@ def _get_quantizable_ops_recursively(self, model, prefix, quantizable_ops): os.remove(self.ipex_config_path) - def get_fuse_ops(self, default_cfgs): + def get_fuse_ops(self, default_cfgs): # pragma: no cover elt_wise = ['relu', 'sigmoid', 'gelu'] inplace_ops = ['relu_', 'add_'] op_patterns = [] @@ -3609,6 +3615,7 @@ def _pre_hook_for_qat(self, dataloader=None): quantizable_ops = [] tmp_model = self.fuse_fx_model(self.model, is_qat=True) self._get_quantizable_ops_recursively(tmp_model, '', quantizable_ops) + self._remove_fallback_ops_for_qat(quantizable_ops) bf16_ops = [] if self.version.release >= Version("1.11.0").release and self.use_bf16 and \ (CpuInfo().bf16 or os.getenv('FORCE_BF16') == '1'): # pragma: no cover @@ -3628,7 +3635,7 @@ def _pre_hook_for_qat(self, dataloader=None): for op in quantizable_ops: op_config_dict[op] = {'weight': {'dtype': 'int8'}, 'activation': {'dtype': 'uint8'}} - if self.version.release < Version("1.11.0").release: + if self.version.release < Version("1.11.0").release: # pragma: no cover quantized_ops["default_qconfig"] = None else: from torch.ao.quantization import default_embedding_qat_qconfig @@ -3720,6 +3727,29 @@ def _post_hook_for_qat(self): self._dump_model_op_stats(self.model._model, self.model.q_config, self.approach) torch_utils.util.get_embedding_contiguous(self.model._model) + def _get_fallback_ops_for_qat(self): + # get fallback ops for quant aware training approach + fallback_ops = {'op_wise': [], 'optype_wise': []} + if self.qat_optype_wise is not None: # pragma: no cover + for optype, optype_config in self.qat_optype_wise.items(): + if 'weight' in optype_config and optype_config['weight']['dtype'] == ['fp32']: + fallback_ops['optype_wise'].append(optype) + if self.qat_op_wise is not None: # pragma: no cover + for op, op_config in self.qat_op_wise.items(): + if 'weight' in op_config and op_config['weight']['dtype'] == ['fp32']: + fallback_ops['op_wise'].append(op) + return fallback_ops + + def _remove_fallback_ops_for_qat(self, quantizable_ops): + # remove fallback ops from quantizable_ops for quant aware training approach + fallback_ops = self._get_fallback_ops_for_qat() + remove_ops = [] + for (op_name, op_type) in quantizable_ops: + if op_name in fallback_ops['op_wise'] or op_type in fallback_ops['optype_wise']: + remove_ops.append((op_name, op_type)) + for (op_name, op_type) in remove_ops: + quantizable_ops.remove((op_name, op_type)) + def train(self, model, dataloader, optimizer_tuple, criterion_tuple, hooks, **kwargs): """Execute the train process on the specified model. @@ -3805,7 +3835,7 @@ def _get_module_op_stats(self, model, tune_cfg, approach): for key in tune_cfg['op']: op_type = key[1] #build initial dict - if op_type not in res.keys(): + if op_type not in res.keys(): # pragma: no cover res[op_type] = {'INT8': 0, 'BF16': 0, 'FP32': 0} value = tune_cfg['op'][key] # Special cases: QuantStub, Embedding diff --git a/neural_compressor/config.py b/neural_compressor/config.py index 5629e172199..465d8f7bcc4 100644 --- a/neural_compressor/config.py +++ b/neural_compressor/config.py @@ -1951,7 +1951,6 @@ def __init__( input_names=None, output_names=None, dynamic_axes=None, - recipe='QDQ_OP_FP32_BIAS', **kwargs, ): """Init a Torch2ONNXConfig object.""" @@ -1964,7 +1963,6 @@ def __init__( output_names=output_names, dynamic_axes=dynamic_axes, ) - self.recipe = recipe self.kwargs = kwargs diff --git a/neural_compressor/experimental/export/torch2onnx.py b/neural_compressor/experimental/export/torch2onnx.py index 92dce31d61e..6b7d4c7d167 100644 --- a/neural_compressor/experimental/export/torch2onnx.py +++ b/neural_compressor/experimental/export/torch2onnx.py @@ -18,6 +18,7 @@ """Helper functions to export model from PyTorch/TensorFlow to ONNX.""" import os +import sys import numpy as np from collections import UserDict from neural_compressor.adaptor.torch_utils.util import input2tuple @@ -29,633 +30,34 @@ ort = LazyImport('onnxruntime') ortq = LazyImport('onnxruntime.quantization') +def _prepare_intputs(pt_model, input_names, example_inputs): + """Prepare input_names and example_inputs.""" + if input_names is None and \ + (isinstance(example_inputs, dict) or isinstance(example_inputs, UserDict)): # pragma: no cover + input_names = list(example_inputs.keys()) + example_inputs = list(example_inputs.values()) + elif isinstance(example_inputs, dict) or isinstance(example_inputs, UserDict): + example_inputs = list(example_inputs.values()) + # match input_names with inspected input_order, especailly for bert in hugginface. + if input_names and len(input_names) > 1: + import inspect + input_order = inspect.signature(pt_model.forward).parameters.keys() + flag = [name in input_order for name in input_names] # whether should be checked + if all(flag): + new_input_names = [] + new_example_inputs = [] + for name in input_order: + if name in input_names: + new_input_names.append(name) + id = input_names.index(name) + new_example_inputs.append(example_inputs[id]) + input_names = new_input_names + example_inputs = new_example_inputs + return input_names, example_inputs -def update_weight_bias( - int8_model, - fp32_onnx_path, -): - """Update wegiht and bias of FP32 ONNX model with QAT INT8 PyTorch model . - - Args: - int8_model (torch.nn.module): int8 model. - fp32_onnx_path (str): path to fp32 onnx model. - """ - # collect weights, bias from int8 PT model - fp32_onnx_model = onnx.load(fp32_onnx_path) - model_dict = int8_model.state_dict() - int8_model_dict = {} - for name, param in model_dict.items(): - # '_packed_params._packed_weight' is specific for quantized Embedding - if '_packed_params._packed_weight' in name: - name = name.replace('._packed_params._packed_weight', '').split('.module')[0] - int8_model_dict[name+'.weight'] = param.dequantize() - # '_packed_params._packed_params' is specific for quantized Linear - elif '_packed_params._packed_params' in name and isinstance(param, tuple): - name = name.replace('._packed_params._packed_params', '').split('.module')[0] - int8_model_dict[name+'.bias'] = param[1] - int8_model_dict[name+'.weight'] = param[0].dequantize() - # '.weight' and '.bias' is specific for quantized Conv - elif '.weight' in name: - int8_model_dict[name] = param.dequantize() - elif '.bias' in name: - int8_model_dict[name] = param - else: - int8_model_dict[name] = param - - # replace weight and bias in onnx fp32 model for QAT - from onnx import helper - tensor_list = [tensor for tensor in fp32_onnx_model.graph.initializer] - for tensor in tensor_list: - if tensor.name in int8_model_dict: - np_tensor = int8_model_dict[tensor.name].detach().cpu().numpy() - new_tensor = helper.make_tensor( - name=tensor.name, - data_type=tensor.data_type, - dims=tensor.dims, - vals=np_tensor, - ) - fp32_onnx_model.graph.initializer.remove(tensor) - fp32_onnx_model.graph.initializer.append(new_tensor) - onnx.save(fp32_onnx_model, fp32_onnx_path) - - -def set_data_type( - dtype, -): - """Set data type of activation and weight with string dtype. - - Args: - dtype (str): data type description. - - Returns: - activation_type: activation type. - weight_type: weight type. - """ - # Get data type for activation and weight from dtype - if 'U8U8' in dtype: # pragma: no cover - activation_type = ortq.QuantType.QUInt8 - weight_type = ortq.QuantType.QUInt8 - elif 'S8S8' in dtype: # pragma: no cover - activation_type = ortq.QuantType.QInt8 - weight_type = ortq.QuantType.QInt8 - elif 'U8S8' in dtype: - activation_type = ortq.QuantType.QUInt8 - weight_type = ortq.QuantType.QInt8 - else: # pragma: no cover - logger.error("Right now, we don't support dtype: {}, \ - please use U8U8/U8S8/S8S8.".format(dtype)) - logger.info("Weight type: {}.".format(weight_type)) - logger.info("Activation type: {}.".format(activation_type)) - return activation_type, weight_type - - -def get_node_mapping( - fp32_model, - fp32_onnx_path, -): - """Get PyTorch module and ONNX node mapping. - - Args: - fp32_model (torch.nn.Module): quantization configuration from PyTorch. - fp32_onnx_path (str): path to fp32 onnx model. - - Returns: - module_node_mapping: op mapping from PyTorch to ONNX. - """ - def check_data(op_type, data, module_dict): - for name, value in module_dict.items(): - if value.shape == data.shape: - if (value == data).all(): - module_dict.pop(name) - return name - elif op_type == 'Conv': - # Convolution weight data have fluction and BN fusion will insert scale. - # We use the weight scale of the first output channel to check. - weight_scale = value[0] / data[0] - if np.allclose(weight_scale - np.mean(weight_scale), 0, atol=1.e-5): - module_dict.pop(name) - return name - return None - - module_dict = {} - for name, module in fp32_model.named_modules(): - if 'Conv' in str(module.__class__.__name__) or \ - 'Embedding' in str(module.__class__.__name__) or \ - 'Linear' in str(module.__class__.__name__): - if hasattr(module, 'weight'): - value = module.weight.detach().cpu().numpy() - module_dict[name] = value - - module_node_mapping = {} - fp32_onnx_model = onnx.load(fp32_onnx_path) - initializer_data = {tensor.name: tensor for tensor in fp32_onnx_model.graph.initializer} - from onnx import numpy_helper - for node in fp32_onnx_model.graph.node: - if node.op_type in op_types_to_quantize: - if node.op_type == 'MatMul' and node.input[1] in initializer_data: - data = numpy_helper.to_array(initializer_data[node.input[1]]).T - elif node.op_type == 'Gather' and node.input[0] in initializer_data: - data = numpy_helper.to_array(initializer_data[node.input[0]]) - elif node.op_type in ['Conv', 'Gemm']: - data = numpy_helper.to_array(initializer_data[node.input[1]]) - else: - continue - pt_name = check_data(node.op_type, data, module_dict) - if pt_name: - module_node_mapping[pt_name] = node.name - return module_node_mapping - - -def get_quantizable_onnx_ops( - int8_model, - module_node_mapping -): - """Get quantizable onnx ops. - - Args: - int8_model (torch.nn.Module): PyTorch int8 model. - module_node_mapping (dict): op mapping from PyTorch to ONNX. - - Returns: - quantize_nodes: all onnx node that should be quantized. - """ - quantize_nodes = [] - for name, module in int8_model.named_modules(): - if 'Conv' in str(module.__class__.__name__) or \ - 'Embedding' in str(module.__class__.__name__) or \ - 'Linear' in str(module.__class__.__name__): - if hasattr(module, 'weight') and callable(module.weight): - if module.weight().dtype in [torch.qint8, torch.quint8]: - if name.split('.module')[0] in module_node_mapping: - node = module_node_mapping[name.split('.module')[0]] - quantize_nodes.append(node) - return quantize_nodes - - -def build_scale_mapping( - fp32_onnx_path, - module_node_mapping, - int8_scale_info, -): - """Build scale mapping. - - Args: - fp32_onnx_path (str): path to fp32 onnx model. - module_node_mapping (dict): op mapping from PyTorch to ONNX. - int8_scale_info (dict): int8 scale infomation. - - Returns: - scale_zp_dict: scale and zero_point dict. - """ - node_module_mapping = {} - for module_name, node_name in module_node_mapping.items(): - node_module_mapping[node_name] = module_name - # Match scale and zeropoint from PyTorch to ONNX node - scale_zp_dict = {} - fp32_onnx_model = onnx.load(fp32_onnx_path) - for node in fp32_onnx_model.graph.node: - if node.name in node_module_mapping: - module_name = node_module_mapping[node.name] - - # For fine-grained fx and fuse pattern - if module_name + '.module' in int8_scale_info: - module_name = module_name + '.module' - elif module_name + '.0' in int8_scale_info: - module_name = module_name + '.0' - elif module_name + '.module.0' in int8_scale_info: - module_name = module_name + '.module.0' - - if module_name in int8_scale_info: - recoder = int8_scale_info[module_name] - input_scale_args = node.input[0] + '_scale' - input_zp_args = node.input[0] + '_zero_point' - scale_zp_dict[input_scale_args] = recoder['input_scale'] - scale_zp_dict[input_zp_args] = recoder['input_zeropoint'] - ### We need Matmul+Add to match Linear for output scale and zero-point - output_scale_args = node.output[0] + '_scale' - output_zp_args = node.output[0] + '_zero_point' - scale_zp_dict[output_scale_args] = recoder['output_scale'] - scale_zp_dict[output_zp_args] = recoder['output_zeropoint'] - return scale_zp_dict - - -def set_scale_info( - int8_onnx_model, - scale_zp_dict, - activation_type, -): - """Set scale to ONNX model. - - Args: - int8_onnx_path (str): path to onnx file. - scale_zp_dict (dict): scale zero_point dict. - activation_type : activation type. - - Returns: - int8_onnx_model: int8 onnx model object. - """ - # set scale and zeropoint from PyTorch int8 model to ONNX int8 model - from onnx import helper - tensor_list = [tensor for tensor in int8_onnx_model.graph.initializer] - for tensor in tensor_list: - if tensor.name in scale_zp_dict: - value = scale_zp_dict[tensor.name] - if 'zero_point' in tensor.name and activation_type == ortq.QuantType.QInt8: - value -= 128 - new_tensor = helper.make_tensor( - name=tensor.name, - data_type=tensor.data_type, - dims=tensor.dims, - vals=[value], - ) - int8_onnx_model.graph.initializer.remove(tensor) - int8_onnx_model.graph.initializer.append(new_tensor) - return int8_onnx_model - - -def recalculate_bias( - int8_onnx_path, - scale_zp_dict, - quantize_nodes, - quant_format, -): - """Recalculate bias. - - Args: - int8_onnx_model (ModelProto): onnx int8 model to process. - scale_zp_dict (dict): scale zero_point dict. - quantize_nodes (list): quantize nodes list. - quant_format (QuantFormat): quantization format. - - Returns: - int8_onnx_model: processed onnx int8 model. - """ - int8_onnx_model = onnx.load(int8_onnx_path) - model = ortq.onnx_model.ONNXModel(int8_onnx_model) - if quant_format == ortq.QuantFormat.QDQ: - for node in int8_onnx_model.graph.node: - if node.name in quantize_nodes and (node.op_type == 'Conv' or node.op_type == 'Gemm'): - input_name, weight_name, bias_name = node.input[:3] - for parent in model.get_parents(node): - if parent.output[0] == input_name: - input_scale_name = parent.input[1] - elif parent.output[0] == weight_name: - weight_scale_name = parent.input[1] - elif parent.output[0] == bias_name: - bias_quantized_name = parent.input[0] - bias_scale_name = parent.input[1] - weight_scale_data = onnx.numpy_helper.to_array(model.get_initializer(weight_scale_name)) - new_input_scale_data = scale_zp_dict[input_scale_name] - origin_bias_quantized_data = onnx.numpy_helper.to_array(model.get_initializer(bias_quantized_name)) - origin_bias_scale_data = onnx.numpy_helper.to_array(model.get_initializer(bias_scale_name)) - origin_bias_data = origin_bias_quantized_data * origin_bias_scale_data - new_bias_scale_data = new_input_scale_data * weight_scale_data - new_bias_quantized_data = (origin_bias_data / new_bias_scale_data).round().astype(np.int32) - model.get_initializer(bias_scale_name).raw_data = new_bias_scale_data.tobytes() - model.get_initializer(bias_quantized_name).raw_data = new_bias_quantized_data.tobytes() - elif quant_format == ortq.QuantFormat.QOperator: - for node in int8_onnx_model.graph.node: - if node.op_type == 'QLinearConv' or node.op_type == 'QGemm': - input_scale_name, weight_scale_name = node.input[1], node.input[4] - bias_quantized_name = node.input[8] if node.op_type == 'QLinearConv' else node.input[6] - weight_scale_data = onnx.numpy_helper.to_array(model.get_initializer(weight_scale_name)) - new_input_scale_data = scale_zp_dict[input_scale_name] - origin_input_scale_data = onnx.numpy_helper.to_array(model.get_initializer(input_scale_name)) - origin_bias_quantized_data = onnx.numpy_helper.to_array(model.get_initializer(bias_quantized_name)) - origin_bias_scale_data = origin_input_scale_data * weight_scale_data - origin_bias_data = origin_bias_quantized_data * origin_bias_scale_data - new_bias_scale_data = new_input_scale_data * weight_scale_data - new_bias_quantized_data = (origin_bias_data / new_bias_scale_data).round().astype(np.int32) - model.get_initializer(bias_quantized_name).raw_data = new_bias_quantized_data.tobytes() - return int8_onnx_model - - -def remove_nodes_by_name(int8_onnx_model, node_names): - """Remove nodes from model by names. - - Args: - int8_onnx_model (ModelProto): onnx int8 model to process. - node_names (list): names of nodes to remove. - - Returns: - int8_onnx_model: processed onnx int8 model. - """ - while node_names: - for node in int8_onnx_model.graph.node: - if node.name in node_names: - int8_onnx_model.graph.node.remove(node) - node_names.remove(node.name) - return int8_onnx_model - - -def sub_graph_with_int32_bias( - int8_onnx_model, - node, - a_info, - b_info, - bias_name, - output_name, -): - """Generate a sub graph with int32 bias. - - Args: - int8_onnx_model (ModelProto): onnx int8 model to process. - node (NodeProto): MatMul node belonging to nn.quantized.Linear module. - a_info (list): info of input a for nn.quantized.Linear module. - b_info (list): info of input b for nn.quantized.Linear module. - bias_name (str): name of bias. - output_name (_type_): output name of the sub graph. - - Returns: - int8_onnx_model: processed onnx int8 model. - """ - from onnx import TensorProto - a, a_scale, a_zero_point = a_info - b, b_scale, b_zero_point = b_info - a_scale = ortq.onnx_model.ONNXModel(int8_onnx_model).get_initializer(a_scale) - a_scale = onnx.numpy_helper.to_array(a_scale) - b_scale = ortq.onnx_model.ONNXModel(int8_onnx_model).get_initializer(b_scale) - b_scale = onnx.numpy_helper.to_array(b_scale) - bias = ortq.onnx_model.ONNXModel(int8_onnx_model).get_initializer(bias_name) - bias_dims = bias.dims - bias = onnx.numpy_helper.to_array(bias) - bias_scale = a_scale * b_scale - quantized_bias = (bias / bias_scale).round().astype(np.int32) - quantized_bias = np.asarray(quantized_bias, dtype=np.int32).reshape(bias_dims) - packed_bias_initializer = onnx.numpy_helper.from_array(quantized_bias, - bias_name + "_quantized") - int8_onnx_model.graph.initializer.extend([packed_bias_initializer]) - - matmul_node = onnx.helper.make_node("MatMulInteger", - inputs=[a, b, a_zero_point, b_zero_point], - outputs=[node.output[0] + '_matmulinteger'], - name = node.name + '_matmulinteger') - add_node = onnx.helper.make_node("Add", - inputs=[node.output[0] + '_matmulinteger', bias_name + '_quantized'], - outputs=[node.output[0] + '_add'], - name = node.name + '_add' - ) - cast_node = onnx.helper.make_node("Cast", - inputs=[node.output[0] + '_add'], - outputs=[node.output[0] + '_cast'], - to=getattr(TensorProto, 'FLOAT'), - name = node.name + '_cast') - - new_tensor = onnx.helper.make_tensor( - name=node.name + '_bias_scale', - data_type=TensorProto.FLOAT, - dims=list(bias_scale.shape), - vals=bias_scale, - ) - int8_onnx_model.graph.initializer.append(new_tensor) - - mul_node = onnx.helper.make_node("Mul", - inputs=[node.output[0] + '_cast', node.name + '_bias_scale'], - outputs=[output_name], - name=node.name + '_mul') - - int8_onnx_model.graph.node.extend([matmul_node, add_node, cast_node, mul_node]) - return int8_onnx_model - -def qdq_fp32_bias( - int8_onnx_model, - quant_format, -): - """Excute post-process on int8 onnx model with recipe 'QDQ_OP_FP32_BIAS'. - - Insert QDQ before quantizable op and using fp32 bias. - - Args: - int8_onnx_model (ModelProto): onnx int8 model to process. - quant_format (QuantFormat): quantization format. - - Returns: - int8_onnx_model: processed onnx int8 model. - """ - # For QDQ quantization format, nn.quantized.Linear module will be - # converted to the following format: - # QuantizeLinear - # | - # DequantizeLinear - # | - # MatMul - # | - # Add - # - # For QOperator quantization format, nn.quantized.Lienar module will be - # converted to the following format: - # QuantizeLinear - # | - # MatMulIntegerToFloat - # | - # Add - if quant_format == ortq.QuantFormat.QDQ: - return int8_onnx_model - elif quant_format == ortq.QuantFormat.QOperator: - remove_nodes = set() - for node in int8_onnx_model.graph.node: - if node.op_type == 'QLinearMatMul': - dequantizelinear_node = ortq.onnx_model.ONNXModel(int8_onnx_model).get_children(node)[0] - add_node = ortq.onnx_model.ONNXModel(int8_onnx_model).get_children(dequantizelinear_node)[0] - a = node.input[0] - a_scale = node.input[1] - a_zero_point = node.input[2] - b = node.input[3] - b_scale = node.input[4] - b_zero_point = node.input[5] - matmulintegertofloat_node = onnx.helper.make_node("MatMulIntegerToFloat", - inputs=[a, b, a_scale, b_scale, a_zero_point, b_zero_point], - outputs=[node.output[0]], - name=node.name + '_matmulintegertofloat', - domain='com.microsoft') - for idx in range(len(add_node.input)): - if add_node.input[idx] == dequantizelinear_node.output[0]: - add_node.input[idx] = node.output[0] - remove_nodes.add(node.name) - remove_nodes.add(dequantizelinear_node.name) - int8_onnx_model.graph.node.extend([matmulintegertofloat_node]) - - int8_onnx_model = remove_nodes_by_name(int8_onnx_model, remove_nodes) - return int8_onnx_model - -def qdq_int32_bias( - int8_onnx_model, - quantize_nodes, - quant_format, -): - """Excute post-process on int8 onnx model with recipe 'QDQ_OP_INT32_BIAS'. - - Insert QDQ before quantizable op and using int32 bias. - - Args: - int8_onnx_model (ModelProto): onnx int8 model to process. - quantize_nodes (list): quantize nodes list. - quant_format (QuantFormat): quantization format. - - Returns: - int8_onnx_model: processed onnx int8 model. - """ - # For QDQ/Operator quantization format, nn.quantized.Linear module will be - # converted to the following format: - # QuantizeLinear - # | - # MatMulInteger - # | - # Add - # | - # Cast - # | - # Mul - if quant_format == ortq.QuantFormat.QDQ: - remove_nodes = set() - replace_input = {} - for node in int8_onnx_model.graph.node: - if node.name in quantize_nodes and node.op_type == 'MatMul': - parents = ortq.onnx_model.ONNXModel(int8_onnx_model).get_parents(node) - add_node = ortq.onnx_model.ONNXModel(int8_onnx_model).get_children(node)[0] - bias_name = None - for inp in add_node.input: - if inp.endswith('.bias'): - bias_name = inp - if not bias_name: # pragma: no cover - continue - - for parent in parents: - grand_parent = ortq.onnx_model.ONNXModel(int8_onnx_model).get_parents(parent) - if grand_parent: - replace_input[parent.output[0]] = grand_parent[0].input[0] - - int8_onnx_model = sub_graph_with_int32_bias(int8_onnx_model, - node, - parents[0].input[:3], - parents[1].input[:3], - bias_name, - add_node.output[0]) - remove_nodes.add(node.name) - remove_nodes.add(parents[0].name) - remove_nodes.add(parents[1].name) - remove_nodes.add(add_node.name) - int8_onnx_model = remove_nodes_by_name(int8_onnx_model, remove_nodes) - for node in int8_onnx_model.graph.node: # pragma: no cover - for i in range(len(node.input)): - if node.input[i] in replace_input: - node.input[i] = replace_input[node.input[i]] - elif quant_format == ortq.QuantFormat.QOperator: - remove_nodes = set() - for node in int8_onnx_model.graph.node: - if node.op_type == 'QLinearMatMul': - dequantizelinear_node = ortq.onnx_model.ONNXModel(int8_onnx_model).get_children(node)[0] - add_node = ortq.onnx_model.ONNXModel(int8_onnx_model).get_children(dequantizelinear_node)[0] - - bias_name = None - for inp in add_node.input: - if inp.endswith('.bias'): - bias_name = inp - if not bias_name: # pragma: no cover - continue - - int8_onnx_model = sub_graph_with_int32_bias(int8_onnx_model, - node, - node.input[:3], - node.input[3:6], - bias_name, - add_node.output[0]) - remove_nodes.add(node.name) - remove_nodes.add(add_node.name) - remove_nodes.add(dequantizelinear_node.name) - - int8_onnx_model = remove_nodes_by_name(int8_onnx_model, remove_nodes) - return int8_onnx_model - -def qdq_fp32_bias_qdq( - int8_onnx_model, - quantize_nodes, - quant_format, -): - """Excute post-process on onnx int8 model with recipe 'QDQ_OP_FP32_BIAS_QDQ'. - - Insert QDQ before and after quantizable op and using fp32 bias. - - Args: - int8_onnx_model (ModelProto): onnx int8 model to process. - quantize_nodes (list): quantize nodes list. - quant_format (QuantFormat): quantization format. - - Returns: - int8_onnx_model: processed onnx int8 model. - """ - # For QDQ quantization format, nn.quantized.Linear module will be - # converted to the following format: - # QuantizeLinear - # | - # DequantizeLinear - # | - # MatMul - # | - # Add - # | - # QuantizeLinear - # | - # DequantizeLinear - # - # For QOperator quantization format, nn.quantized.Lienar module will be - # converted to the following format: - # QuantizeLinear - # | - # MatMulIntegerToFloat - # | - # Add - # | - # QuantizeLinear - # | - # DequantizeLinear - if quant_format == ortq.QuantFormat.QDQ: - for node in int8_onnx_model.graph.node: - if node.name in quantize_nodes and node.op_type == 'MatMul': - quantizelinear_node = ortq.onnx_model.ONNXModel(int8_onnx_model).get_children(node)[0] - deqauntizelinear_node = ortq.onnx_model.ONNXModel(int8_onnx_model).get_children(quantizelinear_node)[0] - add_node = ortq.onnx_model.ONNXModel(int8_onnx_model).get_children(deqauntizelinear_node)[0] - deqauntizelinear_node.output[0] = add_node.output[0] - add_node.output[0] = add_node.output[0] + '_add' - for i in range(len(add_node.input)): - if not add_node.input[i].endswith('.bias'): - add_node.input[i] = node.output[0] - quantizelinear_node.input[0] = add_node.output[0] - elif quant_format == ortq.QuantFormat.QOperator: - import copy - remove_nodes = set() - for node in int8_onnx_model.graph.node: - if node.op_type == 'QLinearMatMul': - dequantizelinear_node = ortq.onnx_model.ONNXModel(int8_onnx_model).get_children(node)[0] - add_node = ortq.onnx_model.ONNXModel(int8_onnx_model).get_children(dequantizelinear_node)[0] - a, a_scale, a_zero_point, b, b_scale, b_zero_point, y_scale, y_zero_point = node.input[:8] - matmulintegertofloat_node = onnx.helper.make_node("MatMulIntegerToFloat", - inputs=[a, b, a_scale, b_scale, a_zero_point, b_zero_point], - outputs=[node.output[0]], - name=node.name + '_matmulintegertofloat', - domain='com.microsoft') - - for idx in range(len(add_node.input)): - if add_node.input[idx] == dequantizelinear_node.output[0]: - add_node.input[idx] = node.output[0] - - quantizelinear_node = onnx.helper.make_node("QuantizeLinear", - inputs=[add_node.output[0] +'_add', y_scale, y_zero_point], - outputs=[node.output[0] + '_quantizelinear'], - name=node.name + '_quantizelinear') - - dequantizelinear_node.input[0] = node.output[0] + '_quantizelinear' - dequantizelinear_node.output[0] = copy.deepcopy(add_node.output[0]) - add_node.output[0] = add_node.output[0] +'_add' - - remove_nodes.add(node.name) - int8_onnx_model.graph.node.extend([matmulintegertofloat_node, quantizelinear_node]) - - int8_onnx_model = remove_nodes_by_name(int8_onnx_model, remove_nodes) - return int8_onnx_model def torch_to_fp32_onnx( - fp32_model, + pt_model, save_path, example_inputs, opset_version=14, @@ -669,53 +71,35 @@ def torch_to_fp32_onnx( """Export FP32 PyTorch model into FP32 ONNX model. Args: - fp32_model (torch.nn.module): fp32 model. - int8_model (torch.nn.module): int8 model. + pt_model (torch.nn.module): PyTorch model. save_path (str): save path of ONNX model. example_inputs (dict|list|tuple|torch.Tensor): used to trace torch model. opset_version (int, optional): opset version. Defaults to 14. - dynamic_axes (dict, optional): dynamic axes. Defaults to {"input": {0: "batch_size"}, - "output": {0: "batch_size"}}. - input_names (list, optional): input names. Defaults to None. - output_names (list, optional): output names. Defaults to None. + dynamic_axes (dict, optional): dynamic axes. Defaults to + {"input": {0: "batch_size"}, "output": {0: "batch_size"}}. + input_names (dict, optional): input names. Defaults to None. + output_names (dict, optional): output names. Defaults to None. do_constant_folding (bool, optional): do constant folding or not. Defaults to True. verbose (bool, optional): dump verbose or not. Defaults to True. """ from neural_compressor.utils.pytorch import is_int8_model - assert is_int8_model(fp32_model) == False, "The fp32 model is replaced during quantization. " + \ + assert is_int8_model(pt_model) == False, "The fp32 model is replaced during quantization. " + \ "please customize a eval_func when quantizing, if not, such as `lambda x: 1`." - if input_names is None and \ - (isinstance(example_inputs, dict) or isinstance(example_inputs, UserDict)): - input_names = list(example_inputs.keys()) - example_inputs = list(example_inputs.values()) - elif isinstance(example_inputs, dict) or isinstance(example_inputs, UserDict): - example_inputs = list(example_inputs.values()) - # match input_names with inspected input_order, especailly for bert in hugginface. - if input_names and len(input_names) > 1: - import inspect - input_order = inspect.signature(fp32_model.forward).parameters.keys() - flag = [name in input_order for name in input_names] # whether should be checked - if all(flag): - new_input_names = [] - new_example_inputs = [] - for name in input_order: - if name in input_names: - new_input_names.append(name) - id = input_names.index(name) - new_example_inputs.append(example_inputs[id]) - input_names = new_input_names - example_inputs = new_example_inputs - - torch.onnx.export( - fp32_model, - input2tuple(example_inputs), - save_path, - opset_version=opset_version, - input_names=input_names, - output_names=output_names, - dynamic_axes=dynamic_axes, - do_constant_folding=do_constant_folding, - ) + + input_names, example_inputs = _prepare_intputs(pt_model, input_names, example_inputs) + + with torch.no_grad(): + torch.onnx.export( + pt_model, + input2tuple(example_inputs), + save_path, + opset_version=opset_version, + input_names=input_names, + output_names=output_names, + dynamic_axes=dynamic_axes, + do_constant_folding=do_constant_folding, + ) + if verbose: info = "The FP32 ONNX Model exported to path: {0}".format(save_path) logger.info("*"*len(info)) @@ -724,129 +108,89 @@ def torch_to_fp32_onnx( def torch_to_int8_onnx( - fp32_model, - int8_model, - q_config, + pt_model, save_path, example_inputs, - opset_version: int = 14, - dynamic_axes: dict = {"input": {0: "batch_size"}, - "output": {0: "batch_size"}}, + q_config, + opset_version=14, + dynamic_axes={"input": {0: "batch_size"}, + "output": {0: "batch_size"}}, input_names=None, output_names=None, quant_format: str = 'QDQ', - dtype: str = 'U8S8', - recipe: str = 'QDQ_OP_FP32_BIAS', + verbose=True, ): """Export INT8 PyTorch model into INT8 ONNX model. Args: - fp32_model (torch.nn.module): fp32 model. - int8_model (torch.nn.module): int8 model. - q_config (dict): containing quantization configuration. + pt_model (torch.nn.module): PyTorch model. save_path (str): save path of ONNX model. example_inputs (dict|list|tuple|torch.Tensor): used to trace torch model. + q_config (dict): containing quantization configuration. opset_version (int, optional): opset version. Defaults to 14. - dynamic_axes (dict, optional): dynamic axes. Defaults to {"input": {0: "batch_size"}, - "output": {0: "batch_size"}}. - input_names (list, optional): input names. Defaults to None. - output_names (list, optional): output names. Defaults to None. - quant_format (str, optional): quantization format of ONNX model. Defaults to 'QDQ'. - dtype (str, optional): data types of activation and weight of ONNX model. Defaults to 'U8S8'. - recipe (str, optionl): Recipe for processing nn.quantized.Linear module. - 'QDQ_OP_FP32_BIAS': inserting QDQ before quantizable op and using fp32 bias. - 'QDQ_OP_INT32_BIAS': inserting QDQ before quantizable op and using int32 bias. - 'QDQ_OP_FP32_BIAS_QDQ': inserting QDQ before and after quantizable op and using fp32 bias. - Defaults to 'QDQ_OP_FP32_BIAS'. + dynamic_axes (dict, optional): dynamic axes. Defaults to + {"input": {0: "batch_size"}, "output": {0: "batch_size"}}. + input_names (dict, optional): input names. Defaults to None. + output_names (dict, optional): output names. Defaults to None. + quant_format (str, optional): _quantization format of ONNX model. Defaults to 'QDQ'. + verbose (bool, optional): dump verbose or not. Defaults to True. """ - global op_types_to_quantize - if q_config['approach'] == 'post_training_dynamic_quant': - op_types_to_quantize=['MatMul', 'Gemm', 'Gather'] - else: - op_types_to_quantize=['MatMul', 'Gemm', 'Gather', 'Conv'] - - quant_format = quant_format.upper() - if quant_format == 'QDQ' and opset_version < 13: # pragma: no cover - opset_version = 13 - logger.warning("QDQ format requires opset_version >= 13, " + - "we reset opset_version={} here".format(opset_version)) - - # pylint: disable=E1101 - fp32_onnx_path = save_path + '.tmp' if save_path else 'int8-model.onnx.tmp' - torch_to_fp32_onnx( - fp32_model, - fp32_onnx_path, - example_inputs, - opset_version=opset_version, - input_names=input_names, - output_names=output_names, - dynamic_axes=dynamic_axes, - verbose=False, - ) - - activation_type, weight_type = set_data_type(dtype) - module_node_mapping = get_node_mapping(fp32_model, fp32_onnx_path) - quantize_nodes = get_quantizable_onnx_ops(int8_model, module_node_mapping) - - if q_config['approach'] == 'quant_aware_training': - update_weight_bias(int8_model, fp32_onnx_path) - if q_config['approach'] != 'post_training_dynamic_quant': - int8_scale_info = q_config['scale_info'] - scale_mapping = build_scale_mapping(fp32_onnx_path, module_node_mapping, int8_scale_info) - - quant_format = ortq.QuantFormat.QOperator if quant_format != 'QDQ' else ortq.QuantFormat.QDQ - - extra_options = {'OpTypesToExcludeOutputQuantizatioin': ['MatMul']} \ - if (recipe != 'QDQ_OP_FP32_BIAS_QDQ' and quant_format == ortq.QuantFormat.QDQ) else {} - - REDUCE_RANGE = q_config['reduce_range'] - if REDUCE_RANGE: - logger.info("Reduce range is {}".format(str(REDUCE_RANGE))) - - if q_config['approach'] == 'post_training_dynamic_quant': - logger.info("Quantization format is not avalible when executing dynamic quantization.") - ortq.quantize_dynamic( - fp32_onnx_path, - save_path, - per_channel=True, - reduce_range=REDUCE_RANGE, - weight_type=weight_type, - nodes_to_quantize=quantize_nodes, - nodes_to_exclude=[], - extra_options={} - ) - - else: - from .utils import DummyDataReader - dummy_datareader = DummyDataReader(fp32_onnx_path) - ortq.quantize_static( - fp32_onnx_path, - save_path, - dummy_datareader, - quant_format=quant_format, - per_channel=True, - reduce_range=REDUCE_RANGE, - weight_type=weight_type, - activation_type=activation_type, - nodes_to_quantize=quantize_nodes, - nodes_to_exclude=[], - extra_options=extra_options, - ) - - int8_onnx_model = recalculate_bias(save_path, scale_mapping, quantize_nodes, quant_format) - int8_onnx_model = set_scale_info(int8_onnx_model, scale_mapping, activation_type) - - if recipe == 'QDQ_OP_FP32_BIAS': - int8_onnx_model = qdq_fp32_bias(int8_onnx_model, quant_format) - elif recipe == 'QDQ_OP_INT32_BIAS': - int8_onnx_model = qdq_int32_bias(int8_onnx_model, quantize_nodes, quant_format) - elif recipe == 'QDQ_OP_FP32_BIAS_QDQ': - int8_onnx_model = qdq_fp32_bias_qdq(int8_onnx_model, quantize_nodes, quant_format) - - onnx.save(int8_onnx_model, save_path) - - os.remove(fp32_onnx_path) - info = "The INT8 ONNX Model is exported to path: {0}".format(save_path) - logger.info("*"*len(info)) - logger.info(info) - logger.info("*"*len(info)) + from neural_compressor.utils.pytorch import is_int8_model + assert is_int8_model(pt_model), "The exported model is not INT8 model, "\ + "please reset 'dtype' to 'FP32' or check your model." + + assert not q_config is None, "'q_config' is needed when export an INT8 model." + + if q_config['approach'] == 'post_training_dynamic_quant': # pragma: no cover + assert False, "Post training dynamic quantized PyTorch model is not supported " \ + "to export to ONNX directly. Please follow this step to get a post training " \ + "dynamic quantized ONNX model: " \ + "1. export FP32 PyTorch model to FP32 ONNX model. " \ + "2. use FP32 ONNX model as the input model for post training dynamic quantization." + + input_names, example_inputs = _prepare_intputs(pt_model, input_names, example_inputs) + + def model_wrapper(model_fn): + # export doesn't support a dictionary output, so manually turn it into a tuple + # refer to https://discuss.tvm.apache.org/t/how-to-deal-with-prim-dictconstruct/11978 + def wrapper(*args, **kwargs): + output = model_fn(*args, **kwargs) + if isinstance(output, dict): + return tuple(v for v in output.values() if v is not None) + else: + return output + return wrapper + pt_model.forward = model_wrapper(pt_model.forward) + + with torch.no_grad(): + try: + torch.onnx.export( + pt_model, + input2tuple(example_inputs), + save_path, + opset_version=opset_version, + input_names=input_names, + output_names=output_names, + dynamic_axes=dynamic_axes, + ) + except Exception as e: + config_name = "QuantizationAwareTrainingConfig" \ + if q_config['approach'] == "quant_aware_training" else "PostTrainingQuantConfig" + logger.error("Export failed, possibly because unsupported quantized ops. Check " + "neural-compressor/docs/source/export.md#supported-quantized-ops " + "for supported ops.") + logger.error("Please fallback unsupported quantized ops by setting 'op_type_dict' or " + "'op_name_dict' in '{}' config. ".format(config_name)) + return + + if quant_format != "QDQ": + sess_options = ort.SessionOptions() + sess_options.graph_optimization_level=ort.GraphOptimizationLevel.ORT_ENABLE_EXTENDED + sess_options.optimized_model_filepath=save_path + ort.InferenceSession(save_path, sess_options) + + if verbose: + info = "The INT8 ONNX Model exported to path: {0}".format(save_path) + logger.info("*"*len(info)) + logger.info(info) + logger.info("*"*len(info)) \ No newline at end of file diff --git a/neural_compressor/experimental/export/utils.py b/neural_compressor/experimental/export/utils.py deleted file mode 100644 index 08d1b59e9a9..00000000000 --- a/neural_compressor/experimental/export/utils.py +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -# Copyright (c) 2021 Intel Corporation -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Utility functions to export model from PyTorch/TensorFlow to ONNX.""" - -import numpy as np -from neural_compressor.utils.utility import LazyImport - -ort = LazyImport('onnxruntime') -ortq = LazyImport('onnxruntime.quantization') - - -def ONNX2Numpy_dtype(onnx_node_type): - """Get Numpy data type from onnx data type. - - Args: - onnx_node_type (str): data type description. - - Returns: - dtype: numpy data type - """ - # Only record sepcial data type - ONNX2Numpy_dtype_mapping = { - "tensor(float)": np.float32, - "tensor(double)": np.float64, - } - if onnx_node_type in ONNX2Numpy_dtype_mapping: - dtype = ONNX2Numpy_dtype_mapping[onnx_node_type] - return dtype - else: - tmp = onnx_node_type.lstrip('tensor(').rstrip(')') - dtype = eval(f'np.{tmp}') - return dtype - - -class DummyDataReader(ortq.CalibrationDataReader): - """Build dummy datareader for onnx static quantization.""" - - def __init__(self, fp32_onnx_path): - """Initialize data reader. - - Args: - fp32_onnx_path (str): path to onnx file - """ - session = ort.InferenceSession(fp32_onnx_path, None) - input_tensors = session.get_inputs() - input = {} - for node in input_tensors: - shape = [] - for dim in node.shape: - shape.append(dim if isinstance(dim, int) else 1) - dtype = ONNX2Numpy_dtype(node.type) - input[node.name] = np.ones(shape).astype(dtype) - self.data = [input] - self.data = iter(self.data) - - def get_next(self): - """Generate next data.""" - return next(self.data, None) diff --git a/neural_compressor/model/torch_model.py b/neural_compressor/model/torch_model.py index 43efcbbcaad..f90fc0c444a 100644 --- a/neural_compressor/model/torch_model.py +++ b/neural_compressor/model/torch_model.py @@ -348,28 +348,32 @@ def export( conf, ): """Export PyTorch model to ONNX model.""" + from packaging.version import Version + from ..adaptor.pytorch import get_torch_version + version = get_torch_version() + if version.release < Version("1.12.0").release: # pragma: no cover + assert False, "PyTorch to ONNX export function requires a minimum torch version of {}, " \ + "but the torch version found is {}".format(Version("1.12.0"), version) + from neural_compressor.experimental.export import ( torch_to_fp32_onnx, - torch_to_int8_onnx - ) + torch_to_int8_onnx) + if conf.dtype == 'int8': torch_to_int8_onnx( - self.fp32_model, self.model, - self.q_config, save_path, conf.example_inputs, + self.q_config, opset_version=conf.opset_version, dynamic_axes=conf.dynamic_axes, input_names=conf.input_names, output_names=conf.output_names, quant_format=conf.quant_format, - dtype='U8S8', - recipe=conf.recipe, - ) + verbose=True,) elif conf.dtype == 'fp32': torch_to_fp32_onnx( - self.fp32_model, + self.model, save_path, conf.example_inputs, opset_version=conf.opset_version, @@ -377,8 +381,7 @@ def export( input_names=conf.input_names, output_names=conf.output_names, do_constant_folding=True, - verbose=True, - ) + verbose=True,) else: # pragma: no cover assert False, "Not allowed dtype: {}, pleas use 'fp32' or 'int8'.".format(conf.dtype) diff --git a/neural_compressor/training.py b/neural_compressor/training.py index 1ed7549eb27..5d6d90e5e63 100644 --- a/neural_compressor/training.py +++ b/neural_compressor/training.py @@ -102,6 +102,12 @@ def __init__(self, model: Callable, confs: Union[Callable, List], **kwargs): framework_specific_info.update( {"inputs": conf.inputs, "outputs": conf.outputs}) + + # TODO: will be removed once 'op_type_dict' and 'op_name_dicts' + # for quant_aware_training can be handled in strategy + framework_specific_info['qat_optype_wise'] = conf.op_type_dict + framework_specific_info['qat_op_wise'] = conf.op_name_dict + self.adaptor = FRAMEWORKS[conf.framework](framework_specific_info) self.adaptor.model = self.model callbacks_list.append(QuantizationAwareTrainingCallbacks(conf, adaptor=self.adaptor)) @@ -133,6 +139,12 @@ def __init__(self, model: Callable, confs: Union[Callable, List], **kwargs): framework_specific_info.update( {"inputs": confs.inputs, "outputs": confs.outputs}) + + # TODO: will be removed once 'op_type_dict' and 'op_name_dicts' + # for quant_aware_training can be handled in strategy + framework_specific_info['qat_optype_wise'] = confs.op_type_dict + framework_specific_info['qat_op_wise'] = confs.op_name_dict + self.adaptor = FRAMEWORKS[confs.framework](framework_specific_info) self.adaptor.model = self.model callbacks_list.append(QuantizationAwareTrainingCallbacks(confs, adaptor=self.adaptor)) diff --git a/test/export/test_torch2onnx.py b/test/export/test_torch2onnx.py index 4e5da1e1101..c89ae77f784 100644 --- a/test/export/test_torch2onnx.py +++ b/test/export/test_torch2onnx.py @@ -4,6 +4,7 @@ import torch import unittest import numpy as np +import copy from neural_compressor import quantization from neural_compressor.experimental.common import Model from neural_compressor.config import Torch2ONNXConfig @@ -12,6 +13,7 @@ from neural_compressor.training import prepare_compression from neural_compressor.data import Datasets, DATALOADERS from transformers import AutoModelForSequenceClassification, AutoTokenizer +from neural_compressor.utils.constant import FP32 import torch.utils.data as data @@ -106,7 +108,7 @@ def tearDownClass(self): os.remove('int8-nlp-qlinear-model.onnx') def test_fp32_CV_models(self): - model = self.cv_model + model = copy.deepcopy(self.cv_model) inc_model = Model(model) fp32_onnx_config = Torch2ONNXConfig( dtype="fp32", @@ -120,62 +122,8 @@ def test_fp32_CV_models(self): check_CV_onnx('fp32-cv-model.onnx', self.cv_dataloader) def test_int8_CV_models(self): - for fake_yaml in ["dynamic", "static", "qat"]: - model = self.cv_model - if fake_yaml == "qat": - quant_conf = QuantizationAwareTrainingConfig() - compression_manager = prepare_compression(copy.deepcopy(model), quant_conf) - q_model = train_func_cv(compression_manager, compression_manager.model) - else: - if fake_yaml == "dynamic": - quant_conf = PostTrainingQuantConfig(approach="dynamic") - elif fake_yaml == "static": - # Random fallback one op to test - fallback_op= { - "conv1": { - "activation": {"dtype": ["fp32"]}, - "weight": {"dtype": ["fp32"]} - } - } - quant_conf = PostTrainingQuantConfig( - approach="static", - op_name_dict=fallback_op, - ) - q_model = quantization.fit( - model, - quant_conf, - eval_func=eval_func, - calib_dataloader=self.cv_dataloader if fake_yaml == "static" else None) - - int8_onnx_config = Torch2ONNXConfig( - dtype="int8", - opset_version=14, - quant_format="QDQ", - example_inputs=torch.randn(1, 3, 224, 224), - input_names=['input'], - output_names=['output'], - dynamic_axes={"input": {0: "batch_size"}, - "output": {0: "batch_size"}}, - ) - q_model.export('int8-cv-qdq-model.onnx', int8_onnx_config) - check_CV_onnx('int8-cv-qdq-model.onnx', self.cv_dataloader) - - int8_onnx_config = Torch2ONNXConfig( - dtype="int8", - opset_version=14, - quant_format="QLinear", - example_inputs=torch.randn(1, 3, 224, 224), - input_names=['input'], - output_names=['output'], - dynamic_axes={"input": {0: "batch_size"}, - "output": {0: "batch_size"}}, - ) - q_model.export('int8-cv-qlinear-model.onnx', int8_onnx_config) - check_CV_onnx('int8-cv-qlinear-model.onnx', self.cv_dataloader) - - def test_int8_CV_models_recipe2(self): - for fake_yaml in ["dynamic", "static", "qat"]: - model = self.cv_model + for fake_yaml in ["static", "qat", "dynamic"]: + model = copy.deepcopy(self.cv_model) if fake_yaml == "qat": quant_conf = QuantizationAwareTrainingConfig() compression_manager = prepare_compression(copy.deepcopy(model), quant_conf) @@ -187,7 +135,7 @@ def test_int8_CV_models_recipe2(self): # Random fallback one op to test fallback_op= { "conv1": { - "activation": {"dtype": ["fp32"]}, + "activation": {"dtype": ["fp32"]}, "weight": {"dtype": ["fp32"]} } } @@ -210,10 +158,15 @@ def test_int8_CV_models_recipe2(self): output_names=['output'], dynamic_axes={"input": {0: "batch_size"}, "output": {0: "batch_size"}}, - recipe='QDQ_OP_INT32_BIAS', ) - q_model.export('int8-cv-qdq-model.onnx', int8_onnx_config) - check_CV_onnx('int8-cv-qdq-model.onnx', self.cv_dataloader) + if fake_yaml == "dynamic": + try: + q_model.export('int8-nlp-qdq-model.onnx', int8_onnx_config) + except Exception as e: + self.assertIsInstance(e, AssertionError) + elif fake_yaml == "static": + q_model.export('int8-cv-qdq-model.onnx', int8_onnx_config) + check_CV_onnx('int8-cv-qdq-model.onnx', self.cv_dataloader) int8_onnx_config = Torch2ONNXConfig( dtype="int8", @@ -224,72 +177,22 @@ def test_int8_CV_models_recipe2(self): output_names=['output'], dynamic_axes={"input": {0: "batch_size"}, "output": {0: "batch_size"}}, - recipe='QDQ_OP_INT32_BIAS', - ) - q_model.export('int8-cv-qlinear-model.onnx', int8_onnx_config) - check_CV_onnx('int8-cv-qlinear-model.onnx', self.cv_dataloader) - - def test_int8_CV_models_recipe3(self): - for fake_yaml in ["dynamic", "static", "qat"]: - model = self.cv_model - if fake_yaml == "qat": - quant_conf = QuantizationAwareTrainingConfig() - compression_manager = prepare_compression(copy.deepcopy(model), quant_conf) - q_model = train_func_cv(compression_manager, compression_manager.model) - else: - if fake_yaml == "dynamic": - quant_conf = PostTrainingQuantConfig(approach="dynamic") - elif fake_yaml == "static": - # Random fallback one op to test - fallback_op= { - "conv1": { - "activation": {"dtype": ["fp32"]}, - "weight": {"dtype": ["fp32"]} - } - } - quant_conf = PostTrainingQuantConfig( - approach="static", - op_name_dict=fallback_op, - ) - q_model = quantization.fit( - model, - quant_conf, - eval_func=eval_func, - calib_dataloader=self.cv_dataloader if fake_yaml == "static" else None) - - int8_onnx_config = Torch2ONNXConfig( - dtype="int8", - opset_version=14, - quant_format="QDQ", - example_inputs=torch.randn(1, 3, 224, 224), - input_names=['input'], - output_names=['output'], - dynamic_axes={"input": {0: "batch_size"}, - "output": {0: "batch_size"}}, - recipe='QDQ_OP_FP32_BIAS_QDQ', ) - q_model.export('int8-cv-qdq-model.onnx', int8_onnx_config) - check_CV_onnx('int8-cv-qdq-model.onnx', self.cv_dataloader) + if fake_yaml == "dynamic": + try: + q_model.export('int8-nlp-qdq-model.onnx', int8_onnx_config) + except Exception as e: + self.assertIsInstance(e, AssertionError) + elif fake_yaml == "static": + q_model.export('int8-cv-qlinear-model.onnx', int8_onnx_config) + check_CV_onnx('int8-cv-qlinear-model.onnx', self.cv_dataloader) - int8_onnx_config = Torch2ONNXConfig( - dtype="int8", - opset_version=14, - quant_format="QLinear", - example_inputs=torch.randn(1, 3, 224, 224), - input_names=['input'], - output_names=['output'], - dynamic_axes={"input": {0: "batch_size"}, - "output": {0: "batch_size"}}, - recipe='QDQ_OP_FP32_BIAS_QDQ', - ) - q_model.export('int8-cv-qlinear-model.onnx', int8_onnx_config) - check_CV_onnx('int8-cv-qlinear-model.onnx', self.cv_dataloader) def test_fp32_NLP_models(self): symbolic_names = {0: 'batch_size', 1: 'max_seq_len'} dynamic_axes = {k: symbolic_names for k in self.nlp_input.keys()} - model = self.nlp_model + model = copy.deepcopy(self.nlp_model) inc_model = Model(model) fp32_onnx_config = Torch2ONNXConfig( dtype="fp32", @@ -305,130 +208,12 @@ def test_int8_NLP_models(self): symbolic_names = {0: 'batch_size', 1: 'max_seq_len'} dynamic_axes = {k: symbolic_names for k in self.nlp_input.keys()} - for fake_yaml in ["dynamic", "static", "qat"]: - model = self.nlp_model + for fake_yaml in ["static", "qat", "dynamic"]: + model = copy.deepcopy(self.nlp_model) if fake_yaml == "qat": - quant_conf = QuantizationAwareTrainingConfig() - compression_manager = prepare_compression(copy.deepcopy(model), quant_conf) - q_model = train_func_nlp( - compression_manager, - compression_manager.model, - self.nlp_input + quant_conf = QuantizationAwareTrainingConfig( + op_type_dict={"Embedding":FP32}, ) - else: - if fake_yaml == "dynamic": - quant_conf = PostTrainingQuantConfig(approach="dynamic") - elif fake_yaml == "static": - # Random fallback one op to test - fallback_op= { - "distilbert.transformer.layer.5.ffn.lin2": { - "activation": {"dtype": ["fp32"]}, - "weight": {"dtype": ["fp32"]} - } - } - quant_conf = PostTrainingQuantConfig( - approach="static", - op_name_dict=fallback_op, - ) - q_model = quantization.fit( - model, - quant_conf, - eval_func=eval_func, - calib_dataloader=self.nlp_dataloader if fake_yaml == "static" else None) - - int8_onnx_config = Torch2ONNXConfig( - dtype="int8", - opset_version=14, - quant_format="QDQ", - example_inputs=tuple(self.nlp_input.values()), - input_names=list(self.nlp_input.keys()), - output_names=['labels'], - dynamic_axes=dynamic_axes, - ) - q_model.export('int8-nlp-qdq-model.onnx', int8_onnx_config) - check_NLP_onnx('int8-nlp-qdq-model.onnx', self.nlp_input) - - int8_onnx_config = Torch2ONNXConfig( - dtype="int8", - opset_version=14, - quant_format="QLinear", - example_inputs=tuple(self.nlp_input.values()), - input_names=list(self.nlp_input.keys()), - output_names=['labels'], - dynamic_axes=dynamic_axes, - ) - q_model.export('int8-nlp-qlinear-model.onnx', int8_onnx_config) - check_NLP_onnx('int8-nlp-qlinear-model.onnx', self.nlp_input) - - def test_int8_NLP_models_recipe2(self): - symbolic_names = {0: 'batch_size', 1: 'max_seq_len'} - dynamic_axes = {k: symbolic_names for k in self.nlp_input.keys()} - - for fake_yaml in ["dynamic", "static", "qat"]: - model = self.nlp_model - if fake_yaml == "qat": - quant_conf = QuantizationAwareTrainingConfig() - compression_manager = prepare_compression(copy.deepcopy(model), quant_conf) - q_model = train_func_nlp( - compression_manager, - compression_manager.model, - self.nlp_input - ) - else: - if fake_yaml == "dynamic": - quant_conf = PostTrainingQuantConfig(approach="dynamic") - elif fake_yaml == "static": - # Random fallback one op to test - fallback_op= { - "distilbert.transformer.layer.5.ffn.lin2": { - "activation": {"dtype": ["fp32"]}, - "weight": {"dtype": ["fp32"]} - } - } - quant_conf = PostTrainingQuantConfig( - approach="static", - op_name_dict=fallback_op, - ) - q_model = quantization.fit( - model, - quant_conf, - eval_func=eval_func, - calib_dataloader=self.nlp_dataloader if fake_yaml == "static" else None) - - int8_onnx_config = Torch2ONNXConfig( - dtype="int8", - opset_version=14, - quant_format="QDQ", - example_inputs=tuple(self.nlp_input.values()), - input_names=list(self.nlp_input.keys()), - output_names=['labels'], - dynamic_axes=dynamic_axes, - recipe='QDQ_OP_INT32_BIAS', - ) - q_model.export('int8-nlp-qdq-model.onnx', int8_onnx_config) - check_NLP_onnx('int8-nlp-qdq-model.onnx', self.nlp_input) - - int8_onnx_config = Torch2ONNXConfig( - dtype="int8", - opset_version=14, - quant_format="QLinear", - example_inputs=tuple(self.nlp_input.values()), - input_names=list(self.nlp_input.keys()), - output_names=['labels'], - dynamic_axes=dynamic_axes, - recipe='QDQ_OP_INT32_BIAS', - ) - q_model.export('int8-nlp-qlinear-model.onnx', int8_onnx_config) - check_NLP_onnx('int8-nlp-qlinear-model.onnx', self.nlp_input) - - def test_int8_NLP_models_recipe3(self): - symbolic_names = {0: 'batch_size', 1: 'max_seq_len'} - dynamic_axes = {k: symbolic_names for k in self.nlp_input.keys()} - - for fake_yaml in ["dynamic", "static", "qat"]: - model = self.nlp_model - if fake_yaml == "qat": - quant_conf = QuantizationAwareTrainingConfig() compression_manager = prepare_compression(copy.deepcopy(model), quant_conf) q_model = train_func_nlp( compression_manager, @@ -449,7 +234,9 @@ def test_int8_NLP_models_recipe3(self): quant_conf = PostTrainingQuantConfig( approach="static", op_name_dict=fallback_op, + op_type_dict={"Embedding":FP32}, ) + q_model = quantization.fit( model, quant_conf, @@ -464,10 +251,15 @@ def test_int8_NLP_models_recipe3(self): input_names=list(self.nlp_input.keys()), output_names=['labels'], dynamic_axes=dynamic_axes, - recipe='QDQ_OP_FP32_BIAS_QDQ', ) - q_model.export('int8-nlp-qdq-model.onnx', int8_onnx_config) - check_NLP_onnx('int8-nlp-qdq-model.onnx', self.nlp_input) + if fake_yaml == "dynamic": + try: + q_model.export('int8-nlp-qdq-model.onnx', int8_onnx_config) + except Exception as e: + self.assertIsInstance(e, AssertionError) + elif fake_yaml == "static": + q_model.export('int8-nlp-qdq-model.onnx', int8_onnx_config) + check_NLP_onnx('int8-nlp-qdq-model.onnx', self.nlp_input) int8_onnx_config = Torch2ONNXConfig( dtype="int8", @@ -477,10 +269,15 @@ def test_int8_NLP_models_recipe3(self): input_names=list(self.nlp_input.keys()), output_names=['labels'], dynamic_axes=dynamic_axes, - recipe='QDQ_OP_FP32_BIAS_QDQ', ) - q_model.export('int8-nlp-qlinear-model.onnx', int8_onnx_config) - check_NLP_onnx('int8-nlp-qlinear-model.onnx', self.nlp_input) + if fake_yaml == "dynamic": + try: + q_model.export('int8-nlp-qdq-model.onnx', int8_onnx_config) + except Exception as e: + self.assertIsInstance(e, AssertionError) + elif fake_yaml == "static": + q_model.export('int8-nlp-qlinear-model.onnx', int8_onnx_config) + check_NLP_onnx('int8-nlp-qlinear-model.onnx', self.nlp_input) if __name__ == "__main__": unittest.main()