MLIR的随机舍入(Stochastic Rounding)支持
一个让我熬夜三天的bug
去年秋天,我在调试一个低精度推理引擎时遇到了一个诡异的问题。模型在FP32下跑得好好的,量化到INT8后,某些边缘场景的精度损失远超理论预期。更让人抓狂的是,同样的输入,每次跑出来的结果都不一样——不是那种微小的浮点误差,而是直接差了几个数量级。
我盯着反汇编看了两天,最后发现罪魁祸首是编译器在生成向量化代码时,对某些中间结果做了“过于聪明”的优化。它把几个浮点运算合并了,但合并后的舍入方式完全不是我们想要的。那一刻我意识到,在低精度计算的世界里,舍入策略不是细节,而是核心。
为什么需要随机舍入
传统舍入(round-to-nearest-even)在大多数场景下工作良好。但在低精度计算中,特别是当数值分布不均匀时,确定性舍入会引入系统性偏差。想象一下,你有一堆很小的正数,每次都被舍入到0,累积起来就是灾难。
随机舍入(Stochastic Rounding)的思路很简单:不是简单地取最近的可表示值,而是以一定概率向上或向下舍入。这个概率由原始值与最近两个可表示值的距离决定。比如,一个值距离0.75比距离1.0更近,那么它有75%的概率被舍入到1.0,25%的概率被舍入到0.0。
数学上,这保证了舍入误差的期望值为零。对于深度学习训练和某些对精度敏感的推理场景,这简直是救命稻草。
MLIR里的随机舍入实现
MLIR在arith</