The quant_config Introduction

When converting a model, you can use quant_config to configure the model's quantization parameters from multiple levels: model_config, op_config, subgraph_config and node_config:

  • model_config: Configure the overall quantization parameters for the model, key is a custom name.

  • op_config: Configure the quantization parameters for nodes with a certain type, key is the operator type.

  • subgraph_config: Configure the quantization parameters for a subgraph, key is the subgraph name.

  • node_config: Configure the quantization parameters for a specific node, key is the name of the node.

There is a priority relationship between the four levels, the smaller the configuration granularity, the higher the priority, i.e., priority model_config < op_config < subgraph_config < node_config. When a node is configured by more than one level at the same time, the level with the highest priority takes effect in the end.

Note

Since the model quantization and compilation process internally will split and fuse some operators, it may cause some split operators' names to not be exactly the same as those of the original model operators. For such operators, when specifying the node_config, the operator names should refer to the corresponding operator names in the optimized_float_model.onnx model generated during the process.

Configure Computation Accuracy

The quant_config supports the configuration of int8/int16/float16 three kinds of computation accuracy data types, about these three kinds of data types are described as follows:

  • int8: The default quantization type for most operators, which generally does not need to be actively configured by you.

  • int16: You can refer to the section int16 Configuration.

  • float16: When configured as the float16 type, the tool will internally only configure this operator as the float16 computation accuracy type.

Attention

For the float16 datatype:

  • There will be no computation broadcast updates to the float16 computation operator context operators.

  • Different computing platforms have different support scopes for float16 operators. For the specific support scope, please refer to the Toolchain Operator Support Constraint List.

  • If you configure an operator that doesn't support float16 type to conduct float16 calculation, we will revert it to the float32 type for calculation.

Configure the Computation Accuracy for the Entire Model

Primary ParameterSecondary ParameterParameter TypeRequired or NotDescription
model_configall_node_typeStringOptionalSet the inputs of all nodes in the model to the specified type at once, with optional configuration of int16,float16.
model_output_typeStringOptionalSet the output tensor of the model to the specified type, with optional configuration of int8,int16.

Configure the Computation Accuracy for Nodes with Certain Type

Primary ParameterSecondary ParameterTertiary ParameterParameter TypeRequired or NotDescription
op_configNodeKindqtypeStringOptionalConfigure the input data type of a node of a certain type, with optional configuration of int8,int16,float16,float32,dual-int16.
Attention
  • 'dual-int16' only effective for 'Conv', 'MatMul', 'Gemm', and 'ConvTranspose'.

  • 'dual-int16' is equivalent to configuring {'input0': 'int16', 'input1': 'int16'} in node_config.

For details on node_config, please refer to Configure the computation accuracy for a specific node

Configure the Computation Accuracy for a Subgraph

Primary ParameterSecondary ParameterTertiary ParameterParameter TypeRequired or NotDescription
subgraph_configSubgraphNameinputsListRequiredConfigure input node names for enclosed subgraphs. Extraction operations abort when encountering unenclosed subgraphs due to missing input nodes.
outputsListRequiredConfigure output node names for enclosed subgraphs.
qtypeStringOptionalConfigure the input data type for all nodes within the subgraph, with optional configuration of int8,int16,float16,float32.

Configure the Computation Accuracy for a Specific Node

Primary ParameterSecondary ParameterTertiary ParameterParameter TypeRequired or NotDescription
node_configNodeNameqtypeStringOptionalConfigure the input data type of a node with a specified name, with optional configuration of int8,int16,float16,float32.
input0StringOptionalConfigure the 0th input data type of a node with a specified name, with optional configuration of int8,int16,float16,float32.
input1StringOptionalConfigure the 1st input data type of a node with a specified name, with optional configuration of int8,int16,float16,float32.
Attention

The input data type of a node can be specified by qtype, input0, or input1. qtype is generally used to specify the data type for all inputs of a node. input0 and input1 are used to specify the data type for the 0th and 1st inputs of a node, respectively. Moreover, the priority of input0 and input1 is higher than that of qtype.

Configuring Calibration Parameters

