7 / 24 · 概念
累加器位宽、舍入与饱和
十八位有符号数是否足以保存九个有符号 int8 乘积之和,且偏置为零?
课时内容可免费阅读,选课后可保存学习进度。
累加需要单独确定位宽
八位操作数和八位输出不意味着累加器也只需八位。有符号八位编码的最大绝对值为 128。零点为零、共有 L 项时,和的绝对值保守上界为 L×128×128,再加上偏置绝对值。应选择正最大值可以覆盖该界限的有符号位宽;符号位占用一位。
位宽计算示例
C=3 且卷积核为 3×3 时,L=27。两个操作数都为 −128 时,每个乘积为 +16384,和为 442368。十九位有符号数最大只能达到 262143。二十位可达到 524287,还能覆盖绝对值不超过 1000 的偏置,得到界限 443368。经过证明的较小操作数范围可能减少所需位宽,但几个普通测试输入不能证明界限。
零点为零的无符号编码可达到 255,因此 128 的假设不再成立。先计算 A=max(abs(qmin−zx),abs(qmax−zx)),并为权重计算类似的 B。使用 L×A×B+abs(b)。中心化操作本身就可能需要比存储编码更多的位。
固定输出转换顺序
乘数为 sx×sw/sy。乘数 0.5、输出零点 128 时,累加器九变为半值 4.5,舍入为偶数四,得到 132。累加器十一把 5.5 舍入为六,得到 134。累加器 −3 把 −1.5 舍入为 −2。负值下,截断、向零截断和算术右移并不相同。练习使用专门的最近偶数舍入函数,而不是编程语言默认的舍入函数。
对于 int8 输出,转换后的 300 饱和为 127,−300 饱和为 −128。丢弃高位会回绕成无关数值。记录截断之前的数值及饱和次数。约定还应包含 ReLU 所在位置,以及它使用的零表示。
验证较大的正和与负和、精确半值、两个饱和边界和大偏置。刻意比较宽参考与位宽不足的累加器,以暴露溢出。本课程的可运行测试数据均处于 JavaScript 整数可精确表示的范围内;更大的参考模型也必须证明宿主算术的精度足够。
自己试试
十八位有符号数是否足以保存九个有符号 int8 乘积之和,且偏置为零?
阅读解释
正上界为 9×16384=147456,超过十八位最大值 131071。十九位有符号数最大可达到 262143。