CANN 组织链接 : https://atomgit.com/cann
ops-math 仓库链接 : https://gitcode.com/cann/ops-math
1. 低精度算术的核心:最大化吞吐量
INT8 及更低精度(如未来的 INT4)运算的目标是最大化周期内吞吐量 (Throughput),牺牲一定的精度表示范围来换取速度和带宽优势。
1.1 整数运算的特殊性
ops-math 中的整数算子(如 Add, Mul, Sub)直接映射到硬件的整数ALU(Arithmetic Logic Unit)。
- 饱和(Saturation)处理 :与浮点运算不同,整数运算(如加法)在溢出时必须进行饱和处理,以符合量化推理的预期行为(防止数值环绕)。
ops-math的 INT8 加法指令内部必须包含溢出检测和饱和写入逻辑。 - 乘法累加的位宽 :即使输入是 INT8,为了保持精度,
ops-math的乘法操作结果(和后续的累加)都会暂存在 32 位(INT32)累加器中,这一点在前面的分析中提到,是保证 INT8 矩阵乘法精度的关键。
1.2 尺度因子应用中的整数优化
在量化过程中,Scale 和 Zero Point 的应用涉及到浮点数与整数的混合运算。
- 融合的定点化 :为了避免频繁地将 INT8 数据反量化为浮点数,现代硬件倾向于使用**定点(Fixed-Point)**运算来近似浮点乘法。
ops-math中的缩放(Scaling)操作,如果针对 INT8 输出,可能会被编译为特殊的定点乘法指令,减少浮点单元的开销。
2. 基础函数(Exp/Log)的低精度近似
非线性函数在低精度下的实现更加依赖于硬件的近似能力。
2.1 低精度下 Exp \text{Exp} Exp 的误差边界
在 FP16 精度下,由于指数范围较窄, Exp ( x ) \text{Exp}(x) Exp(x) 函数的输入 x x x 必须被严格限制在一个很小的范围内(通常 ± 6 \pm 6 ±6 到 ± 8 \pm 8 ±8 之间)。
- 截断与剪枝 :
ops-math的 FP16 Exp \text{Exp} Exp 算子通常在输入端内置了对 x x x 的裁剪操作(Clip)。如果输入值超出范围,则直接使用最大或最小可表示的 FP16 值作为输出,避免计算溢出。
2.2 查表法的低精度优化
对于查表法(Lookup Table, LUT),低精度意味着更稀疏的采样。
- LUT 尺寸优化 :如果精度要求降低(例如,从 FP16 降到 INT8 部署),LUT 的条目数量可以相应减少。
ops-math的实现会针对不同的精度模式,加载不同尺寸的 LUT 到 Local Memory 中,以节省缓存空间,并可能通过更粗粒度的线性插值来保持速度。
3. 自定义算子对 ops-math 的引用与性能锁定
自定义算子(Ascend C)在实现如稀疏激活函数或自定义损失函数时,必须复用 ops-math 提供的底层优化。
- 指令复用 :自定义算子不应自己实现
Exp或Log的多项式逼近,而应直接调用 ops-math 提供的、已经与 PTO-ISA 完美对齐的底层函数。这样做的好处是:只要硬件或 ops-math 更新了底层 Exp \text{Exp} Exp 的性能或精度(例如,使用了新的系数),自定义算子就能自动继承这些优化,无需重新编译。
CANN 组织链接 : https://atomgit.com/cann
ops-math 仓库链接 : https://gitcode.com/cann/ops-math