拓冰建站拓冰建站
首页 / 资讯中心 / 正文

权重量化中的非对称零点对 ARM 汇编乘加指令周期的拖累实测

权重量化中的非对称零点对 ARM 汇编乘加指令周期的拖累实测在深度学习模型量化算法Quantization的理论推导中非对称量化Asymmetric Quantization / Affine Quantization由于引入了可浮动的零点Zero-Point / Offset, $Z$能够完美贴合带有非负偏置的非对称数据分布例如经过 ReLU 激活后的特征图全部在 $[0, \infty)$ 之间在数学上能够最大程度压低量化误差MSE。很多偏学术背景的算法工程师因此在模型量化时盲目勾选“全网络统一采用非对称量化”。然而当模型被编译下沉到底层硬件汇编如 ARM Cortex-A 架构的 NEON 汇编指令时非对称量化中那个看似人畜无害的“零点 $Z$”却在硬件矩阵乘法循环中演化成了吞噬时钟周期的“指令黑洞”。本文深入剖析对称量化与非对称量化在 ARM 汇编层面的指令级差异并给出硬件友好的量化配置准则。对称与非对称量化的代数展开对比设输入激活值为 $X$权重为 $W$。两者的数学映射模型如下----------------------------------------------------------------------------------------- | 量化模式 | 浮点映射公式 (Dequantization) | 零点约束 (Zero-Point) | ----------------------------------------------------------------------------------------- | 对称量化 | x S_x * q_x | Z_x 0 (零点严格固定为 0) | | (Symmetric) | w S_w * q_w | Z_w 0 | ----------------------------------------------------------------------------------------- | 非对称量化 | x S_x * (q_x - Z_x) | Z_x ≠ 0 (零点为任意 INT8 整数) | | (Asymmetric) | w S_w * (q_w - Z_w) | Z_w ≠ 0 | -----------------------------------------------------------------------------------------矩阵乘法展开式的残酷代数现实对于对称量化内积计算极其纯粹$$Y \sum (x_i \cdot w_i) S_x S_w \sum (q_{x, i} \cdot q_{w, i})$$硬件只需要执行一组纯粹的整数乘累加指令Integer Multiply-Accumulate而对于非对称量化将零点代入展开式$$Y \sum \Big[ S_x (q_{x, i} - Z_x) \cdot S_w (q_{w, i} - Z_w) \Big] S_x S_w \left[ \sum (q_{x, i} \cdot q_{w, i}) - Z_w \sum q_{x, i} - Z_x \sum q_{w, i} N \cdot Z_x Z_w \right]$$展开式中凭空多出了三项繁重的修正项项 1纯整数点积$\sum (q_{x, i} \cdot q_{w, i})$项 2激活值行求和$- Z_w \sum q_{x, i}$必须在运行时对动态输入特征图的每一行实时计算累加和项 3权重列求和$- Z_x \sum q_{w, i}$可以在离线编译期预先算好但运行时仍需每次做一次向量减法项 4常量偏置$ N \cdot Z_x Z_w$。ARM64 NEON 指令级循环对战为了看清指令周期的消耗我们对比两种量化在 ARM64 汇编内循环中的指令开销1. 对称量化内循环汇编极致极简在 ARMv8.2-A 上一条SDOT有符号点积指令直接在 1 个时钟周期内完成 4 组 INT8 乘加// 对称量化核心循环 (每次处理 16 个 INT8 元素) .L_symm_loop: ldr q0, [x0], #16 // 加载 16 个激活值 q_x ldr q1, [x1], #16 // 加载 16 个权重值 q_w sdot v2.4s, v0.16b, v1.16b // 单周期直接累加到 32 位寄存器 v2 中 subs x2, x2, #16 b.gt .L_symm_loop // 循环体内仅需 3 条核心指令指令吞吐极高2. 非对称量化内循环汇编指令膨胀与流水线停顿由于需要维护动态激活值的行求和 $\sum q_{x, i}$CPU 无法使用单一的SDOT必须额外插入大量的符号扩展与跨通道加法指令// 非对称量化核心循环 .L_asymm_loop: ldr q0, [x0], #16 // 加载 16 个激活值 ldr q1, [x1], #16 // 加载 16 个权重值 // 1. 执行点积 sdot v2.4s, v0.16b, v1.16b // 2. 额外执行激活值行累加 (维护 sum(q_x)) saddlp v3.8h, v0.16b // 16 字节两两相加扩展为 8 个 16 位整型 (指令 1) saddlp v4.4s, v3.8h // 8 个 16 位相加扩展为 4 个 32 位整型 (指令 2) add v5.4s, v5.4s, v4.4s // 累加至激活值行累加寄存器 (指令 3) subs x2, x2, #16 b.gt .L_asymm_loop // 循环退出后还必须从主存加载预计算的权重偏置并执行向量减法修正... // 内存访存与寄存器压力翻倍非对称量化使得循环体内的指令数量从 3 条飙升至 7 条且引入了寄存器跨通道合并指令SADDLP造成严重的流水线停顿Pipeline Stall。工业实测性能对账在四核 Cortex-A55 1.8GHz 嵌入式板卡上对相同尺寸的密集全连接层GEMM: $1024 \times 1024$ 矩阵乘法进行实测对账量化模式与硬件指令单次 GEMM 耗时CPU 指令总数 (Instructions)每周期执行指令数 (IPC)纯对称量化 (Symmetric INT8 SDOT)4.25 ms1,850,000 条1.72 (极高指令吞吐)非对称量化 (Asymmetric INT8 动态修正)9.80 ms (慢了 2.3 倍)4,280,000 条0.85 (流水线频繁停顿)工业级黄金量化法则在进行模型工程量化时必须遵循以下黄金法则硬件亲和量化准则 1. 【权重矩阵 (Weights)】: 强制 100% 采用【对称量化 (Symmetric, Z_w 0)】 (离线权重分布对称性极好对称量化几乎零掉点直接消灭动态激活行求和项) 2. 【激活值矩阵 (Activations)】: - 若硬件支持高效零点广播: 可采用非对称量化 - 通用 ARM NEON / NPU 部署: 强烈推荐采用【对称量化 (Symmetric, Z_x 0)】在精度损失允许的微小范围内优先选用对称量化以消除零点修正项让硬件能够全速释放SDOT单周期点积指令的狂暴吞吐。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门