The quant_config supports configuring multiple calibration algorithms such as kl, max, etc. For each calibration algorithm, you can also flexibly control the specific hyperparameter configuration(if not configured, default value will be used). In addition, some independent calibration functions such as per_channel, asymmetric, bias_correction can also be configured.

Attention

If quant_config is not configured, multiple pre-set calibration algorithms will be tried by default, and the calibration algorithm with minimum quantization loss will be selected.

Configuring Calibration Parameters for Activation

Primary ParameterSecondary ParameterTertiary ParameterParameter TypeRequired or NotDescription
model_configactivationcalibration_typeString/List[String]OptionalCalibration algorithms for activation, with optional configuration of kl, max. It supports configuring a List with multiple calibration algorithms.
num_binInt/List[Int]OptionalParameter of kl calibration algorithm, requires num_bin > 128, and the default value is 1024. It supports configuring a List with multiple num_bin values.
max_num_binIntOptionalParameter of kl calibration algorithm, requires max_num_bin >= num_bin, and the default value is 16384.
max_percentileFloat/List[Float]OptionalParameter of max calibration algorithm, with parameter range in [0.5, 1.0], and the default value is 1.0. It supports configuring a List with multiple max_percentile values.
per_channelBool/List[Bool]OptionalWhether per-channel quantization is enabled or not, with optional configuration of false, true, and the default value is false. It supports configuring a List that includes both per-channel enabled and disabled.
asymmetricBool/List[Bool]OptionalWhether asymmetric quantization is enabled or not, with optional configuration of false, true, and the default value is false. It supports configuring a List that includes both asymmetric enabled and disabled.

Configuring Calibration Parameters for Weight

Primary ParameterSecondary ParameterTertiary ParameterQuaternary ParameterParameter TypeRequired or NotDescription
model_configweightbias_correctionnum_sampleIntOptionalThe number of samples for bias correction, requires num_sample >= 1, and the default vaue is 1.
metricStringOptionalThe model error metric for bias correction, with optional configuration of cosine-similarity, mse, mae, mre, sqnr and chebyshev, and the default value is cosine-similarity.

Configuring Search Methods for Calibration Parameters

The quant_config supports two search methods with different granularities:

  • modelwise_search: Search for quantization parameters at model level. This method allows multiple calibration algorithms to be configured at one time. By comparing the quantization loss with metric configured by you based on the model output before and after quantization, a calibration algorithm with the minimum quantization loss is selected.

  • layerwise_search: Search for quantization parameters at node level. This method calculates the quantization loss with metric configured by you based on the model output before and after the quantization of each node, and assigns the calibration algorithm with the minimum quantization loss to the node.

Attention

If multiple calibration algorithms are configured, modelwise search will be enabled by default to find the optimal algorithm for current model; if the layerwise search parameters are configured, a layer by layer search for the optimal algorithm will be initiated.

Configuring the Modelwise Search Method

Primary ParameterSecondary ParameterTertiary ParameterParameter TypeRequired or NotDescription
model_configmodelwise_searchmetricStringOptionalThe model error metric for modelwise search, with optional configuration of cosine-similarity, mse, mae, mre, sqnr and chebyshev, and the default value is cosine-similarity.

Configuring the Layerwise Search Method

Primary ParameterSecondary ParameterTertiary ParameterParameter TypeRequired or NotDescription
model_configlayerwise_searchmetricStringOptionalThe model error metric for layerwise search, with optional configuration of cosine-similarity, mse, mae, mre, sqnr and chebyshev, and the default value is cosine-similarity.

Configuration Example of the json Template

The following is an example of a json template configuration of the quant_config with all the configurable options, you can refer to this template for configuration.

