资讯动态

三元权重网络实战解析:极低比特量化的精度与部署

发布时间:2026/10/17 5:58:46 来源:尧图企业网站定制
最近项目组在给一个边缘设备做模型压缩量化方案从8比特一路试到4比特回头再看三元权重网络这篇论文感受完全不一样了。以前觉得权重只有三种取值实在太激进精度肯定崩真正复现一遍才知道只要训练细节给足三值权重在不少任务上能把精度损失压到两个点以内而模型体积和计算量是真的下来了。这篇论文属于神经网络量化里非常经典的一支核心思路是把权重约束到{-1, 0, 1}三种取值上配合一个缩放系数来补偿尺度信息。文章不复杂但涉及训练技巧、梯度处理、BN层配合、部署加速等多个层面适合做模型压缩和边缘部署的人精读。如果你现在正在纠结量化方案怎么选或者想知道权重只剩三种值还能不能保住精度这篇笔记应该能给你一个比较完整的答案。1. 看完这篇论文先搞清楚它解决了什么问题1.1 量化是模型落地绕不开的一关现在的深度学习模型越做越深但落地的时候第一个卡住的地方就是内存和算力。一个普通的卷积神经网络单层卷积权重动辄几百KB整体模型几十MB很常见。边缘设备上的Flash和RAM都有限而且很多芯片没有浮点加速单元跑Float32的卷积非常吃力。量化就是为了解决这个问题。理想情况下把32位浮点权重变成8位整数内存直接砍到四分之一计算也能用整数运算替代浮点运算速度有数倍提升。再往前走一步就是低位宽量化4比特、2比特甚至1比特。三元权重网络属于极低比特量化这一档它把权重压缩成三种离散值理论上每个权重只需要2比特就可以表示三种状态可以用00、01、10编码11可以留作符号位或者复用相比32比特是16倍的存储压缩相比8比特也有4倍收益。不过这里必须说清楚压缩倍数只是一个面另一个关键是计算友好。三值权重和{0, 1}二值权重一样卷积乘法可以直接退化成加减法和累加因为权重是常数很多硬件实现可以把乘法器替换成简单的选通电路。这个特性在FPGA或者专用NPU上尤其明显具体后面会展开。1.2 三元权重与二值网络的区别很多人会把三元权重网络和二值网络混在一起其实区别很关键。二值网络比如经典的BNN把权重约束到只有{-1, 1}两个值几何上是一个立方体的两个顶点。这样表达能力强但信息容量有限因为所有权重都被强制站队没有中立选项。三元权重网络引入了0这个状态相当于给权重加了这个连接不重要可以断开的选项。别小看这个0它的意义非常大一方面0不会对激活产生任何贡献天然具有稀疏性很多不重要的连接会被直接置为0模型变得稀疏另一方面从信息论角度看三个状态比两个状态多出了log2(3)≈1.58比特的信息量表达能力更强。实验里通常三元网络的精度都会优于同结构的二值网络尤其是在ImageNet这个级别的大数据集上差距可能达到3到5个点。论文里还讨论了一个容易被忽略的点三值化之后的权重如果加上缩放因子会从纯{-1, 0, 1}变成{-α, 0, α}。这个缩放因子不是凭空拍的它是由层的统计信息算出来的目的是让三值权重的L2范数尽量接近原始全精度权重。这样做的好处是每一层的输出幅度不会因为量化发生剧烈偏移后面BN层和激活层也能更稳地工作。可以说三值化加缩放是这篇论文在二值网络基础上做出的核心改进之一。2. 核心方法拆解权重只做三选一为什么还能work2.1 三值化映射与缩放因子论文里最核心的数学表达可以归纳成三步先把原始实值权重W分成正负两个部分分别计算一个阈值Δ通常是按比例取均值或者百分位然后根据阈值把每个权重映射到-1、0或1最后对整个权重张量乘一个缩放因子α。具体来说常见的映射规则是这样的如果权重大于某个正阈值就变成1如果小于某个负阈值就变成-1介于两者之间的一律变成0。这里的阈值怎么定直接影响量化误差。论文推荐的做法是利用权重本身的正负分部来估算比如正阈值取正权重绝对值的均值负阈值取负权重绝对值的均值。但我在实际复现中发现用这种简单均值阈值在浅层网络里效果不错到了深层比如ResNet-50就不太稳定有人改用使量化前后L2误差最小的阈值搜索效果会更好。这个细节后面讲复现时再展开。缩放因子α的推导是论文里一个很精彩的地方。目标是让量化后的权重 { -α, 0, α } 尽可能接近原始全精度权重 W 的L2范数。经过推导最优的 α 可以取被置为非零的那些权重的绝对值的平均值。也就是说α不是全体权重的平均而是只对“被保留下来”的非零权重做平均。这背后的直觉是当你把一些权重清零时你损失了这部分信息为了让保留部分尽量接近原始贡献就应该用保留部分的平均强度去作为共同的缩放基准。这里我想用个生活化类比。就好比一个团队有的人是核心骨干、有的人是透明人。你不给透明人发任务只挑核心骨干干活那团队的产出水平就应该参考骨干的平均能力而不是全员平均α就是那个“骨干平均能力”。如果硬拿全员平均当基准骨干的能力会被拉低模型输出就偏弱了。2.2 训练中的梯度流通与阈值选择三值化的映射函数是一个分段常数函数导数几乎处处是0没法正常反向传播。论文的处理方式是前向传播时使用三值权重反向传播计算梯度时使用一个straight-through estimator式的梯度替代——本质上是把三值化这步当作恒等函数来处理让梯度能直接穿过量化操作。这在二值网络里已经是通用操作但放到三元上有一个额外注意点梯度虽然穿过但对那些被置为0的权重梯度是否应该更新需要谨慎处理。我在复现时试过两种做法。一种是对权重更新不做任何限制所有位置的梯度都反传另一种是只对被置为非零的权重回传梯度零权重位置梯度置0。论文没有刻意强调这一点但从收敛速度来看前一种方式更稳。原因是如果某个权重一开始被置0梯度也被屏蔽那它可能永远无法被激活模型就失去了学习新连接的能力。保留梯度穿过等于给每个连接留有复活的机会训练初期尤其重要。阈值Δ的设定还会直接影响梯度更新的分布。如果阈值过大大量权重被置0网络有效参数太少表达能力不足。阈值过小三值和二值就没什么区别0状态形同虚设。实践中常用比例阈值比如正阈值为正权重绝对值的0.5到0.7倍负阈值同理。但更稳妥的做法是把阈值也变成一个per-layer的可学习参数或者做阈值搜索。我后来在项目里改成按百分比截断把该层所有权重绝对值排序取第60到70百分位数作为阈值结果比均值法更稳定对网络深度不敏感。2.3 激活和权重的不对称处理论文还有一点值得注意它只对权重做三值化激活值仍然保留全精度。这一点和很多全量化方案不同。为什么这样设计因为权重的三值化可以直接压缩存储和卷积计算而激活值的量化会引入额外误差并且需要处理动态范围、统计分布等问题。作者选择先解决主要矛盾——权重存储和乘法计算激活量化留作后续工作。这并不意味着激活完全不受影响。由于权重变成了离散值卷积输出分布和全精度模型有明显差异。实际训练时要特别配合BN层使用这一点几乎成为所有极低比特量化网络的共识。BN会把每层输出重新拉回一个合理范围再交给激活函数否则三值权重的离散特性很容易让深层激活迅速膨胀或衰减。论文在实验部分也提到标准的BNReLU结构在三值权重下表现稳定。从计算角度看激活保持全精度反而给部署带来一定便利你只需要针对权重做特殊处理激活路径还可以沿用浮点或8比特整数的计算框架。在不少边缘芯片上8比特激活配合三值权重已经可以做到相当可观的加速。所以这个不对称不是偷懒而是一个务实的中间方案。3. 复现这篇论文时需要留意的关键细节3.1 网络骨架怎么选层间结构怎么搭论文里的实验主要在经典的深度卷积网络上进行比如VGG、ResNet这类结构。我在复现时发现骨架的选择对精度影响比想象中更大。原因很简单三值权重本身表达能力有限如果网络本身很浅或者通道数很少信息瓶颈会被进一步放大如果网络过深没有残差连接的话梯度消失问题也会提早暴露。优先推荐带残差连接的网络比如ResNet系列。残差连接给梯度提供了一条高速路让三值权重层即使梯度传导不畅也能保证底层参数正常更新。另外第一层卷积和最后全连接层是否量化也值得单独考虑。论文里通常第一层输入是原始图像RGB像素动态范围特点明显最后一层直接输出类别分数。这两个位置对精度影响很大很多复现实现会把它们保留为全精度换取更稳定的收敛。我在自己的任务上也验证了这个做法第一层不量化最终精度能高0.8到1.2个点。还有个容易被忽略的参数是卷积层的bias。权重被三值化了bias如果还保留实值计算过程反而多了一层浮点加法部署时并不友好。但训练时又需要bias去拟合偏移。我个人的建议是训练时保留bias做完整训练部署转换时再把它并到BN层的均值偏移里去获得纯整数加点。这样既不影响训练精度又能把模型简化到真正适合硬件的形式。3.2 优化器、学习率和BN层的配合三值网络对训练超参的敏感度要比全精度网络高不少。全精度模型用SGD从0.1的学习率开始跌到0.001就完事三值网络这么搞很容易在中途卡住。我在多次尝试后推荐使用带动量且多阶段衰减的学习率策略初始学习率要比全精度模型低一些比如全精度用0.1三值化之后用0.05或0.02然后分阶段指数衰减。为什么学习率要降低因为三值化引入了一个不可逆的离散化过程梯度更新虽然能穿过但更新后权重又要立刻重新三值化。如果学习率太大一个step就跨越很大距离权重反复在几个阈值边缘跳动模型永远落不到一个稳定的值附近。学习率小一些权重更新平滑三值化损失函数曲面上的抖动会小很多。BN层在三值网络里不仅是常规操作它几乎是不可或缺的稳定器。每个卷积层后面接BN训练时用batch统计量推理时用累计均值方差。这里有个坑BN的滑动平均动量要设置成比默认值更大比如0.99以上因为三值权重造成的激活分布波动比全精度大如果动量太小统计量的估计本身就抖动推理时误差会被放大。我看到不少复现翻车就是在这里没调好。3.3 从论文实验到本地数据集的迁移直接把论文里的超参搬到自己的数据集上通常不会得到论文报告的效果。论文的基线是ImageNet这种百万级大图类别多、每个类别样本数足够模型容量需求高因此三值网络即使有精度损失绝对值也不会太难看。但如果你在几千张图片的小数据集上做情况就完全不同了。小数据集上模型容量冗余较大量化带来的精度损失容易被过拟合掩盖。常见现象是训练集精度和全精度几乎一样验证集却掉了三四个点。这说明模型在三值化后泛化能力变弱需要在数据增强、正则化上补强。我的经验是加一点权重衰减L2正则通常有帮助因为三值权重本身已经离散化正则化不会像全精度那样直接限制参数大小而是通过梯度层面的作用影响哪些权重被激活。同时数据增强里稍微加一些随机裁剪和颜色抖动也能缓解量化网络的过拟合倾向。迁移时还要注意输入图像尺寸。论文用的224x224如果你的任务输入是32x32或64x64前几层的感受野占比完全不同。我建议至少保留论文主干结构但适当减少一开始卷积层的通道数比例比如通道数乘以0.75可以在精度损失不大的情况下进一步压缩。不过通道压缩要在量化之前做如果你一开始就压缩通道再叠加三值量化两个损失会相互放大这时候最好能用NAS或者手动搜索来平衡。4. 实测踩坑记录与问题排查4.1 梯度截断导致模型假死第一个我想说的坑是梯度传播中的假死现象。有人为了追求稀疏性在训练时对置0权重位置的梯度也做屏蔽结果模型训着训着大部分权重都被冻结成0训练损失下降得非常缓慢甚至停滞。这就是梯度被截断导致的网络假死。排查思路其实很简单打印每一层非零权重的比例如果某个比例在训练早期就迅速掉到10%以下并且不再回升那基本就是梯度屏蔽策略出了问题。解决方法也很直接恢复所有位置的梯度穿过操作并且适当调低权重衰减系数。我在这个坑上浪费过差不多一周时间现在每当有人说三值网络训练不收敛我第一反应就是让他检查梯度要不要屏蔽。4.2 BN统计量的滑动均值和推理结果不一致第二个坑非常隐蔽训练过程一切正常验证集上的loss也还在降但导出模型后一跑效果差很多。最后定位到是BN层的滑动平均动量设置的问题。我用的框架里BN默认momentum是0.1这个值对全精度网络没什么问题但三值网络的激活分布波动大0.1的动量意味着统计量更新太快历史信息被迅速覆盖。在训练后期一个batch的分布稍微偏离就会污染累计均值。推理时使用的是累计均值和训练时的瞬时分布不一致误差就这么累积出来了。后来我把momentum改成0.99同时增加训练末尾的BN校准步骤——用一部分训练数据重新计算各层均值方差再固化成推理参数。改了之后导出和在线评估结果基本一致。这个坑让我意识到三值网络部署链路里BN统计量的校准和固化应该作为标准操作而不是可选项。4.3 精度崩了该怎么一步步定位最后一个问题是最常见的明明照着论文做了精度还是掉了五个点以上。这时候不要慌按顺序排查。先看第一个卷积层和最后一个全连接层的量化设置把它们改为全精度看精度是否立刻回升。如果显著回升说明问题出在边界层而不是中间层。再看激活值分布打印每个卷积层的输出均值和方差和全精度模型对比。如果某层输出均值漂移特别大优先检查BN是否生效或者阈值是否对该层过激。最后逐层替换回全精度做消融实验。比如先把最后三层的三值权重换成全精度精度涨了说明误差主要来自后面如果没变化问题就在前段。这种消融定位法虽然耗时但比瞎调超参高效得多。我在一次项目中用这个方法发现真正让精度崩掉的是倒数第二层的阈值设得太宽松导致有效秩大幅下降和量化方式本身关系不大。5. 三元权重网络后续扩展和我的使用建议5.1 和低比特激活组合成伪全量化权重三值化只是第一步激活值保持全精度虽然省心但在真正的低功耗硬件事上激活的存储和计算仍然占大头。所以现在更常见的方案是把三值权重和低比特激活比如4比特、8比特搭配使用组成一种伪全量化模型。具体做法是训练阶段先把权重换成三值激活暂时保持float让模型先收敛到一个比较好的解。训练结束后再用校准集统计激活值的动态范围确定4比特或8比特的量化尺度把激活量化成整数。这样分两步走每一步的误差来源都是可控的。我在一个目标检测模型上试过权重三值加激活8比特精度损失只要1.5个点模型体积比FP32减少将近十倍实测推理速度在支持整数运算的芯片上有2到3倍提升。5.2 部署场景下的实际收益三元权重网络最大的应用场景是那些内存和功耗受限的边缘设备比如语音唤醒、小型图像分类、简单的物体检测。在这些场景下模型精度要求没有高到苛刻但延迟和体积非常敏感。我做过一个对比同样一个三层卷积小模型FP32版本大约1.2MB8比特量化后0.3MB三值权重后只有0.09MB而且因为权重只有-1/0/1卷积里大量乘法变成了加法甚至纯选通有些专用硬件可以直接把这一层的乘加阵列换成简单逻辑能效提升非常明显。论文里报告的理论压缩比是16倍我实测在排除文件格式开销后内存占用确实能压到原来的6%到8%但需要注意的是如果模型里还有全精度激活的中间结果缓存实际内存收益会打折。部署时要把中间激活的存储也一并规划才是真正的整体优化。5.3 后续可以尝试的改进方向我从这篇论文出发后期还试过几个扩展简单分享下。一是阈值和缩放因子的联合搜索。不要固定用均值法而是把它当成一个小的优化问题在训练集上按层搜索最优的阈值和α通常能带来0.5到1个点的精度提升。二是把三值权重和剪枝结合起来。既然是-1/0/1天然就有稀疏性可以在训练后对全零行做结构化剪枝进一步去掉冗余通道。我试过在最后几层做通道剪枝模型的FLOPs又能减少20%到30%。三是注意力机制和三元权重的适配。现在很多轻量网络都带SE模块或注意力分支这部分分支往往通道少、敏感度高直接三值化会掉点。比较稳妥的做法是先保留注意力分支为8比特把主干卷积做成三元工程上平衡性很好。最后说一点个人体会。三元权重网络不是那种让你白嫖压缩的技术它要求你对训练过程的每个细节都比较敏感。但只要把训练策略、阈值设定、BN统计量这些点都打磨到位它带来的收益真不是表面那点存储压缩而是计算范式的变化。如果你正在做边缘模型部署我建议不要只盯着8比特把三元权重这套思路吃透很多看不太懂的低比特优化文章回过头再读就顺了。以上是我围绕这篇论文的完整阅读笔记中间穿插了不少实际复现时的调整和踩坑记录。希望对正在研究模型量化的朋友有参考价值。如果你在复现过程中遇到别的坑也欢迎一起交流。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