AscendAntiQuant
Applicability
|
Product |
Supported |
|---|---|
|
Atlas 350 Accelerator Card |
√ |
|
|
√ |
|
|
√ |
|
|
x |
|
|
√ |
|
|
x |
|
|
x |
Function Usage
Performs fake quantization by element. For example, apply fake quantization to convert the int8_t data type to the half data type. The formulas are as follows:
- PER_CHANNEL scenario (quantization by channel)
- PER_TENSOR scenario (quantization by tensor)
- PER_TOKEN scenario (quantization by token)
- PER_GROUP scenario (quantization by group)
Based on the input data type, PER_GROUP is classified into two scenarios: fp4x2_e2m1_t/fp4x2_e1m2_t scenario (referred to as the float4 scenario) and int8_t/hifloat8_t/fp8_e5m2_t/fp8_e4m3fn_t scenario (referred to as the b8 scenario).
- fp4x2_e2m1_t/fp4x2_e1m2_t scenario (float4 scenario)
- Configurable groupSize API
The compute direction of a group is defined as k. In the k direction, each groupSize element of src shares scale. When the shape of src is [m, n], if kDim is 0, k is in the m direction, and the shape of scale is [(m + groupSize – 1)/groupSize, n]; if kDim is 1, k is in the n direction, and the shape of scale is [m, (n + groupSize – 1)/groupSize]. If isTranspose is set to True, src, scale, and dst are transposed matrices.
- k is the m direction, indicating that the i axis in the formula is the compute direction of the group: (kDim is 0 and isTranspose is False) or (kDim is 1 and isTranspose is True).
dst[i][j] = scale[i/groupSize][j] x src[i][j]
- k is the n direction, indicating that the j axis in the formula is the compute direction of the group: (kDim is 0 and isTranspose is True) or (kDim is 1 and isTranspose is False).
dst[i][j] = scale[i][j / groupSize] * src[i][j]
- k is the m direction, indicating that the i axis in the formula is the compute direction of the group: (kDim is 0 and isTranspose is False) or (kDim is 1 and isTranspose is True).
- groupSize fixed at 32
If isTranspose is set to True, src, scale, and dst are transposed matrices.
- Input transposing disabled (isTranspose = False)
dst[i][j] = scale[i/groupSize][j] x src[i][j]
- Input transposing enabled (isTranspose = True)
dst[i][j] = scale[i][j/groupSize] x src[i][j]
- Input transposing disabled (isTranspose = False)
- Configurable groupSize API
- int8_t/hifloat8_t/fp8_e5m2_t/fp8_e4m3fn_t scenario (b8 scenario)
The compute direction of a group is defined as k. In the k direction, each groupSize element of src shares a group of scale and offset. When the shape of src is [m, n], if kDim is 0, k is in the m direction, and the shape of scale and offset is [(m + groupSize – 1)/groupSize, n]; if kDim is 1, k is in the n direction, and the shape of scale and offset is [m, (n + groupSize – 1)/groupSize]. offset is an optional input. If isTranspose is set to True, src, scale, and dst are transposed matrices.
- k is the m direction, indicating that the i axis in the formula is the compute direction of the group: (kDim is 0 and isTranspose is False) or (kDim is 1 and isTranspose is True).

- k is the n direction, indicating that the j axis in the formula is the compute direction of the group: (kDim is 0 and isTranspose is True) or (kDim is 1 and isTranspose is False).