{
    // Configure model-level parameters
    "model_config": {
         // Configure input data types for all nodes at once
         "all_node_type": "int16"/"float16",
         // Configure the data type of the model output
         "model_output_type": "int8"/"int16",
         // Configure calibration parameters for activation
         "activation": {
             // Configure calibration algorithm for activation, with parameter type: String or List[String]
             "calibration_type": "max"/"kl"/["max", "kl"],
             // Configure the parameter for kl calibration algorithm, with parameter type: Int or List[Int]
             "num_bin": 1024/2048/[1024, 2048],
             // Configure the parameter for kl calibration algorithm, with parameter type: Int
             "max_num_bin": 16384,
             // Configure the parameter for max calibration algorithm, with parameter type: Float or List[Float]
             "max_percentile": 0.99995/1.0/[0.99995, 1.0],
             // Configure whether per-channel quantization is enabled or not, with parameter type: Bool or List[Bool]
             "per_channel": true/false/[true, false],
             // Configure whether asymmetric quantization is enabled or not, with parameter type: Bool or List[Bool]
             "asymmetric": true/false/[true, false]
         },
         // Configure calibration parameters for weight
         "weight": {
             // Configure bias correction
             "bias_correction": {
                 // Configure the number of samples for bias correction, with parameter type: Int
                 "num_sample": 1,
                 // Configure the model error metric for bias correction, with parameter type: String
                 "metric": "cosine-similarity"/"mse"/"mae"/"mre"/"sqnr"/"chebyshev"
             }
         },
         // Configure modelwise search, if multiple calibration algorithms are configured, modelwise search will be enabled to select the best one with minimum quantization loss
         "modelwise_search": {
             // Configure the model error metric for modelwise search, with parameter type: String
             "metric": "cosine-similarity"/"mse"/"mae"/"mre"/"sqnr"/"chebyshev"
         },
         // Configure layerwise search, if layerwise search parameters are configured, a layer by layer search for the optimal algorithm will be initiated
         "layerwise_search": {
             // Configure the model error metric for layerwise search, with parameter type: String
             "metric": "cosine-similarity"/"mse"/"mae"/"mre"/"sqnr"/"chebyshev"
         }
    },
    // Configure the parameters of a node type, change the op_name to the node type name, e.g. “Conv”, “Add”, “Softmax”...
    "op_config": {
        // Configure the type of input data for a certain type of node
        "op_name1": {"qtype":"int8"/"int16"/"float16"},
        "op_name2": {"qtype":"int8"/"int16"/"float16"}
    },
    // Configure parameters for a subgraph, change the subgraph_name to your custom subgraph name, 
    // and update input_node/output_node with the actual input/output node names of the subgraph. e.g. “Conv_0”, “Add_1”...
    "subgraph_config": {
        // Configure the input data type for all nodes within the subgraph
        "subgraph_name1": {
            "inputs": ["input_node1", "input_node2"],
            "outputs": ["output_node1"],
            "qtype": "int8"/"int16"/"float16"
        }
    },
    // Configure the parameters of a node, change the node_name to the name of the node, e.g. “Conv_0”, “Add_1”...
    "node_config": {
        // Configure the input data type of a node
        "node_name1": {"qtype": "int8"/"int16"/"float16"},
        "node_name2": {"qtype": "int8"/"int16"/"float16"}
    }
}

The int16 Configuration

In the process of model conversion, most of the operators in the model are quantized to int8 for computation, and by configuring the quant_config parameter. You can specify in detail the input or the output of an op as int16 calculation (The range of operators supporting the configuration of int16 you can refer to Toolchain Operator Support Constraint List) The basic principle is as follows:

After you configure an op input/output data type to int16, the model conversion automatically performs an update and check of the op input/output context int16 configuration internally. For example, when configuring op_1 input/output data type as int16, it actually potentially specifies that the previous/next op of op_1 needs to support computation in int16 at the same time. For unsupported scenarios, the model conversion tool will print a log indicating that the int16 configuration combination is temporarily unsupported and fall back to int8 computation.

Platform Experience Templates

The field specification above describes how to configure each quant_config field in general. In practice, the starting quantization strategy differs across platforms. This section organizes a set of experience templates per platform for the starting point, along with common pitfalls. For the specific difference dimensions and link selection recommendations, refer to the Platform Differences section.

J6E/M and J6B Template

On J6E/M and J6B, we recommend "int8 + int16 mixed accuracy" as the starting strategy, with int8 as the default. For a basic starting point, first use hb_compile --fast-perf to generate the int8 configuration. If accuracy does not meet expectations, use quant_config to promote quantization-sensitive operators or nodes to int16.

