FT_DSP.gitlink.net/master/html/_sources/functionlib/dsplib/dynamicquant.rst.txt

139 lines
4.1 KiB
ReStructuredText
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

DynamicQuant
=================
将 FP32 输入张量按给定的 scale 和 zero pointzp动态量化为 INT8 输出张量。
支持按整张量量化或按指定轴分段量化per-axis dynamic quantization
.. math::
q_i = \mathrm{clip}\left( \mathrm{round}\left( \frac{x_i}{scale} + zp \right), q_{min}, q_{max} \right)
其中:
- :math:`x_i` 为输入浮点值
- :math:`scale` 为量化比例因子
- :math:`zp` 为零点zero point
- :math:`q_{min} = -128`
- :math:`q_{max} = 127`
当输入为 :math:`+\infty`:math:`-\infty` 时,输出分别饱和到最大或最小量化值。
---
输入:
- **real_values** - 输入 FP32 数据地址
- **element_num** - 输入元素总数
- **scale** - 量化 scale 数组地址
- **zp** - 量化 zero point 数组地址
- **segment_num** - 分段数量(用于按轴量化)
- **axis_num** - 量化轴标识
- ``0``整张量量化per-tensor
- ``!=0``按轴分段量化per-axis
输出:
- **quant_values** - 输出 INT8 量化结果地址
---
支持平台:
``FT78NE``
``MT7004``
---
.. note::
- 当前算子仅支持 **FP32\Fp16 → INT8** 的动态量化
-``axis_num = 0`` 时,仅使用 ``scale[0]````zp[0]`` 进行整张量量化
-``axis_num != 0`` 时,输入按 ``segment_num`` 进行分段,每段使用对应的 ``scale[i]````zp[i]``
- 分段大小通过 ``UP_DIV(element_num, segment_num)`` 计算,最后一段自动处理剩余元素
- 量化结果会被限制在 ``[-128, 127]`` 范围内
---
**私有存储版本:**
.. c:function:: void fp_QuantData_p(float* real_values, int8_t* quant_values, int element_num, float* scale, int* zp, int segment_num, int axis_num)
.. c:function:: void hp_QuantData_p(half* real_values, half* quant_values, int element_num, half* scale, int* zp, int segment_num, int axis_num)
---
**C调用示例**
.. code-block:: c
:linenos:
:emphasize-lines: 11
#include <stdio.h>
#include <quant.h>
int main(int argc, char* argv[]) {
float *input = (float *)0x10000000; // FP32 输入
int8_t *output = (int8_t *)0x10004000; // INT8 输出
float scale[4] = {0.1f, 0.12f, 0.11f, 0.09f};
int zp[4] = {0, 0, 0, 0};
int element_num = 1024;
int segment_num = 4;
int axis_num = 1;
fp_QuantData_p(input, output, element_num,
scale, zp, segment_num, axis_num);
return 0;
}
---
**共享存储版本:**
.. c:function:: void fp_QuantData_s(float* real_values, int8_t* quant_values, int element_num, float* scale, int* zp, int segment_num, int axis_num, int core_mask)
.. c:function:: void hp_QuantData_s(half* real_values, half* quant_values, int element_num, half* scale, int* zp, int segment_num, int axis_num, int core_mask)
---
**C调用示例**
.. code-block:: c
:linenos:
:emphasize-lines: 11
#include <stdio.h>
#include <quant.h>
int main(int argc, char* argv[]) {
float *input = (float *)0x10000000; // FP32 输入
int8_t *output = (int8_t *)0x10004000; // INT8 输出
float scale[4] = {0.1f, 0.12f, 0.11f, 0.09f};
int zp[4] = {0, 0, 0, 0};
int element_num = 1024;
int segment_num = 4;
int axis_num = 1, core_mask = 0xff;
fp_QuantData_s(input, output, element_num,
scale, zp, segment_num, axis_num, core_mask);
return 0;
}
---
**实现说明:**
-``axis_num == 0`` 时:
- 对整个输入数组执行一次统一量化
- 等价于 per-tensor quantization
-``axis_num != 0`` 时:
- 输入数据按 ``segment_num`` 均分为多个分段
- 每个分段使用独立的 ``scale[i]````zp[i]``
- 等价于 per-axis dynamic quantization
- 核心量化过程由 ``DoQuantizeFp32ToInt8`` 完成,包括:
- 反 scale 计算
- 四舍五入
- 饱和裁剪
- INF 特殊值处理