- k is the m direction, indicating that the i axis in the formula is the compute direction of the group: (kDim is 0 and isTranspose is False) or (kDim is 1 and isTranspose is True).
- fp4x2_e2m1_t/fp4x2_e1m2_t scenario (float4 scenario)
Principles
The preceding figure shows the algorithm block diagram of AscendAntiQuant in typical scenarios. The computation process is divided into the following steps, all of which are performed on vectors:
- Precision conversion: Convert the input src to the half type.
- Offset calculation: Perform Add calculation when offset is a vector, and perform Adds calculation when offset is a scalar.
- Scale calculation: Perform Mul calculation when scale is a vector, and perform Muls calculation when scale is a scalar.
On the
- src precision conversion: Convert the input src to the half type, and then convert it to the float type and store it in tmp1.
- Offset precision conversion: When the input offset is a vector, it is converted to the float type and stored in tmp2; when the input offset is a scalar, it is converted to the float type through Cast.
- Offset calculation: When the input offset is a vector, perform the Add calculation with tmp2. When it is a scalar, perform the Adds calculation.
- Scale precision conversion: When the input scale is a vector, it is converted to the float type and stored in tmp2; when the input scale is a scalar, it is converted to the float type through Cast.
- Scale calculation: When the input scale is a vector, perform the Mul calculation with tmp2. When it is a scalar, perform the Muls calculation.
- dst precision conversion: Convert tmp1 to the bf16 type.
The computation logic in the PER_TOKEN b8/float4 and PER_GROUP b8/float4 scenarios is as follows:
- Data reading: Read the input src continuously, and use different modes to read the input scale and offset based on actual scenarios. For example, the input data is broadcast in the PER_TOKEN scenario, and gathered in the PER_GROUP scenario.
- Precision conversion: Convert the data types of src, scale, and offset based on the input data type combination.
- Computation: Perform the addition and multiplication operations on the data after type conversion.
- Precision conversion: Convert the computation result to the dstT type as the final output.
Prototype
- Pass the temporary space through the sharedTmpBuffer input parameter.
- PER_CHANNEL scenario (quantization by channel)
1 2
template <typename InputDataType, typename OutputDataType, bool isTranspose> __aicore__ inline void AscendAntiQuant(const LocalTensor<OutputDataType>& dst, const LocalTensor<InputDataType>& src, const LocalTensor<OutputDataType>& offset, const LocalTensor<OutputDataType>& scale, const LocalTensor<uint8_t>& sharedTmpBuffer, const uint32_t k, const AntiQuantShapeInfo& shapeInfo = {})
- PER_CHANNEL scenario (quantization by channel without offset)
1 2
template <typename InputDataType, typename OutputDataType, bool isTranspose> __aicore__ inline void AscendAntiQuant(const LocalTensor<OutputDataType>& dst, const LocalTensor<InputDataType>& src, const LocalTensor<OutputDataType>& scale, const LocalTensor<uint8_t>& sharedTmpBuffer, const uint32_t k, const AntiQuantShapeInfo& shapeInfo = {})
- PER_TENSOR scenario (quantization by tensor)
1 2
template <typename InputDataType, typename OutputDataType, bool isTranspose> __aicore__ inline void AscendAntiQuant(const LocalTensor<OutputDataType>& dst, const LocalTensor<InputDataType>& src, const OutputDataType offset, const OutputDataType scale, const LocalTensor<uint8_t>& sharedTmpBuffer, const uint32_t k, const AntiQuantShapeInfo& shapeInfo = {})
- PER_TENSOR scenario (quantization by tensor without offset)
1 2
template <typename InputDataType, typename OutputDataType, bool isTranspose> __aicore__ inline void AscendAntiQuant(const LocalTensor<OutputDataType> &dst, const LocalTensor<InputDataType> &src, const OutputDataType scale, const LocalTensor<uint8_t> &sharedTmpBuffer, const uint32_t k, const AntiQuantShapeInfo& shapeInfo = {})
- PER_GROUP float4 scenario (quantization by group)
It is supported only by the Atlas 350 Accelerator Card.
1 2
template <typename InputDataType, typename OutputDataType, bool isTranspose> __aicore__ inline void AscendAntiQuant(const LocalTensor<OutputDataType>& dst, const LocalTensor<InputDataType>& src, const LocalTensor<fp8_e8m0_t>& scale, const LocalTensor<uint8_t>& sharedTmpBuffer, const uint32_t k, const AntiQuantShapeInfo& shapeInfo = {})
- PER_TOKEN b8/float4 (quantization by token) or PER_GROUP b8/float4 scenario (quantization by group)
It is supported only by the Atlas 350 Accelerator Card.
1 2
template <typename dstT, typename srcT, typename scaleT, const AscendAntiQuantConfig& config, const AscendAntiQuantPolicy& policy> __aicore__ inline void AscendAntiQuant(const LocalTensor<dstT>& dstTensor, const LocalTensor<srcT>& srcTensor, const LocalTensor<scaleT>& scaleTensor, const LocalTensor<scaleT>& offsetTensor,const LocalTensor<uint8_t>& sharedTmpBuffer, const AscendAntiQuantParam& para)
- PER_CHANNEL scenario (quantization by channel)
- Allocate the temporary space through the API framework.
- PER_CHANNEL scenario
1 2
template <typename InputDataType, typename OutputDataType, bool isTranspose> __aicore__ inline void AscendAntiQuant(const LocalTensor<OutputDataType>& dst, const LocalTensor<InputDataType>& src, const LocalTensor<OutputDataType>& offset, const LocalTensor<OutputDataType>& scale, const uint32_t k, const AntiQuantShapeInfo& shapeInfo = {})
- PER_TENSOR scenario
1 2
template <typename InputDataType, typename OutputDataType, bool isTranspose> __aicore__ inline void AscendAntiQuant(const LocalTensor<OutputDataType>& dst, const LocalTensor<InputDataType>& src, const OutputDataType offset, const OutputDataType scale, const uint32_t k, const AntiQuantShapeInfo& shapeInfo = {})
- PER_GROUP float4 scenario (groupSize fixed at 32)
It is supported only by the Atlas 350 Accelerator Card.
1 2
template <typename InputDataType, typename OutputDataType, bool isTranspose> __aicore__ inline void AscendAntiQuant(const LocalTensor<OutputDataType>& dst, const LocalTensor<InputDataType>& src, const LocalTensor<fp8_e8m0_t>& scale, const uint32_t k, const AntiQuantShapeInfo& shapeInfo = {})
- PER_TOKEN b8/float4 or PER_GROUP b8/float4 scenario (configurable groupSize)
It is supported only by the Atlas 350 Accelerator Card.
1 2
template <typename dstT, typename srcT, typename scaleT, const AscendAntiQuantConfig& config, const AscendAntiQuantPolicy& policy> __aicore__ inline void AscendAntiQuant(const LocalTensor<dstT>& dstTensor, const LocalTensor<srcT>& srcTensor, const LocalTensor<scaleT>& scaleTensor, const LocalTensor<scaleT>& offsetTensor,const AscendAntiQuantParam& para)
- PER_CHANNEL scenario
Due to the complex mathematical computation involved in the internal implementation of this API, extra temporary space is required to store intermediate variables generated during computation. The temporary space can be allocated through the API framework or passed by developers through the sharedTmpBuffer input parameter.
- When the API framework is used for temporary space allocation, developers do not need to allocate the space, but must reserve the required size for the temporary space.
- When the sharedTmpBuffer input parameter is used for passing the temporary space, the tensor serves as the temporary space. In this case, the API framework is not required for temporary space allocation. This enables developers to manage the sharedTmpBuffer space and reuse the buffer after calling the API, so that the buffer is not repeatedly allocated or deallocated, improving the flexibility and buffer utilization.
If the API framework is used, developers must reserve the temporary space. If sharedTmpBuffer is used, developers must allocate space for sharedTmpBuffer. To obtain the size of the temporary space (BufferSize) to be reserved, use the API provided in GetAscendAntiQuantMaxMinTmpSize.
Parameters
|
Parameter |
Description |
|---|---|
|
InputDataType |
Input data type. |
|
OutputDataType |
Output data type. |
|
isTranspose |
Whether to enable input data transposing. |
|
Parameter |
Description |
||
|---|---|---|---|
|
dstT |
Data type of the destination operand. |
||
|
srcT |
Data type of the source operand. |
||
|
scaleT |
Data type of scale. |
||
|
config |
Quantization API parameter. The definition is as follows:
|
||
|
policy |
Quantization policy parameter of the enumeration type. The following values are supported:
|
|
srcDtype |
scaleDtype/offsetDtype |
dstDtype |
|---|---|---|
|
int8_t |
half |
half |
|
bfloat16_t |
bfloat16_t |
|
|
float |
float |
|
|
float |
half |
|
|
float |
bfloat16_t |
|
|
hifloat8_t |
half |
half |
|
bfloat16_t |
bfloat16_t |
|
|
float |
float |
|
|
float |
half |
|
|
float |
bfloat16_t |
|
|
fp8_e5m2_t/fp8_e4m3fn_t |
half |
half |
|
bfloat16_t |
bfloat16_t |
|
|
float |
float |
|
|
float |
half |
|
|
float |
bfloat16_t |
|
|
fp4x2_e1m2_t/fp4x2_e2m1_t (Currently, only the PER_GROUP scenario is supported.) |
fp8_e8m0_t |
half |
|
bfloat16_t |
|
Parameter |
Input/Output |
Description |
||
|---|---|---|---|---|
|
dst |
Output |
Destination operand. The type is LocalTensor, and TPosition can be VECIN, VECCALC, or VECOUT. For the Atlas 350 Accelerator Card, the supported data types are half and bfloat16_t. For the For the For the |
||
|
src |
Input |
Source operand. The type is LocalTensor, and TPosition can be VECIN, VECCALC, or VECOUT. For the Atlas 350 Accelerator Card, in the PER_CHANNEL and PER_TENSOR scenarios, the supported data types are int8_t, fp8_e4m3fn_t, fp8_e5m2_t, hifloat8_t. In the PER_GROUP float4 scenario, the supported data types are fp4x2_e2m1_t and fp4x2_e1m2_t. For the For the For the |
||
|
offset |
Input |
Offset when the input data is dequantized. The type is LocalTensor, and TPosition can be VECIN, VECCALC, or VECOUT. For the Atlas 350 Accelerator Card, the supported data types are half and bfloat16_t. For the For the For the |
||
|
scale |
Input |
Scaling factor when the input data is dequantized. The type is LocalTensor, and TPosition can be VECIN, VECCALC, or VECOUT. For the Atlas 350 Accelerator Card, the supported data types are half and bfloat16_t in PER_CHANNEL and PER_TENSOR scenarios. In PER_GROUP float4 scenarios, the supported data type is fp8_e8m0_t. For the For the For the |
||
|
sharedTmpBuffer |
Input |
Temporary buffer. The type is LocalTensor, and TPosition can be VECIN, VECCALC, or VECOUT. For details about how to obtain the temporary space size (BufferSize), see GetAscendAntiQuantMaxMinTmpSize. |
||
|
k |
Input |
If isTranspose is set to true, the shape of src is [N, K]. If isTranspose is set to false, the shape of src is [K, N]. The parameter k corresponds to the K value. |
||
|
shapeInfo |
Input |
Shape information of offset and scale. This parameter is configured only in the PER_CHANNEL scenario. This parameter is optional. In the PER_CHANNEL scenario, if this parameter is not specified or the data in the struct is set to 0, the shape information of offset and scale is obtained from ShapeInfo. The AntiQuantShapeInfo type is defined as follows:
|
|
Parameter |
Input/Output |
Description |
||
|---|---|---|---|---|
|
dstTensor |
Output |
Destination operand. The type is LocalTensor, and TPosition can be VECIN, VECCALC, or VECOUT. For the Atlas 350 Accelerator Card, the supported data types are half, bfloat16_t, and float. |
||
|
srcTensor |
Input |
Source operand. The type is LocalTensor, and TPosition can be VECIN, VECCALC, or VECOUT. For the Atlas 350 Accelerator Card, the supported data types are int8_t, fp8_e4m3fn_t, fp8_e5m2_t, hifloat8_t, fp4x2_e1m2_t, and fp4x2_e2m1_t. Note that the fp4x2_e1m2_t and fp4x2_e2m1_t data types are supported only in the PER_GROUP scenario. |
||
|
sharedTmpBuffer |
Input |
Temporary buffer. The type is LocalTensor, and TPosition can be VECIN, VECCALC, or VECOUT. For details about how to obtain the temporary space size (BufferSize), see GetAscendQuantMaxMinTmpSize. For the Atlas 350 Accelerator Card, the supported data type is uint8_t. |
||
|
scaleTensor |
Input |
Quantization parameter scale. The type is LocalTensor, and TPosition can be VECIN, VECCALC, or VECOUT. For the Atlas 350 Accelerator Card, the supported data types are half, float, bfloat16_t, and fp8_e8m0_t. |
||
|
offsetTensor |
Input |
Quantization parameter offset. The type is LocalTensor, and TPosition can be VECIN, VECCALC, or VECOUT. For the Ascend 910_95 AI Processor, the data type is the same as that of scaleTensor. In the float4 scenario, offsetTensor does not take effect. |
||
|
para |
Input |
Quantization API parameter, which is of the AscendAntiQuantParam type. The definition is as follows:
|
Returns
None
Constraints
- The source operand address must not overlap the destination operand address.
- For details about the operand address alignment requirements, see General Address Alignment Restrictions.
- The length of the data involved in computation of the input and output operands must be 32-byte aligned.
- When inputs are transposed, k must be 32-byte aligned.
- Before calling the API, ensure that the size of the input data is correct, and the size and shape of offset and scale are correct.
- Currently, only the Atlas 350 Accelerator Card supports the PER_TOKEN and PER_GROUP scenarios.
- In the PER_TOKEN b8/float4 and PER_GROUP b8/float4 scenarios, the size of data in the continuous compute direction (n direction) must be 32-byte aligned.
Examples
For a complete call example, see AscendAntiQuant operator sample.
1 2 3 4 5 6 7 8 9 |
// dstLocal: result tensor // srcLocal: quantized input // offsetLocal: offset parameter // scaleLocal: scaling parameter // sharedTmpBuffer: temporary buffer managed by developers, used to store intermediate variables during internal computation // k: length of the k axis // shapeInfo: shape information of the offsetLocal and scaleLocal tensors AscendC::AntiQuantShapeInfo shapeInfo = {1, elementCountOfOffset, 1, elementCountOfOffset}; AscendC::AscendAntiQuant<InputType, OutType, false>(dstLocal, srcLocal, offsetLocal, scaleLocal, sharedTmpBuffer, k, shapeInfo); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
Input data src (shape: [2, 64], non-transposing scenario): [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1] offset (shape: [1, 64]): [2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2.] scale (shape: [1, 64]): [3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3.] Output dstLocal (shape: [2, 64]): [9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9. 9.] |
The following is an example of calling the API in the PER_TOKEN b8 and PER_GROUP b8 scenarios:
1 2 3 4 5 6 7 8 9 |
// Note that m and n must be passed from an external system. constexpr static bool isReuseSource = false; constexpr static AscendAntiQuantConfig config = {has_offset, has_transpose, -1}; constexpr static AscendAntiQuantPolicy policy = AscendAntiQuantPolicy::PER_TOKEN; AscendAntiQuantParam para; para.m = m; para.n = n; para.calCount = calCount; AscendAntiQuant<dstType, srcType, scaleType, config, policy>(dstLocal, srcLocal, scaleLocal, offsetLocal, para); |
