QAT伪量化 📅 发布时间:2026/9/1 5:04:29 👁 浏览次数: QAT伪量化QAT伪量化为什么可行你的理解和QAT真实逻辑差异你的直觉真实硬件推理流程输入浮点 → 量化转 int8权重浮点 → 量化转 int8int8 × int8 整数卷积/矩阵乘得到int32中间结果反量化/偏移缩放 → 输出int8全程算子内部全部整数运算没有浮点数。QAT训练里伪量化FakeQuant全程张量都是float只是模拟量化舍入截断没有真正转int。你疑惑点明明硬件跑整数训练却用浮点数模拟为什么能收敛、PTQ/QAT之后导出onnx给NPU还能跑对1. 先把量化公式写清楚对称量化公式xintround(xfloatscale),xqclip(xint,−128,127)x_{int}round\left(\frac{x_{float}}{scale}\right),\quad x_{q}clip(x_{int},-128,127)xintround(scalexfloat),xqclip(xint,−128,127)反量化x^floatxq⋅scale\hat{x}_{float}x_q \cdot scalex^floatxq⋅scale伪量化 quant dequant 的组合x^Dequant(Quant(x))\hat x Dequant(Quant(x))x^Dequant(Quant(x))输入是float输出还是float。相当于把数值压到离散的量化格点上但数据类型不变。硬件真实推理int8float_in → quant → int8 → conv(int8*int8) → int32 → requant → int8_out → dequant → float_outQAT伪量化前向PyTorchfloat_in → FakeQuant(quantdequant) → float已经落在量化格点→ conv(float * float) → FakeQuant → float_out 前向传播数值行为尽量贴近硬件但数据类型依旧float没有真正int8。2. 反向传播梯度怎么处理round是不可导这是伪量化存在的最核心原因。round()函数导数处处为0直接求导梯度直接死掉网络无法训练。QAT用直通估计器 STE(Straight‑Through Estimator)前向执行roundclip模拟量化噪声反向绕过round直接把梯度原样回传相当于梯度穿过FakeQuant节点∂x^∂x≈1\frac{\partial \hat x}{\partial x} \approx 1∂x∂x^≈1如果训练时真的把张量转成int8类型PyTorch整数张量无法计算梯度autograd直接失效网络完全不能更新权重。这就是训练阶段不能真转整数的根本约束。所以QAT不能真正做int8计算只能用浮点数模拟量化效果。3. 那为什么伪量化训练完导出给NPU跑真实int8可以对齐关键点QAT学习的是scale/zero_point以及权重在量化格点上的最优浮点位置。QAT训练阶段FakeQuant强制权重、激活只能取k * scale的离散浮点值训练结束后把权重直接round到对应整数格点Wint8round(Wfloat/scalew)W_{int8}round(W_{float}/scale_w)Wint8round(Wfloat/scalew)保存int8权重和scaleNPU推理时硬件复现完全一样的scale做真正int8整数乘加。只要训练时的scale、clip范围、round行为和硬件推理严格对齐伪量化训练得到的浮点权重round之后得到的int8权重就是最优的那一组整数权重。简单比喻伪量化训练在浮点数世界强迫参数只能站在整数格子对应的坐标点上训练训练结束直接把每个点取格子编号就是硬件要用的int8。4. 你的设想训练就全部用int8计算有没有这种东西有叫完全整数训练Integer‑only training但工程上很难落地整数的梯度、优化器Adam都需要浮点数优化器状态是float无法全部int整数动态范围窄梯度很容易溢出饱和目前NPU/地平线工具链主流只支持QAT伪量化流程。所以工业界不做训练时int8计算只做前向模拟量化噪声反向STE梯度近似。5. 容易踩坑伪量化与硬件不一致导致精度掉点很多人QAT做完精度崩就是FakeQuant和硬件行为对不上FakeQuant的clip范围、对称/非对称模式和NPU硬件的量化模式不一致requant重量化逻辑卷积输出int32如何缩放到int8QAT仿真和硬件算子实现有差异round模式PyTorch round是银行家舍入部分硬件是四舍五入激活的scale是逐tensor / per‑channel两边配置必须一模一样。地平线J6的QAT插件本质就是重写FakeQuant节点仿真J6硬件真实的量化舍入、截断、重量化行为保证导出ONNX之后NPU真实int8推理数值尽可能贴近QAT仿真输出。简短总结硬件推理确实是输入、权重转int8整数运算。QAT训练不能真转int8整数张量无法求导round不可导。伪量化FakeQuantquant(roundclip)dequantfloat模拟量化离散效应反向用STE直通估计器传梯度。训练收敛后权重/激活用训练得到scale做round得到真正int8交给硬件执行整数运算。QAT的全部价值让网络适应量化噪声学到在离散整数格点上最优的参数而不是训练阶段就跑整数计算。如果你需要我可以写一小段极简PyTorch伪量化STE的示例代码直观看到前向round、反向直通的行为。