已关闭
int8 池化内核重量化结果窄化回绕,负值窗口输出翻转(MaxPoolingInt8 / MaxPoolingInt8V1) #448
李浩林创建于 8月29日关闭于 9月12日
8月29日 修改标题为 “int8 池化内核重量化结果窄化回绕,负值窗口输出翻转(MaxPoolingInt8 / MaxPoolingInt8V1)”,原标题为“pool算子micro的精度不达标”
8月29日 修改标题为 “int8 池化内核重量化结果窄化回绕,负值窗口输出翻转(MaxPoolingInt8 / MaxPoolingInt8V1)”,原标题为“pool算子micro的精度不达标”
8月29日 修改了issue 的描述
8月29日 修改了issue 的描述
8月29日 关闭了 issue
8月29日 重新打开了 issue
9月12日 issue状态由 TODO 改变为 DONE
9月12日 关闭了 issue
现象
全量化 int8 模型推理时,MaxPool 输出张量中的个别元素发生数量级翻转:本应为 -128(饱和下限)的元素变成 +112~+127。在 WS63(RISC-V)单算子全量化测试中,
[1,64,6,6]、kernel 2×2/stride 2×2 规格的 576 个输出中恰有 1 个元素翻转,导致输出与 golden 的余弦相似度从 0.9999 降至 0.9947。根因
mindspore-lite/src/litert/kernel/cpu/nnacl_c/int8/pooling_int8.c中,重量化结果被直接赋给int8_t中间变量后再做饱和 clamp:int8_t tmp_max = INT8_MIN; ... // 窗口求 max tmp_max = (int)round((tmp_max - input_zp) * real_multiplier + output_zp); // ← 窄化点 int8_t real_out = tmp_max < out_min ? out_min : tmp_max; // ← clamp 失效 real_out = real_out > out_max ? out_max : real_out;当 requant 结果超出 int8 范围(典型如 -129 ~ -144)时,int → int8_t 的窄化截断使数值回绕为正值(如 -144 → +112),恰好落在 (out_min, out_max] 区间内,上下限饱和双双失效,错误值直接写出。
受影响的函数(同写法两处):
MaxPoolingInt8MaxPoolingInt8V1触发条件(三者叠加)
真实 CNN 中 pool 常跟在 conv/ReLU 后(输入非负、zp 近 0),故长期未暴露;随机数据全量化单算子测试可稳定复现。