Quantization and Dequantization of Matrix Multiplication Outputs
Overview
For specific input and output data types, Matmul allows you to quantize or dequantize the output C matrix elements when the computation result is moved from CO1 to to the global memory.
- Matmul quantization scenario: During Matmul computation, the left matrix A and right matrix B are of the half or bfloat16_t data type, and the output matrix C is of the int8_t data type. In this scenario, when the data of matrix C is moved from CO1 to the global memory, quantization is performed to quantize the final result to the int8_t type, as shown in the following figure.
Figure 1 Matmul quantization scenario
- Matmul dequantization scenario: During Matmul computation, the left matrix A and right matrix B are of the int8_t or int4b_t data type, and the output matrix C is of the half data type. Alternatively, both the left matrix A and right matrix B are of the int8_t data type, and the output matrix C is of the int8_t data type. In this scenario, when the data of matrix C is moved from CO1 to the global memory, dequantization is performed to dequantize the final result to the half or int8_t type, as shown in the following figure.
Figure 2 Matmul dequantization scenario
- Quantization or dequantization of the same coefficient (PER_TENSOR mode): The entire matrix C corresponds to one quantization parameter, whose shape is [1]. You can call the SetQuantScalar API on the operator kernel to set quantization parameters.
- Vector quantization or dequantization (PER_CHANNEL mode): The shape of matrix C is [m, n]. Each channel dimension, that is, each column of matrix C, corresponds to a quantization parameter, whose shape is [n]. You can call the SetQuantVector API on the operator kernel to set quantization parameters.
|
Mode |
Tiling API |
Kernel API |
|---|---|---|
|
Quantization or dequantization of the same coefficient |
SetDequantType(DequantType::SCALAR) |
SetQuantScalar(gmScalar) |
|
Vector quantization or dequantization |
SetDequantType(DequantType::TENSOR) |
SetQuantVector(gmTensor) |
Application Scenarios
Matrix computation results need to be quantized or dequantized. The following table lists the data types supported by the Matmul input and output matrices in this scenario.
|
Matrix A |
Matrix B |
Matrix C |
Supporting Platform |
|---|---|---|---|
|
half |
half |
int8_t |
|
|
bfloat16_t |
bfloat16_t |
int8_t |
|
|
int8_t |
int8_t |
half |
|
|
int4b_t |
int4b_t |
half |
|
|
int8_t |
int8_t |
int8_t |
|
Restrictions
- The quantization or dequantization mode set on the kernel should be the same as that set in the tiling process.
- The SetQuantScalar API is called on the kernel to set the quantization or dequantization mode of the same coefficient, and the SetDequantType API is called in the tiling process to set the mode to DequantType::SCALAR.
- The SetQuantVector API is called on the kernel to set the vector quantization or dequantization mode, and the SetDequantType API is called in the tiling process to set the mode to DequantType::TENSOR.
- If matrix A and matrix B are of the int8_t or int4b_t type and matrix C is of the half type, the outputs of the features mentioned in this section do not support the INF_NAN mode. If the results need to be output as INF_NAN, you are advised to send the results to TPosition::VECIN when calling the Matmul API, set the output data type to int32_t, and then use the high-level API AscendDequant based on the AIV core to dequantize the results to the half type.
Example
For a complete operator example, see matmul_quant operator sample.
- Tiling implementation
Call the SetDequantType API to set the quantization or dequantization mode. Other implementation details are the same as those in basic scenarios.
1 2 3 4 5 6 7 8 9 10 11 12
auto ascendcPlatform = platform_ascendc::PlatformAscendC(context->GetPlatformInfo()); matmul_tiling::MatmulApiTiling tiling(ascendcPlatform); tiling.SetAType(matmul_tiling::TPosition::GM, matmul_tiling::CubeFormat::ND, matmul_tiling::DataType::DT_INT8); tiling.SetBType(matmul_tiling::TPosition::GM, matmul_tiling::CubeFormat::ND, matmul_tiling::DataType::DT_INT8); tiling.SetCType(matmul_tiling::TPosition::GM, matmul_tiling::CubeFormat::ND, matmul_tiling::DataType::DT_INT32); tiling.SetBiasType(matmul_tiling::TPosition::GM, matmul_tiling::CubeFormat::ND, matmul_tiling::DataType::DT_INT32); tiling.SetShape(M, N, K); tiling.SetOrgShape(M, N, K); tiling.EnableBias(true); tiling.SetDequantType(DequantType::SCALAR); // Set the quantization or dequantization of the same coefficient. // tiling.SetDequantType(DequantType::TENSOR); //: Set the vector quantization or dequantization. ... // Perform other configuration operations.
- Kernel implementation
Call the SetQuantScalar or SetQuantVector API to set quantization parameters in line with the quantization mode. Other implementation details are the same as those in basic scenarios.
- Quantization or dequantization of the same coefficient
1 2 3 4 5 6 7 8
REGIST_MATMUL_OBJ(&pipe, GetSysWorkSpacePtr(), mm, &tiling); float tmp = 0.1; // Multiplied by 0.1 during output to the global memory. uint64_t ans = static_cast<uint64_t>(*reinterpret_cast<int32_t*>(&tmp)); // Quantization coefficient of the floating-point value converted to the uint64_t type for setting. mm.SetQuantScalar(ans); mm.SetTensorA(gm_a); mm.SetTensorB(gm_b); mm.SetBias(gm_bias); mm.IterateAll(gm_c);
- Vector quantization or dequantization
1 2 3 4 5 6 7 8
GlobalTensor gmQuant; ... REGIST_MATMUL_OBJ(&pipe, GetSysWorkSpacePtr(), mm, &tiling); mm.SetQuantVector(gmQuant); mm.SetTensorA(gm_a); mm.SetTensorB(gm_b); mm.SetBias(gm_bias); mm.IterateAll(gm_c);
- Quantization or dequantization of the same coefficient