Reference quant_config json template:

{
  "op_config": {
    "Softmax": {"qtype": "int16"},
    "LayerNormalization": {"qtype": "int16"}
  },
  "node_config": {
    "Conv_0": {"qtype": "int16"}
  }
}

int8 is the default quantization type for most operators and generally does not need to be actively set via model_config.all_node_type. Use op_config to batch-promote sensitive operators to int16 by operator type, or use node_config to fine-control by specific node names. The Softmax / LayerNormalization / Conv_0 in the example are only common quantization-sensitive operator demonstrations. In actual use, replace them with the operator types or node names in your model based on the model accuracy evaluation.

If a hard-to-quantize model still does not meet expectations, you can run an accuracy upper-bound configuration to check the accuracy ceiling, then gradually fall back to a balanced mixed-accuracy configuration. The accuracy upper-bound configuration on J6E/M and J6B is all_node_type global int16 plus dual-int16 for Conv / MatMul / ConvTranspose / Gemm. The corresponding template is:

{
  "model_config": {
    "all_node_type": "int16"
  },
  "op_config": {
    "Conv": {"qtype": "dual-int16"},
    "MatMul": {"qtype": "dual-int16"},
    "Gemm": {"qtype": "dual-int16"},
    "ConvTranspose": {"qtype": "dual-int16"}
  }
}

dual-int16 only takes effect on Conv, MatMul, Gemm, and ConvTranspose. It is equivalent to configuring both inputs of these operators as int16. For details, refer to the Configuring Accuracy for an Operator Type subsection on this page.

J6H/P Template

On J6H/P, we recommend "global float16 + Conv / GEMM / MatMul / ConvTranspose fallback to int8" as the starting strategy. The corresponding quant_config json template is as follows:

{
  "model_config": {"all_node_type": "float16"},
  "op_config": {
    "Conv": {"qtype": "int8"},
    "ConvTranspose": {"qtype": "int8"},
    "MatMul": {"qtype": "int8"},
    "Gemm": {"qtype": "int8"},
    "Resize": {"qtype": "int8"},
    "GridSample": {"qtype": "int8"},
    "Sin": {"qtype": "float32"},
    "Cos": {"qtype": "float32"}
  }
}
Note
  • Why explicit int8 fallback for Resize / GridSample: Based on experience, Resize / GridSample generally only need to be set to int8, and int8 performs noticeably better than int16 / float16 on these operators. If later sensitivity analysis indicates the need for higher accuracy, choose between int16 and float16 based on the upstream and downstream operators. For example, in a Resize + Conv structure, Resize should first try int16 to match the fixed-point input of Conv.

  • Why Sin / Cos must be explicitly configured as float32: Sin / Cos are accuracy-sensitive operators, and using global float32 is recommended.

Common Pitfalls

Common pitfalls when using quant_config:

  • quant_config is set but the tool falls back due to operator constraints: The tool ultimately follows operator constraints. If the configured qtype exceeds the operator's supported input/output data types, the tool automatically falls back to a supported type (for example, from float16 to int8, or from BPU to CPU), and prints a hint in hb_compile.log. To judge whether qtype actually takes effect, look at the Output Data Type column in hb_compile.log, not the yaml / json configuration.

  • Resize / GridSample not explicitly configured with int8 fallback, causing sub-optimal performance: Under the J6H/P global-float16 starting strategy, Resize / GridSample should first try int8 (int8 performs better on these operators). It is recommended to explicitly configure the qtype of these two operators as int8.

  • Tail BPU-accelerable operators fall back to CPU: To preserve accuracy, tail Conv outputs int32 / float32 by default. The BPU-accelerable operators following it (such as ReLU, Add) fall back to CPU by default. If performance is prioritized and some accuracy loss is acceptable, explicitly configure the qtype of these operators via op_config or node_config in quant_config to force them onto BPU. The cost is potential quantization loss, which needs to be weighed via dataset-level accuracy verification described in the Model Accuracy Evaluation section.